Aprendiendo OOo Basic

Autor : Correo : Fecha : Licencia : Ultima modificación : Para ayudar :

Mauricio Baeza Servín mauricio (NO-SPAM) universolibre PUNTO org 15 de Septiembre del 2007 GNU Free Documentation License, v1.2 o posterior 22 de septiembre de 2009 Apoya este proyecto

Copyright (c) 2007 Mauricio Baeza Servin. Se concede permiso para copiar, distribuir y/o modificar este documento bajo los términos de la Licencia de Documentación Libre de GNU, Versión 1.2 o cualquier otra versión posterior publicada por la Free Software Foundation; sin Secciones Invariantes ni Textos de Cubierta Delantera ni Textos de Cubierta Trasera. Una copia de la licencia está incluida en la sección titulada GNU Free Documentation License.

Todo el código incluido en este libro esta bajo la siguiente licencia: Copyright (C) 2007 Mauricio Baeza Servín Este programa es software libre: usted puede redistribuirlo y/o modificarlo bajo los términos de la Licencia Pública General GNU publicada por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o (a su elección) cualquier versión posterior. Este programa se distribuye con la esperanza de que sea útil, pero SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública General GNU para obtener una información más detallada. Debería haber recibido una copia de la Licencia Pública General GNU junto a este programa. En caso contrario, consulte <http://www.gnu.org/licenses/>.

Aprendiendo OOo Basic

3

Índice de contenido
1 - Introducción.................................................................................................8 2 - Conceptos iniciales...................................................................................10 3 - Mi primer macro........................................................................................16 4 - El lenguaje OOo Basic..............................................................................23
4.1 - Declarando y usando variables..............................................................26 4.2 - Instrucciones y funciones en OOo Basic................................................32 4.3 - Constantes – Siempre lo mismo............................................................36 4.4 - Bifurcaciones – Tomando decisiones.....................................................36 4.5 - Bucles – Repitelo otra vez......................................................................39 4.6 - Matrices – Juntos pero no revueltos.......................................................47 4.7 - Ámbito de variables – Ahora me ves, ahora no......................................57 4.7.1 - Ámbito Local...................................................................................57 4.7.2 - Ámbito Privado...............................................................................60 4.7.3 - Ámbito de Dominio Publico.............................................................63 4.7.4 - Ámbito Global.................................................................................63 4.8 - Funciones y subrutinas – Divide y vencerás..........................................63 4.9 - Operadores............................................................................................74 4.9.1 - “ ^ ” Exponenciación (aritmético)....................................................74 4.9.2 - “ * ” Multiplicación (aritmético)........................................................76 4.9.3 - “ / ” División (aritmético)..................................................................77 4.9.4 - “ \ ” División entera (aritmético).......................................................78 4.9.5 - “Mod” Resto de una división entera (aritmético).............................79 4.9.6 - “ + ” Suma (aritmético)....................................................................80 4.9.7 - “ - ” Resta (aritmético).....................................................................81 4.9.8 - Operadores de relación..................................................................82 4.9.9 - Not – Negación (lógico)..................................................................82 4.9.10 - And – Y (lógico)............................................................................83 4.9.11 - Or – O (lógico)..............................................................................84 4.9.12 - Xor – O exclusiva (lógico).............................................................85 4.9.13 - Eqv – Equivalencia (opuesto a Xor) (lógico).................................86 4.9.14 - Imp – Implicación (lógico).............................................................86

4 4.9.15 - Precedencia de operadores..........................................................87 4.10 - Control de errores................................................................................89 4.11 - Validación de datos..............................................................................97 4.12 - El IDE – Mucho más que un editor.....................................................103

5 - Trabajando con OpenOffice.org..............................................................116
5.1 - Mis macros – un archivo especial........................................................117 5.2 - Asignando macros...............................................................................119 5.3 - Creando nuestro primer “servicio” (objeto)...........................................125 5.3.1 - Propiedades especiales de depuración........................................132 5.4 - Trabajando con documentos................................................................135 5.4.1 - Creando nuevos documentos.......................................................135 5.4.2 - Rutas de archivos y directorios.....................................................137 5.4.3 - Abriendo, guardando y cerrando documentos..............................138 5.4.4 - Exportando a PDF........................................................................146 5.4.5 - Tareas comunes en documentos..................................................147

6 - Trabajando con hojas de calculo – Calc.................................................150
6.1 - Trabajando con hojas...........................................................................150 6.1.1 - Insertando hojas...........................................................................155 6.1.2 - Borrando hojas.............................................................................157 6.1.3 - Moviendo hojas............................................................................158 6.1.4 - Copiando hojas.............................................................................161 6.1.5 - Renombrando hojas.....................................................................162 6.1.6 - Ocultando y mostrando hojas.......................................................164 6.1.7 - Protección y desprotección de hojas............................................165 6.2 - Referencia a rangos.............................................................................166 6.2.1 - Referencia a celdas individuales..................................................166 6.2.2 - Referencia a un rango de celdas..................................................168 6.2.3 - Referencia a varios rangos de celdas...........................................170 6.2.4 - Referencia a filas y columnas.......................................................172 6.2.5 - Referencia a la selección actual...................................................176 6.2.6 - Obteniendo información de rangos...............................................178 6.2.7 - Trabajando con Cursores.............................................................181 6.2.8 - Selecciones especiales................................................................188 6.3 - Manipulando rangos.............................................................................197

Aprendiendo OOo Basic

5

6.3.1 - Moviendo rangos..........................................................................197 6.3.2 - Insertando rangos.........................................................................201 6.3.3 - Eliminando rangos........................................................................203 6.3.4 - Copiando rangos..........................................................................205 6.4 - Manipulando datos...............................................................................209 6.4.1 - Obteniendo datos ........................................................................209 6.4.2 - Introduciendo datos......................................................................214 6.4.3 - Borrando datos.............................................................................217 6.4.4 - Llenando series de datos..............................................................219 6.4.5 - Buscar y reemplazar.....................................................................222 6.4.6 - Trabajando con notas...................................................................229 6.5 - Dando formato.....................................................................................233 6.5.1 - Formato de celdas........................................................................233 6.5.2 - Formato de filas y columnas.........................................................243 6.5.3 - Estilos y autoformato....................................................................246 6.5.4 - Formato de página.......................................................................254 6.5.5 - Formato condicional.....................................................................272 6.6 - Imprimiendo.........................................................................................277 6.7 - Rangos de datos..................................................................................285 6.7.1 - Definiendo rangos........................................................................286 6.7.2 - Ordenar datos...............................................................................288 6.7.3 - Filtrar datos...................................................................................292 6.7.4 - Subtotales....................................................................................305 6.7.5 - Validando datos............................................................................308 6.7.6 - Agrupando datos..........................................................................316 6.8 - Bases de datos....................................................................................323 6.8.1 - Importando datos..........................................................................326 6.8.2 - Insertando nuevos datos..............................................................338 6.8.3 - Actualizando datos.......................................................................343 6.8.4 - Borrando datos.............................................................................345 6.9 - Graficando datos..................................................................................346 6.10 - Trabajando con elementos gráficos...................................................371 6.10.1 - Trabajando con imágenes..........................................................371 6.10.2 - Trabajando con autoformas........................................................383
6.10.2.1 - Principales propiedades de línea...............................................385 6.10.2.2 - Principales propiedades de relleno............................................388

6
6.10.2.3 - Principales propiedades de sombra..........................................394 6.10.2.4 - Otras propiedades de las autoformas........................................395 6.10.2.5 - Agrupando y desagrupando formas..........................................397 6.10.2.6 - Trabajando con FontWork.........................................................399 6.10.2.7 - Propiedades particulares de algunas formas............................401

6.11 - Funciones personalizadas..................................................................405 6.12 - Configuración global de Calc.............................................................411

7 - Trabajando con formularios....................................................................418
7.1 - Formularios (Forms).............................................................................418 7.2 - Etiquetas (Label)..................................................................................422 7.3 - Cuadros de texto (TextBox).................................................................424 7.4 - Casilla de verificación (CheckBox).......................................................429 7.5 - Campo formateado (FormattedField)...................................................431 7.6 - Botón de comando (CommandButton).................................................432 7.7 - Botón de opción (OptionButton)...........................................................433 7.8 - Cuadro de lista (ListBox)......................................................................436 7.9 - Cuadro combinado (ComboBox)..........................................................443 7.10 - Botón de selección (SpinButton)........................................................445 7.11 - Barra de desplazamiento (ScrollBar)..................................................446 7.12 - Otros controles...................................................................................447 7.12.1 - Botón gráfico (ImageButton).......................................................448 7.12.2 - Control de imagen (ImageControl)..............................................449 7.12.3 - Selección de archivo (FileSelection)...........................................449 7.12.4 - Campo de fecha (DateField).......................................................451 7.12.5 - Campo de hora (TimeField)........................................................452 7.12.6 - Campo numérico (NumericField)................................................454 7.12.7 - Campo moneda (CurrencyField).................................................455 7.12.8 - Campo enmascarado (PatternField)...........................................456 7.12.9 - Cuadro de grupo (GroupBox).....................................................458 7.12.10 - Control de tablas (TableControl)...............................................458 7.12.11 - Barra de navegación.................................................................459

8 - Trabajando con cuadros de dialogo.......................................................461 9 - Trabajando con eventos.........................................................................462

Aprendiendo OOo Basic

7

- Hemos llegado a un tema central en la programación de OOo, central por que una gran parte de la programación en OOo, tiene que responder a la pregunta ¿cuando?, ¿cuando queremos que se ejecute una macro?, .........462

10 - Apéndices.............................................................................................463
10.1 - Seguridad en macros.........................................................................463 10.2 - Errores más comunes en tiempo de diseño.......................................465 10.3 - Instalando SDK..................................................................................476 10.4 - Mostrar información de un objeto en un archivo de Calc....................478 10.5 - Formulas de Calc español-ingles.......................................................479 10.6 - Listar fuentes en un archivo de Calc..................................................486 10.7 - Listar formatos en un archivo de Calc................................................488

11 - Bibliografía............................................................................................490 12 - Índice Alfabético....................................................................................491

8

1 Introducción

1 Introducción

"Quien recibe una idea de mí, recibe instrucción sin disminuir la mía; igual que quien enciende su vela con la mía, recibe luz sin que yo quede a oscuras" Thomas Jefferson

¿Así que quieres aprender a programar en OOo Basic? Bien, pues yo también, y ese es un buen interés común y buen comienzo. No se si llegaste al lugar indicado, ya me lo contaras. Sabe de antemano que soy un programador autodidacta que reconoce que tiene vicios de los cuales tal vez no me doy cuenta, espero y deseo, que algún buen samaritano que se encuentre con estas notas me ayude a identificarlos. Estos apuntes no tienen otro propósito que compartir mi experiencia al ir experimentando con este maravilloso programa llamado OpenOffice.org y por supuesto, con su lenguaje de macros OOo Basic, una experiencia sumamente placentera. Me decidí a aventurarme a escribir, por la falta de documentación en español para programar con OOo Basic, a base de paciencia y disciplina he ido profundizado en el dominio del lenguaje, creo que puedo ayudarte a que tu curva de aprendizaje no sea tan larga como la mía, si se cumple este segundo y sencillo propósito, el tiempo y esfuerzo invertido, bien habrán valido la pena, así que, como dicen en mi pueblo -sobre advertencia no hay engaño-, adelante, empecemos... La versión de OpenOffice.org que utilizo para escribir estas notas y mostrarte los ejemplos de programación, normalmente es la ultima estable (3.1 en este momento) descargada directamente desde http://es.openoffice.org, esto es por que algunas distribuciones GNU/Linux, compilan sus propias versiones, casi todas “deberían” de trabajar de forma satisfactoria, pero te recomiendo bajar e instalar la oficial para que nos entendamos mejor. Daré por sentado que esta versión es también con la que trabajas, no te garantizo que los ejemplos mostrados aquí funcionen con otras versiones, de hecho no te garantizo que funcionen con ninguna, ojo, no me malinterpretes, es tan alta la cantidad de equipos, sistemas y configuraciones diferentes, que es cuestión software es difícil garantizar algo y si lo dudas, leete alguna de las muchas licencias de software que hay en el mercado, incluyendo por supuesto, las de software libre. Lo que si te puedo asegurar, es que cada uno de los ejemplos que te muestro los he probado más de una vez antes de darlos por buenos, así que en general espero no tengas problemas con ellos. También, es importante que sepas, que trabajo sobre GNU/Linux en varias distribuciones (por ahora) ArchLinux (http://archlinux-es.org), aunque continuamente y más seguido de lo que te imaginas cambio de distribución, pues aun no puedo abandonar esa manía de probar y experimentar (y a veces suicidarte), tanto las nuevas distribuciones como las nuevas versiones de las ya existentes, por lo que las interfaces podrían variar un poco con respecto al sistema operativo (S.O.) que usas, por ejemplo Mac/OS o Windows u otro, aunque espero que esto no sea un problema pues en si lo único que cambia es la decoración de las ventanas, lo demás, “debería” ser igual en la mayoría de los casos, no obstante no esta de más que al enviar una consulta especifiques la versión de OOo que usas y el S.O. donde trabajas, aunque claro, como no habría de recomendartelo, que esperas para probar alguna de las decenas de distribuciones GNU/Linux existentes, seguro que alguna se adapta a tu gusto y forma de trabajar, por lo menos, no dejes de intentarlo. Este documento esta en constante crecimiento, puedes verificar la ultima versión en: www.universolibre.org, como eres libre de distribuirlo, si te parece que lo merece, te invito a que hables de el y lo difundas, y si no te gusta, pues no seas chismoso.

Aprendiendo OOo Basic

9

Para comentarios, notificación de errores, sugerencias, colaboraciones y dudas puedes usar las siguientes alternativas:  Presionar la tecla F1 ayuda mucho, antes de escribir para dudas, asegúrate que: • No esta resuelta en estas notas • No esta resuelta en la ayuda • No se ha comentado en las listas de correo • ¿Ya realizaste una consulta en tu buscador favorito? • Y lo más importante, que hayas tratado de resolverlo por ti mismo  De preferencia, plantea tus dudas en las listas y no a mi correo, estoy en la mejor disposición de ayudarte, pero recuerda que tu duda, tal vez otros la tengan, y si se publica en alguna lista o foro, la posible respuesta también le podrá servir a mas de uno, si aun así, deseas escribirme, procura ser lo mas claro posible en tu exposición y aunque procuro contestar siempre, no te garantizo una respuesta inmediata pues a parte de escribir estas notas, tengo otras varias actividades que tal vez no sean de tu interés, pero que consumen un poco de mi tiempo, agradezco tu comprensión al respecto.  Inscribete a cualquiera de las siguientes listas de correo, de preferencia a las dos, pues en las dos participo constantemente. Para enviar mensajes users@es.openoffice.org ooobasic_es@egrupos.net Para subscribirse users-subscribe@es.openoffice.org http://www.egrupos.net/grupo/ooobasic_es/alta

Procuro participar en el foro oficial de macros: Foro de Macros en Español

 Estas notas son posibles gracias a la generosidad de la gran comunidad OpenOffice.org en todo el mundo y por supuesto a la comunidad mundial del software libre, es decir, a las personas que “todos los días” desarrollan, usan y difunden el software libre.

Dedico este trabajo a las personas que me aman sin su amor, no seria lo que soy.. .

10

2 Conceptos iniciales

2 Conceptos iniciales
Como soy una persona floja, tal vez pienses que no me gusta trabajar y estarás en lo correcto, por ello, cuando descubrí lo que se podía hacer con los lenguajes de programación, comprendí que esto es lo que necesitaba (y lo que me gustaba), los lenguajes de programación nos permiten hacer que la computadora haga por nosotros, esas tareas complejas, repetitivas y tediosas (también las divertidas), en estos apuntes, trataremos de aprender como hacer en OpenOffice.org, esas tareas complejas, repetitivas y tediosas con uno de sus varios lenguajes con los que se puede programar en el, me refiero claro esta, al OOo Basic. Las instrucciones que usamos para decirle al programa que hacer, como, cuando, el orden y la secuencia en que queremos que lo haga, las llamaremos MACROS, estas macros podemos hacerlas de forma "semiautomática" con la Grabadora de macros (por ahora solo presente en Writer y Calc) o escribirlas nosotros desde cero (podemos crearlas desde todas las aplicaciones de OpenOffice.org), a mi criterio, a esta grabadora todavía le falta madurar un poco, por lo cual, crearemos nuestras macros desde cero, veras que no es tan complicado y si, muy divertido. Lo primero que tienes que aprender (y recordar) es que las macros se guardan en módulos, estos a su vez se guardan y organizan en bibliotecas, las cuales, están contenidas dentro de documentos, con lo cual tendremos el siguiente diagrama, por cierto, hecho en Draw.

. asegurate de que dentro del cuadro de lista desplegable Ubicación.. pero no puedes eliminarla. Empecemos con lo divertido.ods". En la siguiente imagen puedes ver un documento (1) con una biblioteca (2). un modulo (3) y dos macros (4).Aprendiendo OOo Basic 11 Todos los documentos.org Basic. este seleccionado el . da un clic en la ficha Bibliotecas. a esta biblioteca le puedes agregar y eliminar módulos. presiona el botón de comando Administrar Al mostrarte el siguiente cuadro de dialogo. Ve al menú Herramientas | Macros | Organizar macros | OpenOffice. para nuestros fines usaremos el nombre "Ejemplos de macros. además de macros. Te mostrara el siguiente cuadro de dialogo. mas adelante veremos y aprenderemos que los módulos también. tal como esta y el cual nos servirá para guardar las macros que vayamos creando: Abre Calc (puedes usar cualquier otra aplicación de OpenOffice. pueden contener "funciones". crearemos el archivo que te muestro en la imagen anterior. y los documentos también pueden contener "diálogos".org) y guarda el documento nuevo en el lugar y con el nombre que consideres. tienen una biblioteca especial predeterminada llamada Standard.

presiona el botón de comando Nuevo. tras lo cual te mostrara un cuadro de dialogo.ods Inmediatamente después. notaras que la nueva biblioteca se agrego a la lista. regresa a la ficha Módulos y observa que automáticamente a la nueva biblioteca se le anexo un modulo nuevo llamado Module1. el documento de Calc. tal ves tengas que dar clic en el botón expandir representado por un signo de suma (+) a la izquierda del nombre del documento. si no lo vez. la cual llamaremos miBiblioteca. .12 2 Conceptos iniciales documento al que le anexaremos la nueva biblioteca. Ejemplos de macros. ahora. Da un clic en el botón de comando Cerrar para regresar al anterior cuadro de dialogo. en nuestro caso. Después de dar clic en Aceptar. solicitando el nombre de la nueva biblioteca.

una macro nueva y vacía con el nombre de Main. lo que veas tiene que ser igual o muy parecido a la siguiente ilustración. este crea de forma predeterminada. te abrirá una nueva ventana.Aprendiendo OOo Basic 13 Ahora. esta nueva ventana de hecho es una nueva aplicación. para lo cual. pues ella nos permitirá escribir todas las macros que nos permita nuestro tiempo e imaginación. esto lo logras con el icono del símbolo mas (+) que esta a la izquierda del nombre del documento. observa que también en la lista de macros. esta aplicación. cuando agregamos un nuevo modulo. da un clic en el botón de comando Editar. como lo haremos a continuación. recibe el nombre de Entorno de Desarrollo Integrado (IDE por sus siglas en ingles) y es muy “importante que te familiarices con el” lo mas posible. una aplicación muy especial. aparece ya una con el nombre de Main (elipse roja). del mismo modo que al agregar una nueva biblioteca esta aparece con un nuevo modulo llamado de forma predeterminada Module1. la cual será el centro de trabajo de "todo" lo que hagamos en OOo Basic. lo . un nombre que te resultara familiar si alguna vez programaste en C. pero se pueden cambiar cuando quieras. Al dar clic en Editar. Estos nombres vienen predeterminados. despliega los elementos de nuestro documento.

14 2 Conceptos iniciales cual. o da un clic en el conocido icono de Guardar. da un clic con el botón secundario de tu ratón (normalmente el botón secundario es el derecho) sobre la ficha que muestra el nombre actual (2). como en la mayor parte de los programas de computo. la que mejor te convenga o guste y guarda tu documento.. nos los mostraría en fichas contiguas a este. puedes reemplazar este nombre por el que quieras (bueno. da un clic en ella y el cursor de escritura (el que parpadea) se posicionara al final del nombre actual del modulo. que. para nuestro ejercicio le llamaremos miModulo. esta área en realidad es un editor de textos. . para terminar nuestro primer ejercicio. cambiemos el nombre del modulo. hay mas de una manera de hacer la misma acción. te mostrara un menú contextual entre cuyas opciones veras Cambiar nombre. ya sea con el nombre propuesto o con el que consideres correcto. veremos las restricciones al respecto). al terminar presiona la tecla {Enter} para aceptar el cambio o simplemente activa el área de escritura de código (3) con un clic. con lo cual lograremos seleccionar la palabra completa. más adelante.. para continuar con nuestro ejercicio escribiremos Mi_Primer_Macro. por ultimo. Observa como nos muestra el nombre del documento en donde nos encontramos. ahora. en caso de que hubiese más. así como el nombre de la biblioteca en la que estamos trabajando (1). usa. Main (3) Como siguiente paso. puedes cambiarlo por el que quieras. salvo un pequeño cambio (que ya notaste) quedo igual al que propusimos al inicio de estas notas. o presiona la combinación de teclas CRTL+G. el nombre del modulo activo actualmente (2). ve al menú Archivo | Guardar. nos muestra. afortunadamente se da como consecuencia intrínseca de programar en OOo Basic. da un doble clic a la palabra Main. Por ultimo. ve al menú Herramientas | Macros | Organizar macros | OpenOffice. casi por el que quieras. En esta misma ventana. para ello. y comprueba que lo que tienes es bastante similar a la imagen siguiente.org Basic. observa la macro mencionada en el inciso anterior. pero un editor con muchas características especiales que iremos conociendo poco a poco.

no es cierto. •Practicar mucho •Agregar y eliminar módulos a diferentes bibliotecas. conste que solo lo pretendo. •!Ah¡ y practica mucho. así que tu tarea es: mucho •Agregar y eliminar bibliotecas a diferentes documentos de OpenOffice. también puedes enviarme tus problemas existenciales.001% de lo que pretendo. •Practicar mucho •Envíame tus comentarios. tienen algunos controles mas. espero que si. trata de investigar para que sirven o cual es su función. que soy un profesor que deja mucha tarea. como un servicio agregado. con esto cubrimos el 0. siento mucho decirte y confesarte. tan tan y hasta pronto.. una macro no puede ir dentro de otra. como consejo. •Practicar . quejas y dudas.Aprendiendo OOo Basic 15 ¿Te gusto el curso?. Para finalizar este capitulo y esta noche (ya me canse). No. •Practicar mucho •Observar como esta estructurada nuestra primer macro y tratar de hacer mas. •Practicar mucho •Los cuadro de dialogo vistos hasta ahora.org.. eso es todo. impresiones.

org Basic. Abre tu archivo de trabajo. cuando abres un archivo de OpenOffice. te mostrara el siguiente aviso de seguridad.16 3 Mi primer macro 3 Mi primer macro Ahora que ya sabes donde crearemos nuestras macros. Ve al menú Herramientas | Macros | Organizar macros | OpenOffice.. Puede ser que no te muestre este mensaje y te abra el archivo directamente con las macros deshabilitadas. si has seguido estas notas. empecemos con ellas. Con la acción anterior. más adelante aprenderemos a evitar este mensaje para los archivos que sabemos son seguros. escribir código. daré por hecho.. tu biblioteca y tu modulo..y navega hasta tu documento. si este es tu caso. es un documento de Calc nombrado Ejemplos de macros.. es bastante claro. que ya lo dominas. inmediatamente después de seleccionar la macro que lleva por nombre Mi_Primer_Macro. que creo. De forma predeterminada. es la forma que usaremos para acceder a la edición de cualquier macro vista en estas notas. nuestro archivo. Por supuesto. Esta serie de acciones. es decir. para poder trabajar correctamente tienes que habilitar las macros.ods. de aquí en adelante. presiona el botón de comando Editar. decirle al programa que .org que contiene macros. por lo cual. te abrirá el Entorno de desarrollo (de aquí en adelante IDE) y este es el punto interesante y el más divertido.1 Seguridad en macros. tienes que cambiar el nivel de seguridad como te muestro en 7.

"ejecuta". es una "instrucción" de OOo Basic. ¿que mensaje?. tendrás que ver el cuadro de mensaje que te mostré lineas arriba. muestra un "mensaje" en un cuadro de dialogo.. empezaremos con un clásico. en el caso de esta "palabra clave o reservada" (llamada así. recuerda esto bien.Aprendiendo OOo Basic 17 haga lo que queramos. presiona el botón de ejecución (circulo rojo en la imagen anterior) o presiona la tecla {F5} y listo. como habrás notado (por que de aquí en adelante tendrás que ser muy observador). "hace". Y para lograrlo. en conjunto con el IDE. ya eres todo un programador. pero espera. es decir.. que realice su trabajo. asegurate de escribirla o copiarla tal cual: MsgBox "¡¡Hola Mundo!!" De modo que quede de la siguiente manera: Ahora. solo te falta el saber el "porque". es decir.. cuando queramos y como queramos. lo ideal es saber "como" y "por qué". pues ya sabes el "como". no eres todavía un programador completo. para no salirnos de los "santos cánones" de la programación. una palabra especial. analicemos la linea que acabamos de agregarle a nuestra macro: MsgBox "¡¡Hola Mundo!!" La primer palabra. por que “solo” OOo Basic puede hacer uso de ella. para "ejecutar" la macro. una tarea especifica. para lograr lo que decía mi entrañable profesor de topografía: El hombre teórico sabe "por qué". el mensaje que muestra es .. el hombre practico sabe el "cómo". que el lenguaje. Para entender el "¿por qué?". agrega la siguiente linea a la macro. reconoce de modo especial y "realiza". ¡Felicidades!. solo OOo Basic la puede usar) MsgBox.

así como todos los programadores con los que compartas tu código. así: REM Muestra un mensaje en un cuadro de dialogo MsgBox "¡¡Hola Mundo!!" Los comentarios. si decides que sea software libre. y sencillamente lo que "hace". si has seguido al pie de la letra. y que. procura comentar la mayor parte de tu código. es decir. comentar las lineas de código es una practica sumamente útil. de modo que te quede. es decirle al programa (nuestra macro). el lenguaje se lo saltara olímpicamente sin hacerle caso. al final de la linea de código: MsgBox "¡¡Hola Mundo!!" REM Muestra un mensaje.. como te recomiendo que sea. -siempre comenta tus lineas de código-. de dialogo Reitero. Así que ve al código de nuestra macro y comenta la linea que le agregaste. Ahora veamos la linea donde inicia nuestra macro: Sub Mi_Primer_Macro .. MsgBox 1234567890 MsgBox 15/01/1974 MsgBox 1dfgdfh245 Realiza todos los experimentos que quieras y me cuentas que sucede. tu memoria te lo agradecerá. lo tenemos que hacer entre comillas y separada de la instrucción por un espacio.. y como es una "cadena" de texto. Observa la primer linea de la macro que acabas de hacer. también puedes establecerlos con una comilla simple (') 'Muestra un mensaje en un cuadro de dialogo MsgBox "¡¡Hola Mundo!!" Ademas. es un comentario.. que todo lo haya después de esta palabra. podemos agregarlos. como una regla.dialogo MsgBox "¡¡Hola Mundo!!" 'Muestra un mensaje. asume esta recomendación. ¿y con fechas o algun otro valor?. pero como nosotros somo “amateur” haremos caso omiso de ese comentario.. no tendrías que haber modificado: REM ***** BASIC ***** La primer palabra . sobre todo. pues como dijo alguna vez Ling Yu Tan -me gusta la gente amateur-. así que. también es una palabra clave de OOo Basic.18 3 Mi primer macro el que "nosotros" le indicamos delante de ella. por ahí leí en algún foro que un código bien escrito y profesional no necesitaba comentarios.. cuando las macros van creciendo de tamaño y complejidad. ¿sucederá lo mismo con números?. "casi".

al ejecutar. Gram. para identificarla. que por ahora. te mostrara un mensaje. 1. de συντάσσειν. en nuestro caso le pusimos: Mi_Primer_Macro. Parte de la gramática que enseña a coordinar y unir las palabras para formar las oraciones y expresar conceptos. coordinar). la cual nos sirve para definir una "subrutina". o sea. Inform. f.Aprendiendo OOo Basic 19 Como se que eres observador. y este del gr. si lo hace. como también se les conoce a las macros. efectivamente. σύνταξις. le asignamos un nombre. (Del lat. syntaxis. si. "sintaxis". te mostrara el siguiente mensaje de error: •NO Observa la primer linea de los mensajes de las dos imágenes anteriores. quiere decir: sintaxis. no puede haber dos que se llamen igual. dentro del modulo en que se declara. no analizaremos. si nos atenemos a lo que dice la Doña Real Academia Española. nombre que: puede llevar espacios. pero recuerdalo para más adelante. ya habrás deducido que la primer palabra. que. 2. es una palabra clave de OOo Basic. si tratas de hacer lo anterior. Conjunto de reglas que definen las secuencias correctas de los . aquí. la palabra importante es. te mostrara el siguiente mensaje de error: debe repetirse el nombre de la macro. si lo haces. las dos son iguales -Error de sintaxis de BASIC-. •NO •NO puede iniciar con un número. f.

como en el siguiente ejemplo. ni tan complejas y como seguro habrás notado. pero por puro gusto y también. cada línea de código y. son bastante explicitas. el IDE nos informa muchas veces cuando implementamos mal. es decir. para terminar este capitulo. las cuales. esto es muy útil cuando se esta programando. Real Academia Española © Todos los derechos reservados De estas definiciones. puedes tener varias sentencias en una sola línea. pero recuerda que sigue siendo la misma sentencia: Sub LineasLargas() MsgBox "Estas es una linea larga de codigo. Para finalizar este capitulo. como las llamaremos de aquí en adelante. no son tantas. trata de recordarla -Conjunto de reglas que definen las secuencias correctas de los elementos de un lenguaje de programación-. uso la siguiente combinación de colores: para las palabras claves • Verde para los comentarios • Rojo para los números Rojo obscuro para las cadenas de texto • Negro para todo lo demás • Azul • Aquí un ejemplo de como se mostraría el código con esta combinación de colores: Option Explicit Rem Pruebas de comentario . puedes usar el carácter de continuación de línea. si las separas con dos puntos. pues en las siguientes páginas."Ejemplo " & _ "de linea larga" End Sub Y ahora si. observa que el IDE nos muestra diferentes colores en las palabras. analicemos la ultima y muy sencilla linea de nuestra macro: End Sub Si.20 3 Mi primer macro elementos de un lenguaje de programación. este conjunto de reglas. el lenguaje lo reconocerá como una sentencia de OOo Basic. 0 . nos indican el final de nuestro "programa". como en: Sub VariasSentencias() MsgBox "Estas es una sentencia" : MsgBox "Esta es otra sentencia" End Sub En sentencias largas. que es el guion bajo _. creo. trataremos de aprender e implementar este conjunto de reglas. como en este ejemplo". cuando comúnmente hacemos mal uso de la “sintaxis” de Ooo Basic. Entonces. las dos son palabras claves del lenguaje y también. te confesaré. como una herencia del VBA (aunque también pesa el hecho de tener una macro ya hecha que convierte estos colores en formato HTML). lo confieso. "subrutina" o "macro". se puede dividir " & _ "usando el guion bajo. la que nos interesa es la numero dos. hasta donde se encuentre un salto de línea.

tienes que recordar que para OOo Basic. "debería" de funcionar igual con: •minúsculas sub mi_primer_macro msgbox "¡¡Hola Mundo!!" end sub •MAYUSCULAS SUB MI_PRIMER_MACRO MSGBOX "¡¡Hola Mundo!!" END SUB de ambas. en OpenOffice.. Esta es la de a de veras. para terminar este capitulo.. con el uso y la practica. para que quede de la siguiente manera Recuerda que esto es solo una recomendación. Sub Mi_Primer_Macro •Combinación . que es la forma mas común y la forma que yo usare a todo lo largo de estas notas. o una combinación de ambas. tu. es decir. como nuestro original. no dudes ni un momento en establecer los colores que más te agraden. es indistinto el uso de MAYUSCULAS o minúsculas. ahora si. ve al menú Herramientas | Opciones. si no. nuestra macro. decidirás si es así como te gusta.org escoge Representación. gusten o simplemente te den la gana que para eso es la libertad.Aprendiendo OOo Basic 21 Sub Pruebas(ByVal Pal As String) ' comentario Dim intNum As Integer intNum = 10 + 10 MsgBox "Prueba" 'comentario End Sub Para configurar estos u otros colores que sean de tu agrado.

así que: • • • • • Practica mucho. Envíame tus comentarios. . no te iguala las palabras a mayúsculas o minúsculas (todavía).22 MsgBox "¡¡Hola Mundo!!" End Sub 3 Mi primer macro El IDE. te ayuda mucho a mejorar tu mecanografía. Practica mucho. pero esto. Investiga mas acerca de la instrucción MsgBox. aportes y dudas. a ser mejor observador. Practica mucho. no hace una autocorrección de las palabras. presionar {F1} "ayuda" mucho.

ahora es el momento. si tienes como primer macro alguna otra. Y cada vez que trates de ejecutar. escribiré todo mi código. por que cada nueva instrucción que aprendamos. es correcto.. su facilidad y sencillez. solo se ejecutara la que se llama Mi_Primer_Macro. agrega una tercer macro: Sub MiTercerMacro 'Lo que quieras MsgBox "OOo Basic es fácil y divertido" End Sub Observaciones (¿recuerdas que íbamos a ser observadores?. por que revisa la sintaxis.Aprendiendo OOo Basic 23 4 El lenguaje OOo Basic OOo Basic. ¿es correcto?. presiona {F5} y observa muy bien que sucede. comparte con ellos la mayor parte de su sintaxis. solamente te mostrara: . ya no use guiones para separar las palabras. esta será la que se ejecute. la tienes que probar "dentro" de una macro. ¿ya?. aquí esta: Sub Mi_Segunda_Macro 'Algo más interesante MsgBox "¡Hola Nena!" End Sub Y ya encarrilados. repacemos una vez mas esto. ser buen observador es una excelente virtud en un programador): En la tercer macro. ¿verdad?. esto es importante que lo domines bien. cada vez que "ejecutamos" la macro. así que para que no haya excusas. si. vamos a escribir nuestra segunda macro. Supongo que has ido probando cada macro. por ahora. para nuestros fines. respuesta. forma parte de la familia de lenguajes Basic. esta es más que suficiente. no entraremos aquí en disquisiciones filosóficas de su historia o diferencia con otros "sabores" Basic. en el nombre. daré por entendido que así es. El IDE. me limitare a mostrarte el uso de su sintaxis lo mas claramente que me sea posible. a OOo Basic se le denomina un "lenguaje interpretado". uno de los requisitos es que el nombre "no" lleve espacios. en la que usamos la técnica denominada de "camello". es muy sencilla la explicación. si no es así. esta es la forma en que de aquí en adelante.. por ello. pues que de aquí en adelante. "solo". El IDE. creo que es bastante obvio ¿por que?. Ahora ya conoces donde inicia y donde termina una macro. se encarga de revisar la correcta "sintaxis" (recordando que sintaxis es un "conjunto de reglas") de cada línea que nosotros escribamos. así que si tienes las tres macros que hemos hecho. La estructura básica para una macro es: Sub Nombre_de_la_Macro REM Aquí van todas las instrucciones que queramos End Sub Por supuesto existen más variantes. ejecuta la primer macro que este en el módulo activo. Claro. ya la habrás deducido. como nombrarla y como ejecutarla. así que esta bien escrito MiTercerMacro. procurando que los ejemplos sean tu principal fuente de consulta.

esto me parece bien. ahora si vemos lo que queremos ver: . pero todavía no esta implementado en la distribución oficial. he notado que la macro que se ejecuta al presionar F5. Del cuadro de dialogo que te muestra. Como diría un buen amigo -ansina si-. ve a la barra de herramientas y da un clic en el icono Seleccionar macro.24 4 El lenguaje OOo Basic En algunas distribuciones Linux. es la macro donde este el cursor de escritura en ese momento. Para ejecutar la macro que quieras. escoges la macro que desees y presiona el botón Ejecutar.

observa como es tan sencillo como escribir el nombre correcto de la macro que deseamos "llamar". es que puedes "llamar" a más de una macro.. por ejemplo. desde esta. "llamar" a una macro. y. desde otra. Sub Pruebas Mi_Primer_Macro . es crear una primer macro que se llame por ejemplo: Pruebas.. Sub Pruebas Mi_Primer_Macro End Sub Para llamar a la segunda macro seria así: Sub Pruebas Mi_Segunda_Macro End Sub Tu haces la tercera. Lo interesante. desde otra. así quedarían nuestras macros: REM ***** BASIC ***** Sub Pruebas Mi_Primer_Macro End Sub Sub Mi_Primer_Macro 'Todo un clásico MsgBox "¡Hola Mundo!" End Sub Sub Mi_Segunda_Macro 'Algo mas interesante MsgBox "¡Hola Nena!" End Sub Sub MiTercerMacro 'Lo que quieras MsgBox "OOo Basic es fácil y divertido" End Sub Y esto. es algo que tendrás que dominar muy bien. "llamar" a las otras.Aprendiendo OOo Basic 25 Y la tercera también: Otra técnica para ejecutar la macro que sea.

puede dividirse en partes simples- 4.1 Declarando y usando variables Cada vez que programes tus macros. el resultado es el mismo: Sub Pruebas Call Mi_Primer_Macro Call Mi_Segunda_Macro End Sub Se que tendríamos que escribir el nombre de la macro a llamar para probar la que deseamos cada vez que la necesitamos. ademas. recuerda el siguiente sencillo diagrama: Si analizas cada programa de computo que usas. cumple el flujo anterior. más adelante. de la siguiente manera. cada uno de estos tres pasos los podemos dividir en muchos más. es usando la instrucción Call. pero recuerda que solo es de prueba. Descartes -todo lo complejo. tal vez podríamos obtener además del número de letras o palabras: •El día de la semana en que nació •Cuantos días lleva vivo •Cuantos años tiene •Cuantas vocales tiene el nombre •¿Se te ocurren otra “información” que puedas obtener? .26 Mi_Segunda_Macro End Sub 4 El lenguaje OOo Basic Otra forma de "llamar" a otras macros. veamos un sencillo ejemplo: •Solicitamos que el usuario capture su nombre completo (Entrada) •Contamos el número de letras (o palabras) que contiene (Proceso) •Mostramos el resultado obtenido (Visualización) Ahora. veras que en mayor o menor medida. que pasa si ademas del nombre solicitamos que capture su fecha de nacimiento. pero esa división tu mismo la iras notando y desglosando conforme profundices en este o cualquier otro lenguaje. veras que este ultimo método de pruebas es mejor que el primero y que esto nos sirve como afirmación de lo que decía el Sr. cuando aprendamos más opciones de como declarar y usar macros.

Variable = Dato Veamos un ejemplo de esto. en la llamada memoria RAM. De acuerdo a los dos diagramas anteriores. algunos textos también la nombran como “marcador”. todo este “rollo” lleva un fin. los datos que obtengamos los guardamos “temporalmente” en variables. manipulan eficientemente los datos para darnos “información” y entre el flujo de los datos a la “información”. vamos a solicitarle al usuario que nos proporcione su nombre. no en nuestra memoria. normalmente solo provee de “velocidad” y tu. resumiendo. pero estos temas iniciales son determinantes para comprender todo lo que venga después. existen dos entes que son determinantes para la calidad de la información obtenida. tendremos que poner en algún lugar para poder tenerla disponible y para poder manipularla. esto es importante. la cual. ya sea traerlos de algún lado o solicitarlos al usuario. a esta área que estamos nombrando. el inicio de toda “macro” (o programa). es en memoria. el primer lugar donde tenemos que aprender a guardar datos. creo que casi cualquier persona que usa computadoras. podemos obtener mucha “información”. sabe que una función. que pone toda su inteligencia. veamos cual es. es la que permite tomar las decisiones. de uno que no lo es. le llamaremos “variable”. No pienses que estoy desvariando. “normalmente”. sino en la de la computadora. uno es la computadora. con lo cual tenemos esta primer sencilla ecuación. recuerdalo bien “variable”. aunque sea de forma temporal. por supuesto. el programador. los buenos programas. nos regresa un valor. retomando el sencillo ejemplo con el que empezamos este capitulo. pero lo más común es llamarlo “variable”. precisamente por que su valor o contenido puede variar durante los procesos que haga nuestra macro. tendremos que darle un nombre a una porción de dicha memoria. otra vez. Recuerda que primero hay que saber caminar para después correr.Aprendiendo OOo Basic 27 Observa como con solo dos datos. es obtener los datos. esta sencilla ecuación hace la diferencia entre un programa eficiente. retorna un valor. en el caso de nuestra macro. que. que iremos ampliando según vayamos avanzando en nuestro curso. lo cual lograremos con la “función” InputBox. unos mas otros menos. al servicio del proceso de convertir los datos en “información”. para ello. que como sabes. así que no desesperes si ves que vamos algo lento. ojo con la palabra “función” ya que es importante. Entonces. mostrando el nombre de una novia que tuve: Sub MostrarNombre 'Asignamos un valor a una variable Nombre = "Nicole Kidman" 'Mostramos el valor de la variable MsgBox Nombre End Sub Observa como en la linea: Nombre = "Nicole Kidman" .

desde el inicio de tu macro. por que al asignarle un valor por primera vez a una variable. etc) en ella. “declaración implícita”.28 4. esta forma de usar las variables. con la instrucción Dim. se puede guardar cualquier “tipo” de dato (texto. veamos algunos ejemplos de nombres de variables: •Direccion Correcto •Telefono2 Correcto •FechaDeNacimiento Correcto •Correo electronico Incorrecto (tiene un espacio) •3Fax Incorrecto (inicia con número) •Áéíóú Incorrecto (no se permiten caracteres especiales) •Calle. Observa que el nombre de las variables inmediatamente nos da una idea acerca del dato que guardaremos en ella. esta segunda forma de usar las variables se denomina. no es nada recomendable. OOo Basic hace uso de ella. por eso. normalmente guardara un texto. de esta forma. que variables son las que usaremos. en el caso de la variable Direccion. apartame un cachito de memoria que se llame Direccion para que yo la use-. hay una palabra clave para ello. numero. ademas de no poder llevar caracteres especiales. veamoslo con un ejemplo: Sub VariablesTipoVariant Dim UnDato UnDato MsgBox UnDato MsgBox UnDato MsgBox End Sub = "Esto es un texto" UnDato = 12345678 UnDato = "15/01/1974" UnDato 'Guardamos un texto 'Guardamos un numero 'Guardamos una fecha . en contraste. el nombre de las variables. simplemente con usar el nombre correcto de una variable. se llama Dim y su uso es muy sencillo. aquí el ejemplo: Sub DeclarandoVariables 'Declaramos cuatro variables Dim Direccion Dim Telefono2 Dim FechaNacimiento Dim Edad 'Mas código End Sub De esta forma. de la forma como están declaradas las variables. nosotros somos los que le indicamos al lenguaje. esta forma de usar variables se conoce como. el lenguaje lo hará para nosotros. a este tipo de variables se le conoce como “variant”. le estamos diciendo -oye mi hermano. el hacer uso de las variable de esta forma se vuelve (y no exagero) una verdadera locura. no pueden llevar espacios y no pueden empezar con un número. en la variable FechaNacimiento una fecha y en la variable Edad un número.Numero Incorrecto (no se permiten comas ni puntos) Como notaste. y efectivamente. al igual que el nombre de las macros. fecha.1 Declarando y usando variables Estamos asignando el “dato” "Nicole Kidman”. “declaración explícita”. conforme tus macros se hacen más grandes y complejas. a la “variable” Nombre. pero (dicen que siempre hay un pero). que variables son las que usaras para que reserve la memoria necesaria. el lenguaje reserva el espacio en memoria para su uso. es más eficiente y mucho más claro si le dices al lenguaje.

a pesar de que en este ejemplo es bastante evidente nuestro error (una pequeña “s” de diferencia). Almacena valores entre -922337203685477.402823 x 10E38 a 1. la variable Nombre. Precisión doble y coma flotante (1.401298 x 10E-45).5808 y +922337203685477.79769313486232 x 10E308 a 4. no nos muestra nada en el cuadro de mensaje.535 caracteres Enteros entre 0 y 255 Enteros entre -32768 y 32767 Enteros entre -2147483648 y 2147483647 Precisión simple y coma flotante (3. puedes copiarla: Sub DameTuNombre Dim Nombre As String 'Otra de mis novias Nombre = "Miranda Otto" MsgBox Nombres End Sub ¿Que pasa al ejecutarla?. junto con Dim y el tipo de variable. le indiquemos explicitamente al lenguaje que tipo de datos guardaremos en una variable. en vez de usar variables tipo “Variant”. es diferente de la variable Nombres y a la variable Nombres no le hemos asignado ningún valor todavía. tipo de declaración predeterminado Para hacer referencias a objetos Boolean Date Variant Object Lógica Fecha Variante Objeto Veamos este nuevo ejemplo de una macro.Aprendiendo OOo Basic 29 La recomendación es que. cuando se programa y haces uso de unas cuantas decenas de variables declaradas. efectivamente.5807 Solo puede contener valores True (verdadero) o False (falso) Cualquier valor. asegúrate de transcribirla tal cual o mejor aun. para el lenguaje. para ello. para minimizar este tipo de errores. esto no es tan evidente a simple vista. . esto es por que. existe una instrucción que nos ayuda a ello. por ejemplo: Sub Dim Dim Dim DeclaracionExplicitaDeVariables Direccion As String 'Variable tipo texto Edad As Integer 'Variable tipo numero entero Fecha As Date 'Variable tipo fecha Direccion = "Parque San Andres N° 14" Edad = 32 MsgBox Direccion MsgBox Edad End Sub Aquí. se usa la palabra clave As.94065645841247 x 10E-324) Máximo de 15 números antes del signo decimal y cuatro después de el. la lista completa del tipo de variables que puedes usar en OOo Basic: Tipo Descripción Valores que puede contener String Byte Integer Long Single Double Currency Texto Entero Entero Entero largo Simples Dobles Moneda Hasta 65.

además. que el IDE nos indica con una flecha la línea donde ocurrió el error. El inicio de este tema. observa en la imagen (el subrayado rojo). que aunque bello. de modo que nuestra anterior macro quedara así: Option Explicit Sub DameTuNombre Dim Nombre As String 'Otra de mis novias Nombre = "Miranda Otto" MsgBox Nombres End Sub Vuelve a ejecutar esta macro y observa que pasa. es decir. la instrucción básica para ello era: Variable = Dato y como ejemplo mostramos: Sub MostrarNombre 'Asignamos un valor a una variable Nombre = "Nicole Kidman" 'Mostramos el valor de la variable MsgBox Nombre End Sub Lo cual funciona. mencionábamos que una macro (o programa). es decir. nos muestra el siguiente mensaje: Como ves el mensaje es muy claro: Variable no definida. La segunda variante que veremos para asignarle un valor a una variable y que servirá como preámbulo para los siguiente capítulos es la siguiente: . no hemos usado la instrucción Dim para declararla. otra recomendación que tienes que tomar como regla -siempre usa Option Explicit al programar-. que nos obliga a declarar con la instrucción Dim.30 4. esta instrucción. empieza con la solicitud de algún dato al usuario (generalmente). cuando se use. debe hacerse como primer linea de cualquier modulo (solo una vez por modulo). así que. siempre nos mostrara el mismo nombre. así es. también veíamos que este dato o datos se guardan temporalmente en variables (generalmente). cualquier variable antes de usarla. creo que terminara por cansarnos.1 Declarando y usando variables Option Explicit. pero no es muy versátil que digamos. mas adelante veremos que otras herramientas implementa el IDE para ayudarnos con la localización de errores y la depuración de nuestras macros. usando esta instrucción te volverás un poco menos loco cuando busques ¿por que? no funciona tu macro.

Aprendiendo OOo Basic 31 Variable = Funcion En donde Funcion. se que es un gran simplificación pero nos es bastante útil para nuestros propósitos. veamos cuantas letras tiene. es cualquier instrucción que nos “retorne” una valor. y comprobar que si funciona el primer diagrama de este capitulo. veamos un ejemplo de la función InputBox. •Investiga •Practica mucho . te mostrara lo que hayas escrito: Para cerrar el circulo. esto lo logramos con la función Len. Ni modo. nuestra macro completa quedaría así: Sub MiNombre Dim Nombre As String Dim NumeroDeLetras As Integer Nombre = InputBox( "¿Cual es tu nombre?" ) NumeroDeLetras = Len( Nombre ) MsgBox NumeroDeLetras End Sub 'Entrada de datos 'Proceso de datos 'Visualización de resultado Observa como se cumple el flujo del diagrama mostrado al inicio de este capítulo. que nos dice cuantos caracteres tiene una cadena. Sub MiNombre Dim Nombre As String Nombre = InputBox("¿Cual es tu nombre?") MsgBox Nombre End Sub Al ejecutar. “hagamos algo” con el dato. no se me olvida dejarte tarea: •Practica mucho mas de la función InputBox. entonces. te tendrá que mostrar el siguiente cuadro de dialogo: Y al escribir tu nombre y dar clic en Aceptar.

se llaman así por que solo OOo Basic puede hacer uso de ellas?. el IDE nos muestra el siguiente error. la linea con la instrucción MsgBox. en este caso. al igual que las variables. no trabajara mientras no lo incorporemos a la linea de código. para mostrarte las diferencias entre las instrucciones y las funciones. . MsgBox Efectivamente. son de un “tipo de dato”). Usaremos una instrucción que ya conoces. esta cadena de texto. las podemos dividir en dos grandes grupos. ¿necesita algún otro?. mucho. Estas palabras clave. es necesario o requerido. tampoco puedes declarar variables con alguna de estas palabras. Veamos la siguiente linea de código. por ello. recuerdalo bien. MsgBox. con lo cual se deduce fácilmente que el argumento Mensaje.1 Declarando y usando variables tus comentarios. 4. las instrucciones y las funciones. es decir. no. aportes y dudas. la linea del error. que. ¿Has probado a intentar ejecutar esta instrucción sin ningún argumento?.32 •Envíame •Practica 4.2 Instrucciones y funciones en OOo Basic ¿Recuerdas que mencionamos que las palabras claves o reservadas de OOo Basic. es crucial para el entendimiento y desarrollo óptimo de los siguientes capítulos. el texto. Y nos señalara con la flecha que ya conoces. recibe el nombre de “argumento”. nos muestra un mensaje en pantalla. con este argumento es más que suficiente para que trabaje. que le indicamos entre comillas. MsgBox "Estoy aprendiendo OOo Basic" Estamos usando MsgBox como una instrucción. como primer aproximación a una definición útil. los argumentos. de aquí en adelante “cadena de texto”. ¿que?. no puedes crear una macro que se llame MsgBox u Option. pues esta palabra clave tiene la particularidad de poder usarse como una u otra dependiendo de nuestras necesidades. que es de tipo “cadena de texto” (ojo con esto. recibe el nombre de “parámetro” o “argumento”. ¿verdad que lo recuerdas?. diremos que: Las instrucciones “hacen” algo Las funciones “devuelven” algo La diferencia entre una y otra. por que esta “haciendo” algo. ¿que muestra?.

"Icono de exclamación" MsgBox "Estoy aprendiendo OOo Basic". es un número entero. todas dicen soffice.Aprendiendo OOo Basic 33 pero eso si. tiene un tercer argumento opcional que se llama Titulo. prueba las siguientes lineas de código. "Icono de Stop" MsgBox "Estoy aprendiendo OOo Basic". que te muestro aquí: La instrucción MsgBox. "Icono de información" Y observa el resultado. solo de la segunda linea: . el cual permite personalizar el titulo del cuadro de dialogo. para hacerlo. 48. 64. 32. en esta caso. puede llevar más argumentos. compruébalo. por ejemplo. existen otro dos iconos que puedes mostrar. "Icono de pregunta" MsgBox "Estoy aprendiendo OOo Basic". 32 Entonces. MsgBox "Estoy aprendiendo OOo Basic". nunca me creas completamente hasta no haberlo comprobado por ti mismo. prueba la siguiente línea de código y observa el resultado. el cual. debes de agregarle un segundo argumento que se llama Tipo. que como notas en las cuatro imágenes anteriores. si quieres que te muestre un icono con la señal de “stop”. 16. MsgBox "Estoy aprendiendo OOo Basic". para el primer caso un 16 y para el icono de interrogación ponemos un 32. el icono de exclamación (48) y el icono de información (64). 16 Y ahora esta: MsgBox "Estoy aprendiendo OOo Basic".

y veamos que también podemos establecer los botones de comando que queramos se muestren en el cuadro de dialogo. observa como los argumentos se separan por comas y los argumentos opcionales se encierran entre corchetes. "OOo Basic" MsgBox "Estoy aprendiendo OOo Basic.2 Instrucciones y funciones en OOo Basic Creo que todavía mantengo tu confianza. la sintaxis completa y correcta de esta instrucción es: MsgBox Mensaje As String. "Instrucción MsgBox" Cuando quieras mostrar una combinación de botones e iconos. es muy importante. Mostrar los botones Aceptar y Cancelar. Mostrar los botones Sí y No. Repetir y Ignorar. pasarle a un argumento un tipo de dato que NO es el que espera.34 4. ¿quieres continuar?". espero que si. ¿verdad?. observa que se especifica el tipo de dato que se espera se use en el argumento. las dos lineas siguientes son equivalentes: MsgBox "Estoy aprendiendo OOo Basic. Mensaje. 2. simplemente establece el argumento Tipo. Regresemos al argumento Tipo. Mostrar los botones Repetir y Cancelar. ¿quieres continuar?". Estos son los tres argumentos que puede usar la instrucción MsgBox. Sigamos. Y una muestra: MsgBox "Estoy aprendiendo OOo Basic". Tipo y Titulo. puede producir errores o resultados imprevisibles. [Tipo As Integer]. No y Cancelar. aquí esta la lista completa de estas opciones: 0 1 2 3 4 5 Mostrar sólo el botón Aceptar. ademas. Muestre los botones Cancelar. "OOo Basic" Que nos mostrara: . como una suma de los valores que quieres mostrar. 36. [Titulo As String] Lo importante aquí es que aprendas a distinguir la estructura o sintaxis de una instrucción. esto. Mostrar los botones Sí. 4 + 32. por lo cual. y muy importante.

usaremos MsgBox pero ahora. en el caso de las funciones. por ahora. es que aprendas a consultar esta documentación. es muy importante que la variable donde guardemos el valor sea del “mismo tipo” del valor que esperamos nos devuelva la función. es tema de otro capitulo. el cual. Integer. como saber que tipo de valor de retorno tendrás. en la documentación de OOo Basic. espero me alcancen las ganas de mostrarte todas las funciones que usa OOo Basic. por supuesto. van siempre entre paréntesis y. o en su defecto. etc). por lo que la variable donde guardes el valor de retorno debes de declararla como tipo entera (Integer) y así para cada valor de retorno de cada función que uses. ya con su variable de retorno: Sub InstruccionesYFunciones Dim Respuesta As Integer Respuesta = MsgBox ( "Estoy aprendiendo OOo Basic. ¿como saber cual? y actuar en consecuencia. las funciones. que la variable debe ser declarada del mismo tipo del valor que esperamos devuelva la función. también es de un tipo especifico (String. es que en la variable Respuesta. viendo estructuras como las que te he mostrado. normalmente viene especificado este valor de retorno para cada función. así que sigue leyendo. debes de ser capas de hacer uso de cualquier función o instrucción. por lo cual. los argumentos que lleve la función. es decir. completo. saber que argumentos necesita y de que tipo. así. como función. ¿como sabemos que botón es el que presiono el usuario?. devuelve un entero (Integer). como resultado. te mostrara el mismo cuadro de dialogo. 36. necesitamos usar el signo igual. no veras mucha diferencia. al devolver un valor. para empezar. ya que es muy importante. Veamos el ejemplo anterior. la estructura completa de la función MsgBox seria: Variable As [Titulo As String]) Integer = MsgBox (Mensaje As String. [Tipo As Integer]. solo te paso la lista completa de los valores que puede retornar la función MsgBox. en este caso en especifico. segundo. como van asignadas a una variable. "OOo Basic" ) MsgBox Respuesta End Sub Por supuesto. la función MsgBox. Recordando. En las funciones. ¿quieres continuar?". tendremos el valor del botón que el usuario haya presionado. Lo realmente importante. para ello tienes que recordar que: una función devuelve un valor. pero la gran diferencia. por ahora. 1 Aceptar 2 Cancelar 3 Cancelar 4 Repetir 5 Ignorar . guardaremos en una variable. la respuesta es sencilla.Aprendiendo OOo Basic 35 Y apuesto a que ya te hiciste la pregunta interesante. espero que si.

Un buen ejemplo del uso de constantes. puede regresar un valor 2 o 3. este tema es muy importante para los siguientes capítulos. la lógica.3 Constantes – Siempre lo mismo Hemos visto como guardar un dato temporalmente en una variable. la ayuda del programa o manuales como este. solo tenemos que cambiar su valor una vez en la sección donde la declaramos. para hacer real lo que decía Don Aristoteles. 4. es que. que un valor será constante durante toda la ejecución de una macro. el uso de constantes es muy sencillo y nos evita tener que estar recordando valores específicos. lo verdaderamente importante es que “aprendas a reconocer la sintaxis y estructura de cualquier instrucción o función”. lo importante y relevante al programar. pero para ello. -somos lo que hacemos día con día. de modo que la excelencia no es un acto sino un habitoMás adelante aprenderemos a crear nuestras propias instrucciones que aquí llamaremos “subrutinas” y también nuestras propias funciones. •Practicar mucho. te encontraras muy seguido con esta forma de declarar constantes. dependiendo de con que otros botones se muestre. otro valor agregado de las constantes. •Enviarme tus dudas. declarar las constantes con MAYUSCULAS. el botón Cancelar.1416 Es una practica común en los programadores. si esta llega a cambiar. más rápido y productivo serás. es sustituir el uso de los enteros en el argumento Tipo de la instrucción MsgBox. Para declarar una constante. comentarios y aportes. no olvides de: •Practicar •Prueba mucho. usamos la palabra clave Const de la siguiente manera: Const I = 100 Aunque lo más recomendable. que solo son referencia. el resto es solo consultar la documentación del lenguaje. aunque esto no es una regla. no debes de tener duda alguna de como se usan las que incorpora OOo Basic.2 Instrucciones y funciones en OOo Basic 6 7 Sí No No creas que esta mal la lista. eso. veamos como: . con esto. visto en el capitulo anterior. a combinar los diferentes valores del argumento Tipo. solo se logra con la practica diaria. pero habrá ocasiones. Y un nuevo capitulo ha llegado a su fin. pero recuerda que no es necesario aprenderse de memoria todo esto. es también establecer el tipo de constante: Const PI As Single = 3. •Practicar mucho. Entre más conozcas y domines las instrucciones y funciones de OOo Basic. •No te deben de quedar dudas.36 4.

tomamos uno u otro camino. pero que tal que dice que “si”. dependiendo de la respuesta. Veamos su uso. pero a fin de cuentas tu gusto y criterio son los que mandan.4 Bifurcaciones – Tomando decisiones ¿Te has puesto a pensar cuantas decisiones tomas al día?. si dice que “no” ¿que hago?. Ahora. ICONO_PREGUNTA + BOTONES_SINO. "Novios" ) . recuerda. "OOo Basic" Para nombrar a las constantes.Else. checa la siguiente macro: Sub Novios3 Dim Respuesta As Integer 'La pregunta importante Respuesta = MsgBox( "¿Quieres ser mi novia?".. 4.Then. de acuerdo a los valores mostrados en la sección 2. con Ustedes. aplican las mismas reglas vistas para nombrar a las macros y a las variables. "Novios" ) 'Evaluamos la respuesta.. por lo que no las repetiremos aquí. o eso dicen..Aprendiendo OOo Basic Const ICONO_PREGUNTA As Integer = 32 Const BOTONES_SINO As Integer = 4 37 MsgBox "Estoy aprendiendo OOo Basic". 32 + 4. para solventar esto. es una buena practica de programación. "Novios" ) MsgBox Respuesta End Sub Copia y ejecuta la macro anterior y observa como únicamente estamos obteniendo la información del botón que selecciono el usuario: un 6 para el botón “Si” y un 7 para el botón “No”. la instrucción If. pero cuando se presiona el botón “Si”. Dependiendo del tamaño de tu proyecto. 32 + 4. Sub Novios2 Dim Respuesta As Integer 'La pregunta importante Respuesta = MsgBox( "¿Quieres ser mi novia?". actuaremos en consecuencia. veamos como hacerlo. un 7 es igual No If Respuesta = 7 Then MsgBox "De lo que te pierdes" End If End Sub Observa que solo logramos saber cuando se presiono el botón de “No”.. simplemente no lo sabemos. para ello te presento una nueva instrucción que te acompañara (esta sí) para el resto de tu programación. la vida esta hecha de decisiones. Señoras y señores. 32 + 4. y en las macros no nos salvamos de ellas. casi siempre hay que estar decidiendo algo y en base a esta decisión. usar un modulo único para declarar variables y constantes. Un pregunta importante: ¿Quieres ser mi novia?. Afortunadamente en OOo Basic es mucho más sencillo que en la vida. preguntemosle: Option Explicit Sub Novios Dim Respuesta As Integer Respuesta = MsgBox( "¿Quieres ser mi novia?".

puedes usar tantos ElseIf como quieras..Else es: If CONDICION Then 'Código si condición es verdadera [ElseIf CONDICION_2 Then] 'Código si condición 2 es verdadera [Else] 'Cualquier otro valor End If . Si quisiéramos saber que día de la semana corresponde a otro valor. veamos como: Sub DiaDeLaSemana2 Dim Dia As Integer 'Solicitar un numero digamos entre 1 y 10 Dia = InputBox( "¿Que dia quieres saber (1 a 10)?" ) If Dia = 1 Then MsgBox "Este dia es Domingo" ElseIf Dia = 2 Then MsgBox "Este dia es Lunes" Else MsgBox "NO se que dia es" End If End Sub De esta manera. un 7 es igual No If Respuesta = 7 Then MsgBox "De lo que te pierdes" Else 'Cualquier otro valor diferente del que se evalúa en la condición MsgBox "Que inteligente eres" End If End Sub Notaras al ejecutar.. veamoslo con un ejemplo: Sub DiaDeLaSemana Dim Dia As Integer 'Solicitar un numero digamos entre 1 y 10 Dia = InputBox( "¿Que dia quieres saber (1 a 10)?" ) If Dia = 1 Then MsgBox "Este dia es Domingo" Else MsgBox "Este dia NO es Domingo" End If End Sub Observa como “solamente” con el valor de 1. Resumiendo: la estructura general de la instrucción If. la ejecución continua en la línea inmediata. usaremos una variante de la instrucción If.Then. [TAREA] completa la macro para que nos de todo los días de la semana y en caso de otro valor nos informe que no es un día de la semana. es decir.. es como se nos informa que es Domingo. podemos hacer tantas comparaciones como queramos.38 4.. Debes de poner atención a algo importante. si la variable tiene “cualquier” otro valor o condición. cualquier otro valor nos muestra el segundo mensaje..Then.Else. que ahora si sabemos cuando se presiono cada uno de los botones de nuestro cuadro de dialogo.. en nuestro ejemplo.4 Bifurcaciones – Tomando decisiones 'Evaluamos la respuesta. Como pista. entonces hace lo segundo. si el valor de la variable Respuesta era 7. significa “cualquier” otro valor o caso o condición.. recuerda. la instrucción Else.

pero las dos. ElseIf bolHayComillas = False And (strPalabra = "'" Or UCase(strPalabra) = "REM") Then ElseIf EsPalabraClave(strPalabra) And bolHayComillas = False Then Volviendo al ejemplo de los días de la semana. veamos un ejemplo: Sub DiaDeLaSemana3 Dim Dia As Integer Dia = InputBox( "¿Que Select Case Dia Case 1 MsgBox Case 2 MsgBox Case 3 MsgBox Case 4 MsgBox Case Else MsgBox End Select End Sub día quieres saber (1 a 10)?" ) "Este día es Domingo" "Este día es Lunes" "Este día es Martes" "Este día es Miércoles" "NO se que día es" Observa que fácil es esta instrucción. sobre todo cuando se compara la misma variable varias veces... de Lunes a Viernes Case 2 To 6 MsgBox "Que horror. sino tan solo quiero mostrarte un caso “diferente” de condición. no necesariamente tienes que usarlas. día de trabajo" Case Else MsgBox "NO se que día es" End Select End Sub ¿Verdad que es fácil? Al igual que con la instrucción If. puede ir “cualquier” instrucción susceptible de ser evaluada como verdadera o falsa y puede ser tan sencilla como las vistas hasta ahora o compleja como el siguiente ejemplo. que por ahora. en ocasiones. tenlas siempre a la mano. es posible usar otra instrucción de bifurcación..Else. ahora... 7 MsgBox "Por fin a descansar" 'Y aquí si es entre semana.Aprendiendo OOo Basic 39 Recuerda que las opciones que están entre corchetes son “opcionales”. son el pan nuestro de cada día en la programación.Case. . Ademas. puede usar varios valores a evaluar o rangos de valores. por ejemplo: Sub DiaDeLaSemana4 Dim Dia As Integer Dia = InputBox( "¿Que día quieres saber (1 a 10)?" ) Select Case Dia 'Aquí evaluamos si es sábado o domingo Case 1. así que. En CONDICION. las condición a evaluar puede ser muy sencilla o compleja.Then. pero veras que casi siempre así será. aprenderás a usar Select. no te importe como esta construida. pero veras que más adelante aprenderemos a hacer..

Observa que solo te mostrara el mensaje dos veces.. si bien funciona con el operador +.. veamos ejemplos de cada una. no te puse cien por que tendrías que dar cien clics para terminar la macro. con frecuencia te encontraras que algunos programadores usan la letra I. muy seguido) es necesario realizar el mismo paso una y otra vez. la B también es muy linda. escogimos la variable Contador..Next..5 Bucles – Repitelo otra vez 4. te acuerdas cuando te portabas mal y la maestra te dejaba escribir cien veces -Tengo que portarme bien-.40 4.Next y Do. pero mejor lo explicamos para que no haya ninguna duda y ningún pretexto de como aplicarlo más adelante. por ejemplo.. necesitamos repetir bloques de código las veces que queramos o cuando (o hasta) que se cumpla una condición especifica.5 Bucles – Repitelo otra vez En ocasiones (de hecho. que son las indicadas por el limite inferior y superior del contador especificadas con 1 To 2. en programación a la “suma” de cadenas de texto se le conoce como “concatenar” y no es otra cosa que pegar cadenas de texto una con otra. para nuestro caso. Para ello. es necesaria una variable de apoyo.Loop. si en eso entonces hubiese sabido programar (y conste que cuando iba a la primaria ya existían las computadoras) le hubiese entregado a la maestra el siguiente código: Option Explicit Sub PortarseBien Dim Contador As Integer 'Inicia el contador con los limites especificados For Contador = 1 To 2 'Este es el código que se ejecuta el numero de veces 'especificado con los limites en nuestro caso 2 veces MsgBox "Tengo que portarme bien" Next End Sub Se que esta muy claro. J y subsecuentes como contadores. Para hacer uso de la estructura For. es decir. es más común usar el símbolo de ampersan (&) como concatenador de cadenas de texto: Sub TuNombre2 . por ejemplo: Sub Dim Dim Dim Dim TuNombre Nombre As String Apellido1 As String Apellido2 As String NombreCompleto As String Nombre = InputBox( "¿Cual es tu Nombre?") Apellido1 = InputBox( "¿Cual es tu primer Apellido?") Apellido2 = InputBox( "¿Y el segundo?") NombreCompleto = Nombre + Apellido1 + Apellido2 MsgBox "Tu nombre completo es: " + NombreCompleto End Sub Observa como solicitamos el nombre y apellido y al final lo mostramos en una sola línea de texto. vamos a conocer dos nuevas estructuras para hacer bucles o repeticiones.. pero para establecer valores más grandes. aprovecharemos para ver como “sumar” cadenas de texto. la letra M es muy bonita. están son: For. pero tu eres libres de elegir y usar la variable que más te plazca.

Ahora si.Aprendiendo OOo Basic Dim Dim Dim Dim Nombre As String Apellido1 As String Apellido2 As String NombreCompleto As String 41 Nombre = InputBox( "¿Cual es tu Nombre?") Apellido1 = InputBox( "¿Cual es tu primer Apellido?") Apellido2 = InputBox( "¿Y el segundo?") NombreCompleto = Nombre & Apellido1 & Apellido2 MsgBox "Tu nombre completo es: " & NombreCompleto End Sub Por supuesto habrás notado que el nombre completo sale todo pegado. te dejo de tarea que te quede muy presentable y bonito. ¿verdad?. probemos primero con 10: Sub PortarseBien2 Dim Contador As Integer Dim Texto As String For Contador = 1 To 10 Texto = Texto & "Tengo que portarme bien" Next MsgBox Texto End Sub Rápido pero no nos gusta todo el texto junto. le agregaremos un saldo de línea al final de cada una. podemos hacer nuestro bucle más grande. . Para mejorarlo un poco. así: Sub PortarseBien3 Dim Contador As Integer Dim Texto As String For Contador = 1 To 10 Texto = Texto & "Tengo que portarme bien" & Chr(13) Next MsgBox Texto End Sub ¿Recuerdas como decía mi amigo? -ansina si-.

5 Bucles – Repitelo otra vez ¿Y que te parecería si lo mejoramos agregándole el número a cada línea?: Sub PortarseBien4 Dim Contador As Integer Dim Texto As String For Contador = 1 To 10 Texto = Texto & Contador & ". ¿no crees?..Tengo que portarme bien" & Chr(13) Next MsgBox Texto End Sub Mucho mejor. Los limites inferior y superior no necesariamente tienen que ser positivos: For Contador = -5 To 5 Tampoco tienen por que ir de uno en uno. cuando podemos ir de dos en dos. Sub PortarseBien5 Dim Contador As Integer Dim Texto As String For Contador = 1 To 20 Step 2 .42 4. de tres en tres o en el rango que necesitemos.

que de eso se trata la libertad. co2 As Integer .1 Texto = Texto & Contador & ". Sub PortarseBien6 Dim Contador As Integer Dim Texto As String For Contador = 0 To 1 Step 0. a fin de cuentas. en este caso Step. ojo. sobre todo cuando hay muchas líneas de código entre ellos. decidirás si lo usas o no. Por supuesto observaste que le agregamos un argumento a la instrucción.. mucho ojo con esto. Sub BuclesAnidados Dim co1 As Integer. de nuevo. pero en otras ocasiones..Aprendiendo OOo Basic 43 Texto = Texto & Contador & ". en el capitulo de variables puedes encontrar ayuda. pero no esta de más como ayuda. por ejemplo: For Contador = 0 To 1 Step 0. puedes usar después de la palabra clave Next. ni positivo. claro que el IDE de indica si falta alguno. tu tarea es indicarme cual es.Tengo que portarme bien" & Chr(13) Next MsgBox Texto End Sub Esto se esta poniendo divertido. el mismo nombre de la variable que este usando como contador.1 'Aquí va código Next Contador Esto es sumamente útil cuando tienes varios bucles de repetición anidados. tu y solo tu. es un poco complejo saber donde termina uno. La siguiente macro tiene un pequeño error. For Contador = 100 To 10 Step -10 Y aquí te lo dejo para que hagas todas las pruebas que quieras y nos las cuentes en el foro o lista de correo.Tengo que portarme bien" & Chr(13) Next MsgBox Texto End Sub Como ultimo comentario de esta instrucción. muchas veces el uso de la sangría es suficiente para distinguir unos de otros. para indicarle que salto queremos y este salto no necesariamente tiene que ser ni entero.

de “a deveras” para finalizar. por ello es que con la línea sLetra = Chr( Rnd() * 25 + 65 ) Obtenemos un valor aleatorio entre 65 y 90 y Chr nos devuelve dicha letra.5 Bucles – Repitelo otra vez For co1 = 1 To 5 For co2 = 1 To 10 Next co2 Next co1 End Sub Ahora si. "Ejemplo Exit For" End Sub La función Chr(valor) nos devuelve el carácter ASCII correspondiente a dicho valor. la letra A tiene un valor de 65 y la letra Z tiene un valor de 90. solo en el caso de que la letra devuelta sea una S (de Salida).Next. veamos cuales son: .. esta nos sirve para salir anticipadamente de un ciclo For.Next se interrumpe y sale con Exit For. después evaluamos si es una vocal. veamos un ejemplo divertido de su uso: Option Explicit Sub Dim Dim Dim Dim Usando_Exit_For() co1 As Integer sLetra As String sVocales As String sConsonantes As String For co1 = 1 To 100 sLetra = Chr( Rnd() * 25 + 65 ) Select Case sLetra Case "A". hay otro tipo de ciclos llamados “indeterminados”. el ciclo For. al final. ya me contaras como te va a ti con tus pruebas. Observa que debajo de la linea de comentario.. algunos autores le llama “determinado” pues sabemos donde empieza y donde termina. es decir en el momento que quieras. pues dependen de una o unas condiciones para empezar o terminar el ciclo. "U" sVocales = sVocales & " " & sLetra Case "S" Exit For Case Else sConsonantes = sConsonantes & " " & sLetra End Select Next MsgBox "El ciclo termino en: " & co1 & Chr(13) & Chr(13) & _ "Vocales: " & sVocales & Chr(13) & _ "Consonantes: " & sConsonantes. recuerda bien la estructura de esta instrucción: For Variable = Inicio To Fin [Step Salto] 'codigo [Exit For] Next [Variable] Y recuerda que lo que esta entre corchetes es opcional.. Al tipo de ciclo usado en For. nunca termino el ciclo. hay una instrucción que no hemos visto.Next. se trata de: Exit For. si es la letra S o si es una consonante. "E". "O". es mis pruebas curiosamente salio varias veces en 1 y lo máximo fue 98.. es decir. 0. "I".44 4. mostramos el valor del contador para saber si termino el ciclo o salio antes..

pero en vez de usar un contador. en este caso un nombre Loop While Nombre = "" 'Continuamos el bucle “mientras” la condición sea VERDADERA End Sub 'Finalizamos la macro Habrás notado que de esta forma.. si bien es posible. a ellos nos atenemos: Sub DameTuNombre Dim Nombre As String Do Nombre = InputBox( "¿Cual es tu Nombre?") Loop While Nombre = "" End Sub Analicemos línea por línea la macro anterior: Sub DameTuNombre 'Iniciamos la macro Dim Nombre As String 'Declaramos una variable de texto Do 'Iniciamos el bucle Nombre = InputBox( "¿Cual es tu Nombre?") 'Solicitamos un valor.. Como creo que es más claro con ejemplos.Aprendiendo OOo Basic 45 La instrucción Do. para probar una primer alternativa para ello. también nos sirve para hacer repeticiones. proporcionar casi siempre una forma de cancelar o interrumpir el bucle. 32 + 4. Parece que funciona bien la macro anterior. nos apoyaremos en una estructura ya vista: Sub DameTuNombre2 Dim Nombre As String Dim Respuesta As Integer Do Nombre = InputBox( "¿Cual es tu Nombre?" ) If Nombre = "" Then Respuesta = MsgBox( "Al parecer no escribiste nada.Loop. que se usa de la siguiente forma: Sub DameTuNombre3 Dim Nombre As String Dim Respuesta As Integer Do Nombre = InputBox( "¿Cual es tu Nombre?" ) Nombre = Trim( Nombre ) If Nombre = "" Then . te presento a la instrucción Trim. "Salir" ) 'Recuerda que un 6 significa que el usuario presiono el botón SI If Respuesta = 6 Then 'Establecemos la variable con cualquier cosa para que termine el bucle Nombre = "cualquier cosa" End If End If Loop While Nombre = "" End Sub Recuerda siempre de ir probando el código. forzamos al usuario a escribir un valor en el cuadro de dialogo. recuerda que es deseable. haremos uso de una función integrada en OOo Basic que nos sirve para eliminar los espacios vacíos al inicio y al final de una cadena. para subsanar este inconveniente. ¿realmente quieres salir?". se usa una condición para saber cuando terminar un bucle e incluso cuando empieza o tal vez nunca empezar. pero hay una simple forma de “engañarla”. prueba a introducir puros espacios y veras que sale inmediatamente.

contenga algo. hay más de una forma de hacer las cosas. Recuerda que no todos tenemos el mismo modo de “razonar”. con validación y todo. sea un buen momento para ampliar tus horizontes. ojo. recuerda esta palabra muy bien. ¿se te ocurren más alternativas por “prever” o mejorar?. sea “diferente” de vacía. otras no. lo siento. la macro completa. En casi todo y más en la programación. "Salir" ) 'Recuerda que un 6 significa que el usuario presiono el boton SI If Respuesta = 6 Then 'Establecemos la variable con cualquier cosa para que termine el bucle Nombre = "cualquier cosa" End If End If Loop Until Nombre <> "" End Sub Tal vez. detente un momento y trata de entender la forma “diferente” de razonar del otro. 32 + 4. con justa razón. te preguntaras. . es el pan nuestro de cada día al programar. Sub DameTuNombre5 Dim Nombre As String Dim Respuesta As Integer Do Nombre = InputBox( "¿Cual es tu Nombre?") Nombre = Trim( Nombre ) If Nombre = "" Then Respuesta = MsgBox( "Al parecer no escribiste nada. pero al haber varias maneras de resolver el mismo problema. Ahora. esa es tu tarea.46 4. funciona mejor. ¿realmente quieres salir?". la cuestión se enriquece. También. lo que hicimos fue cambiar un argumento y el operador de la condición. es casi seguro que unas se adaptaran rápidamente a tu forma de razonar. ¿porque dos formas de hacer lo mismo?.5 Bucles – Repitelo otra vez Respuesta = MsgBox( "Al parecer no escribiste nada. ¿realmente quieres salir?". Para continuar. en negritas) que la variable Nombre. nota que la condición tiene que seguir siendo verdadera para que el bucle termine. veremos una variante de esta estructura que nos permite invertir la lógica de la condición. así que la próxima vez que estés pronto a prejuzgar. tal vez. validación. veamos como: Sub DameTuNombre4 Dim Nombre As String Do Nombre = InputBox( "¿Cual es tu Nombre?") Loop Until Nombre <> "" End Sub Se muy atento. 32 + 4. a los fundamentalistas de cualquier extremo y color se les reconoce fácilmente por su “pensamiento” uniforme y negación a ver otro o al otro. es decir. observa como ahora le decimos “hasta” (con la instrucción Until. "Salir" ) 'Recuerda que un 6 significa que el usuario presiono el botón SI If Respuesta = 6 Then 'Establecemos la variable con cualquier cosa para que termine el bucle Nombre = "cualquier cosa" End If End If Loop While Nombre = "" End Sub Ahora sí.

Anidar funciones. Y sí.. simplemente pasamos la instrucción al inicio de la estructura." & Nombre 'Solicitamos otro nombre Nombre = Trim( InputBox( "¿Dame otro Nombre?") ) Loop 'Si la lista contiene algo lo mostramos If Lista <> "" Then MsgBox Lista End If End Sub Fácil. te mostrare la instrucción para finalizar anticipadamente un ciclo Do. la cual consiste en que logres el mismo propósito. ¿verdad?. Ten cuidado con los ciclos indeterminados. una condición mal planteada te puede dejar dentro de un ciclo infinito.Loop. muchas cosas. necesitamos forzosamente que se cumpla una condición. Empieza a pensar en como automatizarías esos pasos tan repetitivos y tediosos .Loop. te debe de resultar muy familiar si eres un usuario medio/avanzado de cualquier hoja de calculo. en vez de While. Habrá ocasiones en que necesitemos o queramos que no se ejecute ni una sola vez. de la siguiente forma: Sub DameTuNombre6 Dim Nombre As String Dim Lista As String 'Solicitamos un dato Nombre = InputBox( "¿Dame un Nombre?") 'Le quitamos los espacios sobrantes al inicio y al final Nombre = Trim( Nombre ) 'Iniciamos el bucle. ejecuta el código entre Do. Para hacer esto. ¿por ejemplo?. ya se pueden hacer muchas. una. observa como las dos variantes de la estructura vista. Para finalizar este tema de los bucles. Me creerás que con los elementos vistos hasta ahora. conocimiento que te resultara muy útil en programación ya que es muy recurrida.. si la variable es diferente de vacía Do While Nombre <> "" 'Formamos una lista de los nombres introducidos Lista = Lista & " . al menos una vez. la que ya conoces en la condición final.. pero con la palabra clave Until. la primera de forma directa y la segunda de forma anidada. si el usuario escribe correctamente la palabra clave y salimos con Exit Do. Aquí nota las dos formas en que hacemos uso de la instrucción InputBox. y la otra. estas palabras clave son: Exit Do y se usan de la siguiente manera: Option Explicit Sub Usando_Exit_Do() Dim sClave As String Dim sTmp As String sClave = "mellon" Do sTmp = Trim(InputBox("Habla amigo y entra")) If sTmp = "mellon" Then MsgBox "Y se abren las puertas de Moria" Exit Do End If Loop Until sTmp = "salir" End Sub Observa como tenemos dos formar de terminar el bucle. pues hay tarea.Aprendiendo OOo Basic 47 Y hablando de variedad. imagina que para entrar en el bucle.

tal vez quiera decir que es hora de pasar a usar bases de datos. Para ello. mucho menos. “casi” todo lo que se hace en programación responde aproximadamente bien a el. el indicarte que sea un tipo Integer (Entero) es más indicativo que restrictivo. eso quiero hacer y para terminar este capitulo. por ejemplo: los días de la semana. las matrices pueden ser de mucha utilidad o convertirse en un verdadero galimatias si no se manejan correctamente. No he encontrado documentación al respecto del limite de este valor. he hecho la prueba con valores más grande que un Integer (Entero).y solo la practica diaria te dará el dominio de la herramienta para obtener de ella el mejor provecho. una simple lista sería así: ● ● ● ● ● ● ● Domingo Lunes Martes Miércoles Jueves Viernes Sábado . en mis pruebas estoy casi seguro que esta condicionado más por el limite de la memoria Ram del equipo donde se ejecute que de otra causa.5 Bucles – Repitelo otra vez que siempre haces. como dice el dicho -la practica hace al maestro. pues muchas estructuras de OpenOffice. o en una tabla de filas y columnas en las mas compleja. mantén siempre en tu mente el diagrama que vimos en el capitulo 4. que te hagas llamar programador.6 Matrices – Juntos pero no revueltos En el cual veremos como manipular muchos datos en una sola variable. "El genio es 1% de inspiración y 99% de transpiración" Thomas Alva Edison 4. no te engañes. en este caso. experiencia y pruebas el limite de elementos a usar.1. pero no me imagino una macro que use tantos elementos y si lo hay. con solo leer estas notas o cualquiera otra documentación que encuentres o adquieras (y te lo digo por experiencia) no es suficiente para que resuelvas tus problemas informáticos. Te dejo a tu criterio. Te resultara muy fácil pensar en las matrices con una lista de valores en su presentación más sencilla. Tamaño se refiere al número de elementos que contendrá la matriz. La sintaxis más sencilla para una matriz es la siguiente: Dim Nombre_Matriz( Tamaño As Integer ) As Tipo En donde para Nombre_Matriz tiene que cumplir las mismas condiciones que para nombrar las macros y las variables vistas anteriormente. estarás en lo cierto. si crees que estoy tratando de influenciarte para que practiques mucho. recuerda lo que decía un hombre que practicaba y experimentaba mucho.org vienen implementadas en matrices. es importante que aprendas a utilizarlas.48 4.

podemos forzar a que las matrices empiecen en 1 (uno). de la siguiente manera: Option Explicit Option Base 1 Sub Ejemplo_Matrices3 Dim miSemana(7) As String Dim co1 As Integer miSemana(1) miSemana(2) miSemana(3) miSemana(4) miSemana(5) miSemana(6) miSemana(7) = = = = = = = "Domingo" "Lunes" "Martes" "Miércoles" "Jueves" "Viernes" "Sábado" For co1 = 1 To 7 MsgBox miSemana( co1 ).org inician en 0 (cero). 64. sería así: Sub Ejemplo_Matrices1 Dim miSemana(6) As String miSemana(0) = "Domingo" miSemana(1) = "Lunes" miSemana(2) = "Martes" miSemana(3) = "Miércoles" miSemana(4) = "Jueves" miSemana(5) = "Viernes" miSemana(6) = "Sábado" MsgBox miSemana( 3 ) End Sub Y observa que con un simple bucle. que es la forma predeterminada. podemos acceder a toda la matriz Sub Ejemplo_Matrices2 Dim miSemana(6) As String Dim co1 As Integer miSemana(0) miSemana(1) miSemana(2) miSemana(3) miSemana(4) miSemana(5) miSemana(6) = = = = = = = "Domingo" "Lunes" "Martes" "Miércoles" "Jueves" "Viernes" "Sábado" For co1 = 0 To 6 MsgBox miSemana( co1 ). "Toda la semana" Next End Sub Option Base “no” puede ir dentro de una macro. 64.Aprendiendo OOo Basic 49 Para guardar esto en una matriz. así que usaremos este valor de inicio como predeterminado en todo el libro. usando la palabra clave Option Base. "Toda la semana" Next End Sub Nota que la matriz empieza en 0 (cero). Si te es necesario un inicio y un fin diferentes pues usar la siguiente variante para la declaración de matrices. tiene que ir al inicio de un modulo en el área de declaración de variables. La mayoría de las estructuras de OpenOffice. .

58." misDatos( 5 ) = 37000 For co1 = 0 To 5 MsgBox misDatos( co1 ).26. cuando queremos recorrer una matriz con un bucle. como en el siguiente ejemplo: Sub Ejemplo_Matrices5 Dim misDatos(5) As Variant Dim co1 As Integer misDatos( 0 ) = "Mauricio Baeza" misDatos( 1 ) = 1974 misDatos( 2 ) = "Miguel Angel 64" misDatos( 3 ) = "Mexico" misDatos( 4 ) = "D.35. en muchos casos.58.98. "Números" MsgBox misColores( 0 ).26. pero muy bien podemos combinar datos si declaramos la matriz como Variant. 64.F.51.50 4. "Colores" End Sub Observa como en los dos casos.48. en una guardamos números y en la otra texto. cuenta con dos funciones muy útiles para conocer estos valores: Sub Ejemplo_Matrices6 Dim misDatos() As Integer Dim co1 As Integer misDatos() = Array( 87.12. las matrices tienen los mismos diez elementos.16 ) . 64.6 Matrices – Juntos pero no revueltos Dim Nombre_Matriz( Inicio As Tipo To Fin As Tipo ) As Tipo En donde Inicio puede ser incluso un valor negativo como en los ejemplos siguientes: Sub Ejemplo_Matrices4 Dim misNumeros(5 To 14) As Integer Dim misColores(-5 To 4) As String misNumeros(5) = 123 misNumeros(6) = 345 misNumeros(7) = 567 misNumeros(8) = 890 misNumeros(9) = 135 misNumeros(10) = 246 misNumeros(11) = 147 misNumeros(12) = 258 misNumeros(13) = 369 misNumeros(14) = 951 misColores(-5) = "Azul" misColores(-4) = "Verde" misColores(-3) = "Morado" misColores(-2) = "Rojo" misColores(-1) = "Blanco" misColores(0) = "Rosa" misColores(1) = "Violeta" misColores(2) = "Gris" misColores(3) = "Negro" misColores(4) = "Oro" MsgBox misNumeros( 9 ).35. hemos establecido los valores superior e inferior de la matriz declarada previamente. 64. "Mis datos" Next End Sub Notaras que en los casos vistos hasta ahora. en estos casos. no sera posible conocer los valores de inicio y fin de una matriz. OOo Basic.

"Mis amigos" Next . por ello existen varias alternativas para lograr este propósito. "Mis datos" Next End Sub En este ejemplo aprendemos cuatro nuevas funciones de OOo Basic. "Mis amigos" Next Redim misAmigos(4) misAmigos(3) = "Lidia": misAmigos(4) = "Anita" For co1 = LBound( misAmigos() ) To UBound( misAmigos() ) MsgBox Str( co1 ) & " . no importándole el valor con el que hayamos declarado la matriz. 64. 64. "Hola". Cambiar de tamaño o de cantidad de elementos que puede contener una matriz de forma dinámica durante la ejecución de una macro. que nos permite crear una matriz introduciendo directamente los valores que contendrá. cada uno separado por una coma. LBound que nos devuelve el limite inferior de una matriz y UBound que nos devuelve el limite superior. Usando estas dos ultimas funciones. claramente notamos que la matriz se “redimenciona” con el número de elementos que tenga la función Array. "Prueba" ) MsgBox "Limite Inferior = " & Str( LBound( misdatos3() )) & Chr( 13 ) & _ "Limite Superior = " & Str( UBound( misdatos3() )) End Sub Al observar los valores inferior y superior que nos devuelve cada matriz. Puedes declarar una matriz de un determinado tamaño y usar Array para llenar la matriz sin que necesariamente correspondan el número de elementos.Aprendiendo OOo Basic 51 MsgBox "Limite Inferior = " & Str( LBound( misdatos() )) MsgBox "Limite Superior = " & Str( UBound( misdatos() )) For co1 = LBound( misdatos() ) To UBound( misDatos() ) MsgBox misDatos( co1 ). "Prueba". 45." & misAmigos( co1 ). "Hola". 27. 18. es una tarea habitual de programación. OOo Basic cuenta con una instrucción especifica para lograr esto. 15 ) MsgBox "Limite Inferior = " & Str( LBound( misdatos1() )) & Chr( 13 ) & _ "Limite Superior = " & Str( UBound( misdatos1() )) 'Con menos elementos misDatos2() = Array( "Paola". como en los siguiente ejemplos: Sub Dim Dim Dim Dim Ejemplo_Matrices7 misDatos1(5) As Variant misDatos2(5) As Variant misDatos3(3) As Variant co1 As Integer 'Llenamos la primer matriz con el numero exacto de elementos declarados misDatos1() = Array( "Lizet". "Hola" ) MsgBox "Limite Inferior = " & Str( LBound( misdatos2() )) & Chr( 13 ) & _ "Limite Superior = " & Str( UBound( misdatos2() )) 'Con mas elementos misDatos3() = Array( "Mariana". y por ultimo la función Str que convierte en cadena de texto el argumento pasado. 30. 64." & misAmigos( co1 ). se llama ReDim y se usa de la siguiente manera: Sub Ejemplo_Matrices8 Dim misAmigos(2) As String Dim co1 As Integer misAmigos(0) = "Edgar": misAmigos(1) = "Gloria" : misAmigos(2) = "Toñito" For co1 = LBound( misAmigos() ) To UBound( misAmigos() ) MsgBox Str( co1 ) & " . ni siquiera tenemos que enterarnos de los limites de una matriz. Array. 25.

5. por supuesto que en ocasiones desearemos mantener los valores que existan. "Mis números" Next End Sub Una primera solución es la propuesta siguiente: Sub Dim Dim Dim Ejemplo_Matrices11 misNumeros(9) As Integer mTmp() As String co1 As Integer 'Llenamos la matriz con 10 números misNumeros() = Array( 1.9." & misAmigos( co1 ).9.7.10 ) For co1 = LBound( misNumeros() ) To UBound( misNumeros() ) MsgBox misNumeros( co1 ). 64. 64.5. esta.8.10 ) 'Redimencionamos la matriz temporal Redim mTmp(4) 'Pasamos los valores a la matriz temporal For co1 = LBound( mTmp() ) To UBound( mTmp() ) mTmp( co1 ) = misNumeros( co1 ) Next 'Redimencionamos la matriz original Redim misNumeros(4) 'Copiamos loa valores temporales misNumeros() = mTmp() 'Verificamos que esten los datos For co1 = LBound( misNumeros() ) To UBound( misNumeros() ) . borra los valores que hayamos introducido previamente en la matriz.52 4.6 Matrices – Juntos pero no revueltos End Sub Se que eres muy observador y ya notaste que en el segundo bucle. Pero ReDim no solo sirve para aumentar elementos.6.4.7.3. solo nos muestra los valores de los indices 3 y 4." & misAmigos( co1 ). como lo demuestra el siguiente ejemplo: Sub Ejemplo_Matrices10 Dim misNumeros(9) As Integer Dim co1 As Integer misNumeros() = Array( 1. todo se mantiene con la palabra clave Preserve. esto es por que al redimencionar la matriz con ReDim. también sirve para disminuirlos. 64. te mantiene los valores previos.8.3. esto. 64. "Mis números" Next ReDim Preserve misNumeros(4) For co1 = LBound( misNumeros() ) To UBound( misNumeros() ) MsgBox misNumeros( co1 ). "Mis amigos" Next End Sub Ahora si.2.6.4. "Mis amigos" Next ReDim Preserve misAmigos(4) misAmigos(3) = "Lidia": misAmigos(4) = "Anita" For co1 = LBound( misAmigos() ) To UBound( misAmigos() ) MsgBox Str( co1 ) & " . pero tiene el inconveniente de que ni aun usando Preserve.2. se logra agregando una simple palabra clave: Sub Ejemplo_Matrices9 Dim misAmigos(2) As String Dim co1 As Integer misAmigos(0) = "Edgar": misAmigos(1) = "Gloria" : misAmigos(2) = "Toñito" For co1 = LBound( misAmigos() ) To UBound( misAmigos() ) MsgBox Str( co1 ) & " .

ByVal Tamano As Integer) As Variant Dim mTmp() As Variant Dim co1 As Integer If Tamano > UBound( Matriz() ) Then ReDim Preserve Matriz( Tamano ) ElseIf Tamano < UBound( Matriz() ) Then ReDim mTmp( Tamano ) For co1 = LBound( mTmp() ) To UBound( mTmp() ) mTmp( co1 ) = Matriz( co1 ) Next Redim Matriz( Tamano ) Matriz() = mTmp() Erase mTmp End If FuncionRedimencionarMatriz = Matriz() End Function Pero para que no quede duda. veamos su uso. que hace exactamente lo mismo. ByVal Tamano As Integer) Dim mTmp() As Variant Dim co1 As Integer If Tamano > UBound( Matriz() ) Then ReDim Preserve Matriz( Tamano ) ElseIf Tamano < UBound( Matriz() ) Then ReDim mTmp( Tamano ) For co1 = LBound( mTmp() ) To UBound( mTmp() ) mTmp( co1 ) = Matriz( co1 ) Next Redim Matriz( Tamano ) Matriz() = mTmp() Erase mTmp End If End Sub Como una función. si es mayor solo redimensiona.5. seguro que si.Divide y vencerás. si es igual la deja tal cual: Sub RedimencionarMatriz( Matriz() As Variant. es una tarea idónea para convertirla en una subrutina o si lo deseas en una función como se ve en el tema 4. copia los valores a mantener y redimenciona.7. excepto que devuelve el valor en vez de manipular el parámetro pasado.3. Aquí las dos formas y tu decides cual usar. "Mis números" Next 'Borramos la memoria usada por la matriz temporal Erase mTmp End Sub ¿Se te ocurre alguna otra?. Function FuncionRedimencionarMatriz( Matriz() As Variant.Aprendiendo OOo Basic 53 MsgBox misNumeros( co1 ).9.8. en donde le pasamos la matriz a redimensionar y el nuevo tamaño que tendrá.2.6. 64. tanto como subrutina y como función: 'Usándola como subrutina Sub Ejemplo_Matrices12 Dim misNumeros(9) As Variant Dim mTmp() As String Dim co1 As Integer misNumeros() = Array( 1.10 ) . Como es una tarea habitual (el disminuir de tamaño una matriz y desear mantener los valores restantes). si es menor.4.8 Funciones y subrutinas . Como una subrutina.

6. hemos visto la declaración y el uso de matrices de una sola dimensión.7.54 4. 1 ) = "1-1" . "Mis números" Next End Sub 'Usándola como función Sub Ejemplo_Matrices13 Dim misNumeros(9) As Variant Dim mTmp() As String Dim co1 As Integer 'Llenamos la matriz misNumeros() = Array( 1. 2 ) As String 'Llenamos los datos mDatos( 0. Sub Matrices_Multidimension1 Dim mDatos( 2. 0 ) = "0-0" mDatos( 0. crecemos la matriz misNumeros() = FuncionRedimencionarMatriz( misNumeros(). si bien ahora la mayoría de las maquinas disponen de muchos megas de ram. es posible declarar y usar matrices de más de una dimensión veamos como se hace. 15 ) 'Asignamos un valor al indice 12 misNumeros(12) = 12 'Verificamos que lo haya guardado MsgBox misNumeros(12) 'Llamamos de nuevo a la funcion. le indicamos dos tamaños separados por una coma. observa el uso de la palabra clave Erase para borrar de memoria las matrices dinámicas que ya no usemos.3. 5 ) 'Verificamos que estén los datos For co1 = LBound( misNumeros() ) To UBound( misNumeros() ) MsgBox misNumeros( co1 ).2. Tamaño As Integer) As Tipo Observa como ahora. 64. un ejemplo es más ilustrativo.5. 64. 1 ) = "0-1" mDatos( 0.9. "Mis números" Next End Sub OOo Basic es muy noble en el manejo de las matrices. observa el paso de argumentos.10 ) 'Llamamos a la funcion. 15) misNumeros(12) = 12 MsgBox misNumeros(12) Call RedimencionarMatriz( misNumeros().4. esta vez la disminuimos misNumeros() = FuncionRedimencionarMatriz( misNumeros(). Hasta ahora. La sintaxis para declarar matrices multidimensionales es la siguiente: Dim Nombre_Matriz( Tamaño As Integer. 0 ) = "1-0" mDatos( 1.6 Matrices – Juntos pero no revueltos Call RedimencionarMatriz( misNumeros(). procura mantener el control de la cantidad de memoria que usas en tus macros. 2 ) = "0-2" mDatos( 1. 5) 'Verificamos que estén los datos For co1 = LBound( misNumeros() ) To UBound( misNumeros() ) MsgBox misNumeros( co1 ). observa que sencillo es copiar una matriz en otra MatrizDestino() = MatrizOrigen() También.8.

no obstante. nos da dicho número aleatorio entre estos dos y sin querer tienen ahora el “algoritmo” para que devuelvas un número aleatorio entre dos valores dados. Sub Matrices_Multidimension2 Dim mNumeros( 9. co2 As Integer 'Recuerda que por default los indices de las matrices empieza en cero For co1 = 0 To 9 For co2 = 0 To 9 mNumeros( co1. 2 ) = "1-2" mDatos( 2. parece ser que el limite esta determinado una vez más por la cantidad de memoria ram que contenga la maquina donde se ejecute la macro. 1 ) 2. creo que es más por mis limites y flojera que no lo he comprobado. Con las matrices de dos dimensiones podemos simular el uso de una pequeña base de datos o el uso de una hoja de calculo donde guardamos una serie de datos en columnas que se denominan “campos” y filas que se denominan “registros”. co2 ) = Rnd() * 100 + 1 Next Next 'Comprobamos un indice cualquiera MsgBox mNumeros( 4. 9 ) As Integer Dim co1 As Integer. 1 ) = "2-1" mDatos( 2. así que te invito a que hagas tus pruebas con muchas dimensiones y las compartas conmigo. llenamos una matriz de 10 x 10 elementos y la llenamos con valores aleatorios de entre 1 y 100. que nos devuelve un número aleatorio entre 0 y 1 que al ser multiplicado por el valor superior que nos interesa y sumarle el valor inferior que nos interesa. en lo personal matrices con más de tres dimensiones se me hacen complicadas de manipular. 2 ) = "2-2" 'Mostramos los MsgBox mDatos( MsgBox mDatos( MsgBox mDatos( End Sub datos 0. veamos un sencillo ejemplo: Sub Matrices_Multidimension3 Dim mTelefonos( 2. 2 ) 55 Piensa en las matrices de dos dimensiones como en una hoja de calculo formada por filas y columnas. Otro ejemplo divertido.Aprendiendo OOo Basic mDatos( 1. la matriz anterior quedaría así: 0 0 1 2 0-0 0-1 0-2 1 1-0 1-1 1-2 2 2-0 2-1 2-2 Por supuesto puedes declarar y usar matrices de más de dos dimensiones ¿hasta cuantas?. 0 ) = "2-0" mDatos( 2. 4 ) End Sub Observa el uso de la función Rnd(). 0 ) 1. 1 ) As String .

solo la primer dimension Redim Preserve mDirectorio( co1. 1 ) = Telefono 'Vamos construyendo nuestro directorio sTmp = sTmp & "El telefono de " & mDirectorio( co1. 0 ) & " es " & mTelefonos( 2.6 Matrices – Juntos pero no revueltos MsgBox "El telefono de " & mTelefonos( 2. con lo cual. llenando la variable sTmp “después” de salir del bucle. 2. "Continuar" ) Loop While iContinuar = 6 'Mostramos nuestro directorio MsgBox sTmp End Sub Observa atentamente que hacemos un poco de trampa al ir guardando los valores introducidos por el usuario en un variable temporal (sTmp). 0 ) = Nombre mDirectorio( co1. 1 ) & Chr(13) 'Incrementamos nuestro contador de registros co1 = co1 + 1 'Preguntamos si desea continuar iContinuar = MsgBox( "¿Deseas capturar mas datos?". 1 ) = "12345678" mTelefonos( 1. 1 ) = "32458924" 4. como en el ejemplo siguiente: MsgBox Ubound( mDirectorio. 0 ) = "Lidia" mTelefonos( 2. 1 ) As String Nombre As String Telefono As String iContinuar As Integer co1 As Integer sTmp As String Do 'Solicitamos el nombre. no estamos muy seguros de que efectivamente los datos estén siendo guardados dentro de la matriz. "Nombre" ) ) Telefono = Trim( InputBox( "Ahora su telefono". 0 ) = "Antonio" mTelefonos( 1. para resolver esto tienes que hacer uso de la función UBound vista más arriba. Te muestre tu directorio completo. pero con una pequeña variante. para corroborarlo. veamos como: Sub Dim Dim Dim Dim Dim Dim Matrices_Multidimension4 mDirectorio( 0. si le estableces un número superior al de dimensiones que tiene la matriz. pero OJO. 0 ) & " es " & mDirectorio( co1. Obliga al usuario a introducir un nombre y teléfono. le tienes que indicar de que dimensión quieres saber su limite superior. 1 ) = "87654321" mTelefonos( 2. observa el uso de la funcion Trim para quitar espacios sobrantes Nombre = Trim( InputBox( "Escribe un nombre". "Telefono" ) ) 'Redimencionamos la matriz. 0 ) = "Gloria" mTelefonos( 0. que no estén vacíos estos campos . 4 + 32. es decir. 1 ) En donde nos mostrara el indice superior de la primer dimensión y así sucesivamente. te dará un error. 1 ) End Sub Pero lo interesante y divertido es darle la oportunidad al usuario de ir capturando estos datos e ir creciendo la matriz según las necesidades de este. de tarea tienes que modificar la macro para que: 1.56 mTelefonos( 0. 1 ) 'Guardamos los datos en el nuevo indice mDirectorio( co1.

"b" ."m"."."+"."_"."¡"."j" ."Ñ". como una matriz dentro de otra.". pero ya lo notaste."k" ."Oso". es decir."5"."[") 'Nuestra contraseña sera de 10 caracteres For co1 = 1 To 10 'Seleccionamos aleatoriamente.". UNO de los cuatro grupos mTmp = mDatos( CInt( Rnd() * 3 ) ) 'Seleccionamos aleatoriamente. borrarlo efectivamente."B" . Si."c" . ingeniatelas para poder darle la oportunidad al usuario de borrar un registro."g" . pero esta dentro de lo posible y confío en tus capacidades. están implementadas de estar forma."Fierro") mTmp = MsgBox mTmp = MsgBox mTmp = MsgBox End Sub mDatos(0) mTmp(0) mDatos(1) mTmp(1) mDatos(2) mTmp(2) Observa el uso de una variable temporal (mTmp) para asignar la matriz interna y así poder acceder a sus valores."&" . algunas funciones y estructuras de OpenOffice."x"."U"."/" ."Potasio". de ahí la importancia de que las conozcas."y". y por supuesto."Y".">".Aprendiendo OOo Basic 57 3.":". algunos autores a estas le llamas matrices escalares."·" . veamos su uso: Sub Matrices_Matrices1 Dim mDatos(2) As Variant Dim mTmp As Variant mDatos(0) = Array("Perro"."s"."."."8"."o".org que veremos más adelante."N"."!" ."l" ."n"."Q"."$" . observa como tenemos cuatro grupos. es decir."<"."h" . letras mayusculas. veamos un ejemplo divertido de los que me gustan: Sub Dim Dim Dim Dim Dim Matrices_Matrices2 mDatos(3) As Variant mTmp As Variant co1 As Integer sCaracter As String sContra As String 'Llenamos los datos."0") mDatos(3) = Array( "\" ."Plata". Otra variante del uso de las matrices."Caoba"."D" ."}"."."Pino"."%" ."R"."L" . es decir."=" ."V"."Gato"."G" ."z") mDatos(1) = Array( "A" . numeros y caracteres especiales mDatos(0) = Array( "a"."¿"."O"."H" ."X". reconozco que el punto tres no esta nada fácil cuando uno va empezando."Z") mDatos(2) = Array("1"."i" ."e" ."]". Por ultimo."M"."Tiburon". así que. letras minusculas."I" ."T"."J" ."3". si."u"."C" ."|" ."{"."S"."2"."ñ". UN elemento del grupo.")" ."P"."?" ."F" ."v"."(" ."d" . a trabajar."E" ."k"."w"."p". observa como usamos la funcion Rnd y la multiplicamos por el indice superior del grupo seleccionado sCaracter = mTmp( CInt( Rnd() * UBound(mTmp) ) ) 'Vamos juntando los caracteres de la contraseña sContra = sContra & sCaracter Next 'Mostramos la contraseña MsgBox "Tu contraseña es: " & sContra ."7"."4"."r"."f" ."Manganeso"."9". tener dentro de una matriz otra matriz. su uso es muy sencillo."6"."Azufre"."Fresno") mDatos(2) = Array("Cobre". tienes que encontrar la manera de preguntarle al usuario si quiere borrar un registro."W"."t"."-"."K" . es tener matrices de matrices."Burro") mDatos(1) = Array("Cedro".

las variables también se crean y fenecen. El lugar donde declares una variable y como lo hagas. entendiendo por tiempo de vida.7. este capitulo.1 Ámbito Local Estas variables son las que se declararan dentro del cuerpo de una macro o función y se crean al invocar a esta y se destruyen al finalizar. digamos entre 5 y 50 caracteres Y sin querer tenemos un nuevo capitulo completo. queda a tu curiosidad e imaginación buscarle sus aplicaciones practicas y las no tan practicas. para comprobar que efectivamente. la buena noticia es que nosotros decidimos cuando y cuanto. casi completo.7 Ámbito de variables – Ahora me ves. veamos cual es: 4. determinara su “visibilidad” y tiempo de vida. tienes tarea. el tiempo que esta disponible para poder acceder y manipular su contenido.6 Matrices – Juntos pero no revueltos End Sub Analizala y veras que no es tan complejo como parece y si. aquellas que no sirven para nada. el nivel más bajo y básico ya lo conoces pues. solo esta macro puede “ver” a la variable iEdad. ponle un rango mínimo y máximo que pueda escoger. lo siento. pero todas lo hacen. modifica la macro de modo que le pregunte al usuario de cuantos caracteres quiere su contraseña. ¡Feliz programación! 4. dar por completo un tema es un poco aventurado. si. lo damos por concluido. que a veces. si has seguido estos apuntes. bueno. como en: Option Explicit Sub Variables_Locales1 Dim iEdad As Integer 'Mostramos el valor de la variable MsgBox iEdad 'Cambiamos su valor iEdad = 34 'Mostramos de nuevo el valor de la variable MsgBox iEdad End Sub Ejecuta varias veces la macro anterior para que observes como “siempre” el valor inicial de la variable es cero. unas duran más otras menos. los has venido usando desde el inicio de estas notas. son las más divertidas. a esta visibilidad y tiempo de vida se le conoce como ámbito de la variable. crea una segunda macro desde donde intentemos usar esta variable: Sub Variables_Locales2 .58 4. a estas alturas ya te habrás dado cuenta de la cantidad de variantes que se pueden tener con unas cuantas instrucciones de OOo Basic por lo cual. ahora no Como todo en esta vida. lo cual aprenderemos en este capitulo. pero para fines prácticos.

si tienes la precaución de usar la palabra clave Option Explicit.Aprendiendo OOo Basic 59 'Intentamos mostrar el valor de la variable iEdad MsgBox iEdad End Sub Por supuesto. Veamos un ejemplo más. el IDE de solo te mostrara un error. Copia las dos macros siguientes y ejecuta la que se llama Variables_Locales4 varias veces: Option Explicit Sub Variables_Locales4 Call Contar() . ojo. te evitara muchos dolores de cabeza. Entonces. lo cual. tienes que ejecutar la macro que se llama Variables_Locales3: Option Explicit Sub Variables_Locales3 Dim sTmp As String sTmp = "Aquí no soy nadie" Call Soy_Filosofo Call Soy_Divertido MsgBox sTmp End Sub Sub Soy_Filosofo Dim sTmp As String sTmp = "Ahora soy un filosofo" MsgBox sTmp End Sub Sub Soy_Divertido Dim sTmp As String sTmp = "Ahora soy divertido" MsgBox sTmp End Sub Tienes que ser muy observador para que notes como la variable toma el valor asignado en cada macro. todas la variables declaradas dentro de macros. si ejecutas la segunda macro. te tiene que dar un error como el de la siguiente imagen: Observa la flecha en el margen izquierdo que nos indica la línea donde se produjo el error y observa también el mensaje que es muy claro. en resumen. no hemos definido la variable para “esa macro” dentro de esa macro. tienen ámbito local. cada una es diferente y se inicializa y termina con la macro donde se declara. te recomiendo que nunca olvides de usar.

dentro de la macro Contar. específicamente en la declaración de la variable y volvemos a ejecutar la macro Variables_Locales4. ejecutando varias veces la macro Variables_Locales4. como podrás demostrarlo. pero esta segunda versión donde llamamos varias veces a la macro Contar: Option Explicit Sub Variables_Locales4 Call Contar() Call Contar() Call Contar() End Sub Sub Contar Static iContador As Integer iContador = iContador + 1 MsgBox iContador End Sub ¿Lo notaste?. este valor lo conservara mientras se ejecute la macro que llamo a la macro donde esta declarada la variable Static.60 End Sub Sub Contar Dim iContador As Integer iContador = iContador + 1 MsgBox iContador End Sub 4.7 Ámbito de variables – Ahora me ves. es decir. observa como declaramos la variable iContador en la macro Contar. en nuestro caso. vamos a hacer un pequeño cambio a la macro Contar. incrementa el valor de la variable una unidad cada vez. aunque estemos declarando la variable iContador como Static. el siguiente cambio en la macro te debería dar un error de -variable no definida-. ahora no Siempre lo mismo. ¿verdad?. ¿que pasará si llamamos a la macro varias veces como en el ejemplo siguiente?: Option Explicit Sub Variables_Locales4 Call Contar() Call Contar() Call Contar() End Sub Sigue igual. en vez de usar la palabra clave Dim. siempre te muestra el valor 1. Option Explicit Sub Variables_Locales4 Call Contar() Call Contar() Call Contar() 'La siguiente linea “deberia” darte un error MsgBox iContador . como puedes comprobarlo fácilmente tratando de mostrar su valor desde la macro Variables_Locales4. el valor máximo siempre es tres. ¿verdad?. usamos la palabra clave Static. pero ahora. no por ello deja de ser una variable de ámbito local. con lo que le estamos indicando que conserve el valor entre las llamadas a la macro. OJO. por que llamamos a la macro Contar tres veces y esta.

dice el maestro Savater. Espero que lo hayas notado. ahora. recuerda que la cabecera es el inicio de un modulo. "Continuar") 'Recuerda que si el usuario presiona Si. pues eso. para que cuente hasta que le digamos que “No”. tu decides. donde “siempre” tienes que agregar la otra importante palabra clave Option Explicit. pero te aseguro que lo agradecerás más de una vez.7. Observa el ejemplo siguiente: Option Explicit 'Observa que en vez de Dim estamos usando Private Private intContador As Integer Sub Sumar_y_Restar 'Llamamos a la macro Sumar Call Sumar() 'Mostramos el valor de la variable MsgBox intContador 'Llamamos a la macro Restar Call Restar() 'Mostramos de nuevo el valor de la variable MsgBox intContador End Sub Sub Sumar 'Aquí aumentamos la variable en dos unidades intContador = intContador + 2 End Sub Sub Restar 'y aquí restamos a la variable una unidad intContador = intContador . el valor que devuelve MsgBox es 6 Loop While iRespuesta = 6 End Sub 4. -nos vienen bien las enseñanzas de los maestros. estamos solos para decidir-. te recuerdo. pero continuamente te invito a experimentar y a que tomes tus propias decisiones y te forjes tus propios criterios para tu programación. para que nos avise siempre si no hemos declarado una variable. corresponde a las variables declaradas en la cabecera de un modulo usando la palabra clave Private. no es obligatorio. le haremos un pequeño cambio a la macro Variables_Locales4. esto. si lo prefieres. Option Explicit Sub Variables_Locales5 Dim iRespuesta As Integer Do Call Contar() iRespuesta = MsgBox( "¿Continuar contando?". pero al final.Aprendiendo OOo Basic End Sub 61 ¿Verdad que es muy divertido?.2 Ámbito Privado Este segundo nivel. aquí como en la vida.1 End Sub . 4+32. puedes crear otra macro para que la anterior quede tal cual.

antes de demostrarte esto. la teoría dice que estas variables. es “visible” y manipulable por cualquier macro o función declarada en el modulo. solo son visibles para el modulo donde se declaran. 3. ahora no Nota como ahora. como se que eres observador. seleccionas Insertar y después Modulo BASIC como te muestro en la siguiente imagen. vamos a adelantarnos un poquito en los temas y veremos como agregar un segundo modulo a nuestra biblioteca para agregar más macros y demostrar como las variables declaradas a nivel modulo con Private son visibles por cualquier otro modulo.62 4. tienes la opción de cambiar el nombre del modulo. veamos una variante de la macro anterior para seguir sumando y restando: Option Explicit Private intContador As Integer Sub Sumar_y_Restar2 Dim iRes As Integer Do iRes = MsgBox( "Para sumar presiona SI" & Chr(13) & "Para restar presiona NO" & _ Chr(13) & "Para salir presiona CANCELAR". nos basta tener dos módulos para pruebas como en: . para ello. Tienes que ver el nuevo modulo al lado del anterior.7 Ámbito de variables – Ahora me ves. da un clic con el botón secundario de tu ratón (normalmente el derecho) sobre la etiqueta del modulo actual donde estés trabajando. pero en mis pruebas TAMBIEN son visibles en otros módulos. de este. "Sumar y Restar") Select Case iRes Case 6 Call Sumar() Case 7 Call Restar() End Select MsgBox intContador Loop Until iRes = 2 End Sub Ahora si. te dejo a tu criterio que lo hagas. por ahora. la variable intContador. notaras en el menú contextual anterior. esta acción te tiene que mostrar un menú contextual. ojo.

Option Explicit Dim intContador As Integer 4. que es cero. de forma predeterminada. debe ser declarada en la cabecera de un módulo con la palabra clave Global de la siguiente manera: Option Explicit . por lo que no lo repetiré aquí. que las variables declaradas a nivel cabecera de modulo usando la palabra clave Dim. pues de este modo.7. pues recuerda que el valor inicial de toda variable numérica es cero. solo esperemos que pronto se arregle y funcione como dicen que debe hacerlo. veamos que pasa: Option Explicit Sub MostrarValor() MsgBox intContador End Sub Nota que la macro anterior esta en el modulo 2 y al ejecutarla nos muestra el valor de la variable. copia y ejecuta la siguiente macro: Option Explicit Private intContador As Integer Sub ValorVariable intContador = 100 'Llamamos a la macro del modulo 2 Call MostrarValor() End Sub Creo que es bastante claro que la variable se puede manipular y acceder desde cualquier otro modulo.3 Ámbito de Dominio Publico En este ámbito. aun y cuando se declare con Private.4 Ámbito Global Este ámbito es igual al de dominio publico en cuanto a su visibilidad. Te agradeceré si haces tus pruebas y si notas algo diferente o te funciona como “debería” me lo hagas saber. este agrega la declaración de una nueva macro. pero observa como “no” nos da error. usar Private y Dim es indistinto y el siguiente tema no tiene razón de ser. se supone. son visibles para cualquier modulo de la biblioteca. como dice la teoría. pues toma la declaración de la variable del modulo 1. 4.Aprendiendo OOo Basic 63 Nota que al insertar un modulo. pues esta guarda su ultimo valor.7. la variable es accedida desde otras bibliotecas del archivo. pero difiere en cuanto a su función. Para que una variable sea de ámbito global. pero en mis pruebas es visible hasta por los módulos de otras bibliotecas del archivo y se comporta exactamente del mismo modo que las variables de ámbito privado vistas en el tema anterior. Volvamos al modulo 1. en mis pruebas. incluso. vamos a renombrarla y trataremos de acceder a la variable intContador declarada y usada en el modulo uno. lo cual espero se arregle en futuras versiones. aun y cuando se termina la macro.

48. en otras ocasiones. la recomendación para este tema es procurar usar lo más posible variables de ámbito local y después de ámbito publico. esperemos que con los muchos ejemplos que mostramos. aun y cuando ya termino la ejecución de la macro. 48. "Aprendiendo OOo Basic" MsgBox "Ya voy a medio camino".64 Global intgContador As Integer Sub Variable_Global() intgContador = intgContador + 100 MsgBox intgContador End Sub 4. "Aprendiendo OOo Basic" End Sub . 48. pero nos resultara muy útil para nuestros propósitos. comencemos con los ejemplos y después las explicaciones. esto es por que conforme ya no uses una variable. como en otros más que tal vez se te presenten. 4.8 Funciones y subrutinas – Divide y vencerás “Todo lo complejo puede dividirse en partes simples” Rene Descartes En ocasiones. El decidir que variables usar y con que ámbito no es un tema menor y cuando uno va empezando se convierte casi en un problema existencial.7 Ámbito de variables – Ahora me ves. Su uso podría compararse en función a las variables de ámbito local. En estos casos. "Aprendiendo OOo Basic" MsgBox "Ya tengo sueño". "Aprendiendo OOo Basic" MsgBox "Es fácil y divertido". En el tema 4. no nos son suficientes para resolver algún problema planteado o su complejidad nos obliga a pensar en otra alternativa. el código se vuelve tan largo que se vuelve difícil de leer. En este capitulo veremos como declararlas y usarlas . las funciones e instrucciones incorporadas del lenguaje.2 Instrucciones y funciones en OOo Basic . "Aprendiendo OOo Basic" End Sub Si. Y con esto terminamos un tema más. no tiene nada de extraordinario. Vamos a suponer una segunda macro similar a la anterior: Sub MostrarMensaje2() MsgBox "Es un poco tarde". analizar o mejorar. vimos algunos conceptos que nos serán muy útiles en este. pero no te preocupes. pero a nivel global de todas las macros del archivo. "Aprendiendo OOo Basic" MsgBox "Solo acabamos este tema". esta se destruye y se libera la memoria usaba por ella al concluir la macro donde se use. por supuesto esto no es restrictivo solo tu practica y experiencia te dirán cual es la mejor opción. declaradas con la palabra clave Static. 48. ahora no Al ejecutar varias veces la macro anterior. recurrimos a crear nuestras propias funciones y subrutinas. copia y ejecuta la siguiente macro: Option Explicit Sub MostrarMensaje1() MsgBox "Estoy aprendiendo OOo Basic". al ser de ámbito local. 48. 48. notaras como guarda el valor. te sea más fácil aprender a decidir lo mejor en cada caso.

al llamarla. En lo personal el uso de Call solo lo uso para saber que es una subrutina personalizada. también. que no es más que una macro creada por nosotros a la que comúnmente (no es obligatorio) se le pasa un/unos parámetro(s) o argumento(s) y realice una tarea. También observa que usamos la palabra clave Call para llamar a la macro. Cuando pasamos los argumentos por valor. pero ya sabes. podemos modificar su valor “dentro” de la subrutina. los argumentos pasados sean del mismo tipo de los esperados. siempre son los mismos. El uso de paréntesis como abras notado también es opcional. Ahora. como muchas instrucciones que usa OpenOffice. las siguiente líneas son equivalentes: Sub MostrarMensaje3() Call MuestraMensaje( "Estoy aprendiendo OOo Basic" ) MuestraMensaje( "Estoy aprendiendo OOo Basic" ) MuestraMensaje "Estoy aprendiendo OOo Basic" End Sub Observa como en la primera usamos Call y paréntesis. el valor de este argumento solo se puede usar “dentro” de la subrutina que la usa. a una subrutina. este caso es idóneo para que hagamos una subrutina. lo que estamos haciendo es pasarle la “ubicación” de la variable en la memoria. por lo cual. no importa el nombre. una es por valor y otra por referencia. en la segunda omitimos Call y en la tercera quitamos Call y los paréntesis. sino que sea de tipo String. por lo cual. esto no es requisito. Es decir “haga” algo. veremos un tema importante. el icono mostrado y el titulo del cuadro de dialogo. en realidad lo que se hace es pasarle una “copia” del valor de la variable. "Aprendiendo OOo Basic" End Sub Lo importante es que aprendas como llamamos a una macro con argumentos y que es muy importante que. en lo personal. observa como la macro MuestraMensaje “necesita” un argumento llamado Mensaje que es de tipo String. por lo que lo único que cambia es la cadena mostrada. entonces. cuando los argumentos se pasan por referencia.org hacen uso de los paréntesis. y sigamos con nuestras suposiciones. queda a tu criterio su uso u omisión. Copia la siguiente macro y modifica las dos primeras macros para que queden de la siguiente manera: Option Explicit Sub MostrarMensaje3() Call MuestraMensaje( Call MuestraMensaje( Call MuestraMensaje( Call MuestraMensaje( Call MuestraMensaje( Call MuestraMensaje( End Sub "Estoy aprendiendo OOo Basic" ) "Es facil y divertido" ) "Ya voy a medio camino" ) "Es un poco tarde" ) "Ya tengo sueño" ) "Solo acabamos este tema" ) Sub MuestraMensaje(Mensaje As String) MsgBox Cadena. comprobemoslo con un ejemplo: Option Explicit Sub PasoPorReferencia() Dim sMensaje As String . tienes la ultima palabra.Aprendiendo OOo Basic 65 Ahora tenemos dos macros que hacen cosas muy similares. en cambio. se le pueden pasar los argumentos o parámetros de dos maneras. la diferencia es muy sencilla pero es de suma importancia esta diferencia. hago uso de ellos. supongamos que de nuestros mensajes. 48. “necesitamos” pasarle una variable.

"Cadena Original" 'Intentamos modificar el argumento pasado Cadena = "Eso lo dijo Oscar Wilde" End Sub Ahora. Las preocupaciones del uso de la memoria. 48. "Cadena Original" 'Modificamos el argumento pasado Cadena = "Eso lo dijo Lao Tse" End Sub Observa como en este caso. se pasa por valor.org por ejemplo. . 48. no así. otros dicen que todos los argumentos deberían pasarse por valor. tu decides. los argumentos se pasan por referencia. por el momento. pues una subrutina tiene que ser como una unidad completa por si misma. se las vamos a dejar a grandes proyectos. cambiado en la subrutina MsgBox sMensaje End Sub Sub CambiaValor(Cadena As String) 'Mostramos el mensaje con la cadena pasada MsgBox Cadena. la variable origen quedo intacta. Por default. pero observa la diferencia en la declaración de la subrutina. algunos programadores opinan que todos los argumentos deberían pasarse por referencia. y la memoria usada se libera al finalizar la subrutina. para pasar un argumento por valor. He observado que hay dos criterios encontrados en el uso de los argumentos por valor o referencia. como OpenOffice. es decir 'no hemos podido cambiar su valor en la subrutina MsgBox sMensaje End Sub 'Observa el cambio en la declaracion del argumento usando ByVal Sub NoCambiaValor( ByVal Cadena As String ) 'Mostramos el mensaje con la cadena pasada MsgBox Cadena. Una pregunta que nos ayuda a saber si declaramos una variable por valor o referencia es: ¿necesito manipular su valor en la subrutina?. no estamos usando más memoria a este criterio podría argumentarse que los equipos actuales tienen mucha más memoria. donde están involucradas millones de líneas de código. en el siguiente ejemplo: Option Explicit Sub PasoPorValor() Dim sMensaje As String 'Asignamos una cadena a la variable sMensaje = "El trabajo es el refugio de los que no tienen nada que hacer" 'Llamamos a la subrutina y le pasamos el argumento Call NoCambiaValor( sMensaje ) 'Mostramos la variable que nos muestra lo mismo. pues al pasar la dirección de la variable en memoria. tienes que usar la palabra clave ByVal “antes” del nombre del argumento.8 Funciones y subrutinas – Divide y vencerás 'Asignamos una cadena a la variable sMensaje = "La travesia de mil kilometros comienza con un paso" 'Llamamos a la subrutina y le pasamos el argumento Call CambiaValor( sMensaje ) 'Mostramos la variable con el nuevo valor. para nuestros fines prácticos. si pasas los argumentos en subrutinas y funciones por valor o referencia.66 4. salvo que se indique lo contrario. modificamos el argumento pasado y el cambio se ve reflejado en la variable origen. si es no. si la respuesta es si se pasa por referencia.

escribir “código compacto” no es sinónimo de “código eficiente”. cierta ocasión. leí que una macro.Aprendiendo OOo Basic 67 Todas las subrutinas que tengan argumentos tienen que ser invocadas (llamadas) desde otra macro. te dará el siguiente error: Las subrutinas nos ayudan a dividir nuestro código en bloques lógicos o más manejables... es decir. algunos autores no recomiendan el uso de la instrucción Exit Sub. si intentas ejecutar directamente una subrutina con argumentos desde el IDE. existe una instrucción que se llama Exit Sub. para ello. te dará el siguiente error: Y si la intentas ejecutar desde la interfaz del usuario. Habrá ocasiones. no recuerdo donde. procedimiento o subrutina. una vez más. no “debería” . en “teoría” una subrutina “debería” ser completa. desde el menú Herramientas | Macros | Ejecutar macro. no “debería” tener más de una página de líneas. sale inmediatamente de la macro con la instrucción Exit Sub. esto por supuesto es sumamente subjetivo. es decir. en que quieras salir anticipadamente de una subrutina. veamos su uso: Option Explicit Sub Ejemplo_ExitSub() Dim sFrase As String sFrase = Trim(InputBox("Escribe una frase")) Call ContarLetras( sFrase ) End Sub Sub ContarLetras( Cadena As String) If Cadena = "" then Exit Sub Else MsgBox "Hay" & Str(Len(Cadena)) & " letras en la cadena" & Chr(13) & Chr(13) & Cadena End If End Sub Observa como en la subrutina ContarLetras si el argumento pasado esta vacío.. la practica diaria te dictara los mejores argumentos para programar.

por supuesto queda a tu criterio y experiencia su uso. que un gran porcentaje de código. Solo te digo.8 Funciones y subrutinas – Divide y vencerás necesitar salidas “forzadas”. "1" ) ) ) 'Solo si tenemos valores mayores a cero If sRadio > 0 Then dArea = PI * ( sRadio ^ 2 ) MsgBox "El area de un circulo de radio = " & Str(sRadio) & " es =: " & Str(dArea) End If . por ejemplo. que estas “deberían” hacer solo su trabajo y pasarle los datos correctos. por que dentro de la subrutina no es necesario hacer ninguna validación. se tiene que hacer “antes” de llamar a una subrutina. sus defensores y sus detractores. es decir. ya te darás cuenta. es decir. que es el tipo de variable esperado sRadio = CSng( Trim( InputBox( "¿Cual es el radio?". la subrutina anterior podría quedar así: Sub ContarLetras1( Cadena As String) If Cadena <> "" then MsgBox "Hay" & Str( Len(Cadena) ) & " letras en la cadena" & Chr(13) & Chr(13) & Cadena End If End Sub Observa como solo ejecutamos el código si el argumento Cadena “no” esta vacío. despues convertimos el valor a tipo Single. por supuesto esto tiene sus pros y sus contras. algunos autores más exigentes. Supongamos que nos piden hacer una macro que solicite el radio de un circulo y se calcule su área: Option Explicit Sub CalcularAreaCirculo1() Dim dArea As Double Dim sRadio As Single Const PI As Single = 3. es “validar tus datos”. se nos va. un gran porcentaje de errores en muchos programas es por una deficiente validación de datos y también. observa las modificaciones a las macros anteriores: Sub Ejemplo_ExitSub2() Dim sFrase As String sFrase = Trim(InputBox("Escribe una frase")) If sFrase <> "" Then Call ContarLetras2( sFrase ) End If End Sub Sub ContarLetras2( Cadena As String) MsgBox "Hay" & Str(Len(Cadena)) & " letras en la cadena" & Chr(13) & Chr(13) & Cadena End Sub Nota que la validación la hacemos con la linea: If sFrase <> "" Then Por lo que al llamar a la macro ContarLetras2. otra vez lo repito. Lo que si nunca. "Area de un circulo". incluso.1416 'Solicitamos el radio del circulo a calcular. correcto. Veamos otro ejemplo de una subrutina. observa que primero limpiamos los espacios 'con Trim. aplica tu criterio que la experiencia y la practica serán tus mejores aliadas. validando datos. nunca debes de dejar de hacer. garantizar que sean correctos.68 4. para ejemplificar esto. no importa donde lo hagas pero validalos. argumentan que la “validación de datos” (no se te olvide esta frase). ya le estamos pasando un dato validado.

es el tipo de valor “devuelto” por una función. en vez de usar la palabra clave Sub. la macro anterior. debemos cerrarlas con End Function. como el paso por valor o referencia. las funciones también devuelven un “tipo” especifico de valor. usando una función. Otro cambio importante es que para devolver el valor dentro de la función. pero un cambio importante. dArea ) MsgBox "El area de un circulo de radio " & Str(sRadio) & " es =: " & Str(dArea) End If End Sub Sub DevuelveAreaCirculo( Radio As Single. usamos una nueva palabra clave Function. "Area de un circulo". podría ser algo así: Option Explicit Sub CalcularAreaCirculo2() Dim dArea As Double Dim sRadio As Single sRadio = CSng( Trim( InputBox( "¿Cual es el radio?". Area As Double ) Const PI As Single = 3. si se quiere “devolver” un valor. es decir. por supuesto.1416 'Observa como usamos el nombre de la función para devolver al valor AreaCirculo = PI * ( Radio ^ 2 ) End Function Observa el modo de declarar una función. "1" ) ) ) If sRadio > 0 Then 'Observa como usamos la funcion y asignamos el resultado a una variable dArea = AreaCirculo( sRadio ) MsgBox "El area de un circulo de radio = " & Str(sRadio) & " es =: " & Str(dArea) End If End Sub Function AreaCirculo( Radio As Single ) As Double Const PI As Single = 3. es usar una función en vez de una subrutina. en vez de usar End Sub como hasta ahora. "Area de un circulo".1416 Area = PI * ( Radio ^ 2 ) End Sub Si bien lo anterior funciona. la declaración de los argumentos tiene las mismas características usadas en las subrutinas. "1" ) ) ) If sRadio > 0 Then Call DevuelveAreaCirculo( sRadio. usamos el mismo nombre de la función como destino y para finalizar. también pueden devolver el tipo por default de las variables que es Variant pero la recomendación es especificar siempre que te sea posible el tipo de valor que esperas devuelva la función. en vez de usar otro argumento o variable. .Aprendiendo OOo Basic End Sub 69 Si creamos una subrutina. no es común usar subrutinas para manipular variables y argumentos. sino. ahora. lo más usual. en “todas” las declaraciones de Function. quedaría de la siguiente manera: Option Explicit Sub CalcularAreaCirculo3() Dim dArea As Double Dim sRadio As Single sRadio = CSng( Trim( InputBox( "¿Cual es el radio?". te dará un error.

a las funciones también es posible pasarle como argumentos. "1" ) ) ) If sRadio > 0 Then 'Aqui usamos la funcion SIN el argumento opcional dArea = Circulo( sRadio ) 'Y aqui usamos la funcion CON el argumento opcional dPeri = Circulo( sRadio. supongamos que ahora se nos pide hacer una macro que calcule ya sea el área o el perímetro de un circulo. continuemos con nuestro ejemplo del circulo. le agregaremos un argumento opcional para saber si lo que queremos calcular es el perímetro: Option Explicit Sub Dim Dim Dim CalcularCirculo dArea As Double dPeri As Double sRadio As Single sRadio = CSng( Trim( InputBox( "¿Cual es el radio?".8 Funciones y subrutinas – Divide y vencerás El paso de argumentos en subrutinas y funciones. pero en tus funciones puede declarar al igual que los otros argumentos. verdadera o falsa (Boolean). tiene otra posibilidad muy interesante.1416 'Comprobamos si el parametro se paso o no If IsMissing( Perimetro ) Then 'Si no se paso le asignamos el valor por default Perimetro = False End If If Perimetro Then Circulo = PI * ( Radio * 2 ) Else Circulo = PI * ( Radio ^ 2 ) End If End Function Nota el uso de la palabra clave Optional. "Circulo". veamos un ejemplo de uno y otro: Option Explicit Sub Sumando Dim mDatos(9) As Integer Dim co1 As Integer . 64. como se ve en el ejemplo anterior. Por supuesto. puedes declarar tantos argumentos opcionales como necesites. De tarea. para verificar si se paso o no un argumento usas la función de OOo Basic IsMissing( Argumento ). True ) MsgBox "Area = " & Str(dArea) & chr(13) & _ "Perimetro = " & Str(dPeri). en otros casos. Optional Perimetro As Boolean ) As Double Const PI As Single = 3. lo único que tienes que considerar es que los argumentos esperados como matrices. tienes siempre que declararlos como Variant si para llenar dicha matriz usas la función Array. ¿que es lo que desea calcular? Y por supuesto. "Circulo" End If End Sub Function Circulo( Radio As Single. le asignes un valor por default a dicho argumento. modifica la macro para que le preguntes al usuario. solo muestra el valor del calculo solicitado. el punto importante es que “compruebes” si se paso o no el argumento para que en su defecto. el paso de argumentos opcionales. puedes usar el mismo tipo con que declares tu matriz. matrices. del tipo que necesites. para fines de lo que se nos pide usamos una variable tipo boleana.70 4. para usar la misma función.

60. también es posible hacer uso de la instrucción Exit. siempre devuelve una matriz tipo Variant. siempre.40. esto es por que la función Array. En las funciones. así que no ahondare en ello.30.70.20. ahora. aquí usaremos Exit Function. Corrige la declaración de la función y ahora si. Function SumaMatriz ( Datos() As Variant ) As Integer Dim co1 As Integer For co1 = LBound( Datos() ) To UBound( Datos() ) SumaMatriz = SumaMatriz + Datos( co1 ) Next End Function Observa como cambiamos a tipo Variant el tipo de matriz que espera con lo cual.Aprendiendo OOo Basic 71 'Llenamos la matriz con datos aleatorios entre 1 y 100 For co1 = LBound( mDatos() ) To UBound( mDatos() ) mDatos( co1 ) = Rnd() * 100 + 1 Next MsgBox "La suma de la matriz es = " & Str( SumaMatriz( mDatos() ) ) End Sub Function SumaMatriz ( Datos() As Integer ) As Integer Dim co1 As Integer For co1 = LBound( Datos() ) To UBound( Datos() ) SumaMatriz = SumaMatriz + Datos( co1 ) Next End Function Observa como se declaro la matriz tipo Integer. debe de funcionar. no importa como hayas declarado la matriz. tan solo te muestro un sencillo ejemplo de su uso: . la razón es que la función espera una matriz de tipo Integer y se le esta pasando una matriz de tipo Variant. tanto la variable en la macro como el argumento en la declaración de la función.90) 'Intentamos sumar la matriz iSuma = SumaMatriz( mDatos() ) MsgBox Str( iSuma ) End Sub Function SumaMatriz ( Datos() As Integer ) As Integer Dim co1 As Integer For co1 = LBound( Datos() ) To UBound( Datos() ) SumaMatriz = SumaMatriz + Datos( co1 ) Next End Function Nos da un error. tiene las mismas consideraciones que te comente para la instrucción Exit Sub.80. ¿verdad?. ya no nos da error.50. intentemos usar una matriz. haciendo uso de la función Array y veamos que pasa: Option Explicit Sub Sumando2() Dim mDatos() As Integer Dim iSuma As Integer 'Llenamos la matriz con la funcion Array mDatos() = Array(10. claro.

"@" ) 'No debe ser ni el primero ni el ultimo carácter 'en el siguiente tema aprenderemos más de los operadores lógicos If pos > 1 And pos < Len(Correo) Then ValidarCorreo = True Else ValidarCorreo = False End If End If End Function Para terminar este tema. por ejemplo. pues al salir con Exit Function 'la función devuelve Falso. salimos de la función If Correo = "" Then 'Si lo deseas esta linea la puedes omitir. el siguiente: Option Explicit Sub MostrarMensajes1() Dim sMensaje As String sMensaje = "Por favor escoge una opcion: CANCELAR = Sales del programa " & _ "REPETIR = Intenta de nuevo IGNORAR = No hace nada" MsgBox sMensaje. Supongamos que tenemos que mostrar muchos mensajes al usuario. "Opcion" End Sub Como podrás notar. la estética no es muy bonita que digamos: . veamos el ejemplo de una función que hace uso de una función incorporada del lenguaje que es muy bonita.8 Funciones y subrutinas – Divide y vencerás 'Para fines didácticos. Correo.72 Option Explicit Sub Correo() Dim sCorreo As String sCorreo = Trim(InputBox("Dame tu correo")) If ValidarCorreo( sCorreo ) Then MsgBox "Correo Valido" Else MsgBox "Correo NO valido" End If End Sub 4. pero tal vez en otros casos que no sea booleana 'la respuesta. necesites asignarle un valor predeterminado diferente ValidarCorreo = False Exit Function Else 'Buscamos la posicion de la arroba con la función InStr pos = InStr( 1. 2. solo validaremos que el correo tenga 'el obligado símbolo de arroba (@) y que no sea ni el primer 'ni el ultimo carácter Function ValidarCorreo( Correo As String ) As Boolean Dim pos As Integer 'Si el argumento Correo esta vacío.

para ello.400. espera como argumentos."REPETIR = Intenta de nuevo". no es una actividad que digamos muy placentera. es una función que me gusta mucho. nuestro cuadro de mensaje tiene mucha mejor presentación Pero imaginate que tienes que mostrar múltiples mensajes con diferentes cadenas y estar concatenando los saltos de linea en cada una."".200. se hace usando la función Chr pasandole el argumento 13. juntamos en una cadena unos números separados por un guion: Sub JuntarDatos() Dim mDatos() As Variant Dim sCadena As String mDatos() = Array(100."IGNORAR = No hace nada") 'Llamamos a la funcion que inserta los saltos de linea . hagamos una función que lo haga por nosotros Function InsertarSaltos( Datos() ) As String InsertarSaltos = Join( Datos(). 2. lo que hace es juntar cada elemento de la matriz separados por el carácter separador.500) sCadena = Join( mDatos(). "Opcion" End Sub Ahora si. la función Join de OOo Basic.Aprendiendo OOo Basic 73 Mejoremos un poco la vista de nuestro cuadro de mensaje. una matriz y un carácter separador. insertando unos saltos de linea. que es el valor ASCII para el salto de linea. de la siguiente manera: Sub MostrarMensajes2() Dim sMensaje As String sMensaje = "Por favor escoge una opcion:" & Chr(13) & Chr(13) & _ "CANCELAR = Sales del programa" & Chr(13) & _ "REPETIR = Intenta de nuevo" & Chr(13) & _ "IGNORAR = No hace nada" MsgBox sMensaje."CANCELAR = Sales del programa". que. en el ejemplo siguiente. "-") MsgBox sCadena End Sub La función InsertarSaltos la usamos de la siguiente manera: Sub MostrarMensajes3() Dim mMensajes() As Variant Dim sMensaje As String 'Recuerda que la funcion Array SIEMPRE devuelve una matriz Variant mMensajes() = Array("Por favor escoge una opcion:". Chr(13) ) End Function Observa que función más sencilla y que útil y linda es.300. como sabes.

2. "Opcion" End Sub 4.8 Funciones y subrutinas – Divide y vencerás Dividir nuestro código en subrutinas y funciones.74 sMensaje = InsertarSaltos( mMensajes() ) 'Mostramos el mensaje MsgBox sMensaje. otro tema a llegado a su fin. por ahora. es el pan nuestro de cada día. no debes de tener duda pues más adelante las usaremos frecuentemente. !!Feliz programación¡¡ .

El número resultante del siguiente ejemplo. tal vez te resulte familiar: Option Explicit Sub Dim Dim Dim Potencias1() iNum1 As Integer iNum2 As Integer iResul As Integer iNum1 = 2 iNum2 = 10 'Base 'Exponente iResul = iNum1 ^ iNum2 MsgBox Str(iResul) End Sub En general con todos los operadores. de relación y lógicos.Aprendiendo OOo Basic 75 4. es decir. 4. la siguiente operación te tiene que dar un error de desbordamiento.1 “ ^ ” Exponenciación (aritmético) a n Se usa para elevar un número llamado base a otro llamado exponente. por ejemplo.9 Operadores OOo Basic soporta los siguiente operadores aritméticos. debes de tener la precaución de proveer lo mejor posible que el resultado de la operación no exceda el “tamaño” de la variable destino. Sub Dim Dim Dim Potencias2() iNum1 As Integer iNum2 As Integer iResul As Integer iNum1 = 3 iNum2 = 10 'Base 'Exponente iResul = iNum1 ^ iNum2 MsgBox Str(iResul) End Sub .9. el resultado no cabe en la variable iResul declarada como Integer.

como se comprueba en los siguiente ejemplos: Sub Dim Dim Dim Potencias4() iNum1 As Single iNum2 As Single iResul As Double iNum1 = -2 'Base iNum2 = 4 'Exponente iResul = iNum1 ^ iNum2 MsgBox Str(iResul) 'Resultado positivo iNum1 = -2 'Base iNum2 = 5 'Exponente iResul = iNum1 ^ iNum2 MsgBox Str(iResul) 'Resultado negativo End Sub En el caso de que el exponente sea negativo. Dim iResul As Long La base y el exponente no tienen por que ser enteros. lo que hace el lenguaje. pero según tus necesidades podría ser incluso más grande. si este es par será positiva. si es impar será negativa. .54 'Base 'Exponente iResul = iNum1 ^ iNum2 MsgBox Str(iResul) End Sub Tampoco tienen por que ser positivos. el signo de la potencia lo determinará el exponente. como lo dictan las matemáticas.53 iNum2 = 5. invierte la base para que el exponente sea positivo. en este caso Long.76 4. observa el cambio de declaración de las variables: Sub Dim Dim Dim Potencias3() iNum1 As Single iNum2 As Single iResul As Double iNum1 = 2.9 Operadores La solución es cambiar la variable iResul por una más grande. cuando la base es negativa. de acuerdo a las leyes de los signos que ya conoces desde la escuela elemental.

en este caso. que puedes multiplicar valores enteros y no enteros.125 3 2 8 4.Aprendiendo OOo Basic Sub Dim Dim Dim Potencias5() iNum1 As Single iNum2 As Single iResul As Double iNum1 = 2 'Base iNum2 = -3 'Exponente iResul = iNum1 ^ iNum2 MsgBox Str(iResul) End Sub 77 2 = −3 1 1 = = 0. Option Explicit Sub Dim Dim Dim Multiplicacion2() iNum1 As Integer iNum2 As Integer iResul As Integer iNum1 = 11 iNum2 = 56 iResul = iNum1 * iNum2 MsgBox Str(iResul) iNum1 = -11 iNum2 = 56 iResul = iNum1 * iNum2 MsgBox Str(iResul) iNum1 = 11 iNum2 = -56 iResul = iNum1 * iNum2 MsgBox Str(iResul) . las leyes de los signos aplican correctamente. positivos y negativos. al resultado se le llama producto y los números multiplicados factores: Option Explicit Sub Dim Dim Dim Multiplicacion1() iNum1 As Integer iNum2 As Integer iResul As Integer 'Factores iNum1 = 365 iNum2 = 34 iResul = iNum1 * iNum2 MsgBox Str(iResul) End Sub Recuerda que la variable donde asignes el resultado.9.2 “ * ” Multiplicación (aritmético) La multiplicación es la operación aritmética que nos permite hacer una suma abreviada. debe ser lo suficientemente grande para contenerlo.

es. negativos y positivos. Puedes dividir numero enteros y no enteros. Option Explicit Sub Dim Dim Dim Division1() iNum1 As Single iNum2 As Single iResul As Double iNum1 = 123456790 iNum2 = 123 iResul = iNum1 / iNum2 MsgBox Str(iResul) End Sub Sub Dim Dim Dim Division2() iNum1 As Integer iNum2 As Integer iResul As Integer iNum1 = 589 'Dividendo iNum2 = -25 'Divisor iResul = iNum1 / iNum2 'Dividendo 'Divisor . las leyes de los signos aplican de la misma forma que en la multiplicación. al resultado entero se le llama “cociente” y si no es exacta la división a lo que resta se le llama “residuo”.78 iNum1 = -11 iNum2 = -56 iResul = iNum1 * iNum2 MsgBox Str(iResul) End Sub 4. El número a dividir se llama “dividendo”. podría decirse.3 “ / ” División (aritmético) Operación aritmética para saber cuantas veces cabe un número en otro. al otro “divisor”.9 Operadores Recuerda que en las multiplicaciones el orden de los factores no altera el producto (propiedad conmutativa): Sub Dim Dim Dim Multiplicacion3() iNum1 As Integer iNum2 As Integer iResul As Long iNum1 = 12345 iNum2 = 18 iResul = iNum1 * iNum2 MsgBox Str(iResul) iNum1 = 18 iNum2 = 12345 iResul = iNum1 * iNum2 MsgBox Str(iResul) End Sub 4. Es la operación inversa a la multiplicación.9. una resta abreviada.

este operador te devuelve el siguiente entero.1 . es muy diferente que un número sea dividendo que divisor como podemos verlo en el siguiente ejemplo: Sub Dim Dim Dim Division3() iNum1 As Single iNum2 As Single iResul As Double iNum1 = 98765 iNum2 = 321 iResul = iNum1 / iNum2 MsgBox Str(iResul) iNum1 = 321 iNum2 = 98765 iResul = iNum1 / iNum2 MsgBox Str(iResul) End Sub 4. cuando el valor decimales es muy cercano al siguiente entero. el orden de los operandos si importa.9. como en: Sub Dim Dim Dim Division_Entera2() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 100 iNum2 = 25.4 “ \ ” División entera (aritmético) Con este operador obtenemos solo la parte entera de una división: Option Explicit Sub Dim Dim Dim Division_Entera1() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 100 iNum2 = 15 iResul = iNum1 / iNum2 MsgBox Str(iResul) 'Devuelve solo la parte entera iResul = iNum1 \ iNum2 MsgBox Str(iResul) End Sub En algunos casos.Aprendiendo OOo Basic 79 MsgBox Str(iResul) End Sub En el caso de la división.

80 4. como te muestro aquí: Sub Dim Dim Dim Division_Entera3() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 100 iNum2 = 25.1 iResul = iNum1 / iNum2 MsgBox Str(iResul) iResul = iNum1 \ iNum2 MsgBox Str(iResul) iResul = Int( iNum1 / iNum2 ) MsgBox Str(iResul) End Sub 4.9 Operadores iResul = iNum1 / iNum2 MsgBox Str(iResul) iResul = iNum1 \ iNum2 MsgBox Str(iResul) End Sub Si quieres asegurarte que “siempre” te regrese “solo” la parte entera. mejor usa la función Int(valor) que te devuelve solo la parte entera del valor pasado.9.5 “Mod” Resto de una división entera (aritmético) Este operador nos devuelve el residuo entero de una división entera: Option Explicit Sub Dim Dim Dim Resto_Division1() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 100 iNum2 = 15 iResul = iNum1 Mod iNum2 MsgBox Str(iResul) End Sub 15 6 100 10 El siguiente ejemplo hace uso de los operadores “Mod” y ”\” (división entera) para convertir un número decimal en binario: Sub Dim Dim Dim Decimal_Binario() iDec As Integer sBin As String iBase As Integer 'Número entero a convertir iDec = 100 .

55 iResul = iNum1 + iNum2 MsgBox Str( iResul ) End Sub Por su propiedad conmutativa.9.Aprendiendo OOo Basic 81 'El sistema binario es base 2 iBase = 2 'Hasta que el número sea menor que la base Do Until iDec < iBase 'Obtenemos el residuo y lo vamos concatenando sBin = (iDec Mod iBase) & sBin 'Obtenemos la división entera y reasignamos el numero 'si no haces esto. el orden de los sumandos no altera la suma: Sub Dim Dim Dim Sumas2() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 1974 iNum2 = 34 iResul = iNum1 + iNum2 MsgBox Str( iResul ) iNum1 = 34 iNum2 = 1974 iResul = iNum1 + iNum2 MsgBox Str( iResul ) . es la operación aritmética que nos permite combinar dos cantidades para obtener una sola. te quedaras en un ciclo infinito iDec = iDec \ iBase Loop 'Por ultimo concatenamos el ultimo cociente sBin = iDec & sBin 'Mostramos el valor en binario MsgBox sBin End Sub 4.25 iNum2 = 489. A dichas cantidades se les llama sumandos y al resultado suma: Option Explicit Sub Dim Dim Dim Sumas1() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 159.6 “ + ” Suma (aritmético) La adición.

al primero se le llama minuendo y al segundo sustraendo. Es la operación inversa de la suma.7 “ .iNum2 MsgBox Str( iResul ) End Sub 'Minuendo 'Sustraendo La resta no tiene propiedad conmutativa. la suma tendrá el signo del mayor sumando: Sub Dim Dim Dim Sumas3() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 4268 iNum2 = -258 iResul = iNum1 + iNum2 MsgBox Str( iResul ) iNum1 = -5689 iNum2 = 197 iResul = iNum1 + iNum2 MsgBox Str( iResul ) End Sub 4. pero fijate que curioso resultado: Sub Dim Dim Dim Restas2() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 562 iNum2 = 956 .9 Operadores Por leyes de los signos. no te dará el mismo resultado.9.82 End Sub 4.” Resta (aritmético) La sustracción o resta es la operación aritmética que nos permite conocer la diferencia entre dos números. es decir. Option Explicit Sub Dim Dim Dim Restas1() iNum1 As Single iNum2 As Single iResul As Single iNum1 = 5000 iNum2 = 2125 iResul = iNum1 . si intercambias el minuendo y el sustraendo.

este ejemplo es más claro pues esta entre paréntesis: bResul = ( iNum1 = iNum2 ) . Option Explicit Sub Dim Dim Dim Operadores_Relacion() bResul As Boolean iNum1 As Integer iNum2 As Integer iNum1 = 99 iNum2 = 19 bResul = iNum1 = iNum2 MsgBox "Son iguales? " & bResul bResul = iNum1 <> iNum2 MsgBox "Son distintos? " & bResul bResul = iNum1 < iNum2 MsgBox "Menor que? " & bResul bResul = iNum1 > iNum2 MsgBox "Mayor que? " & bResul bResul = iNum1 <= iNum2 MsgBox "Menor o igual? " & bResul bResul = iNum1 >= iNum2 MsgBox "Mayor o igual? " & bResul End Sub Ten cuidado de no confundir los signos de igual (=).Aprendiendo OOo Basic iResul = iNum1 .iNum2 MsgBox Str( iResul ) End Sub 83 4. el resultado de la expresión a la derecha del signo se asigna a la variable a la izquierda del signo. es decir. siempre devuelven un valor verdadero (True) o falso (False).iNum2 MsgBox Str( iResul ) iNum1 = 956 iNum2 = 562 iResul = iNum1 . el primero de izquierda a derecha es el signo igual usado como asignación.8 Operadores de relación Estos operadores nos permiten comparar el valor de dos expresiones o términos. un valor booleano.9. el segundo signo igual (en negritas y rojo) es usado como operador de relación entre dos términos.

cualquier otro valor.9 Not – Negación (lógico) 4. devuelve falso (False).9. devuelve verdadero (True) solo en el caso de que los dos operadores sean verdaderos (True). A Not A V F F V 4. primero te muestro su tabla de verdad y después los ejemplos: A B A And B V V F F V F V F V F F F Option Explicit .84 4.9. Se aplica a solo un operador. Option Explicit Sub Negacion() Dim bValor As Boolean 'Valor original Verdadero bValor = True Msgbox bValor 'Le aplicamos el operador bValor = Not bValor Msgbox bValor 'Valor original Falso bValor = False Msgbox bValor 'Le aplicamos el operador bValor = Not bValor Msgbox bValor End Sub Su tabla de verdad es muy sencilla. Ahora. siendo esta una herramienta para conocer los posibles valores de una expresión cuando se le aplican operadores lógicos.9 Operadores Cambia el valor de la expresión de falso a verdadero y viceversa.10 And – Y (lógico) Se aplica a dos operadores.

Aprendiendo OOo Basic 85 Sub Dim Dim Dim Conjuncion() bValor1 As Boolean bValor2 As Boolean bResul As Boolean 'Solo en caso de que los dos sean verdaderos 'el resultado sera verdadero bValor1 = True bValor2 = True bResul = bValor1 And bValor2 Msgbox bResul bValor1 = True bValor2 = False bResul = bValor1 And bValor2 Msgbox bResul bValor1 = False bValor2 = True bResul = bValor1 And bValor2 Msgbox bResul bValor1 = False bValor2 = False bResul = bValor1 And bValor2 Msgbox bResul End Sub 4. Si los dos operadores son falsos (False). devuelve falso (False).11 Or – O (lógico) Se aplica a dos operadores.9. Su tabla de verdad es: A B A Or B V V F F Option Explicit Sub Dim Dim Dim V F V F V V V F Disyuncion() bValor1 As Boolean bValor2 As Boolean bResul As Boolean bValor1 = True bValor2 = True bResul = bValor1 Or bValor2 Msgbox bResul bValor1 = True . cualquier otro valor devuelve verdadero (True).

Su tabla de verdad es: A B A Xor B V V F F Option Explicit Sub Dim Dim Dim V F V F F V V F Operador_Xor() bValor1 As Boolean bValor2 As Boolean bResul As Boolean bValor1 = True bValor2 = True bResul = bValor1 Xor bValor2 Msgbox bResul bValor1 = True bValor2 = False bResul = bValor1 Xor bValor2 Msgbox bResul bValor1 = False bValor2 = True bResul = bValor1 Xor bValor2 Msgbox bResul bValor1 = False bValor2 = False bResul = bValor1 Xor bValor2 Msgbox bResul .86 bValor2 = False bResul = bValor1 Or bValor2 Msgbox bResul bValor1 = False bValor2 = True bResul = bValor1 Or bValor2 Msgbox bResul bValor1 = False bValor2 = False bResul = bValor1 Or bValor2 Msgbox bResul End Sub 4. si son diferentes devuelve verdadero (True).9.12 Xor – O exclusiva (lógico) Se aplica a dos operadores. Si los dos operadores son iguales devuelve falso (False).9 Operadores 4.

Su tabla de verdad es: .9.13 Eqv – Equivalencia (opuesto a Xor) (lógico) Se aplica a dos operadores. Su tabla de verdad es: A B A Eqv B V V F F Option Explicit Sub Dim Dim Dim V F V F V F F V Operador_Eqv() bValor1 As Boolean bValor2 As Boolean bResul As Boolean bValor1 = True bValor2 = True bResul = bValor1 Eqv bValor2 Msgbox bResul bValor1 = True bValor2 = False bResul = bValor1 Eqv bValor2 Msgbox bResul bValor1 = False bValor2 = True bResul = bValor1 Eqv bValor2 Msgbox bResul bValor1 = False bValor2 = False bResul = bValor1 Eqv bValor2 Msgbox bResul End Sub 4. devuelve verdadero (True). Si el primer operador es verdadero (True) y el segundo es Falso (False) devuelve falso (False).9. cualquier otro valor.14 Imp – Implicación (lógico) Se aplica a dos operadores. si son diferentes devuelve Falso (False). Si los dos operadores son iguales devuelve verdadero (True).Aprendiendo OOo Basic End Sub 87 4.

15 Precedencia de operadores En resumen./ \ Mod +. es decir. distinto. menor que.9. > Exponenciación Multiplicación y división División entera Resto de una división entera Suma y resta Igual.= . Operación Tipo Aritmético Aritmético Aritmético Aritmético Aritmético Relacionales . están ordenados de mayor a menor precedencia. Los operadores que están en la misma linea. la prioridad que les asigna el lenguaje cuando en una sentencia están implicados dos o mas operadores. tiene el mismo nivel de precedencia Operador ^ *.9 Operadores V V F F Option Explicit Sub Dim Dim Dim V F V F V F V V Operador_Imp() bValor1 As Boolean bValor2 As Boolean bResul As Boolean bValor1 = True bValor2 = True bResul = bValor1 Imp bValor2 Msgbox bResul bValor1 = True bValor2 = False bResul = bValor1 Imp bValor2 Msgbox bResul bValor1 = False bValor2 = True bResul = bValor1 Imp bValor2 Msgbox bResul bValor1 = False bValor2 = False bResul = bValor1 Imp bValor2 Msgbox bResul End Sub 4. mayor que. <> .88 A B A Imp B 4. son los siguientes. < . los operadores que puedes usar en OOo Basic.

se ejecutan de izquierda a derecha ● La precedencia se puede “romper” (cambiar) usando paréntesis. mayor o igual que Negación Y O O exclusiva Equivalencia (opuesto a Xor) Implicación Lógico Lógico Lógico Lógico Lógico Lógico La prioridad de ejecución es muy importante. sin los paréntesis da un resultado 'totalmente diferente num = 45 * 56 / 10 ^ 3 + 125 MsgBox num . pues si no la utilizas correctamente. ya sea en sucesivas líneas como en el primer ejemplo o usando paréntesis como en el segundo ejemplo: Sub Precedencia_Operadores2() Dim num As Double num = 45 * 56 num = num / 10 num = num ^ 3 num = num + 125 MsgBox num num = (((45 * 56) / 10) ^ 3) + 125 MsgBox num 'Observa como. tienen prioridad los más internos y hacia afuera Option Explicit Sub Precedencia_Operadores1() Dim num As Double 'Observa como la prioridad va de izquierda a derecha '4 16 1 3 num = 2 ^ 2 * 4 Mod 3 + 2 MsgBox num 'Y ahora va de derecha a izquierda '16 32 34 num = 2 + 2 * 4 ^ 2 MsgBox num End Sub Lo más sencillo. es decir. toma en cuenta las siguiente reglas: ● La precedencia va de mayor a menor. se ejecutan primero los operadores de mayor jerarquía ● Si los operadores tienen la misma precedencia. >= Not And Or Xor Eqv Imp menor o igual que. te puede dar resultados diferentes a los esperados. es que tu determines el orden de las operaciones.Aprendiendo OOo Basic 89 <= .

te deberá mostrar el siguiente mensaje de error que es muy claro: Option Explicit Sub Errores1() . 1) Errores en tiempo de diseño: son aquellos que se cometen cuando se esta codificando.por ejemplo. recordando que sintaxis es: -Conjunto de reglas que definen las secuencias correctas de los elementos de un lenguaje de programación. muy comúnmente son errores de sintaxis. en la practica. sabemos que esto no es así.9 Operadores Los paréntesis nos ayudan a determinar el orden en que queramos hacer una operación cuando la precedencia de operaciones no es muy clara. 4. En general podríamos hablar de tres tipos de errores dependiendo de cuando se producen o en que contexto. es que mantengas el control de tu código. generalmente son detectados por el IDE en cuanto tratamos de ejecutar el código y normalmente nos muestra un mensaje indicándonos el tipo de error cometido.10 Control de errores En teoría. el siguiente código. un programa no debería tener errores o no necesitaría de un control de errores. Mi recomendación como casi siempre lo notaras. programando.90 End Sub 4. escribiendo nuestro código.

Aprendiendo OOo Basic 91 En el apéndice A punto 7. por supuesto. entre más grande y complejo sea tu código. pues solo en el tenemos a nuestra disposición el código fuente que es la única forma de verificar que un software haga lo que dice que hace. son los más difíciles de detectar y corregir pues frecuentemente no te dan un mensaje o no se detiene el código. como el que tu y yo usamos. 3) Errores en tiempo de ejecución: estos errores se producen durante el tiempo que se esta ejecutando tu programa o código. la probabilidad de que tenga errores lógicos aumenta considerablemente. esto solo puede suceder con el software libre. ¿verdad?. sino simplemente el código “no hace” las tareas para las que se supone esta desarrollado o “no devuelve” los valores esperados. OOo Basic cuenta con instrucciones y palabras claves para controlar este tipo de errores y son los que aprenderemos en este capitulo.2. Copia y ejecuta la siguiente macro: Option Explicit Sub Manejo_Errores1() Dim sRutaArchivo As String sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" End Sub Si escribes la ruta de un archivo que no existe. los errores son evidentes-. Hay una frase que se le atribuye (no he podido comprobarlo) a Linus Torvalds que dice -ante los ojos de muchos. te “debe” dar el mensaje de error y nota que el ultimo mensaje con MsgBox ya “no” se muestra: . te muestro una lista de los errores en tiempo de diseño más frecuentes 2) Errores lógicos: estos errores. Únicamente la experiencia y la practica te ayudaran a minimizar este tipo de errores.

92 4. "Borrar archivo" End If End Sub En la validación anterior estamos usando una función de OOo Basic que tal vez no conozcas. donde valor puede ser una ruta de archivo. no tienes la seguridad que esos recursos estarán “siempre” disponibles. si “no” encuentra el archivo.10 Control de errores Claro. otros procesos pueden acceder y manipularlos. por ello. en el caso de los archivos. en este y otros casos. 0. considera la utilización de un controlar de errores como en el ejemplo siguiente: Option Explicit Sub Manejo_Errores3() Dim sRutaArchivo As String On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 MsgBox "No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo. devuelve una cadena vacía. estarás pensando que es más fácil y más eficiente el validar antes que exista el archivo y estarás en lo correcto: Sub Manejo_Errores2() Dim sRutaArchivo As String sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) If sRutaArchivo<>"" And Dir(sRutaArchivo)<>"" Then Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Else MsgBox "Ruta invalida o archivo no existe". 48 Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub . Considera que cuando accedes a recursos externos. me refiero a la función Dir(valor).

En nuestro ejemplo. es exactamente igual a la usada en la declaración del controlador de errores. esta. cuya valiosa información nos ayudara a corregirlo. salga de la macro “sin” ejecutar el controlador de errores. afortunadamente. esto es para que si. nota que esta etiqueta. estos. el cual manipulamos con la linea: Case 53 MsgBox "No se encontró la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo. sabemos que si no se encuentra un archivo. también nota. ocurre el error 53. no es la única pero es la que generalmente se usa. Error y Erl. Después de iniciar el controlador de errores. Ahora si. observa que usamos la instrucción Exit Sub. muy importante.Aprendiendo OOo Basic 93 Veamos todas las partes del código anterior. la descripción del error (variable Error) y la línea donde este ocurrió (variable Erl). tenemos la linea: On Error Goto 0 Que no hace otra cosa que reinicializar las variables de error. excepto por que es indistinto las mayúsculas y minúsculas. La estructura de control o administración de errores que acabamos de ver. observa como declaramos la etiqueta usada en la declaración del controlador de errores. mostramos el número de error (variable Err). hay algunas variantes que a criterio puedes . que esta termina en dos puntos (:) . Enseguida. 48 En caso de que ocurra un error no especificado o desconocido. tenemos propiamente el código de nuestra macro. es decir Err. esta variable tendrá valor 0 si no ocurrió ningún error. tenemos una nueva instrucción: On Error Goto CONTROLAERRORES La sintaxis general de esta instrucción es: On Error Goto NombreEtiqueta En donde NombreEtiqueta es cualquier palabra que cumpla las características vistas para nombrar a las variables y literalmente significa -En caso de error salta (o va) a NombreEtiqueta. Después de declarar la macro y las variables a usar. observa que iniciamos un Select Case con la variable Err. son indispensables para que no te muestre el siguiente mensaje de error en tiempo de diseño: Inmediatamente después de la declaración de la etiqueta. Case Else MsgBox "Ocurrió el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl Después de cerrar la estructura Select Case con End Select. es una variable tipo Long de OOo Basic que contiene el número de error que se haya provocado. nuestro código se ejecuta sin problemas.

tan solo corregirlos en tu código. Códigos de error Nº 2 3 4 5 6 7 8 9 10 11 12 13 14 18 20 28 35 48 Descripción Error de sintaxis no especificado Return sin Gosub Restaurar desde el principio Llamada a procedimiento no válida Desbordamiento Memoria agotada Matriz ya dimensionada Sunbíndice fuera de rango Definición duplicada División por cero Variable no definida Discordancia de tipo Parámetro no válido Interrupción de usuario Continuar sin error Espacio de pila agotado Sub o Function no definidos Error al cargar DLL Nº 70 71 73 74 75 76 91 93 94 Descripción Permiso denegado Disco no preparado Prestación no implementada Imposible cambiar nombre con unidad distinta Error de acceso a ruta/archivo Ruta no encontrada Variable de objeto no definida Cadena de secuencia no válida Uso de Null no válido 323 Imposible cargar módulo 341 Índice de objeto no válido 366 No hay documento o vista activos 380 Valor de propiedad incorrecto 382 Propiedad de sólo lectura 394 Propiedad de sólo escritura 420 Referencia de objeto no válida 423 Propiedad o método no encontrados 424 Objeto necesario .94 4.10 Control de errores usar. En caso de que quieras establecer un control de errores genérico. podrías usar: Sub Manejo_Errores4() On Error Goto CONTROLAERRORES 'Aqui va todo tu codigo Exit Sub CONTROLAERRORES: If Err <> 0 Then MsgBox "Ocurrio el error numero: " & Err & Chr(13) & Error & Chr(13) & "En la linea " & Erl End If On Error Goto 0 End Sub Puedes simular el error que quieras simplemente asignando el número de error a la variable Error de la siguiente manera: 'Aqui va todo tu codigo Error(12) Esta es la lista de valores de errores que puedes usar en la variable Error o que en algún momento te pueden aparecer. veamos algunas. toma en cuenta que algunos de estos errores “solo” ocurren en tiempo de diseño y varios de ellos “no” puedes interceptarlos.

por ejemplo: Option Explicit Sub Manejo_Errores5() Dim sRutaArchivo As String Dim iRes As Integer On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 iRes = MsgBox ("No se encontro la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas intentarlo de nuevo?".Aprendiendo OOo Basic 95 Códigos de error Nº 49 51 52 53 54 55 57 58 59 61 62 63 67 68 Error interno Nombre de archivo o número incorrectos Archivo no encontrado Modo de archivo incorrecto Archivo ya abierto Error de E/S de dispositivo Archivo ya existente Longitud de registro incorrecta Disco lleno Entrada más allá del final del archivo Número de registro incorrecto Demasiados archivos Dispositivo no disponible Descripción Convención de llamada a DLL incorrecta Nº Descripción 425 Uso de objeto no válido 430 La clase no admite OLE 438 El objeto no admite este método 440 Error de automatización OLE 445 El objeto no admite esta acción 446 El objeto no admite argumentos con nombre 447 El objeto no admite la configuración de entorno local actual 448 Argumento mencionado no encontrado 449 Argumento no opcional 450 Número de argumentos incorrecto 451 Objeto no es una colección 452 Ordinal no válido 453 Función DLL especificada no encontrada 460 Formato de portapapeles no válido OOo Basic cuenta con una instrucción que complementa el uso de un controlador de errores. es decir. por supuesto. volver a intentar ejecutar la línea que provoco el error. esta instrucción es Resume. 32 + 4 ) If iRes = 6 Then Resume End If Case Else . esto es recomendable ya que se hayan corregido o atendido las causas del error. nos permite regresar. de la primer forma. básicamente tiene tres posibles usos.

preguntamos al usuario si desea volver a intentarlo: Case 53 iRes = MsgBox ("No se encontro la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas intentarlo de nuevo?". por ejemplo: Sub Manejo_Errores6() Dim sRutaArchivo As String Dim iRes As Integer On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 iRes = MsgBox ("No se encontro la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas continuar?". en donde NombreEtiqueta tiene las mismas consideraciones vistas al inicio de este tema. tu tarea es corregir eso. usando Resume Next.10 Control de errores MsgBox "Ocurrio el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub Observa como dentro del bloque donde controlamos el error. La ultima forma es usar la instrucción Resumen NombreEtiqueta. La segunda forma. ejemplo: Sub Manejo_Errores7() Dim sRutaArchivo As String Dim iRes As Integer On Error Goto CONTROLAERRORES REINTENTARLO: sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) . 32 + 4 ) If iRes = 6 Then Resume Next End If Case Else MsgBox "Ocurrio el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub Aquí lo importante es que notes como nos muestra el mensaje de confirmación de borrado. aun y cuando este no se hizo efectivamente. 32 + 4 ) If iRes = 6 Then Resume End If Si no haces lo anterior.96 4. te permite continuar la ejecución de tu código en la línea siguiente a la que provoco el error. puedes quedar en un bucle infinito entre la linea que provoco el error y el controlador de errores.

“antes” de la etiqueta y código de controlador de errores. usamos la instrucción Goto NombreEtiqueta. limitate en su uso lo más posible. aunque el uso más común es redirigir a un segundo bloque donde se sale de la macro de forma controlada. 48 Resume SALIDACONTROLADA Case Else MsgBox "Ocurrio el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 SALIDACONTROLADA: 'Aqui va todo el codigo que quieras. para saltar directamente a la etiqueta de salida. Estas opciones son solo variantes.Aprendiendo OOo Basic 97 Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Exit Sub CONTROLAERRORES: Select Case Err Case 0 Case 53 iRes = MsgBox ("No se encontro la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "¿Deseas intentarlo de nuevo?". la idea 'es salir de forma controlada de tu macro MsgBox "Se saldra correctamente" End Sub Nota también que en vez de usar Exit Sub. la recomendación es que no abuses de los saltos con Resume o Goto. por claridad. . por ejemplo: Sub Manejo_Errores8() Dim sRutaArchivo As String On Error Goto CONTROLAERRORES sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" Goto SALIDACONTROLADA CONTROLAERRORES: Select Case Err Case 0 Case 53 MsgBox "No se encontro la ruta especificada" & Chr(13) & Chr(13) & sRutaArchivo & Chr(13) & Chr(13) & "El programa terminara". una vez más tu decidirás que es lo que mejor se acomoda a tu forma de trabajar y de razonar. 32 + 4 ) If iRes = 6 Then Resume REINTENTARLO End If Case Else MsgBox "Ocurrio el error numero: " & Err & Chr(13) & Error & _ Chr(13) & "En la linea " & Erl End Select On Error Goto 0 End Sub No dejes de observar la declaración de la etiqueta correspondiente a donde va a saltar la instrucción Resume. por ejemplo 'cierre de archivos y bases de datos.

me refiero a la instrucción On Error Resume Next. no importa el número de errores que sucedan Sub Manejo_Errores11() Dim sRutaArchivo As String On Error Resume Next Error(2) Error(3) Error(4) Error(5) Error(6) If Err = 0 Then MsgBox "No ocurrio ningun error" End If End Sub Puedes tener juntas una después de otra las dos instrucciones para controlar errores: On Error Resume Next On Error Goto CONTROLAERRORES Pero tendrá prioridad On Error Resume Next. por lo que no es aconsejable.98 4. te muestro otra instrucción para “omitir” errores. .10 Control de errores Para terminar este tema. no te recomiendo el uso de On Error Resume Next a menos que estés seguro de lo que haces. y se usa de la siguiente manera: Sub Manejo_Errores9() Dim sRutaArchivo As String On Error Resume Next sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" End Sub Intentemos controlar el error Sub Manejo_Errores10() Dim sRutaArchivo As String On Error Resume Next sRutaArchivo = Trim(InputBox("Escribe la ruta del archivo a borrar")) Kill sRutaArchivo If Err = 0 Then MsgBox "El archivo " & sRutaArchivo & " se borro correctamente" End If End Sub Notaras que no es posible. de hecho. continua el la siguiente línea-. que significa -En caso de error.

muchas más que el proceso en si de estos. a esta forma se le llama explicita y nos apoyamos en varias funciones de OOo Basic para hacer estas conversiones. mientras le sea posible. pero recuerda que son solo guías. otras. Para el mejor aprovechamiento de este tema. esto es por que el lenguaje. la instrucción MsgBox. consume bastante líneas de código. como en el siguiente ejemplo: Sub Dim Dim dim Mensajes2() dFecha As Date iNumero As Integer bOpcion As Boolean dFecha = DateSerial(74. es decir “validando” los datos. pero lo recomendable es que nosotros controlemos. esto lo logramos filtrando los datos que el usuario alimenta. OOo Basic cuenta con algunas funciones que nos ayudan a validar datos. por supuesto.1. lo ideal. veamos algunas de ellas. son los datos que un usuario alimenta a un programa. aunque le pasemos un número o una fecha o incluso un valor booleano. Como sabes. muchas de estas conversiones las puede hacer el lenguaje de forma directa. a veces. siempre que sea posible.1. es nuestra responsabilidad como programadores el minimizar este tipo de errores. por ello es un tema muy importante en programación. es que nosotros hagamos esta conversión de forma explicita. pues las opciones son tantas y tan variadas como programadores las implementen.11 Validación de datos Con la experiencia te darás cuenta que hacer una macro o programa libre de errores no es tema menor y que entre más grande sea tu código. la probabilidad de que tenga errores aumenta considerablemente. a una cadena de texto (string). Una fuente frecuente de errores. es decir.Aprendiendo OOo Basic 99 4. [Titulo As String] Veamos los siguientes ejemplos: Option Explicit Sub Dim Dim dim Mensajes1() dFecha As Date iNumero As Integer bOpcion As Boolean dFecha = DateSerial(74. tienes que programartelas (e ingeniertales) tu mismo. estas conversiones. MsgBox Mensaje As String. veras que la validación de datos. una cadena de texto. espera como parámetro “requerido” un argumento llamado Mensaje de tipo String.15) iNumero = 2008 bOpcion = True .15) iNumero = 2008 bOpcion = True MsgBox dFecha MsgBox iNumero MsgBox bOpcion End Sub Observa como. convierte del tipo que reciba. no se te olvide. [Tipo As Integer]. tienes que saber que los lenguajes Basic son muy nobles en al conversión de datos de un tipo a otro. la instrucción MsgBox sigue trabajando. a esta conversión se se llama implícita. VALIDANDO LOS DATOS. hace internamente (de forma implícita) una conversión de tipos.

11 Validación de datos Observa como hacemos uso de la función CStr(valor) que convierte el tipo de “valor” a una cadena de texto (String). veamos las siguientes: Cuando necesites saber si una variable contiene un número usamos IsNumeric: Option Explicit Sub EsNumero() Dim sDato As String sDato = Trim( InputBox( "Introduce un numero" ) ) If IsNumeric( sDato ) Then MsgBox "Es un numero" Else MsgBox "No es un numero" End If End Sub Cuando necesites saber si una variable contiene una fecha usamos IsDate: Sub EsFecha() Dim sDato As String sDato = Trim( InputBox( "Introduce una fecha" ) ) If IsDate( sDato ) Then MsgBox "Es una fecha" Else MsgBox "No es una fecha" End If End Sub . “casi” podemos estar seguros de que no nos dará un error inesperado.100 MsgBox CStr( dFecha ) MsgBox CStr( iNumero ) MsgBox CStr( bOpcion ) End Sub 4. OOo Basic cuenta con funciones para convertir a la mayoría de los tipos de variables posibles: Función CStr(valor) CByte(valor) CInt(valor) CLng(valor) CSng(valor) CDbl(valor) CBool(valor) CDate(valor) Convierte a tipo Byte Convierte a tipo entero (Integer) Convierte a tipo entero largo (Long) Convierte a tipo simple (Single) Convierte a tipo doble (Double) Convierte a tipo booleano (Boolean) Convierte a tipo fecha (Date) Descripción Convierte a cadena de texto (String) OOo Basic cuenta con otras funciones que nos ayudan a saber que tipo de dato tiene una variable. De esta forma.

Aprendiendo OOo Basic 101 Y cuando necesites saber si una variable es una matriz usamos IsArray: Sub EsMatriz() Dim mDato As Variant If IsArray( mDato() ) Then MsgBox "Es una matriz" Else MsgBox "No es una matriz" End If mDato = Array(1. la única condición es que no sea una cadena vacía: Sub Validar1() Dim sDato As String Dim bSalir As Boolean Do sDato = Trim( InputBox("Introduce los datos") ) If sDato <> "" Then bSalir = True End If Loop Until bSalir End Sub Habrás observado en el ejemplo anterior. "Salir" ) If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub . de todos modos no le hacemos caso y lo obligamos a introducir un dato. lo habitual es proporcionar siempre al usuario una forma de cancelar un proceso: Sub Dim Dim Dim Validar2() sDato As String bSalir As Boolean iRes As Integer Do sDato = Trim( InputBox("Introduce los datos") ) If sDato <> "" Then 'Aqui va tu codigo para manipular los datos bSalir = True Else iRes = MsgBox( "Parece que no escribiste nada.5) If IsArray( mDato() ) Then MsgBox "Es una matriz" Else MsgBox "No es una matriz" End If End Sub Veamos algunos ejemplos de validaciones comunes. no es común. que aun cuando el usuario presione Cancelar. el que sea. ¿Deseas salir?". si bien lo podemos hacer.2.4. Obligamos al usuario a introducir un dato. 32 + 4. ni están todas las que son-. solo pretendo que te sea de referencia y las adaptes y complementes a tus necesidades.3. como dicen en mi pueblo -ni son todas las que están.

"Salir" ) If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub Que solo introduzca números: Sub Dim Dim Dim Validar4() sDato As String bSalir As Boolean iRes As Integer Do sDato = Trim( InputBox("Introduce un numero") ) If sDato <> "" Then If IsNumeric(sDato) Then 'Aqui va tu codigo para manipular los datos MsgBox "Es un numero" & Chr(13) & Chr(13) & sDato bSalir = True Else MsgBox "Valor NO valido" End If Else iRes = MsgBox( "Parece que no escribiste nada. 32 + 4.102 4. obligamos al usuario a introducir una cadena de texto. que “no” sea número ni fecha: Sub Dim Dim Dim Validar3() sDato As String bSalir As Boolean iRes As Integer Do sDato = Trim( InputBox("Introduce los datos") ) If sDato <> "" Then If Not(IsDate(sDato)) And Not(IsNumeric(sDato)) Then 'Aqui va tu codigo para manipular los datos MsgBox "Es una cadena" & Chr(13) & Chr(13) & sDato bSalir = True Else MsgBox "Valor NO valido" End If Else iRes = MsgBox( "Parece que no escribiste nada. ¿Deseas salir?". 32 + 4. ¿Deseas salir?".11 Validación de datos Ahora. "Salir" ) If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub Que introduzca una fecha: Sub Dim Dim Dim Validar5() sDato As String bSalir As Boolean iRes As Integer Do sDato = Trim( InputBox("Introduce una fecha") ) If sDato <> "" Then If IsDate(sDato) Then 'Aqui va tu codigo para manipular los datos MsgBox "Es una fecha" & Chr(13) & Chr(13) & sDato .

"Salir" ) If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub Un número. ¿Deseas salir?". 32 + 4. en el rango 50-100" & Chr(13) & Chr(13) & sDato bSalir = True Else MsgBox "Valor NO valido" End If Else iRes = MsgBox( "Parece que no capturaste nada. 32 + 4. 32 + 4. ¿Deseas salir?". digamos. "Salir" ) .Aprendiendo OOo Basic bSalir = True Else 103 MsgBox "Valor NO valido" End If Else iRes = MsgBox( "Parece que no capturaste nada. "Salir" ) If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub Una fecha que no sea fecha futura: Sub Dim Dim Dim Validar7() sDato As String bSalir As Boolean iRes As Integer Do sDato = Trim( InputBox("Introduce una fecha") ) If sDato <> "" Then If IsDate(sDato) Then If CDate(sDato) <= Date() Then 'Aqui va tu codigo para manipular los datos MsgBox "Es una fecha valida" & Chr(13) & Chr(13) & sDato bSalir = True Else MsgBox "Es una fecha futura" End If Else MsgBox "Valor NO valido" End If Else iRes = MsgBox( "Parece que no capturaste nada. ¿Deseas salir?". entre 50 y 100: Sub Dim Dim Dim Validar6() sDato As String bSalir As Boolean iRes As Integer Do sDato = Trim( InputBox("Introduce un numero") ) If sDato <> "" Then If IsNumeric(sDato) And Val(sDato)>=50 And Val(sDato)<=100 Then 'Aqui va tu codigo para manipular los datos MsgBox "Es un numero. con un rango definido.

la VALIDACION de los datos que introduce el usuario es “muy importante” y si conjugas esto con el control de errores. . "Salir" ) If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub No quiero que se te olvide. puedes enviármela para incluirla aquí o en su defecto. Si tienes una validación interesante y que este al nivel básico que venimos manejando. también la incluiremos aquí. sino un 100%.sLetra) 'Si encuentra la letra en la lista de vocales InStr te 'devuelve la posicion. con que sea mayor a cero sabemos 'que ha sido encontrada If pos > 0 Then sTmp = sTmp & sLetra End If Next MsgBox sTmp bSalir = True Else MsgBox "Valor no valido" End If Else iRes = MsgBox( "Parece que no capturaste nada."aeiouAEIOU".11 Validación de datos El siguiente ejemplo es muy divertido. le pedimos al usuario que introduzca solo vocales.104 If iRes = 6 Then bSalir = True End If End If Loop Until bSalir End Sub 4. dejando solo las vocales: Sub Dim Dim Dim Dim Dim Dim Dim Validar8() sDato As String bSalir As Boolean iRes As Integer co1 As Integer sLetra As String sTmp As String pos As Integer Do sDato = Trim( InputBox("Introduce solo vocales") ) If sDato <> "" Then If Not(IsDate(sDato)) And Not(IsNumeric(sDato)) Then 'Aqui va tu codigo para manipular los datos For co1 = 1 To Len(sDato) 'Tomamos una por una cada letra capturada sLetra = Mid(sDato.co1. planteala en las listas de correo y si es lo suficientemente ilustrativa. 32 + 4. si en un porcentaje bastante alto. te aseguro que podrás minimizar el riesgo de fallos en tus aplicaciones.1) 'Averiguamos si es una vocal mayuscula o minuscula pos = InStr(1. seguro capturan lo que se les da la gana. si tienes problemas con alguna validación. así que filtraremos su texto. ¿Deseas salir?". pero ya sabes como son los usuarios.

veremos algunas otras características del IDE que nos pueden ayudar a depurar nuestras macros. es decir. 8. a veces. entendiendo por depurar. lógico. los más complicados de encontrar. las técnicas que nos ayudan a encontrar más fácilmente un error. Barra de titulo Barra de menús Barras de herramientas Ventana de edición Ventana de observador Ventana de llamadas Barra de desplazamiento de módulos y diálogos Barra de estado .12 El IDE – Mucho más que un editor A estas alturas ya habrás notado la gran utilidad del IDE. te colorea las palabras dependiendo de su contexto y te muestra mensajes preventivos o de error siempre que sea posible. 4.Aprendiendo OOo Basic 105 !!Feliz programación¡¡ 4. en este capitulo. sobre todo. 7. 5. 3. que son. 6. Para empezar demos un repaso a nuestro centro de trabajo. 2. al IDE y sus diferentes partes: 1.

106 4.12 El IDE – Mucho más que un editor .

por lo que supongo que en castellano será. Barra de macros. ya que el nombre no aparece en su barra de titulo. Las barras de herramientas las veremos a continuación: La primer barra de herramientas se llama MacroBar. es solo otra aplicación de OpenOffice.Aprendiendo OOo Basic 107 Algunas de estas ya te serán muy familiares. la barra de titulo y la de menús es consistente con las demás aplicaciones que integran la aplicación.org. por lo que no las veremos aquí. Como ya mencionamos. que nos permite crear y editar nuestras macros. el IDE. otras son nuevas pero las veremos en este capitulo. como si lo hace en la mayoría de las barras de herramientas: El primer control que es un cuadro de lista desplegable (control ComboBox) te permite seleccionar el archivo que este abierto y la biblioteca que quieras editar: .

. por lo que esta opción te podría llegar a mostrar varias decenas de módulos dependiendo de cuantos archivos tengas abiertos y de cuantos módulos tengas con código.org. en la barra de desplazamiento de módulos. así como del archivo especial Mis macros y los integrados en OpenOffice. si seleccionas esta opción.108 4. te mostrara “todos” los módulos y diálogos de todos los archivos abiertos.12 El IDE – Mucho más que un editor Observa como la primer opción es Todos.

Aprendiendo OOo Basic 109 .

con este icono activamos (mostramos) y . normalmente se usa junto con el “Observador” para encontrar errores. Icono de compilar: Me gustaría mucho que el código de nuestras macros se pudiese compilar. equivale a presionar la tecla F5. si tu la vez o la sabes.110 4. Icono pasar al siguiente: Permite ejecutar línea a línea el código de nuestra macro. 3. compártela conmigo. Icono de detener macro: Solo esta activo cuando ejecutamos una macro. Icono entrar en el proceso: Realiza la misma acción del icono 4. equivale a presionar la tecla F5. pero en mis pruebas no veo ninguna diferencia. Icono salir de proceso: Cuando ejecutamos una macro línea por línea. 4. este icono nos permite continuar la ejecución de la macro normalmente. pero ya vimos las técnicas para ejecutar las demás macros. que es lo que se supone hace este icono. por lo que para depurar macros. normalmente se usa en conjunción con los iconos 4 y 5. muy útil para depurar y encontrar errores. solo se ejecutan en la primer macro del modulo activo.12 El IDE – Mucho más que un editor El resto de los botones son los siguientes: 1. Icono de ejecutar: Este icono ejecuta “solo” la primer macro del módulo activo. Icono de activar/desactivar puntos de ruptura: Un punto de ruptura es una “señal” que le indica al IDE que detenga la ejecución en la linea indicada por un punto rojo en el margen izquierdo de nuestro editor. 2. 6. te das cuenta que línea es la siguiente a ejecutar por una flecha amarilla en el margen izquierdo del editor. los iconos 4 y 5. 7. es mejor usar “puntos de ruptura”. equivale a presionar la tecla F8 5.

puedes agregar el que quieras. esta ventana normalmente se usa ejecutando la macro línea a línea (F8) o junto con puntos de ruptura para poder observar el valor de las variables. nos permite agregar. más adelante veremos a detalle esta herramienta . tan solo indicando el numero de línea donde deseas establecerlos y presionar el botón nuevo. es decir. con lo cual el punto rojo pasará a ser un punto gris. dentro del margen izquierdo del editor. pero lo mejor es agregar los puntos desde el editor. exactamente en la línea que quieras. así mismo. eliminar o desactivar puntos de ruptura en un cuadro de dialogo. Observa en la siguiente imagen los puntos rojos. también puedes activar y desactivar puntos de ruptura con la tecla F9 o dando un doble clic en la línea que quieras.Aprendiendo OOo Basic 111 desactivamos (ocultamos) los puntos rojos que son puntos de ruptura en la línea actual donde este el cursor de escritura. recuerda que el cursor de escritura es la raya vertical negra de todo editor de texto. también puede eliminar el punto de interrupción que quieras tan solo seleccionándolo y presionando el botón Eliminar. Icono de habilitar inspección: Permite agregar la variable seleccionada a la ventana de observador para visualizar el valor de dicha variable durante la ejecución de una macro. Cada punto de ruptura estará indicado por la línea en donde se encuentre y podrás seleccionar y desactivar el punto que quieras. 9. pero muy importante. Icono gestionar puntos de ruptura: Nos permite administrar los puntos de ruptura existentes en nuestro modulo actual. 8.

copiar. guardar. te permite abrir. 11. nos permite seleccionar todo el texto dentro de dichos paréntesis e incluyendo los paréntesis. Icono de buscar paréntesis: Con el cursor de escritura posicionado “antes” de un paréntesis de apertura o cierre. etc. por lo que no veremos aquí estas opciones. 1. Icono catalogo de objetos: Nos muestra un cuadro de dialogo que nos permite navegar en forma de árbol entre los archivos abiertos y dentro de sus bibliotecas. módulos y macros disponibles. salvo por los tres iconos siguientes solo disponibles en el IDE. 12. a partir de un archivo de texto (normalmente con extensión BAS) insertar el código Basic que contengo en el modulo actual en la posición del cursor de escritura actual.12 El IDE – Mucho más que un editor 10.112 4. imprimir. muy útil sobre todo en funciones anidadas donde se pierden los paréntesis. pegar. Icono de insertar código Basic: Permite. y es muy similar a la mayoría de las barras estándar de las demás aplicaciones. La siguiente barra de herramientas se llama Estándar. con un doble clic sobre la macro seleccionada nos lleva a ella o usando el botón Mostrar (circulo rojo en la imagen): . Icono de guardar código Basic: Nos permite exportar a un archivo de texto con extensión BAS el código seleccionado o todo el modulo si no hay nada seleccionado.

Aprendiendo OOo Basic 113 .

principalmente la hemos usados para ejecutar la macro que queramos. . por ahora. una opción muy interesante y poderosa es “Asignar” una macro. sus bibliotecas y sus módulos.12 El IDE – Mucho más que un editor 2. que se verá más adelante. pero también podemos editar y eliminarlas. Icono de seleccionar macro: Nos muestra un cuadro de dialogo para administrar nuestras macros.114 4. nos permite también navegar entre los archivos abiertos.

Aprendiendo OOo Basic 115 3. el siguiente . la cual te solicitara si intentas editarla. por ejemplo. diálogos y bibliotecas. la ejecución línea a línea. Observa la llave al lado izquierdo de miBiblioteca que nos indica que esta biblioteca tiene establecida una contraseña para su visualización. Veamos ahora como nos pueden ayudar los puntos de ruptura. Icono seleccionar modulo: Nos muestra un cuadro de dialogo que nos permite administrar módulos. lo importante es seguir la secuencia correcta de los pasos siguientes. Puedes usar cualquier macro de las que hayamos desarrollado en estos apuntes o cualquiera que tengas. agregarlos y eliminarlos entre otras opciones como agregar una contraseña a una biblioteca. la ventana de observador y la ventana de llamadas a depurar nuestras macros.

asegurate de que sea la “primer” macro de dicho módulo de código: Option Explicit 'Construimos un seudo-RFC. por ahora no haremos verificacion 'OJO solo por ahora." ") RFC = UCase( Mid(sNombre. "Nombre" )) 'Vamos a suponer una fecha correcta. continua así hasta terminar de ejecutar la macro. "Fecha" )) 'Encontramos la posicion del primer espacio pos1 = InStr(1.12 El IDE – Mucho más que un editor código. Ahora." ") 'Encontramos la posicion del segundo espacio pos2 = InStr(pos1+1.pos2+1."00" ) & _ Format(Day(dNacimiento). asi que prueba fechas correctas dNacimiento = CDate( InputBox( "Ahora tu fecha de nacimiento".pos1+1. pos2 As Byte Dim RFC As String 'Vamos a suponer que capturamos un nombre estandar Nombre Paterno Materno 'por ejemplo Vanessa Bauche Chavira sNombre = Trim( InputBox( "Escribe tu nombre completo". copialo en la parte superior de cualquier módulo. continua presionando F8 y nota como la flecha amarilla va avanzando línea por línea en nuestro código. es decir. nota como aparece una flecha amarilla en el margen izquierdo de nuestro editor.2) & Format(Month(dNacimiento). por supuesto nuestra macro se ejecutara de forma normal. presiona la tecla F5. el RFC es un dato personal y unico en Mexico y digo seudo 'por que no es tan simple como lo pongo aqui. presiona F8.2) & Mid(sNombre.sNombre."00" ) 'Mostramos el RFC construido MsgBox RFC End Sub Tienes que ser muy observador. captura los datos solicitados correctamente y verifica que el resultado sea el esperado.1. empezando por la primer línea de nuestra macro. pero nos sirve muy bien de ejemplo 'Primeras dos letras del apellido paterno 'Primera letra del apellido materno 'Primera letra del nombre 'Año de nacimiento de dos digitos 'Mes de nacimiento de dos digitos 'Dia de nacimiento de dos digitos Sub ObtenerRFC1() Dim sNombre As String Dim dNacimiento As Date Dim pos1 As Byte. .sNombre.116 4.1) ) & _ Right(CStr(Year(dNacimiento)).1) & Mid(sNombre.

pos1."00" ) Posiciona el cursor sobre cada una de las variables sNombre. tiene que ser la línea 28 aproximadamente.pos1+1. .2) & Format(Month(dNacimiento)."00" ) & _ Format(Day(dNacimiento).pos2+1. dNacimiento.1. RFC = UCase( Mid(sNombre. ¿que notas?. detente exactamente en la línea siguiente. pero ahora.2) & Mid(sNombre.1) & Mid(sNombre. que si copiaste el código anterior. muy bien.Aprendiendo OOo Basic 117 Vuelve a empezar presionando F8.1) ) & _ Right(CStr(Year(dNacimiento)). observa como el IDE nos muestra el valor almacenados en cada una de las variables en un pequeño cuadro de texto amarillo que desaparece en cuanto movemos el cursor. pos2 y RFC. muy bien. No esta de más aclararte que la imagen siguiente esta editada para mostrarte el valor de todas la variables.

118 4.12 El IDE – Mucho más que un editor .

tendrás razón. en cualquier momento puedes continuarla de forma normal presionando F5 o de plano detener la macro con el botón Detener Macro o presionando Ctrl+Shift+Q. usaremos la ventana del observador de la siguiente manera. es decir. Con justa razón te preguntaras. repite este proceso con todas las restantes variables y ve observando como en la ventana del observador se van listando las variables. al llegar a la línea donde construimos el RFC. tienes que ver algo muy similar a: . para ver el valor de las variables. línea a línea y ve observando la ventana de inspección. Ahora. vuelve a ejecutar la macro paso a paso. ¿esto no es muy practico cuando tenemos decenas de variables? Y si. Selecciona una variable y presiona el icono “Habilitar inspección” o presiona la tecla F7 que tiene el mismo efecto.Aprendiendo OOo Basic 119 También observa que. mientras estas ejecutando el código línea por línea. ahora para ello.

primero posicionamos el cursor sobre la línea donde nos interese establecer el punto de interrupción. estos cambios los podrás ir analizando en la ventana del observador. en vez de ejecutar nuestro código línea a línea. pero. ejecuta la macro con F5 y observa como después de alimentar los datos. ¿tenemos que ejecutar nuestro código línea a línea para poder ver los valores de las variables?. que. por supuesto si estas variables cambian su valor en el transcurso de ejecución de nuestra macro. ahora.120 4. . como vimos más atrás. te muestra el tipo de variable que es.12 El IDE – Mucho más que un editor Mira que lindo. una frecuente fuente de errores. veo que eres un alumno atento. para estos casos. además. tenemos el valor de todas nuestras variables. ¿y si tenemos decenas o centenas de líneas de código?. muy buena pregunta. es precisamente que en ocasiones al procesar los datos tan rápido. Y surge una nueva pregunta. he ahí su importancia. el código se detiene exactamente en la línea que establecimos. “muy importante”. Agrega un punto de interrupción en la linea donde construimos el RFC de modo que te quede de la siguiente manera: Observa como aun tenemos las variables en la ventana del observador. puede ser que una variable no tenga o no obtenga los datos que necesitamos. son señales que le dejamos al IDE para que se detenga en la línea indicada. Para agregarlos usamos el icono “activar/desactivar puntos de ruptura” o presionamos la tecla F9. usaremos puntos de interrupción.

"Vanessa Bauche Chavira" )) dNacimiento = CDate( InputBox( "Ahora tu fecha de nacimiento". de modo que quede de la siguiente manera: Option Explicit Sub Dim Dim Dim Dim ObtenerRFC2() sNombre As String dNacimiento As Date RFC As String mDatos(2) As String 'Obtenemos los datos sNombre = Trim( InputBox( "Escribe tu nombre completo".Aprendiendo OOo Basic 121 Ahora. puedes continuar ejecutando línea a línea (F8) o continuar normalmente (F5)." ") pos2 = InStr(pos1+1."") RFC = RFC & FechaRFC( dNacimiento ) 'Mostramos el resultado MsgBox RFC End Sub Sub ObtenerIniciales(ByVal Nombre As String. modifica el código anterior para dividirlo en una subrutina y en una función. Para terminar este tema tan divertido.Nombre. puedes establecer tantos puntos de interrupción como quieras o necesites. mDatos() ) RFC = Join(mDatos(). Las variables que agregues a la ventana del observador y los puntos de interrupción que establezcas. veamos para que sirve la ventana de llamadas y veamos como la ventana de observador también nos puede mostrar el valor de una matriz de datos. solo estarán disponibles en tu sesión actual. "Nombre".Nombre. solo selecciona la variable que quieras quitar en la ventana del observador y la eliminas de esta con el icono que esta inmediatamente encima de estas." ") . para esto. "Fecha". mDatos) Dim pos1 As Byte. si cierras tu archivo los perderás. En cualquier momento puedes quitar los puntos de interrupción con F9 sobre la línea donde esta el punto de interrupción o las variables de la ventana del observador. "15/01/74" )) 'Los procesamos Call ObtenerIniciales( sNombre. pos2 As Byte pos1 = InStr(1.

detente en la primer línea donde aparece la variable sNombre.1.1)) End Sub Function FechaRFC(ByVal Nacimiento As Date) As String 4. después agrega la variable mDatos a la ventana del observador (F7) y ejecuta el código paso a paso (F8)."00" ) & _ Format(Day(Nacimiento).pos1+1.12 El IDE – Mucho más que un editor FechaRFC= Right(CStr(Year(Nacimiento)).122 mDatos(0)=UCase(Mid(Nombre.1)) mDatos(2)=UCase(Mid(Nombre. esta vacía.2) & _ Format(Month(Nacimiento). en esta caso."00" ) End Function Ejecuta el código primero (F5) para verificar que obtenemos los resultados esperados. para tener algo muy similar a la siguiente imagen: Tal vez en la ventana del observador tendrás que darle un clic al símbolo del signo más a la izquierda del nombre de la variable para que te despliegue el contenido de la matriz.pos2+1. que. Continua ejecutando paso a paso (F8) y detente en: .2)) mDatos(1)=UCase(Mid(Nombre.

el código salta a dicha subrutina y muy importante. nota como al llegar a la línea donde llamamos a la subrutina. Continua la ejecución paso a paso y detente en: . observa la ventana de llamadas como te muestra el nombre de la subrutina y además. los valores que se le están pasando. tienes que ser muy observador.Aprendiendo OOo Basic 123 Reitero. muy útil para saber si estamos estableciendo correctamente los valores.

Continua paso a paso hasta el inicio de la función FechaRFC y observa la ventana de llamadas que una vez más muestra la función y sus valores pasados: .12 El IDE – Mucho más que un editor Observa como ahora la matriz ya tiene datos y estos se muestran en la ventana del observador.124 4.

Aprendiendo OOo Basic 125 Termina la ejecución de la macro (F5) y observa que la pila de llamadas se vacía. No me resta más que decirte. para ejecutar paso a paso otras macros. así como el valor de las variable en la ventana del observador.. practica mucho. establece primero un punto de ruptura en la linea que te interese dentro de dicha macro y después ejecutas la macro de forma normal para que se detenga en el punto de ruptura establecido. tanto como puedas !!Feliz programación¡¡ .. Y sin querer queriendo dimos un breve repaso a varios temas vistos anteriormente. No se te olvide que las teclas F5 y F8 solo tienen efecto en la primer macro declarada en el modulo activo. a partir de ahí ya puedes usar F8 para continuar paso a paso.

ya que este sera el nombre que usaremos de aquí en adelante. sabiendo "preguntar" lo correcto y consultando el lugar correcto. hasta no haber comprendido cabalmente este. a su vez. a través de OOo Basic. C++.org A mi juicio.126 5 Trabajando con OpenOffice. OpenOffice. si aun queda alguna.org (Java. estos "servicios" se organizan en "módulos". con los vistos en el capitulo 2. pero que se puede embonar perfectamente bien con miles de piezas más para "armar" y "crear" nuevos componentes. a cada una de estas partes. doy por sentado que no tienes dudas de lo visto y explicado en capítulos anteriores. no así para los que usan otros lenguajes con OpenOffice. puedes aplicar tus conocimientos de este " servicio" en el nuevo componente sin ningún problema. vuelve a leer el tema.org precisamente. mi propósito en este capitulo. pero en el lenguaje de OpenOffice.org se le denomina "servicio". estos "servicios". que no se te olvide "servicio". así que solo como conocimiento recuerdalo y concentrate en los "servicios". En OpenOffice. así mismo. se que mis herramientas pedagógicas no son las mejores. no dejes de mencionarlo. hay forma de saber que "servicios" implementa un componente. pero ojo. podemos profundizar óptimamente en las entrañas de OpenOffice. esta forma de organización no tiene mayor relevancia para los que programamos en OO Basic.org. pero estoy en la mejor disposición de ayudarte a resolver tus dudas. por supuesto. etc. eso es OpenOffice.org es un LEGO. no continuar con los siguientes capítulos. de hecho. por su importancia y por la falta de documentación en español es lo que trataremos de aprender a hacer de la mejor forma. si tienes alguna. te estas perdiendo de un maravilloso juego.org. pueden contener otros "servicios". es enseñarte a "preguntarle" a los "servicios" la información necesaria para ponerlos a trabajar.org 5 Trabajando con OpenOffice. entender como esta construido OpenOffice. si tienes algún aporte para ayudar a transparentar este tema. NOTA MUY IMPORTANTE Te sugiero ampliamente. envíame lo mas claramente posible. así que anda. por lo que si sabes usar un "servicio" y este esta implementado en otro componente. le podemos llamar "objeto". esta divido en una finita y conocida cantidad de partes. que es lo que no queda claro.org. Cada pieza del LEGO es un pieza completa. es la diferencia entre aprovechar todo el potencial que tiene OOo Basic o perderte en un laberinto infranqueable por andar buscando "similitudes" con "otros" programas. también. que si no sabes que es. para que recuerdes que "no hay que estar adivinando" nada. el famoso juego de construcción con piezas de plástico.). Tal vez pecando de un excesivo reduccionismo. lo cual. no confundas estos "módulos". . A su vez.

1 Mis macros – un archivo especial. si has seguido estas notas desde el inicio. Como se que eres observador. intentemos primero con la macro que esta en el archivo de Writer. Ahora. la mayoría de las macros que hemos desarrollado y probado. Hasta ahora.org.. uno de Calc y otro de Writer.Aprendiendo OOo Basic 127 5. crea dos nuevos archivos. seguro habrás notado cada vez que habrías tu archivo para editar las macros o ejecutabas alguna. agregales una macro de prueba que nos muestre un mensaje. propusimos un archivo de Calc. por ejemplo: Option Explicit Sub Mensaje_Calc() MsgBox "Estoy en mi archivo de Calc" End Sub Sub Mensaje_Writer() MsgBox "Estoy en mi archivo de Writer" End Sub Toma nota de que son dos macros en “dos” archivos diferentes. todos los archivos que tienes abiertos o solo el archivo activo para ejecutar una macro. esta diferencia es importante para el desarrollo de los siguientes temas.. el organizador de macros te mostraba o bien. las hemos escrito “dentro” de un documento de OpenOffice. aunque muy bien pudiste haber usado un archivo de Writer.. trata de ejecutar cada macro desde el menú Herramientas | Macros | Ejecutar macros. Para empezar a clarificar esto. observa como solo nos muestra el archivo de Writer y no el de Calc. . guardarlos con el nombre que quieras. veamos en que casos te mostraba uno y en que casos lo otro. aparte del archivo que estuvieras usando.

128 5. si. optamos por ir al menú Herramientas | Macros | Organizar macros | OpenOffice. Ahora la macro que esta en el archivo de Calc y observa como solo nos muestra el archivo de Calc y no el de Writer.... Por supuesto. podemos “forzar” que nos muestre todos los archivos abiertos. que nos mostrará: ..org Basic.. en vez de ir al menú Herramientas | Macros | Ejecutar macros.1 Mis macros – un archivo especial..

Aprendiendo OOo Basic 129 Ahora si. que puedes ver aquí: .. Para que tengamos disponibles nuestras macros con cualquier archivo y poder ejecutarlas desde Herramientas | Macros | Ejecutar macros. podemos optar por usar el archivo especial que se llama Mis macros... observa como nos muestra todos los archivos abiertos y podemos tanto editar las macros que contenga o ejecutarlas.

1 Mis macros – un archivo especial. .130 5.

si dentro de archivos individuales o dentro de Mis macros. algo tan sencillo como mostrar la fecha y hora actuales. A partir de aquí. combinaciones de teclas e incluso asignarlas a sucesos de la aplicación. por ejemplo: /home/USUARIO/. En este directorio podrás ver como carpetas las bibliotecas que vayas agregando y dentro de ellas los módulos creados. veamos algunos ejemplos de como hacer esto. por ejemplo.Aprendiendo OOo Basic 131 Dentro de el. barras de herramientas. hemos ejecutado todas nuestras macros desde el IDE o llamándolas desde el menú herramientas. esto. "dddd dd \d\e mmmm \d\el yyyy " & Chr(13) & _ "y \son la\s HH \ho\ra\s con mm \minuto\s" MsgBox sMensaje. puedes crear todas las bibliotecas que quieras y todos los módulos que quieras.org.2 Asignando macros Hasta ahora. a menús. es muy útil respaldar de vez en cuando esta carpeta. claro. pero también podemos asignar las macros para ejecutarlas. es sumamente útil y poderoso. como primer paso. 64. Este archivo se encuentra en el directorio del usuario dentro de la carpeta oculta de OpenOffice."Hoy es" . queda a tu criterio decidir donde guardas tus macros. hay que escribir la macro que nos interesa asignar. por supuesto. 5. con un poco de formato para que sea vea bien: Sub MostrarFechayHora() Dim sMensaje As String sMensaje = Format( Now(). así como los diálogos que aprenderemos a crear y programar más adelante.org/3/user/basic.openoffice. cuando abrimos un archivo.

para ello. .. para nuestro ejemplo. veamos primero lo más sencillo.132 End Sub 5. el siguiente paso es seleccionar la macro que deseamos ejecutar con esta combinación de teclas. Pero observa que tienes una amplia gama de opciones de donde escoger. despliega su contenido y seleccionar “user” que se refiere al archivo especial “Mis Macros”.org. te va a dar cuenta las que ya están en uso.2 Asignando macros Ahora. para ello. así como mostrar las Combinaciones de teclas de OpenOffice. cuidate de seleccionar una que este libre.org. solo te resta seleccionar la biblioteca y el modulo donde esta la macro a asignar. como por ejemplo la tecla F1. esto es por que estas teclas no puedes reasignarlas. ve al menú Ver | Barra de herramientas | Personalizar.org (2). desde cualquier aplicación de OpenOffice. tienes que decidir “cuando” o “como” quieres ejecutarla. están en gris desactivadas. también notaras que algunas teclas. hagamos que se ejecute con una combinación de teclado. por que delante de ellas tienen la tarea asignada (4). El siguiente paso es que escojas la combinación de teclas que quieres asignar a nuestra macro. desplazate en el cuadro de lista Combinación de teclas (3) y escoge la que más te guste. hemos seleccionado CTRL + SHIFT + M (5). primero desplazate en el cuadro de lista Área (6) hasta encontrar la opción Macros de OpenOffice. para nuestro ejemplo.. que te mostrara el siguiente cuadro de dialogo: Asegurate de que este seleccionada la ficha Teclado (1). para nuestro ejemplo se llama MostrarFechayHora (7).

Aprendiendo OOo Basic 133 .

presiona el botón de comando Aceptar. así como de guardar las actuales y restablecer las predeterminadas. Para terminar. te queda de tarea “jugar” y experimentar con estas opciones.2 Asignando macros Observa como tienes opción de cargar combinaciones de teclas guardadas. . Como ultimo paso.134 5. presiona el botón de comando Modificar (8) que asigna finalmente la combinación de teclas (9) a la macro seleccionada (10).

desde cualquier documento. te tiene que mostrar: Con un poco de imaginación puedes crear tus accesos directos para probar todas las macros que quieras de una forma sencilla."Creando documento" End Sub . solo nos resta probar que funcione. presiona la combinación de teclas seleccionada (Ctrl+Shift+M) y si todo esta correcto. a un suceso del sistema. vamos a crear una sencilla macro de ejemplo: Sub MostrarMensaje() Dim sMensaje As String sMensaje = "No te olvides de guardar tu documento" MsgBox sMensaje.Aprendiendo OOo Basic 135 Ahora. 64. Ahora veamos como asignar una macro a un evento. para ello.

te desplegara un cuadro de dialogo que ya conoces. crea tantos nuevos documentos como quieras. presiona Aceptar y listo.org (2) para guardar la asignación que hagamos. . selecciona la macro. selecciona la ficha Eventos (1) y asegurate de seleccionar OpenOffice. Observa como delante del “evento” queda seleccionada la macro. (4). con el botón de comando Macro.. la biblioteca y el modulo que contiene la macro deseada.136 5. solo te resta presionar el botón de comando Aceptar y probar la macro... Para nuestro ejemplo seleccionaremos el “evento” Crear documento (3) que se ejecuta cada vez que creamos un nuevo documento.. Ahora.. esta vez.2 Asignando macros Ve al menú Ver | Barra de herramientas | Personalizar. solo te resta navegar dentro del archivo.

así que te queda de tarea intentar hacerlo. . más adelante profundizaremos en algunas de sus opciones. de cualquier aplicación de OOo. Asignar una macro a un menú o a una barra de herramientas es trivial.Aprendiendo OOo Basic 137 Con cada nuevo documento creado. pues puede ser tan sencillo como nuestros ejemplos. te tiene que mostrar el mensaje: Asignar macros a eventos no es un tema menor. conectarte a una base de datos o a una página web y muchas cosas más.

Dim NombreVariable As Object E inicializarla para poder usarla.frame. tal vez te muestre este otro: . por ahora. para ello.star. existe una palabra clave que nos da acceso inmediato a este “servicio”. 5.star. pues nos permite acceder a “toda” la aplicación y sus componentes.Identifier End Sub Ahora si.frame. vamos a explorar por dentro del OpenOffice.frame.Desktop" ) End Sub El servicio com.Desktop" ) appOpenOffice = StarDesktop Ejecutando la macro anterior. al ejecutar te tiene que mostrar el siguiente mensaje: Pero. modifica la macro para que quede de la siguiente manera: Option Explicit Sub AccediendoAOpenOffice2() Dim appOpenOffice As Object Dim oActivo As Object 'Inicializamos una variable con el servicio com.Desktop appOpenOffice = StarDesktop 'Obtenemos una referencia al componente activo oActivo = appOpenOffice. no veras ningún efecto.sun. Para crear.3 Creando nuestro primer “servicio” (objeto).Desktop es usado muy frecuentemente. la siguientes dos líneas son equivalentes: appOpenOffice = createUnoService( "com. por ello.sun. de la siguiente manera.org.CurrentComponent 'Mostramos el tipo de componente MsgBox oActivo.frame.138 5.star.sun.sun. acceder y manipular un servicio.3 Creando nuestro primer “servicio” (objeto). “necesitas” asignarlo a una variable de objeto. Sub AccediendoAOpenOffice1() Dim appOpenOffice As Object appOpenOffice = createUnoService( "com. pero aquí empieza lo divertido e interesante.star. usamos la función createUnoService. “StarDesktop” por lo que.

presentación.sun.star. es una “propiedad” lo que esta mal. queda a tu criterio. las vas a usar de aquí en adelante y siempre que programes en OOo Basic. En este caso. uno por cada tipo de documento que podemos manejar en OpenOffice.Desktop appOpenOffice = StarDesktop 'Obtenemos una referencia al componente activo oActivo = appOpenOffice. Todos excepto la base de datos te tienen que mostrar el mensaje correctamente y en el caso de la base de datos. pero no estaría de más por que los vamos a usar en repetidas ocasiones.drawing.Identifier Case "com. probemos con la siguiente: Sub AccediendoAOpenOffice3() Dim appOpenOffice As Object Dim oActivo As Object 'Inicializamos una variable con el servicio com. documento de texto. Ejecuta la macro anterior desde cada uno de estos documentos. dibujo. Sabiendo esto.star. aunque lo más practico para los siguientes ejemplos es que programes tus macros dentro de archivo Mis macros.PresentationDocument" MsgBox "Soy una presentacion" Case "com.sheet.sun.star.star. la propiedad Identifier.org (hoja de calculo. En el tema anterior vimos como llamar a una macro desde donde queramos.presentation. es decir.Aprendiendo OOo Basic 139 Incluso tal vez el siguiente: ¿Por que? Porque dependerá desde donde “llames” (ejecutes) la macro. Abre seis archivos. base de datos y formula) no necesariamente tienes que guardarlos.DrawingDocument" . verifícalo. podríamos empezar a proponer una macro genérica para saber que tipo de documento es el activo. te tiene que mostrar el error siguiente: Aprendete muy bien estas dos nuevas palabras “propiedad” y “método”. tal vez la ejecutaste directamente desde el IDE.frame. o tal vez la llamaste desde una hoja de calculo o desde un archivo de texto.sun. no la implementan las bases de datos.CurrentComponent 'Mostramos el tipo de componente Select Case oActivo.SpreadsheetDocument" MsgBox "Soy una hoja de calculo" Case "com.sun.

3 Creando nuestro primer “servicio” (objeto). Todos los objetos admiten un método que nos permite preguntar si dicho objeto soporta un servicio en especial. no resulta muy idónea para diferenciar a cada uno.comp.sun.sun. si quieres. por ejemplo. nota el valor devuelto en las hojas de calculo y como las presentaciones y los dibujos devuelven el mismo resultado. a pesar de estar implementada en todos los tipos de documentos. aquí el resumen de lo que tendrías que obtener en cada caso: Aplicación Writer Calc Impress Draw Base Math Tipo de documento Documento de texto Hoja de calculo Presentaciones Dibujo Base de datos Formula Propiedad ImplementationName SwXTextDocument ScModelObj SdXImpressDocument SdXImpressDocument com. pero notaras que esta propiedad en algunos documentos no es muy clara.ODatabaseDocument com. probemos ahora la propiedad ImplementationName y veamos que pasa: Sub AccediendoAOpenOffice4() Dim oActivo As Object 'Obtenemos una referencia al componente activo oActivo = StarDesktop.sheet.text.ImplementationName End Sub Esta vez si nos muestra un mensaje en todos los documentos.sun.comp. y cada documento soporta un tipo de servicio diferente. ¿Y si en vez de devolver un cadena de texto. busquemos otra alternativa.140 MsgBox "Soy un dibujo" Case "com. claro.star. es decir. por lo que la sintaxis competa de este método es: Variable As Boolean = Objeto. este método se llama supportsService y hay que pasarle como argumento el nombre del servicio que queremos validar y nos devolverá verdadero (True) o falso (False) según soporte o no el servicio.FormulaDocument ¿Te fijas que interesante?.formula. le preguntamos a cada componente si son lo que dicen ser?. una hoja de calculo implementa propiedades y métodos (servicios) para manipular hojas de calculo.math. puedes. implementar un controlador de errores pero por ahora no lo haremos.SpreadsheetDocument”. este servicio se llama "com.sun.FormulaProperties" MsgBox "Soy una formula" Case "com.start. excepto desde la base de datos pues te dará un error. en este caso.CurrentComponent 'Mostramos el tipo de componente MsgBox oActivo.star.supportsService( Nombre_del_Servicio As String) .sun.TextDocument" MsgBox "Soy un documento de texto" End Select End Sub 5. Ejecuta la macro anterior desde cada uno de los seis archivos.dba.start. por ejemplo.star. por lo que esta propiedad.

SupportedServiceNames Como siempre.supportsService("com.OfficeDatabaseDocument") Then MsgBox "Soy una base de datos" ElseIf oActivo.supportsService("com.supportsService("com.supportsService("com.SpreadsheetDocument") Then MsgBox "Soy una hoja de calculo" ElseIf oActivo.star.DrawingDocument") Then MsgBox "Soy un dibujo" ElseIf oActivo.sheet.TextDocument") Then MsgBox "Soy un documento de texto" ElseIf oActivo.BasicIDE") Then MsgBox "Soy el editor de codigo IDE" Else MsgBox "NO se que tipo de documento soy" End If End Sub Ahora si.sun. ya podemos discriminar correctamente los documentos.sheet. es muy importante para minimizar el riesgo de errores y para consultar directamente las propiedades y métodos que implementa dicho servicio sin tener que estar “adivinando” nada y precisamente para no estar adivinando.CurrentComponent bImplementaServicio = oActivo.script.PresentationDocument") Then MsgBox "Soy una presentacion" ElseIf oActivo. no hay como los ejemplos: Sub AccediendoAOpenOffice7() Dim oActivo As Object Dim mServicios() As String .supportsService("com. esta propiedad se llama SupportedServiceNames y su sintaxis es: Variable As Array = Objeto.text.supportsService("com.star.sdb. existe una propiedad que nos devuelve una matriz (array) con los servicios que soporta un objeto.supportsService("com. simplemente consultando si soporta su respectivo “servicio”: Sub AccediendoAOpenOffice6() Dim oActivo As Object oActivo = StarDesktop.supportsService("com.Aprendiendo OOo Basic 141 Veamoslo trabajando en el siguiente ejemplo: Sub AccediendoAOpenOffice5() Dim oActivo As Object Dim bImplementaServicio As Boolean oActivo = StarDesktop.sun.formula.star.sun.FormulaProperties") Then MsgBox "Soy una formula" ElseIf oActivo.sun.star.drawing.sun. Saber si un objeto implementa un determinado servicio.CurrentComponent If oActivo.star.star.sun.star.sun.presentation.SpreadsheetDocument") If bImplementaServicio Then MsgBox "Soy una hoja de calculo" Else MsgBox "NO soy una hoja de calculo" End If End Sub Y prueba desde todos nuestros documentos que funciona correctamente por lo que ya podemos implementar una macro mejor para saber que tipo de documento tenemos activo.star.sun.

OfficeDocument com.GenericDrawingDocument com.OfficeDocument com.DrawingDocumentFactory com.sun.star.sun.star.sun.sun.document.star.DrawingDocument com.PresentationDocument com.star. 'Obtenemos una matriz con los servicios que implementa mServicios() = oActivo. podemos demostrar que lo implementa con el siguiente ejemplo que tienes que ejecutar desde cualquier hoja de calculo.drawing.SpreadsheetDocument com.text.star.star.document.sun.GenericDrawingDocument com.TextDocument com.sun.OfficeDocument com.start.sun.star.sun.OfficeDatabaseDocument com.document. es común a todos los documentos. excepto en la hoja de calculo.GenericTextDocument com.presentation.OfficeDocument") If bImplementaServicio Then MsgBox "Verdad que si esta implementado el servicio" . que.sun.document.star.drawing.sun.CurrentComponent bImplementaServicio = oActivo.142 Dim co1 As Byte 'Obtenemos una referencia al componente activo oActivo = StarDesktop.document.star.document.sun.OfficeDocument com.text.OfficeDocument).sun.star.drawing.drawing.supportsService("com.star.sheet.sun.SupportedServiceNames 'Y mostramos el nombre de cada servicio For co1 = LBound( mServicios() ) To UBound( mServicios() ) MsgBox mServicios( co1 ) Next End Sub Y si ejecutas la macro anterior desde cada uno de nuestros seis documentos abiertos.sun.sun.star.star.sun.CurrentComponent 5.drawing.star.formula. pero recuerda que solo queremos comprobar si la hoja de calculo implementa este servicio: Sub AccediendoAOpenOffice8() Dim oActivo As Object Dim bImplementaServicio As Boolean oActivo = StarDesktop.star.sun.FormulaProperties Calc Impress Hoja de calculo Presentaciones Draw Dibujo Base Math Base de datos Formula Nota como Impress y Draw implementan casi los mismos servicios y observa como hay un servicio (com.star.SpreadsheetDocumentSettings com.star. tienes que obtener la siguiente lista de servicios en cada uno: Aplicación Tipo de documento Writer Documento de texto Propiedad SupportedServiceNames com. pero no creas que la hoja de calculo no lo implementa.3 Creando nuestro primer “servicio” (objeto).sun.OfficeDocument com.sdb.sheet. en todos los demás documentos también te funcionara.star.DrawingDocumentFactory com.document.sun.

pero ve que no hemos usado la propiedad SupportedServiceNames. principalmente cuando vimos variables y funciones. así mismo y muy importante. array.hasMoreElements() 'Nos desplazamos al siguiente elemento y lo asignamos oDocumento = oEnumeraDocumentos. hemos accedido a un solo documento. ten cuidado con los tipos de datos que usas. Por ahora. integer. los objetos son como los sustantivos. copia la siguiente macro y pruebala de nuevo con todos los documentos. en la medida de lo posible. cuando se les pasan argumentos y cuando devuelven un valor se ven afectados por estas consideraciones.getSupportedServiceNames() For co1 = LBound( mServicios() ) To UBound( mServicios() ) MsgBox mServicios( co1 ) Next End Sub Notaras que trabaja exactamente igual que la anterior. por lo que reitero. también es muy usado e importante como más adelante podrás comprobarlo. A lo largo de este capitulo. pero en OOo Basic. casi todos los métodos tienen su correspondencia en una propiedad.Aprendiendo OOo Basic Else 143 MsgBox "NO esta implementado el servicio" End If End Sub Este servicio común a todos los documentos. Sub Dim Dim Dim AccediendoAOpenOffice9() oActivo As Object mServicios() As String co1 As Byte oActivo = StarDesktop.). diferenciados por el prefijo get y los paréntesis. así mismo los métodos. el uso como método y como propiedad. te mostrare.CurrentComponent mServicios() = oActivo. las propiedades son adjetivos y los métodos son verbos. por lo que tienes que tener las mismas consideraciones (y precauciones) vistas en varios temas atrás. Hasta ahora. copia y prueba la siguiente macro: Option Explicit Sub Dim Dim Dim Controlando_OpenOffice1() oDocumentos As Object oDocumento As Object oEnumeraDocumentos As Object 'Accedemos a todos los documentos actualmente abiertos oDocumentos = StarDesktop.org.nextElement() 'Mostramos el tipo de documento MsgBox "Soy un documento de " & TipoDocumento( oDocumento ) Loop End Sub . sino el método getSupportedServiceNames(). los dos hacen lo mismo.getComponents() 'Enumeramos cada uno oEnumeraDocumentos = oDocumentos. pero podemos acceder a todos los documentos actualmente abiertos en OpenOffice.createEnumeration() 'hasMoreElements devuelve verdadero (True) mientras haya elementos Do While oEnumeraDocumentos. recuerda tus clases elementales de español. etc. si te es útil. las propiedades siempre son de un tipo de dato soportado por OOo Basic (string. más adelante me limitare a usar métodos y tu usaras el que más de agrade.

nextElement() 'Verificamos que sea un archivo de Calc If TipoDocumento( oDocumento ) = "Calc" Then 'Si no ha sido modificado o los cambios ya estan guardados 'el metodo isModified devolvera False If Not oDocumento.supportsService("com.createEnumeration() Do While oEnumeraDocumentos.getComponents() oEnumeraDocumentos = oDocumentos.sun.sun.sdb.SpreadsheetDocument") Then sAplicacion = "Calc" ElseIf Documento.dispose() co1 = co1 + 1 End if End If Loop MsgBox "Se cerraron un total de " & CStr(co1) & " archivos de Calc" End Sub .supportsService("com. Muchos objetos en OpenOffice.supportsService("com.org.hasMoreElements() nos sirve para saber si todavía hay elementos y el método .formula. como dicen en mi pueblo -sobre advertencia no hay engaño-. CUIDADO. te cerrara “todos” los archivos de Calc que no tengan cambios por guardar. Function TipoDocumento(ByRef Documento As Object) As String Dim sAplicacion As String If Documento.supportsService("com.sun.3 Creando nuestro primer “servicio” (objeto). permite movernos al siguiente elemento de la enumeración.star. Una “enumeración”. el método .OfficeDatabaseDocument") Then sAplicacion = "Base" ElseIf Documento.nextElement().star.sun.star.sun.PresentationDocument") Then sAplicacion = "Impress" ElseIf Documento.presentation.TextDocument") Then sAplicacion = "Writer" ElseIf Documento.isModified() Then 'el metodo dispose cierra el archivo oDocumento.star. Sub Dim Dim Dim Dim Controlando_OpenOffice2() oDocumentos As Object oDocumento As Object oEnumeraDocumentos As Object co1 As Integer oDocumentos = StarDesktop.FormulaProperties") Then sAplicacion = "Math" ElseIf Documento.star.supportsService("com.drawing. solo son accesibles creando una “enumeración”.supportsService("com.sun.BasicIDE") Then sAplicacion = "Basic" Else sAplicacion = "Desconocido" End If TipoDocumento = sAplicacion End Function Toma nota de como hemos convertido una macro usada anteriormente en una función que nos devuelve el tipo de documento abierto.star.sun. es como un listado de objetos.144 5. la siguiente variante de la macro anterior.sheet. Empecemos con código un poco más divertido.star. si ejecutas la siguiente macro desde un archivo de Calc podrías cerrarte el archivo con resultados inesperados.DrawingDocument") Then sAplicacion = "Draw" ElseIf Documento. así que la estructura de la macro anterior la podrías usar con frecuencia.supportsService("com.script.text.hasMoreElements() oDocumento = oEnumeraDocumentos. se crean con el método createEnumeration().

este cuenta con tres propiedades que nos informan de todas las propiedades.openoffice.org. Para obtener toda la información de un objeto. para saber si el documento ha sido modificado. todos los objetos cuentan con unas propiedades especiales que nos dan mucha información. Dbg_SupportedInterfaces 2. Dbg_Methods Las tres son de tipo texto (string) y se usan de la siguiente manera: .1 Propiedades especiales de depuración Ya vimos en el tema anterior como saber con el método “supportsService” si un objeto soporta un determinado servicio.3. veamos cuales son. 5. te cerrará el archivo sin preguntarte nada. lo ideal es saber de forma anticipada que servicio. estas propiedades son tres: 1. método o propiedad estamos buscando. También vimos el uso del método getSupportedServiceNames() que nos devuelve una matriz con los nombres de los servicios que implementa el objeto. La Interfaz de Programación de la Aplicación (API por sus siglas en ingles) proporciona. métodos e “interfaces” que implementa dicho objeto. Dbg_Properties 3. para ello. tenga o no tenga cambios guardados. la puedes consultar en linea (por ahora solo en ingles) dentro de la página www.html También puedes descargarla y después consultarla fuera de línea para su acceso inmediata o si no tienes conexión permanente a Internet. Para una consulta óptima de esta documentación.org/docs/common/ref/com/sun/star/module-ix.Aprendiendo OOo Basic 145 Ten mucho cuidado con el método dispose.openoffice. pero tiene el inconveniente de que tenemos que saber anticipadamente el nombre de dicho servicio. Observa como usamos la propiedad isModified(). lo cual a veces es un poco complicado. decenas incluso centenas de servicios con métodos y propiedades para controlar y manipular OpenOffice.org http://api. en el Apéndice B te muestro como hacerlo. usalo con conocimiento de causa.

para nuestros fines es perfectamente valido que los llamemos “servicios”. pero en OOo Basic no tiene importancia por que accedemos directamente a las propiedades y métodos de los servicios.3 Creando nuestro primer “servicio” (objeto).146 Sub ConsultandoObjetos1() Dim sDatos As String MsgBox StarDesktop. te tiene que mostrar un cuadro de mensaje con las propiedades del objeto: Sus métodos: .Dbg_Properties MsgBox StarDesktop.Dbg_SupportedInterfaces End Sub 5. La pequeña macro anterior. No te me confundas con esto de las “interfaces”. simplemente piensa en las interfaces como una forma de organizar servicios.Dbg_Methods MsgBox StarDesktop.

pero un método muy importante. te darás cuenta que solo tiene un método loadComponentFromURL.Aprendiendo OOo Basic 147 Y sus interfaces (servicios): Observa el servicio señalado con una flecha.html) o local (file:///opt/openoffice/sdk/docs/common/ref/com/sun/star/frame/XComponentLoader. en línea (http://api.org/docs/common/ref/com/sun/star/frame/XComponentLoader. si vamos a su documentación.html).openoffice. .

XSpreadsheetDocument Creo que con esto queda demostrado que no hay que estar adivinando nada. cualquiera de los servicios mostrados.148 5.Dbg_SupportedInterfaces End Sub Esta vez nos muestra muchos más datos. nota que se nos muestra el tipo de valor que puedes obtener de las propiedades y que será el mismo tipo para establecerla si la propiedad es de escritura.sheet. muestra la información necesaria para ir a la documentación del API y saber que otros servicios soporta. SbxVOID storeAsURL ( SbxSTRING. Ahora. que métodos y que propiedades.star.XTransferable 2. SbxSTRING Location 3.string) y por ultimo un objeto (3. ¿verdad?.. Por ejemplo.view. pues nos permite crear documentos nuevos o abrir archivos existentes. la macro se llama WritedbgInfo y solo hay que pasarle el objeto del cual queremos obtener su información. otra una cadena (2. tenemos: 1. SbxARRAY Printer 2. Por ahora lo importante es saber reconocer la sintaxis de esta información para usarla en nuestras macros. en las propiedades. observa de que forma tan simple podemos obtener mucha información. el método storeAsURL requiere una cadena (string) y un array como argumentos (2). Ahora probemos con los datos del documento activo: Sub ConsultandoObjetos2() Dim sDatos As String MsgBox StarDesktop.star.sun. pero no devuelve ningún valor y por ultimo el método resetActionLocks.3 Creando nuestro primer “servicio” (objeto). existen varias que nos ayudan a depurar nuestras macros.. SbxSTRING getURL ( void ) 2. si ejecutamos la macro anterior desde una hoja de calculo podremos ver entre sus propiedades las siguientes: 1. en los métodos también nos muestra información valiosa.Dbg_Properties MsgBox StarDesktop.object). existe una en especial que te escribe la información de las tres propiedades vistas en un nuevo documento de Writer. SbxARRAY ) 3.org.LoadLibrary( "Tools" ) .datatransfer.Dbg_Methods MsgBox StarDesktop. Por ultimo. SbxOBJECT Sheets Tenemos una propiedad que devuelve un array (1). dentro de las macros que trae OpenOffice.sun. 1.sun. solo hay que hacer las preguntas y búsquedas correctas. para el tema que estamos tratando. lo cual veremos al terminar este tema. Para terminar este tema. com. com. veamoslo con un ejemplo: Sub ConsultandoObjetos3() BasicLibraries.getCurrentComponent().XPrintable 3.star.getCurrentComponent(). SbxINTEGER resetActionLocks ( void ) En este caso tenemos el método getUrl que devuelve una cadena (string) y no necesita argumentos (1). por ejemplo y siguiendo en la suposición de que nos informamos de una hoja de calculo.getCurrentComponent(). com. devuelve un entero (integer) y no necesita argumentos (3).

4 Trabajando con documentos En donde veremos como manipular documentos de OpenOffice. nos escriba la información en una hoja de calculo.loadComponentFromURL( sRuta. y si. Con unas pequeñas variantes podemos hacer que en vez de un documento de Writer.getCurrentComponent() ) End Sub Prueba la macro anterior. lo deduces bien. solo hay que hacer unos pequeños cambios para crear un documento de texto: Sub Dim Dim Dim CreandoNuevosDocumentos2() sRuta As String mArg() oNuevoDocumento As Object sRuta = "private:factory/swriter" oNuevoDocumento = StarDesktop. veamos primero los ejemplos y después las explicaciones: Option Explicit Sub Dim Dim Dim CreandoNuevosDocumentos1() sRuta As String mArg() oNuevoDocumento As Object sRuta = "private:factory/scalc" oNuevoDocumento = StarDesktop.XComponentLoader”. aunque la puedes ejecutar siempre y cuando la variable pasada apunte “efectivamente” a una variable de objeto. mArg() ) End Sub Y los demás tipos de documentos: Sub CreandoNuevosDocumentos3() Dim sRuta As String Dim mArg() .sun. 0.org.4. en el Apéndice B te muestro como hacerlo. "_default". mArg() ) End Sub ¿Ya la probaste?. "_default".1 Creando nuevos documentos Como ya dijimos. creamos una nueva hoja de calculo. crearlos y guardarlos. 0. El trabajo común a la mayoría de los documentos. 5. llamándola desde diferentes documentos.star. muy fácil ¿no?.frame. el método que nos permite crear nuevos documentos se llama loadComponentFromURL y es un método del servicio “com.Aprendiendo OOo Basic 149 Call WritedbgInfo( StarDesktop. 5.loadComponentFromURL( sRuta.

sun.loadComponentFromURL( sRuta.loadComponentFromURL( sRuta.createInstance() . mArg() ) sRuta = "private:factory/sdraw" oNuevoDocumento = StarDesktop. "_default". observa como primero. mArg() ) End Sub Nos da un error ¿verdad? No esta soportado. de los demás documentos podemos crear tantos nuevos documentos como queramos sin tener que guardar nada.4 Trabajando con documentos sRuta = "private:factory/simpress" oNuevoDocumento = StarDesktop. mArg() ) sRuta = "private:factory/smath" oNuevoDocumento = StarDesktop. 0. esto. es decir.150 Dim oNuevoDocumento As Object 5. 0. la respuesta es sencilla. solo pasa con las bases de datos. "_default". intenta abrir una base de datos nueva. probemos: Sub Dim Dim Dim CreandoNuevosDocumentos4() sRuta As String mArg() oNuevoDocumento As Object sRuta = "private:factory/sbase" oNuevoDocumento = StarDesktop. el asistente nos “obliga” primero a guardarla con un nombre y después ya podemos manipularla. "_default".odb" 'Creamos el servicio que nos permite manipular bases de datos oBDServicio = createUnoService( "com.loadComponentFromURL( sRuta. 0. mArg() ) End Sub ¿Y una base de datos?.sdb. tenemos que guardar primero la base de datos: Option Explicit Sub Dim Dim Dim Dim CreandoBaseDeDatos1() oBDServicio As Object oBDNueva As Object sRuta As String mArg() 'Ruta y nombre donde quedara guardada la base de datos sRuta = "/home/mau/Mi_Base_Datos.star.DatabaseContext" ) 'Creamos una nueva instancia de una base de datos oBDNueva = oBDServicio. entonces ¿como creamos una nueva base de datos?. si queremos trabajar con ella.loadComponentFromURL( sRuta. "_default". Para saber por que nos da un error. 0. del mismo modo que lo hacemos desde la interfaz de usuario.

y cualquier otro carácter será convertido y mostrado con su respectivo código.DatabaseDocument. con lo que no tendrás acceso desde otros programas de la aplicación.Aprendiendo OOo Basic 151 'Establecemos el tipo de base oBDNueva.2 Rutas de archivos y directorios OpenOffice. por ejemplo.ods" 'Y la mostramos MsgBox sRuta 'La convertimos al formato URL sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc. 5.org.ods Toma en cuenta que este formato hace uso de los caracteres 0-9. casi como una regla. simplemente lo reemplazara. así que ten cuidado de no usar una ruta o nombre de una base importante que tengas y segundo. hace uso de las rutas de archivos y directorios. al ser multiplataforma. si ya existe. los espacios los reemplazara con %20. la base de datos así creada.4.URL = "sdbc:embedded:hsqldb" 'Y la guardamos oBDNueva. mArg() ) End Sub Toma en cuenta dos cosas muy importantes en la macro anterior. el nombre que uses. por ejemplo: file:///home/usuario/datos/miarchivo. no quedara “registrada” en OpenOffice. a-z y A-Z.ods file:///d:/datos/miarchivo. en el formato URL.ods" ) 'Y vemos el resultado MsgBox sRuta 'Regresamos al formato local sRuta = ConvertFromUrl( sRuta ) 'Y comprobamos que es correcto MsgBox sRuta End Sub Abre varios documentos existentes y ejecuta la siguiente macro desde cada uno: Sub Dim Dim Dim Dim DocumentoActivoMostrarDatos() sRutaURL As String sRutaCompleta As String sRuta As String sNombre As String . procura. veamos como se usan: Sub RutasDeArchivos1() Dim sRuta As String 'Establecemos una ruta sRuta = "/home/mau/Mi archivo de Calc.org. Siempre que le pases una ruta de archivo a cualquier servicio de OpenOffice.org. para ello. OOo Basic cuenta con dos funciones muy útiles que hacen el trabajo ConvertToUrl y ConvertFromUrl. más adelante veremos como registrar una base de datos por código.storeAsURL( sRuta. no te preguntara nada. pasarle la ruta en formato Url.

estas son: FileNameOutOfPath.4.4 Trabajando con documentos 'Referencia al documento activo sRutaURL = ThisComponent. que te devuelve de la ruta pasada solo el nombre del archivo y DirectoryNameoutofPath. te abrirá una copia de dicha plantilla: . se tiene en cuenta la diferencia entre mayúsculas y minúsculas. 0. "_blank". que te regresa solo el directorio de la ruta del archivo pasada.O. el código anterior lo abrirá.3 Abriendo. es buena practica de programación. guardando y cerrando documentos Abrir archivos existentes es sumamente sencillo. es una palabra clave especial que designa al documento desde el cual llamamos a nuestra macro.org. Observa que hacemos uso de algunas funciones incorporadas de OpenOffice. “siempre” utiliza ConvertToUrl cuando uses rutas de archivos o directorios en funciones de OpenOffice. esta se comportara de forma normal.loadComponentFromURL( sRuta. y aun desde el IDE. mArg() ) End Sub Si tu archivo existe. a que lo hagas desde el IDE. es decir.ods" ) oDocumento = StarDesktop. comprobar siempre a que tipo de documento esta apuntando ThisComponent. no es lo mismo si ejecutas una macro desde la interfaz del usuario. Linux.org En nuestro siguiente tema. usamos el mismo método usado para crear nuevos documentos. Estas y otras útiles funciones se encuentran dentro de la biblioteca Tools de OpenOffice. así que siempre verifica que el objeto apuntado con ThisComponent.getURL() 'Convertimos la ruta URL en formato local sRutaCompleta = ConvertFromUrl( sRutaURL ) 'Obtenemos solo el nombre del archivo sNombre = FileNameOutOfPath( sRutaURL ) 'Obtenemos el directorio donde esta el archivo sRuta = DirectoryNameoutofPath(sRutaCompleta. GetPathSeparator()) 'Mostramos los resultados MsgBox sRutaCompleta & Chr(13) & Chr(13) & sNombre & Chr(13) & Chr(13) & sRuta End Sub El objeto ThisComponent. dependerá si haces referencia a el desde un archivo cualquiera o desde el archivo especial Mis Macros.152 5. pero en el parámetro ruta. veremos la importancia de usar las rutas de archivos y directorios en formato Url y recuerda que en S.org que las requieran Si abres una plantilla. 5. le especificamos la ubicación del archivo a abrir de la siguiente manera: Sub Dim Dim Dim AbriendoDocumentos1() sRuta As String mArg() oDocumento As Object 'Reemplaza esta ruta por la ruta de tu archivo sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc. sea el que esperas.

loadComponentFromURL( sRuta. con esta propiedad podemos forzarlos a comportarse como plantillas. Lo interesante de esta propiedad es que perfectamente la puedes aplicar a archivos existentes.ots" ) oDoc = StarDesktop.star. si el valor es falso (False).PropertyValue" oDoc As Object mOpciones(0). pero con la propiedad AsTemplate. "_blank".PropertyValue" oDoc As Object mOpciones(0). observa como se declara la variable mOpciones: Sub Dim Dim Dim AbriendoDocumentos3() sRuta As String mOpciones(0) As New "com.Aprendiendo OOo Basic 153 sRuta = ConvertToUrl( "/home/mau/miplantilla. 0.star.sun. "_blank". mOpciones() ) . en este caso.beans.beans.loadComponentFromURL( sRuta. es decir.Name = "AsTemplate" mOpciones(0).star.Name = "AsTemplate" mOpciones(0). observa como la matriz de la variable mOpciones la hemos inicializado en 0.loadComponentFromURL( sRuta.ott" ) oDocumento = StarDesktop. solo contendrá un par de valores.loadComponentFromURL( sRuta. prueba el siguiente código con algún archivo existente que no sea plantilla: Sub Dim Dim Dim AbriendoDocumentos4() sRuta As String mOpciones(0) As New "com.beans.odt" ) oDoc = StarDesktop. forzamos su apertura como una plantilla.star.Value = False sRuta = ConvertToUrl( "/home/mau/miPlantilla.Name = "ReadOnly" mOpciones(0).sun. le estamos indicando que queremos abrir la plantilla para editarla.PropertyValue" esta conformada por un par de valores. Otras propiedades interesantes son ReadOnly (Solo Lectura) para abrir un archivo como solo lectura y Password (Contraseña) para abrir archivos con contraseña: Sub Dim Dim Dim AbriendoDocumentos5() sRuta As String mOpciones(0) As New "com. pero muy bien puede tener más opciones como veremos más adelante. archivos que “no” necesariamente sean plantillas.Value = True sRuta = ConvertToUrl( "/home/mau/Mi archivo de Writer. 0. por ejemplo.sun. mOpciones() ) End Sub La estructura "com. mArg() ) Pero también podrías querer abrir la plantilla para editarla.PropertyValue" oDoc As Object mOpciones(0). "_blank".sun. mOpciones() ) End Sub Observa como el archivo es un documento de texto normal (ODT).beans. "_blank". 0. en caso contrario (True) abrirá una copia de la plantilla.odt" ) oDoc = StarDesktop. un nombre y un valor y es muy frecuentemente usada cuando se programa en OOo Basic. es decir. En la macro anterior le estamos indicando la propiedad AsTemplate (que seria algo así como Es Plantilla).Value = True sRuta = ConvertToUrl( "/home/mau/Mi archivo de Writer. le indicamos en las opciones de apertura esto. 0.

en el siguiente ejemplo. "_blank".loadComponentFromURL( sRuta.Value = "abrete" 5.PropertyValue" oDoc As Object 'La contraseña más segura mOpciones(0). "_blank".beans.Name = "Password" mOpciones(0). 0.odg" ) 'Verificamos que exista el archivo If Len(Dir(sRuta)) > 0 Then oDoc = StarDesktop.Name = "Password" mOpciones(0). 0.loadComponentFromURL( sRuta.beans.beans.Value = "abrete" sRuta = ConvertToUrl( "/home/mau/Mi archivo de Draw. 0.org. mOpciones() ) End Sub Prueba a poner la contraseña incorrecta y observa el mensaje. por supuesto.Value = sContra sRuta = ConvertToUrl( "/home/mau/Mi archivo de Draw.star.Name = "ReadOnly" mOpciones(0).sun.154 End Sub Sub Dim Dim Dim AbriendoDocumentos6() sRuta As String mOpciones(0) As New "com.PropertyValue" oDoc As Object mOpciones(0).sun. lo podrás abrir con el método loadComponentFromURL.star. "_blank".odg" ) oDoc = StarDesktop.loadComponentFromURL( sRuta. mOpciones() ) Else MsgBox "El archivo no existe" End If End Sub Mientras un tipo de archivo sea soportado por OpenOffice.Value = True mOpciones(1). podemos solicitarle al usuario la contraseña y no esta demás verificar que el archivo exista: Sub Dim Dim Dim Dim AbriendoDocumentos8() sRuta As String mOpciones(0) As New "com.Name = "Password" mOpciones(1).star. un Htm y un Xls: Sub AbriendoDocumentos9() Dim sRuta As String .sun. mOpciones() ) End Sub Por supuesto puedes combinar cualquier cantidad de opciones siempre y cuando no entren en conflicto: Sub Dim Dim Dim AbriendoDocumentos7() sRuta As String mOpciones(1) As New "com. abrimos un archivo tipo Doc.odg" ) oDoc = StarDesktop.4 Trabajando con documentos sRuta = ConvertToUrl( "/home/mau/Mi archivo de Draw.PropertyValue" oDoc As Object sContra As String sContra = Trim( InputBox( "Introduce la contraseña de apertura" ) ) mOpciones(0).

beans.odp" ) oDoc = StarDesktop.beans.star.sun.sun.sun.loadComponentFromURL( sRuta. mOpciones() ) End Sub Otra opción interesante.loadComponentFromURL( sRuta. "_blank".loadComponentFromURL( sRuta.htm" ) oDoc = StarDesktop.ods" ) oDoc = StarDesktop. tu puedes establecer si se abre con las macros activadas. 0. mOpciones() ) sRuta = ConvertToUrl( "/home/mau/datos.loadComponentFromURL( sRuta.Name = "MacroExecutionMode" mOpciones(0).loadComponentFromURL( sRuta.Value = 4 sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc. 0.xls" ) oDoc = StarDesktop. 0.ods" ) oDoc = StarDesktop. mOpciones() ) sRuta = ConvertToUrl( "/home/mau/Renacimiento. veamos como guardar los cambios realizados y cerrar el archivo: Sub Dim Dim Dim AbriendoGuardandoDocumentos1() sRuta As String mOpciones(0) As New "com. ya sea un documento nuevo o uno existente.Value = True sRuta = ConvertToUrl( "/home/mau/Mi archivo de Impress. "_blank".beans.loadComponentFromURL( sRuta. "_blank". así que solo nos resta saber como abrirlo con las macros activadas: Sub Dim Dim Dim AbriendoDocumentos10() sRuta As String mOpciones(0) As New "com. mOpciones() ) 'AQUI va todo el codigo que quieras para manipular el archivo MsgBox "Archivo abierto y modificado correctamente.PropertyValue" Dim oDoc As Object sRuta = ConvertToUrl( "/home/mau/Campamentos.Aprendiendo OOo Basic 155 Dim mOpciones(0) As New "com. 0. mOpciones() ) End Sub Cuando abres un archivo por código y este contiene macros.sun. presione Aceptar para guardar y cerrar" 'Guardamos los cambios . es la que nos permite abrir una presentación e iniciarla inmediatamente: Sub Dim Dim Dim AbriendoDocumentos11() sRuta As String mOpciones(0) As New "com.Name = "StartPresentation" mOpciones(0). 0.star.star.PropertyValue" oDoc As Object mOpciones(0). mOpciones() ) End Sub Por supuesto.doc" ) oDoc = StarDesktop.PropertyValue" oDoc As Object sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc. "_blank". "_blank".beans. 0.star. de forma predeterminada lo abre con las macros desactivadas.PropertyValue" oDoc As Object mOpciones(0). "_blank". la idea general de abrir un archivo es para obtener datos de el o para manipularlo.

0.hasLocation() sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc.isReadOnly() mOpciones(0). como debe ser.PropertyValue" oDoc As Object sRuta = "private:factory/scalc" oDoc = StarDesktop.beans. solo abrelos y ejecutala para que notes la diferencia: Sub EstaModificado() MsgBox ThisComponent.isReadOnly() End Sub . mOpciones() ) MsgBox oDoc. 0. 0.sun. pero con uno nuevo no.store() 'Cerramos el archivo oDoc.sun. Los documentos tienen una propiedades que no ayudan a saber si un documento ya esta guardado o no: Sub Dim Dim Dim AbriendoGuardandoDocumentos2() sRuta As String mOpciones(0) As New "com. "_blank".close(True) End Sub 5.hasLocation() End Sub El primer mensaje debe mostrarte Falso (False) y el segundo Verdadero (True).loadComponentFromURL( sRuta. por supuesto no me creas.loadComponentFromURL( sRuta. También tenemos una propiedad que nos ayuda a saber si un documento ha sido modificado o no. mOpciones() ) MsgBox oDoc. 0. llamándola desde diferentes documentos. otros. te dará un error.loadComponentFromURL( sRuta. "_blank".star. compruébalo.star. "_blank". "_blank".ods" ) oDoc = StarDesktop. mOpciones() ) MsgBox oDoc. ejecuta la siguiente macro.ods" ) oDoc = StarDesktop.loadComponentFromURL( sRuta. mOpciones() ) MsgBox oDoc.4 Trabajando con documentos El código anterior funcionara con un archivo existente.Value = True sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc. unos abrelos y modificalos antes de ejecutarla.beans.156 oDoc.Name = "ReadOnly" mOpciones(0).isModified() End Sub Y otra más que nos informa si el documento es de solo lectura: Sub Dim Dim Dim AbriendoGuardandoDocumentos3() sRuta As String mOpciones(0) As New "com.PropertyValue" oDoc As Object sRuta = "private:factory/scalc" oDoc = StarDesktop.

Toma nota de que si el archivo ya existe lo reemplazara sin avisarte por lo que es buena practica de programación verificar esto: Sub Dim Dim Dim AbriendoGuardandoDocumentos5() sRuta As String mOpciones(0) As New "com.ods" ) oDoc. mOpciones() ) 'Como vez no tengo mucha imaginacion mOpciones(0). guardar con contraseña: Sub Dim Dim Dim AbriendoGuardandoDocumentos6() sRuta As String mOpciones(0) As New "com. antes de guardar un archivo. la ruta del archivo y una matriz de propiedades. no se ha guardado el nuevo archivo" End If End Sub Te queda de tarea implementar la pregunta al usuario para reemplazar o no el archivo.beans.org. mOpciones() ) Else MsgBox "El archivo ya existe. veamos como guardar.beans.PropertyValue" oDoc As Object sRuta = "private:factory/scalc" oDoc = StarDesktop.sun. mOpciones() ) 'Establecemos la ruta y nombre donde se guardara el archivo sRuta = ConvertToUrl( "/home/mau/Archivo de Calc. algunas de las cuales veremos a continuación. veamos como guardar un archivo nuevo con el método storeAsUrl: Sub Dim Dim Dim AbriendoGuardandoDocumentos4() sRuta As String mOpciones(0) As New "com. soporta la importación/exportación de múltiples formatos de archivos.ods" ) 'Guardamos el archivo oDoc.loadComponentFromURL( sRuta.loadComponentFromURL( sRuta. 0.Name = "Password" mOpciones(0).sun.star.star.Aprendiendo OOo Basic 157 Ya te imaginaras que útil es saber.beans. 0. "_blank". por ejemplo. antes de ver trabajando juntas todas estas propiedades.PropertyValue" oDoc As Object sRuta = "private:factory/scalc" oDoc = StarDesktop.Value = "abrete" sRuta = ConvertToUrl( "/home/mau/Archivo de Calc. "_blank". si este es de solo lectura.PropertyValue" oDoc As Object sRuta = "private:factory/scalc" oDoc = StarDesktop.storeAsURL( sRuta. 0. por ejemplo. mOpciones() ) sRuta = ConvertToUrl( "/home/mau/Archivo de Calc. mOpciones() ) End Sub Observa como requiere dos parámetros.sun.storeAsURL( sRuta. mOpciones() ) End Sub Como sabes.ods" ) If Len( Dir( sRuta )) = 0 Then 'Guardamos el archivo oDoc. Veamos algunas propiedades interesantes para guardar archivos. en formato DOC: .loadComponentFromURL( sRuta.storeAsURL( sRuta. si ha sido modificado o si ya ha sido guardado.star. "_blank". OpenOffice.

loadComponentFromURL( sRuta.doc" ) oDoc. mOpciones() ) End Sub El método storeAsURL también lo puedes usar para abrir un archivo existente y guardarlo con otro nombre: Sub Dim Dim Dim AbriendoGuardandoDocumentos8() sRuta As String mOpciones(0) As New "com.Execute() mostramos el cuadro de dialogo 'Si el usuario presiona Abrir el metodo devuelve 1 que podemos evaluar como Verdadero (True) 'Si presiona Cancelar devuelve 0 If oDlgAbrirArchivo.FilePicker. que nos permite hacer esto.star. 0.star. para ello.storeAsURL( sRuta.getFiles() 'El primer elemento de la matriz es el archivo seleccionado sRuta = mArchivo(0) 'Y lo abrimos oDoc = StarDesktop. solo se puede seleccionar un archivo 'pero devuelve una matriz de todos modos con la ruta completa 'del archivo en formato URL mArchivo() = oDlgAbrirArchivo.loadComponentFromURL( sRuta.loadComponentFromURL( sRuta.ods" ) oDoc. mOpciones() ) Else 'Si el usuario presiona Cancelar MsgBox "Proceso cancelado" End If .star.PropertyValue" oDoc As Object 5.dialogs.FilePicker") 'Establecemos el titulo del cuadro de dialogo oDlgAbrirArchivo.storeAsURL( sRuta. mOpciones() ) 'Establecemos el filtro a documentos tipo DOC mOpciones(0). "_blank". 0. mOpciones() ) sRuta = ConvertToUrl( "/home/mau/Nuevo archivo Calc.sun. vamos a hacer un poco más interactivo la apertura y guardado de archivos. permitamos que el usuario escoja la ruta y el archivo desde un cuadro de dialogo. veamos como: Sub Dim Dim Dim Dim Dim AbrirArchivo1() oDlgAbrirArchivo as Object mArchivo() As String mOpciones() sRuta As String oDoc As Object 'Creamos el servicio necesario oDlgAbrirArchivo = CreateUnoService ("com.ui.sun.sun. 0. usaremos el servicio com.158 Sub Dim Dim Dim AbriendoGuardandoDocumentos7() sRuta As String mOpciones(0) As New "com.PropertyValue" oDoc As Object sRuta = ConvertToUrl( "/home/mau/Mi archivo de Calc.Name = "FilterName" mOpciones(0).sun. mOpciones() ) End Sub Para terminar esta capitulo.ui.4 Trabajando con documentos sRuta = "private:factory/swriter" oDoc = StarDesktop.beans.Value = "MS Word 97" sRuta = ConvertToUrl( "/home/mau/Archivo de Word. "_blank".Execute() Then 'De forma predeterminada.setTitle("Selecciona el archivo a abrir") 'Con el metodo .dialogs.beans. "_blank".star.ods" ) oDoc = StarDesktop.

"*.*" ) .Execute() Then mArchivo() = oDlgGuardarArchivo. pues es el mismo cuadro de dialogo oDlgGuardarArchivo = CreateUnoService ("com.ods" ) End With 'Lo mostramos If oDlgGuardarArchivo.ods)".odt)". usa: Sub Dim Dim Dim Dim AbrirArchivo2() oDlgAbrirArchivo as Object mArchivos() As String mOpciones() co1 As Integer oDlgAbrirArchivo = CreateUnoService ("com.sun. mostramos el cuadro de dialogo Guardar Como.star. "*.Aprendiendo OOo Basic 159 End Sub Si quieres abrir más de un archivo a la vez.setTitle("Selecciona los archivos a abrir") 'Establecemos que se puedan seleccionar mas de un archivo oDlgAbrirArchivo. "_blank".odt" ) .*)".ui. mOpciones() ) Else MsgBox "Proceso cancelado" End If End Sub Ahora.star.AppendFilter( "All files (*.FilePicker") oDlgAbrirArchivo.Execute() Then mArchivos() = oDlgAbrirArchivo.sun. "*.FilePicker") 'Establecemos que nos muestre el cuadro de dialogo Guardar Como con las 'casillas de verificacion Autoextension y guardar con contraseña 'com.ui.AppendFilter( "Documento de Texto ODF (.AppendFilter( "Hoja de calculo ODF (.TemplateDescription.ui.getFiles() 'Solo te muestro la ruta y nombre de archivo seleccionado 'Solo te resta guardar el archivo MsgBox ConvertFromUrl( mArchivo(0) ) Else MsgBox "Proceso cancelado" End If End Sub .dialogs.getSelectedFiles() 'Mostramos los archivos seleccionados For co1 = LBound( mArchivos() ) To UBound( mArchivos() ) MsgBox ConvertFromUrl( mArchivos(co1) ) Next 'Te queda de tarea abrir todos los archivos 'oDoc = StarDesktop. 0.Initialize ( mDlgOpciones() ) 'Agreamos filtros de archivos .setMultiSelectionMode(True) If oDlgAbrirArchivo.star.dialogs.loadComponentFromURL( sRuta.FILESAVE_AUTOEXTENSION_PASSWORD = 2 mDlgOpciones() = Array(2) With oDlgGuardarArchivo 'Iniciamos el cuadro de dialogo con las opciones seleccionadas .dialogs. para permitir al usuario seleccionar carpeta y nombre de archivo donde guardar su archivo: Sub Dim Dim Dim Dim GuardarArchivo1() oDlgGuardarArchivo as Object mDlgOpciones() mArchivo() As String mOpciones() 'Usamos el mismo servicio para abrir archivos.sun.

para saber el titulo del documento activo.pdf" 'Guardamos el archivo oDoc. ahondaremos en las características especificas de cada tipo de documento. te devuelve toda la ruta pero sin la extensión del archivo. de la ruta pasada.4 Exportando a PDF Exportar a PDF desde OpenOffice. prueba la siguiente macro desde diferentes documentos. "Impress".4. pero creo que tenemos los elementos para empezar a automatizar nuestras tareas diarias.160 5.5 Tareas comunes en documentos Veamos algunas tareas comunes a la mayoría de los documentos de OOo. Te habrás dado cuenta de que las variantes pueden ser inmensas. lo es también con OOo Basic. mOpciones() ) Case Else MsgBox "Aplicacion no soportada" End Select End Sub La función GetFileNameWithoutExtension viene integrada en las macros de OpenOffice. "Writer". en los siguientes capítulos. por ejemplo.LoadLibrary( "Tools" ) 'Referencia al documento desde donde se llama la macro oDoc = ThisComponent 'Obtenemos el tipo de documento.star. esta función ya la usamos sTipoDoc = TipoDocumento( oDoc ) 'Solo se pueden exportar (por ahora) Select Case sTipoDoc 'los siguiente documentos Case "Calc".sun. también observa que esta vez “no” hemos usado storeAsUrl. 5. "Math" 'Establecemos el tipos de filtro mOpciones(0).getUrl ) & ". te queda de tarea intentar adaptarla para archivos nuevos: Sub Dim Dim Dim dim ExportarPDF() oDoc As Object sTipoDoc As String mOpciones(0) As New "com. "Draw".4 Trabajando con documentos 5. por ahora. usamos: .4.storeToURL( sRuta.Name = "FilterName" 'Contruimos el filtro correcto PDF para cada aplicacion mOpciones(0). usamos el mismo directorio 'y nombre del archivo.PropertyValue" sRuta As string BasicLibraries. sino storeToUrl para exportar el archivo.Value = LCase(sTipoDoc) & "_pdf_Export" 'Construimos la ruta correcta. solo agregamos la extension PDF sRuta = GetFileNameWithoutExtension( oDoc.beans.org. asegurate de que los archivos ya estén guardados antes de exportar.org es muy sencillo. observa como solo le agregamos la extensión PDF.

getCurrentController 'El titulo MsgBox oControlador.getComponents() 'Enumeramos cada uno oEnumeraDocumentos = oDocumentos.setValue( co1 ) 'Esperamos un segundo Wait 1000 Next 'Es importante finalizar la barra de estado para devolverle el control a la aplicación oBarraEstado.nextElement() 'Obtenemos acceso a la ventana oVentana = oDocumento.5 segundos para pasar al siguiente documento Wait 1500 Loop End Sub Una posibilidad interesante.Aprendiendo OOo Basic Sub ControlarAplicacion1() Dim oDoc As Object Dim oControlador As Object 'El documento desde donde se llama esta macro oDoc = ThisComponent 'El controllador del documento actual oControlador = oDoc. es la de controlar la barra de estado de las aplicaciones.getComponentWindow() 'Le enviamos el foco para activarla oVentana.end() End Sub . 10 ) For co1 = 1 To 10 'Establecemos el valor de la barra de progreso oBarraEstado. sobre todo por la opción de poder mostrar una barra de progreso.createEnumeration() 'hasMoreElements devuelve verdadero (True) mientras haya elementos Do While oEnumeraDocumentos.getCurrentController.setFocus() 'Esperamos 1.start( "Contando ". en donde activamos durante un segundo y medio cada documento de OOo abierto. Sub Dim Dim Dim Dim ControlarAplicacion2() oDocumentos As Object oDocumento As Object oVentana As Object oEnumeraDocumentos As Object 'Accedemos a todos los documentos actualmente abiertos oDocumentos = StarDesktop.getCurrentController.getTitle End Sub 161 Para activar el documento que quieras. se usa el método setFocus de la siguiente manera.StatusIndicator 'Establecemos el texto inicial y el limite de la barra de progreso oBarraEstado.getFrame. como en el siguiente ejemplo: Sub ControlarAplicacion3() Dim oBarraEstado As Object Dim co1 As Integer 'Referencia a la barra de estado del documento activo oBarraEstado = ThisComponent.hasMoreElements() 'Nos desplazamos al siguiente elemento y lo asignamos oDocumento = oEnumeraDocumentos.

PropertyValue 'Acceso al marco del documento oDoc = ThisComponent.Value = 150 'Ejecutamos la orden oDH.star. 0. Writer.4 Trabajando con documentos La macro anterior. como en: Sub ControlarAplicacion4() Dim oBarraEstado As Object Dim co1 As Integer 'Referencia a la barra de estado del documento activo oBarraEstado = ThisComponent.CurrentController.sun.frame.start( "Procesando Líneas ". .162 5.sun. Base y Math no lo implementan.CurrentZoom" 'El valor deseado. también puedes cambiar el texto durante el progreso para dar más información al usuario.Frame 'El despachador de instrucciones a nivel usuario oDH = createUnoService("com.getCurrentController. Calc.beans.uno:ZoomSlider". ". mOpc() ) End Sub La opción anterior. funcionará en todas las aplicaciones. Sub Dim Dim dim ControlarAplicacion5() oDoc As Object oDH As Object mOpc(0) As New com. por lo que tienes que validar en su caso si es necesario. solo funcionará en las aplicaciones que soporten zoom. pero no te dará ningún error si llamas a la macro desde estas aplicaciones.Name = "ZoomSlider. excepto en Base. Impress y Draw.end() End Sub Otra opción es cambiar el zoom de la vista del documento. "".StatusIndicator 'Establecemos el texto inicial y el limite de la barra de progreso oBarraEstado. 10 ) For co1 = 1 To 10 'Establecemos el valor de la barra de progreso oBarraEstado. en este caso 150% mOpc(0).star.DispatchHelper") 'El método que deseamos ejecutar mOpc(0).executeDispatch(oDoc.setValue( co1 ) 'Y el texto oBarraEstado. simplemente ignorará la instrucción.setText( "Procesando la línea: " & co1 ) 'Esperamos un segundo Wait 1000 Next 'Es importante finalizar la barra de estado para devolverle el control a la aplicación oBarraEstado.

getCount() Else MsgBox "No es un documento de hoja de calculo" End If End Sub Asegurate de llamar a la macro anterior desde una hoja de calculo. así que te invito a repasar tus apuntes de hoja de calculo. como aprenderemos en este capítulo.getSheets() 'Obtenemos una matriz con los nombres de todas las hojas mNombresHojas() = oHojas. Podemos acceder a los nombres de todas las hojas Sub Dim Dim Dim Dim TodasLasHojas2() oDoc As Object oHojas As Object mNombresHojas() As String sMensaje As String GlobalScope.BasicLibraries.getElementNames() 'Contruimos el mensaje sMensaje = "El archivo " & FileNameOutOfPath( oDoc. usamos: Sub TodasLasHojas1() Dim oDoc As Object Dim oHojas As Object 'Acceso al documento desde donde se llama a esta macro oDoc = ThisComponent 'Nos aseguramos de que sea una hoja de calculo If oDoc. doy por sentado que eres un usuario medio de hoja de calculo. apunta efectivamente a un documento de hoja de calculo como se vio más arriba. de ahora en adelante. abrir y guardar archivos de Calc y otros tipos de documentos. te será más complicado establecerlo por código. 6. en este.sheet. aprenderemos más detalles del manejo de la hoja de calculo con código OOo Basic que se basan en el servicio: com.star.sun.LoadLibrary( "Tools" ) oDoc = ThisComponent oHojas = oDoc.Aprendiendo OOo Basic 163 6 Trabajando con hojas de calculo – Calc En el capitulo anterior aprendiste a crear.getLocation() ) & _ Chr(13) & "tiene las siguientes hojas" & Chr(13) & Chr(13) .sun. por citar solo un ejemplo. pues si no sabes que es un formato condicional.1 Trabajando con hojas Para acceder a todas las hojas de un documento de hoja de calculo.SpreadsheetDocument.supportsService("com.sheet. te recomiendo siempre verificar que ThisComponent.getSheets() 'Mostramos cuantas son MsgBox oHojas.star. daré por hecho que lo sabes y tu determinaras si haces la validación o no.SpreadsheetDocument") Then 'Referencia a TODAS las hojas del documento oHojas = oDoc. si estas usando el archivo especial Mis Macros.

164 sMensaje = sMensaje & Join( mNombresHojas(). viene incorporada en OpenOffice.getElementNames() For co1 = LBound( mNombresHojas() ) To UBound( mNombresHojas() ) MsgBox mNombresHojas(co1) Next End Sub Podemos devolver solo la hoja que nos interesa por su nombre: Sub UnaHoja1() Dim oDoc As Object Dim oHoja As Object oDoc = ThisComponent 'Accedemos a una hoja por su nombre oHoja = oDoc.getSheets().getSheets() 'Obtenemos una matriz con los nombres de todas las hojas mNombresHojas() = oHojas. la macro anterior te dará un error.getByName("Datos Agosto") 'Solo comprobamos que es la hoja correcta MsgBox oHoja.1 Trabajando con hojas La función FileNameOutOfPath. También podemos mostrar los nombres de las hojas una a una: Sub Dim Dim Dim Dim TodasLasHojas3() oDoc As Object oHojas As Object mNombresHojas() As String co1 As Integer oDoc = ThisComponent oHojas = oDoc. lo cual es indispensable para acceder a ella: Sub Dim Dim Dim Dim UnaHoja2() oDoc As Object oHojas As Object oHoja As Object sNombreHoja As String oDoc = ThisComponent oHojas = oDoc.getName() & " . Chr(13) ) 'Lo mostramos MsgBox sMensaje End Sub 6.getSheets() sNombreHoja = "Datos Agosto" 'Comprobamos que la hoja exista para poder acceder a ella If oHojas.org y nos devuelve solo el nombre del archivo de la ruta pasada.getByName( sNombreHoja ) MsgBox oHoja.existe en el documento" Else . el método hasByName es muy útil para saber si una hoja existe.hasByName( sNombreHoja ) then 'Accedemos a una hoja por su nombre oHoja = oHojas.getName() End Sub Pero si la hoja no existe.

Podemos acceder a una hoja por su índice.getName() End Sub Del mismo modo que por el nombre. Este método no distingue entre mayúsculas y minúsculas.getByIndex( 1 ) MsgBox oHoja.org empiezan en cero. también por su índice: Sub Dim Dim Dim Dim TodasLasHojas4() oDoc As Object oHojas As Object oHoja As Object co1 As Integer oDoc = ThisComponent oHojas = oDoc. te dará un error. si tratas de acceder a una hoja por un índice que no exista.getSheets() 'Nota que el limite.getSheets() 'Accedemos a la hoja por el indice oHoja = oHojas. Sub Dim Dim Dim UnaHoja3() oDoc As Object oHojas As Object oHoja As Object oDoc = ThisComponent oHojas = oDoc. en las hojas.getSheets() iNumeroHoja = 1 'Comprobamos que la hoja exista If iNumeroHoja < oHojas.getName() Else MsgBox "Numero de hoja no existe" End If End Sub Por lo que podemos acceder a cada hoja de un documento.Aprendiendo OOo Basic 165 MsgBox "La hoja -" & sNombreHoja & ".getCount() Then 'Accedemos a la hoja por el indice oHoja = oHojas.getByIndex( iNumeroHoja ) MsgBox oHoja. la numeración empieza de izquierda a derecha. recuerda que los índices en OpenOffice. es el total de hojas menos uno.no existe" End If End Sub Nota que el método hasByName es un método del conjunto de las hojas (getSheets) y te devolverá verdadero (True) en caso de que la hoja exista y falso (False) en caso de que no. por que comienza en 0 . lo podemos comprobar asegurándonos que el numero de índice a consultar siempre es menor al total de las hojas: Sub Dim Dim Dim Dim UnaHoja4() oDoc As Object oHojas As Object oHoja As Object iNumeroHoja As Integer oDoc = ThisComponent oHojas = oDoc.

getSheets() ExisteHoja = oHojas.getSheets() .star. no así su nombre.getActiveSheet() Msgbox oHoja.sun. así que siempre comprueba que exista una hoja antes de intentar acceder a ella.1 Trabajando con hojas Toma en cuenta que si mueves una hoja de posición en relación con las demás. una función que nos devuelva falso o verdadero según exista o no el nombre de la hoja pasado como argumento.SpreadsheetDocument") Then oHojas = Documento. una primera aproximación podría ser: Option Explicit Sub SaberSiExisteHoja() MsgBox ExisteHoja( "Hoja3" ) End Sub 'Saber si una hoja existe Function ExisteHoja(ByVal NombreHoja As String) As Boolean Dim oHojas As Object oHojas = ThisComponent. pero el nombre es susceptible de ser cambiado por el usuario.hasByName(NombreHoja) End Function Podemos hacerla incluso más genérica pasándole el documento donde se desea comprobar la existencia de la hoja y comprobando que sea una hoja de calculo: Option Explicit Sub SaberSiExisteHoja2() MsgBox ExisteHoja2( ThisComponent.getByIndex( co1 ) MsgBox oHoja. Otra opción es devolver la hoja activa: Public Sub HojaActiva() Dim oHoja As Object 'Hacemos una referencia a la hoja activa oHoja = ThisComponent.getCurrentController. "Hoja3" ) End Sub 'Saber si una hoja existe Function ExisteHoja2(Documento As Object.supportsService("com. ya puedes crearte tus útiles funciones para trabajar con hojas. por ejemplo.getName() Next End Sub 6.sheet.getName() End Sub Ahora.getCount()-1 oHoja = oHojas.166 For co1 = 0 To oHojas. su índice cambiara. ByVal NombreHoja As String) As Boolean Dim oHojas As Object 'Si no es una hoja de calculo devuelve falso (False) If Documento.

esto lo puedes hacer directamente o usando la función creada más arriba.getByName(NombreHoja) End If End Function De nuevo.getSheets() If oHojas.hasByName(NombreHoja) Then DevuelveHoja1 = oHojas.hasByName(NombreHoja) Then DevuelveHoja2 = oHojas. puedes pasarle el documento del cual te interesa devolver la hoja. ByVal NombreHoja As String) As Object Dim oHojas As Object If Documento. si lo deseas.hasByName(NombreHoja) End If End Function Ahora devolvemos la hoja: Option Explicit Sub DevuelveReferenciaAHoja1() dim oHoja As Object oHoja = DevuelveHoja1( "Datos" ) If IsNull(oHoja) Then MsgBox "La hoja no existe" Else MsgBox oHoja.getSheets() If oHojas.SpreadsheetDocument") Then oHojas = Documento.Aprendiendo OOo Basic 167 ExisteHoja2 = oHojas. 'tienes que verificar que se devolvio algo con IsNull Function DevuelveHoja1(ByVal NombreHoja As String) As Object Dim oHojas As Object oHojas = ThisComponent.sun. "Datos" ) If IsNull(oHoja) Then MsgBox "La hoja no existe" Else MsgBox oHoja. si llamas a esta funcion.star.sheet. observa como comprobamos también que la hoja exista.supportsService("com.getByName(NombreHoja) End If End If End Function .getName() End If End Sub 'Saber si existe la hoja y regresarla. 'tienes que verificar que se devolvio algo con IsNull Function DevuelveHoja2(Documento As Object. si llamas a esta funcion.getName() End If End Sub 'Saber si existe la hoja y regresarla. queda a tu criterio: Sub DevuelveReferenciaAHoja2() dim oHoja As Object oHoja = DevuelveHoja2( ThisComponent.

getSheets() 'Verificamos si ya existe la hoja If Not oHojas. solo hacemos una referencia a ella. esto no es necesariamente así.insertNewByName(sNombre.insertNewByName("Datos Sep". Es sumamente frecuente en programadores noveles.getSheets() oHojas. si no.168 6.hasByName(sNombre) Then 'Si no existe la insertamos el inicio oHojas. Posicion). en donde necesitamos el nombre de la nueva hoja a insertar y la posición donde la queremos. de hecho.1 Trabajando con hojas 6. La ultima linea para activar la hoja no es necesaria para que la manipules.getSheets. la siguiente macro agrega una hoja nueva al inicio de las demás: Sub InsertarNuevaHoja1() Dim oHojas As Object oHojas = ThisComponent. con la referencia es suficiente. tenemos que verificar si la hoja existe o no: Sub Dim Dim Dim InsertarNuevaHoja2() oHojas As Object oHoja As Object sNombre As String 'Solicitamos un nombre para la nueva hoja sNombre = Trim(InputBox("Nombre de la nueva hoja")) 'Verificamos que no este vacio If sNombre <> "" Then 'Referencia a todas las hojas oHojas = ThisComponent. usamos el método insertNewByName(Nombre.1 Insertando hojas Para insertar nuevas hojas.setActiveSheet(oHoja) End If End Sub Observa que si la hoja ya existe.getSheets() .getCurrentController. 0) End If 'Referencia a la nueva hoja o a la existente oHoja = ThisComponent. puedes omitirla. pues no puedes tener dos hojas con el mismo nombre.1. querer “activar” toda hoja que se quiera manipular. solo en caso de que quieras que el usuario haga o manipule algo en ella. la mayor parte de las veces. entonces. También podemos agregar la hoja al final de todas las demás: Sub Dim Dim Dim InsertarNuevaHoja3() oHojas As Object oHoja As Object sNombre As String sNombre = Trim(InputBox("Nombre de la nueva hoja")) If sNombre <> "" Then oHojas = ThisComponent.getByName(sNombre) 'La activamos ThisComponent. 0) End Sub Ejecuta la macro anterior dos veces y notaras que te dará un error.

no te dará error y la insertara al final de las demás hojas.getByName(sNombre) ThisComponent.getCurrentController. Si quieres insertar la hoja antes o después de la hoja activa.getSheets.getCurrentController.getSheets. Para insertar antes de la hoja activa usamos: Sub Dim Dim Dim Dim Dim InsertarNuevaHoja4() oHojas As Object oHoja As Object oHojaActiva As Object sNombre As String pos As Integer sNombre = Trim(InputBox("Nombre de la nueva hoja")) If sNombre <> "" Then oHojas = ThisComponent.1 oHoja = ThisComponent. primero tienes que encontrar el índice de la hoja activa: Sub Dim Dim dim IndiceHojaActiva() co1 As Integer oHojaActiva As Object oHoja As Object oHojaActiva = ThisComponent.1 oHoja = ThisComponent. oHojas.getSheets.Aprendiendo OOo Basic 169 If Not oHojas.insertNewByName( sNombre.getSheets.getActiveSheet() .getName() then MsgBox "El indice de la hoja activa es: " & co1 Exit For End If Next End Sub Que podemos convertir a una función: Function BuscarIndiceHoja(ByVal NombreHoja As String) As Integer Dim co1 As Integer dim oHoja As Object For co1 = 0 To ThisComponent.getActiveSheet() For co1 = 0 To ThisComponent.hasByName(sNombre) Then 'Si no existe la insertamos al final oHojas.getByIndex(co1) If oHoja.getName() = NombreHoja then BuscarIndiceHoja = co1 Exit Function End If Next BuscarIndiceHoja = -1 End Function Observa que si no la encuentra el valor devuelto es -1.getCurrentController.setActiveSheet(oHoja) End If End Sub Observa entonces que el argumento posición puede tomar valores desde 0 y hasta el total de hojas devuelto por getCount() pero incluso si es mayor a este valor.getSheets.getByIndex(co1) If oHoja.getCount() .getName() = oHojaActiva.getCount() .getCount() ) End If oHoja = ThisComponent.getSheets() oHojaActiva = ThisComponent. lo cual hay que evaluar en caso necesario.

getName()) + 1 Podemos aventurar una primera versión de una función genérica para insertar una nueva hoja de calculo donde quieras: 'Como funcion regresamos la nueva hoja insertada o la existente en su caso 'Posicion: 1 = Inicio ' 2 = Final ' 3 = Antes de la hoja activa ' 4 = Despues de la hoja activa Function getNuevaHoja(ByVal NombreHoja As String.Sheet + 1 Case Else : iPos = 0 End Select If Not oHojas.2 Borrando hojas Para borrar hojas.getActiveSheet() Select Case Posicion Case 1 : iPos = 0 Case 2 : iPos = oHojas. no esta de más recomendarte usar con cuidado el borrado de hojas.Sheet Case 4 : iPOs = oHojaActiva. donde Nombre es el nombre de la hoja que queremos borrar. con lo cual nos evitamos tener que hacer un ciclo por las hojas del documento. así como ingeniártelas para pedirle al usuario el número de hojas nuevas que quiera insertar e insertarlas por supuesto.hasByName(sNombre) Then 'Buscamos el indice de la hoja activa pos = BuscarIndiceHoja(oHojaActiva. pos ) End If oHoja = ThisComponent. Puedes mejorar esta función para insertar la hoja en cualquier otro documento. es tu tarea. es que muchas de las . ByVal Posicion As Integer) As Object Dim oHojas As Object Dim oHojaActiva As Object Dim iPos As Integer If NombreHoja <> "" Then oHojas = ThisComponent.getCurrentController. iPos) End If getNuevaHoja = ThisComponent.1.getCount() Case 3 : iPos = oHojaActiva.getName()) oHojas.getRangeAddress().getByName(NombreHoja) End If End Function Nota como estamos obteniendo el índice de la hoja activa.org.getRangeAddress().insertNewByName(NombreHoja. esa.1 Trabajando con hojas Para insertar después de la hoja activa.setActiveSheet(oHoja) End If End Sub 6. aunque algo que me gusta mucho de OpenOffice. 6. solo sumas uno al valor devuelto por la función BuscarIndiceHoja: pos = BuscarIndiceHoja(oHojaActiva.getSheets.getSheets() oHojaActiva = ThisComponent.insertNewByName( sNombre.getSheets.170 If Not oHojas.getByName(sNombre) ThisComponent.hasByName(NombreHoja) Then oHojas.getCurrentController. usamos el método removeByName(Nombre).

el borrado de hojas es una de ellas.removeByName( oHojaActiva.getCount()>1 Then oHojas.getSheets() If oHojas. no te dejara por que un documento de hoja de calculo por lo menos debe de tener una hoja.getActiveSheet() oHojas = ThisComponent.getCurrentController.removeByName( sNombre ) Else MsgBox "La hoja no existe o solo queda una" End If End If End Sub .removeByName( "Hoja11" ) End Sub Por supuesto no puedes borrar una hoja que no exista. así que verifícalo: Sub BorrarHoja2() Dim oHojas As Object Dim sNombre As String sNombre = Trim( InputBox( "Nombre de la hoja a borrar" )) If sNombre <> "" Then oHojas = ThisComponent.getSheets() 'Borramos la hoja por su nombre oHojas.getSheets() oHojas.getSheets() If oHojas.hasByName( sNombre ) Then oHojas. son susceptibles de deshacerse de forma normal con la barra de herramientas o con CTRL+Z. compruébalo: Sub BorrarHoja1() Dim oHojas As Object oHojas = ThisComponent.getName() ) End Sub Ejecuta la macro anterior hasta que no quede ni una. valida que siempre quede más de una: Sub BorrarHoja3() Dim oHojas As Object Dim sNombre As String sNombre = Trim( InputBox( "Nombre de la hoja a borrar" )) If sNombre <> "" Then oHojas = ThisComponent.removeByName( sNombre ) Else MsgBox "La hoja no existe" End If End If End Sub Puedes borrar la hoja activa: Sub BorrarHojaActiva() Dim oHojas As Object Dim oHojaActiva As Object oHojaActiva = ThisComponent. claro.hasByName( sNombre ) And oHojas.Aprendiendo OOo Basic 171 acciones que hacemos por código. para evitar el error que te da al tratar de borrar la ultima hoja.

aun así.1.172 6."o". aquí esta la mía. si quieres saber más de este algoritmo visita: http://es.getSheets() 'Movemos la hoja especificada al final oHojas."e".org/wiki/Bubblesort También puedes crearte tu versión de este algoritmo. Chr(13) ) End Sub La función BubbleSortList."l". oHojas. para ello nos apoyaremos en una función que ordena la matriz que le pasemos: Sub PruebaOrdenar1() Dim mDatos() GlobalScope. como ya sabemos obtener los nombres e indices de cada hoja. puedes ordenar de forma ascendente o descendente: .org y usa el método de burbuja para ordenar la lista pasada. no es el algoritmo más eficiente.cgi?id=92477)."h". PosicionNueva). y ahora hemos aprendido a mover hojas. hagamos una macro que nos ordene alfabéticamente nuestras hojas. pues te puede provocar un error en toda la aplicación.BasicLibraries. este error (bug) se reporto en su momento (http://www.1 Trabajando con hojas 6."y". pero en listas pequeñas y dada su sencillez de implementación es perfectamente válida para nuestros fines. la movemos al final: Sub MoverHoja2() Dim oHojas As Object oHojas = ThisComponent.getSheets() 'Movemos la hoja especificada al inicio oHojas.org/issues/show_bug. usa siempre getCount() para asegurarte."v".1. ten cuidado con mover tus hojas “no más allá de la ultima hoja”."f".1).) 'Mostramos los datos desordenados MsgBox Join( mDatos()."u".openoffice.getCount() ) End Sub Si usas una versión anterior a la 3.3 Moviendo hojas Para mover hojas usamos el método moveByName(NombreHoja. 0 ) End Sub Ahora.moveByName( "Hoja2". viene incorporada a las macros de OpenOffice.wikipedia. Chr(13) ) 'Ordenamos los datos mDatos() = BubbleSortList( mDatos() ) 'Mostramos los datos ordenados MsgBox Join( mDatos().moveByName( "Hoja2". donde NombreHoja tiene que ser el nombre de una hoja existente: Sub MoverHoja1() Dim oHojas As Object oHojas = ThisComponent. Vamos a hacer algo muy divertido.LoadLibrary( "Tools" ) mDatos() = Array("5". y ha sido arreglado a partir de esta versión (3."d".

"e"."l"."h". 1 ) 'Mostramos los datos ordenados MsgBox Join( mDatos().getElementNames() . nuestra macro para ordenar hojas en acción."u"."o". ByRef Dato2 As Variant) Dim sTmp As Variant sTmp = Dato1 Dato1 = Dato2 Dato2 = sTmp End Sub Ahora si.Aprendiendo OOo Basic Sub PruebaOrdenar2() Dim mDatos() 173 mDatos() = Array("5". crearte tu propia versión: Option Explicit 'Ordenamos las hojas por orden alfabetico Sub OrdenarHojas() Dim oHojas As Object Dim mNombres() As Variant Dim aTmp As Variant Dim co1 As Integer Dim oHoja As Object 'Referencia a todas las hojas del documento oHojas = ThisComponent. Chr(13) ) End Sub ' Datos = matriz de datos a ordenar ' Orden = 1 ascendete ' 2 descendente Sub OrdenarBurbuja(ByRef Datos() As Variant.1)) Then Call Intercambio Datos(co2). puedes usar la función o macro que prefieras para ordenar la matriz de nombres obtenida.1) End If End If Next co2 Next co1 End Sub 'Macro para intercambiar un par de valores Sub Intercambio(ByRef Dato1 As Variant."f". Chr(13) ) 'Ordenamos los datos Call OrdenarBurbuja( mDatos(). incluso."d"."v". Datos(co2 ."y".) 'Mostramos los datos desordenados MsgBox Join( mDatos(). co2 As Long NumDatos = UBound(Datos) For co1 = 1 To NumDatos For co2 = NumDatos To co1 Step -1 If Orden = 1 Then If Datos(co2) < Datos(co2 .getSheets() 'Matriz con los nombres de todas las hojas mNombres() = oHojas.1) Then Call Intercambio Datos(co2). ByVal Orden As Integer) Dim NumDatos As Long Dim co1 As Long. Datos(co2 .1) End If Else If Not (Datos(co2) < Datos(co2 .

4 Copiando hojas Para copiar hojas usamos el método copyByName ( NombreHoja. NombreNuevo.getSheets() 'Copiamos la "hoja2" como "Nueva Hoja2" al inicio oHojas.hasByName(sNombre) And (Not oHojas. co1 ) Next co1 End Sub 6. si la hoja a copiar existe y el nombre nuevo no existe If oHojas. oHojas. Posicion ) de la siguiente manera: Sub CopiarHoja1() Dim oHojas As Object oHojas = ThisComponent. sNombreNuevo. por ejemplo: Sub Dim Dim Dim Dim CopiarHojaActiva() oHojas As Object oHoja As Object sNombre As String sNombre2 As String . es evaluarlo antes: Sub Dim Dim Dim CopiarHoja2() oHojas As Object sNombre As String sNombreNuevo As String sNombre = "Datos" sNombreNuevo = "Datos nuevos" oHojas = ThisComponent. sera el mismo de la posición oHojas. "Nueva Hoja2". 1 ) 'Recorremos la matriz For co1 = LBound( mNombres() ) To UBound( mNombres() ) 'El índice en la matriz.copyByName( sNombre.copyByName( "Hoja2".1. lo mejor.moveByName( mNombres(co1).174 'Ordenamos la matriz Call OrdenarBurbuja( mNombres().hasByName(sNombreNuevo)) Then oHojas.1 Trabajando con hojas 6.getSheets() 'Solo copia la hoja.getCount() ) Else MsgBox "No se copio la hoja" End If End Sub Podemos intentar copiar una hoja y asegurarnos de que el nombre no exista. 0 ) End Sub Por supuesto el nombre de la hoja a copiar “debe” de existir y el nombre nuevo de la hoja “no debe” existir. tomando como base el nombre actual de la hoja.

pero.setName( "Prueba" ) End Sub También puedes usar el índice para referirte a la hoja: Sub CambiarNombreHoja2() Dim oHojas As Object oHojas = ThisComponent.hasByName( sNombre2 ) 'Si ya existe incrementamos el contador co1 = co1 + 1 'y construimos el nuevo nombre sNombre2 = sNombre & "_" & Format(co1) Loop 'Sale del ciclo cuando el nuevo nombre no exista.getCount()) 'Referencia a la nueva hoja oHoja = ThisComponent. oHojas. sNombre2.5 Renombrando hojas Para renombrar hojas usamos el método setName. por “Prueba” oHojas. de la siguiente manera: Sub CambiarNombreHoja1() Dim oHojas As Object oHojas = ThisComponent.getSheets.Aprendiendo OOo Basic Dim co1 As Long 'Referencia a todas las hoja oHojas = ThisComponent.getByName(sNombre2) 'Y la activamos ThisComponent.getByName("Hola"). entonces 'podemos copiar la hoja al final (o donde quieras) oHojas.getSheets() .1.getSheets() 175 'Nombre de la hoja activa sNombre = ThisComponent.getCurrentController.getCurrentController.copyByName(sNombre. esa es tu tarea: 6..getName() 'Contador para construir el nuevo nombre co1 = 1 'El nuevo nombre es igual mas un guion bajo y un numero sNombre2 = sNombre & "_" & Format(co1) 'Hace el ciclo mientras el nuevo nombre exista Do While oHojas..setActiveSheet(oHoja) End Sub Solo te resta preguntarle al usuario cuantas nuevas hojas quiere e insertar ese número de hojas nuevas.getSheets() 'Cambiamos el nombre de la hoja “Hola”.getActiveSheet.

cambiamos los nombres de las hojas por números: Sub CambiarNombreHoja4() Dim oHojas As Object Dim co1 As Integer oHojas = ThisComponent.getByIndex( co1-1 ).getSheets() For co1 = 1 To oHojas.hasByName(sNombreNuevo)) Then oHojas. en algunos casos.setName( Chr( co1+64 ) ) Next End Sub O los meses del año: Sub Dim Dim Dim Dim CambiarNombreHoja6() oHojas As Object co1 As Integer Limite As Byte sMes As String . “el cambio de nombre no tendrá efecto”. te toca averiguar ¿porqué? Sub CambiarNombreHoja5() Dim oHojas As Object Dim co1 As Integer oHojas = ThisComponent.hasByName(sNombreActual) And (Not oHojas.getByIndex( 0 ).getSheets() 'Validamos que la hoja exista y el nuevo nombre no If oHojas.getSheets() For co1 = 1 To oHojas.setName( "Gastos" ) End Sub 6. tu tarea es decirme ¿porqué? y corregirlo. también.1 Trabajando con hojas Es recomendable validar que la hoja a renombrar exista y que el nuevo nombre no: Sub Dim Dim Dim CambiarNombreHoja3() oHojas As Object sNombreActual As String sNombreNuevo As String sNombreActual = "Resumen" sNombreNuevo = "Terminado" oHojas = ThisComponent.getCount() oHojas. el código siguiente podría fallarte si tienes más de 25 hojas en tu documento.getByName( sNombreActual ).setName( co1 ) Next End Sub Ahora por letras.getCount() oHojas.176 oHojas.setName( sNombreNuevo ) Else MsgBox "No se renombro la hoja" End If End Sub Solo para divertirnos.getByIndex( co1-1 ).

así mismo.getSheets() 177 'Para que solo cambie las primeras 12 If oHojas. esta no cambia de índice por lo que puedes usar el mismo para .setName( sMes ) Next End Sub Te queda de tarea lograr completar los meses para que sean los doce del año."mmmm") oHojas.getActiveSheet() oHojaActiva.6 Ocultando y mostrando hojas Mostrar y ocultar hojas es muy sencillo. También puedes ocultar una hoja por medio de su índice. como en: Sub OcultarHoja2() Dim oHoja As Object oHoja = ThisComponent. 6.getSheets(). tiene que haber al menos una hoja visible en un documento de Calc.1) .getByIndex( co1-1 ).getByIndex(1) oHoja. sino te dará un error. pero la dejará visible por que. tienes que insertar los meses que te hagan falta si el documento tiene menos de las hojas necesarias. si tiene más de doce borra las sobrantes.getCount() End If For co1 = 1 To Limite 'Obtenemos el nombre del mes sMes = Format( DateSerial(Year(Date).Aprendiendo OOo Basic oHojas = ThisComponent.1. es decir.isVisible = False End Sub Toma en cuenta que: el índice de la hoja “debe” existir. solo hay que establecer su propiedad isVisible en verdadero (True) o falso (False) según se requiera de la siguiente manera: Sub OcultarHoja1() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCount() > 12 Then Limite = 12 Else 'O las que haya si son menos de 12 Limite = oHojas.co1.getCurrentController.isVisible = False End Sub La macro anterior te ocultara la hoja activa. si solo hay una no te dará error. si la ejecutas varias veces te ira ocultando tus hojas hasta que solo quede una. si ocultas una hoja. como sabes.

1.getName() Then oHojas.isVisible = Not oHoja. la siguiente macro alterna entre mostrar y ocultar la primer hoja del documento: Sub OcultarHoja3() Dim oHoja As Object oHoja = ThisComponent. pasándole como argumento.getActiveSheet() 'Para que veas que si me ocurren otras contraseñas .getCount() . con lo que la hoja no estará muy protegida que digamos.getByIndex(0) oHoja.1 Trabajando con hojas acceder a ella.getByIndex(co1).getByIndex(co1). por supuesto. establecer una contraseña para evitar modificaciones a la misma.1 If oHojas.getCurrentController().isVisible End Sub Como ya habrás intuido. 6. la contraseña que queremos establecer. recuerda que para que la protección de celdas individuales sea efectiva. es decir. la hoja debe estar protegida.getSheets() For co1 = 0 To oHojas. muchos usuarios no saben desproteger una hoja.178 6.getName <> oHojaActiva.7 Protección y desprotección de hojas Para terminar este capítulo.getSheets().getCurrentController(). pero creeme. puedes pasarle una contraseña vacía.getByIndex(1) oHoja. Para proteger una hoja. veamos como proteger una hoja. aunque este oculta. usamos el método Protect.isVisible = True End Sub El siguiente código te oculta todas las hojas. para mostrar una hoja oculta simplemente hay que establecer esta propiedad en verdadero (True) Sub OcultarHoja4() Dim oHoja As Object oHoja = ThisComponent. Sub ProtegerHoja1() Dim oHojaActiva As Object oHojaActiva = ThisComponent.isVisible = False End If Next End Sub Tu tarea es hacer la función inversa.getSheets(). además. muestra todas las hojas ocultas. aun sin contraseña.getActiveSheet() oHojas = ThisComponent. excepto la hoja activa: Sub Dim Dim Dim OcultarHoja5() oHojaActiva As Object oHojas As Object co1 As Long oHojaActiva = ThisComponent.

pero no será efectiva la modificación. no obtendrás ningún error.unProtect( "letmein" ) 'Verificamos si tuvo exito la desprotección If oHojaActiva. por ejemplo. tampoco retornará ningún error. verificar si es correcta o no y darle solo tres intentos para ingresarla. el método no te devolverá ningún error como en la interfaz del usuario que te avisa que la contraseña es incorrecta.2 Referencia a rangos Seguro que sabes. para cambiarla. primero tienes que desprotegerla y después cambiarla. usamos el método unProtect. 6. para actuar en consecuencia. procura usar la propiedad para saber si una hoja esta o no protegida (isProtected).Protect( "letmein" ) End Sub 179 Y para desproteger. que el trabajo con rangos es esencial en estos documentos.getActiveSheet() If oHojaActiva. el trabajo con rangos desde código OOo Basic es igualmente importante.isProtected Then MsgBox "La contraseña no es correcta" Else MsgBox "Hoja desprotegida correctamente" End If Else MsgBox "La hoja NO esta protegida" End If End Sub Te queda de tarea modificar la macro para solicitar al usuario la contraseña. así que dejo a tu criterio esta validación. . Sub ProtegerHoja2() Dim oHojaActiva As Object oHojaActiva = ThisComponent. para saber si tuvo éxito o no la desprotección. Fácil. Cuando proteges una hoja e intentas hacer modificaciones a esta. En la siguientes secciones nos centraremos en aprender como hacer referencia a distintos tipos de rangos para después poder manipularlos. escribir en una celda. si es falsa (False). por lo mismo. pero la hoja permanecerá con la contraseña original. si es verdadera (True) la hoja sigue protegida. ya vimos como aseguramos que estamos trabajando en una hoja de calculo. hay que pasársela como argumento. si no es correcta. ¿verdad?. la hoja esta desprotegida. darles formato o hacer con ellos lo que queramos. si eres usuario habitual de una hoja de calculo. si la hoja tiene contraseña.isProtected Then MsgBox "La hoja esta protegida" 'Intentamos desprotegerla oHojaActiva. si intentas proteger una hoja que ya tiene contraseña. Como comentarios finales. hay que verificar la propiedad isProtected.getCurrentController().Aprendiendo OOo Basic oHojaActiva.

pero en cada ejemplo podrás notar que repasamos estos conocimientos. recuerda que los índices de inicio desde código empiezan en 0. por lo que para hacer referencia a la celda E5. “deberías” de validar que los valores proporcionados son correctos. principalmente por su nombre o por su posición.getActiveSheet() 'Referencia a la celda E5 oCelda = oHojaActiva.x tenemos 1024 columnas para trabajar.getCurrentController.2.org. por ejemplo. observa la estructura getCellAddress.Row End Sub Observa como comprobamos en la ultima linea. es decir a la celda E5. la hoja (valor tipo integer. pues te dará un error. primero tienes que acceder a la hoja donde están las celdas que te interesa manipular. que efectivamente hemos hecho referencia a la celda que nos interesa. no esta de más comentarte que tengas cuidado de no establecer una posición fuera de la hoja. el primer valor es para la columna y el segundo para la fila. en la versión 3.x de OpenOffice. esta. si el valor de la fila y columna se la solicitas al usuario.getCurrentController. como acceder a hojas es un tema que ya hemos tratado. la forma más simple de hacer referencia a una celda es por su nombre: Sub AccesoCeldas1() Dim oHojaActiva As Object Dim oCelda As Object 'Referencia a la hoja activa oHojaActiva = ThisComponent.Column & Chr(13) & _ "Fila: " & oCelda. este.getCellAddress.getCellAddress. que en columna y fila es la 4. es muy importante pues a muchos métodos para manipular celdas. solo tiene tres propiedades.getString() 'Mostramos la hoja.getActiveSheet() 'Nos aseguramos que sea un valor con Val y que sea positivo con Abs Col = Abs(Val(InputBox("Dame la columna"))) Fil = Abs(Val(InputBox("Dame la fila"))) .1 Referencia a celdas individuales Podemos acceder a las celdas de una hoja de calculo de varias maneras. Ahora accedemos a una celda por su posición. se les tienen que pasar estructuras como esta. por supuesto. la columna (long) y la fila (long) de esta celda. Sub Dim Dim Dim Dim AccesoCeldas2() oHojaActiva As Object oCelda As Object Col As Long Fil As Long oHojaActiva = ThisComponent. pero muy importante.Sheet & Chr(13) & _ "Columna: " & oCelda.2 Referencia a rangos 6. tenemos que poner la columna 4 y fila 4. también empieza en 0) donde esta la celda referenciada. columna y fila correspondiente a esta celda MsgBox "Hoja: " & oCelda.getCellAddress.getCellRangeByName( "E5" ) 'Mostramos el contenido de la celda MsgBox oCelda.180 6. establecer el valor de la columna en 256 o superior si trabajos con la versión 2. por que recordamos que los número de columna y fila empiezan en 0.

select(oRango) . más adelante veremos todas las posibilidades que tenemos para introducir u obtener datos de las celdas de nuestra hoja de calculo.2. usando el mismo método usado para acceder a una celda: Sub AccesoRango1() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. Sub Dim Dim Dim AccesoCeldas3() oHojaActiva As Object oCelda As Object co1 As Integer oHojaActiva = ThisComponent.co1.setString( Format( DateSerial(Year(Date).Fil ) MsgBox oCelda.setString( Year(Date) ) For co1 = 1 To 12 'Referencia a celda por posicion oCelda = oHojaActiva.Columns. como el ejemplo siguiente que inserta el año como titulo en la celda A1 y los meses del año de la celda A2 a la A13.2 Referencia a un rango de celdas Podemos acceder a un rango de celdas por su nombre.getActiveSheet() 'Referencia al rango A1:E5 oRango = oHojaActiva. y el acceso por posición es muy útil para realizar ciclos.1) . 6.getCellRangeByName( "A1" ) oCelda.getCellRangeByName( "A1:E5" ) 'Y lo seleccionamos ThisComponent.co1 ) oCelda.Aprendiendo OOo Basic 181 'Nos aseguramos que esten dentro de los rangos correctos If Col < oHojaActiva.Rows.getString() Else MsgBox "Valores de celda incorrectos" End If End Sub Es frecuente que el acceso por nombre a una celda se use para establecer valores preestablecidos.getCellByPosition( 0.Count And Fil < oHojaActiva.getCurrentController.getActiveSheet() 'Referencia a celda por nombre oCelda = oHojaActiva."mmmm") ) Next End Sub Observa que hemos estado usando el método getString() para obtener el contenido de una celda y setString(Valor As String) para establecerlo.getCellByPosition( Col. como títulos de campos por ejemplo.Count Then 'Accedemos a la celda oCelda = oHojaActiva.getCurrentController. así como sus diferencias.getCurrentController.

getActiveSheet() 'Seleccionamos el rango B1:B10 oRango = oHojaActiva.getActiveSheet() 'Seleccionamos el rango por su nombre definido oRango = oHojaActiva..0.getCellRangeByName( "Datos" ) 'Y lo seleccionamos ThisComponent. la columna y fila donde empieza nuestro rango y la columna y fila donde termina.9 ) 'Y lo seleccionamos ThisComponent. ese cuadro de lista desplegable (combobox) que esta al lado de la barra de formulas. sino. observa como obtenemos la hoja donde se encuentra.1. si el nombre del rango no existe. los argumentos pasados a este método son cuatro. cuya teclas de acceso rápido son Ctrl+F3. algunos piensan que los dos últimos argumentos son el ancho y alto del rango a usar.getCurrentController. Sub Dim Dim Dim Dim AccesoRango4() oHoja As Object oRango As Object oRangosPorNombre As Object sNombreRango As String . es mejor validar que el rango exista. seleccionamos el rango de celdas llamado Datos. Si el usuario es el que proporciona el nombre del rango.2 Referencia a rangos Para acceder a un rango de celdas por su posición.select(oRango) End Sub Observa que ahora usamos el método getCellRangeByPosition.getCellRangeByPosition( 1. te dará un error en tiempo de ejecución y por supuesto sin sobrepasar el máximo de filas y columnas de la hoja de calculo.182 End Sub 6. como en la ultima línea seleccionamos el rango referenciado. que requiere de cuatro argumentos.. hay que usar un método diferente: getCellRangeByPosition. Sub AccesoRango3() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. estos argumentos también son números de índices de columna y fila respectivamente y tienes que tener la precaución de establecer los segundos iguales o mas grandes que los primeros. es usar nombres definidos de rangos.getCurrentController. este método no es sensible a mayúsculas o minúsculas. recuerda que los números de fila y columna empiezan en 0. te dará un error en tiempo de ejecución. aquellos que establecemos desde el “Cuadro de nombre” en la hoja de calculo.getCurrentController. Toma nota de que si el rango no existe en al hoja desde donde se intenta referenciar.getCurrentController. En el siguiente ejemplo. te dará un error. Observa también.select(oRango) End Sub Por supuesto. no es así. Sub AccesoRango2() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. Para hacer referencia a la hoja correcta donde exista el rango con nombre. es decir. como siempre. que también puedes establecer desde el menú Insertar | Nombres | Definir. Otra posibilidad. ya sabes.

los veremos más adelante.StartRow & Chr(13) & _ "Columna Fin: " & oDirCelda. de hecho.EndRow MsgBox sTmp End Sub Esta estructura también es usada por varios métodos para manipular rangos que veremos más adelante. puedes tener un mismo nombre para un rango de celdas y para un rango de datos. también es posible obtener información. hacemos la selección de un rango y mantenemos presionada la tecla Ctrl y hacemos un segunda selección de un rango y así sucesivamente.EndColumn & Chr(13) & _ "Fila Fin: " & oDirCelda. Sub Dim Dim Dim Dim AccesoRango5() oHojaActiva As Object oRango As Object oDirCelda As Object sTmp As String oHojaActiva = ThisComponent. la columna y fila donde comienza y la columna y fila donde acaba. por lo que es importante que la tengas presente..StartColumn & Chr(13) & _ "Fila Inicio: " & oDirCelda.getSheets.2. con los que puedes establecer en el menú Datos | Definir rango.Sheet & Chr(13) & _ "Columna Inicio: " & oDirCelda. los segundos. pero son dos cosas diferentes.getCurrentController.getCurrentController.getActiveSheet() oRango = oHojaActiva.getByName(sNombreRango).NamedRanges() sNombreRango = Trim( InputBox( "Escribe el nombre del rango a seleccionar" ) ) 'Comprobamos que el rango exista If oRangosPorNombre.Sheet) 'Seleccionamos el rango por su nombre definido oRango = oHoja.getCellRangeByName( sNombreRango ) 'Y lo seleccionamos ThisComponent..select(oRango) Else MsgBox "El rango " & sNombreRango & " no existe en el documento" End If End Sub No confundas estos nombres de rangos.. De los rangos de celdas. 6.Aprendiendo OOo Basic 183 'Referencia a todos los rangos con nombre en la hoja de calculo oRangosPorNombre = ThisComponent.getReferredCells.getByIndex(oRangosPorNombre.getRangeAd dress.getRangeAddress() 'Construimos el texto informativo sTmp = "El rango esta en la hoja: " & oDirCelda. para ello se hace uso de la estructura CellRangeAddress a travez del método getRangeAddress que te devuelve información de: la hoja donde esta el rango.getCellRangeByName( "Nombres" ) 'Obtenemos la información de la dirección oDirCelda = oRango.hasByName( sNombreRango ) Then oHoja = ThisComponent. ya que estos últimos se refieren a rangos considerados como una tabla de datos.3 Referencia a varios rangos de celdas Cuando en la interfaz del usuario. .

getRangeAddress() .star.SheetCellRanges") 'Creamos la estructura CellRangeAddress necesaria oDirRango = oHojaActiva.getCurrentController.getCellRangeByName( "E1:G2" ) 'Y lo agregamos al contenedor de rangos.getCellRangeByName( oRangos.getRangeAddress() .False ) 'Comprobamos que están correctos seleccionándolos ThisComponent.False ) "B4:B5" ).sun. primero debemos crear el “contenedor” de estos rangos.getCurrentController.getCurrentController.184 6.star.getActiveSheet() 'Creamos el contender para los rangos oRangos = ThisComponent. los tres líneas donde se agrega el rango con el método addRangeAddress() son iguales.False ) "E13:E14" ).False ) 'Aquí solo hacemos referencia al rango oRango = oHojaActiva.False ) 'Aquí agregamos un rango directamente al contenedor 'toma en cuenta que se van acumulando oRangos.False ) "C7:C8" ).getCellRangeByName( oRangos. podrás concentrar código de forma más natural.getCellRangeByName( 'Mostramos las direcciones de los rangos MsgBox oRangos.getCellRangeByName( oRangos.getRangeAddress() . por ejemplo.getRangeAddress() . también de estos rangos podemos obtener información.getRangeAddress() . si vas empezando a programar.addRangeAddress( oHojaActiva. veamos como: Sub Dim Dim Dim Dim Acceso_A_Rangos1() oHojaActiva As Object oRangos As Object oRango As Object oDirRango As Object oHojaActiva = ThisComponent. lo que cambia es la forma en que hacemos referencia a la dirección del rango.sheet.2 Referencia a rangos estamos hablando de un conjunto de rangos que tiene sus características particulares para su control y manejo.sheet.select(oRangos) End Sub No te confundas.getRangeAddress() . por ahora.addRangeAddress( oHojaActiva.addRangeAddress( oHojaActiva.False ) .addRangeAddress( oDirRango .addRangeAddress( oHojaActiva. con el tiempo y la experiencia. Por supuesto.getRangeAddress() .sun.addRangeAddress( oRango. usa todas las líneas que consideres pertinentes para que tu código lo entiendas con solo verlo.False ) "D10:D11" ).SheetCellRanges") 'Agregamos los rangos que queramos oRangos.getCellRangeByName( "A1:B2" ).addRangeAddress( oHojaActiva.createInstance("com.getActiveSheet() 'Creamos el contender para los rangos oRangos = ThisComponent.getCellRangeByName( "D4:E5" ). te recomiendo ir desglosando cada línea.getRangeAddress() 'Y lo agregamos al contenedor de rangos oRangos.createInstance("com.addRangeAddress( oHojaActiva.getRangeAddressesAsString() End Sub "A1:A2" ).getCellRangeByName( oRangos. Para seleccionar varios rangos desde código. los nombres de los rangos que contiene: Sub Acceso_A_Rangos2() Dim oHojaActiva As Object Dim oRangos As Object oHojaActiva = ThisComponent. nota como tenemos que usar 'el método getRangeAddress para pasarle el argumento correcto oRangos.

si el rango que quieres remover no existe en la colección.sun.sheet.getRangeAddressesAsString() 'Removemos el rango deseado oRangos.getCellRangeByName( oRangos. de tarea te queda garantizar que se corresponde uno con el otro. que el objeto que apunta a la hoja.getActiveSheet() 'Creamos el contender para los rangos oRangos = ThisComponent.removeRangeAddress(oHojaActiva.. observa que le pasamos el nombre del rango como texto ("Hoja1.getRangeAddress() .getCellRangeByName( 'Comprobamos que estén los rangos MsgBox oRangos.getRangeAddress() ) 'Volvemos a verificar que se haya removido MsgBox oRangos.hasByName("Hoja1..4 Referencia a filas y columnas .. Sub Acceso_A_Rangos4() Dim oHojaActiva As Object Dim oRangos As Object oHojaActiva = ThisComponent.D10:D11") Then 'Removemos el rango deseado oRangos. te dará un error en tiempo de ejecución.Aprendiendo OOo Basic 185 Nota como los rangos es una cadena larga de las direcciones de los rangos separados por un “ .Chr(13)) 'Mostramos el resultado MsgBox sTmp Los rangos también se pueden remover de la colección. cuando consultamos con hasByName si el rango existe.getRangeAddress() .2. reemplaza los puntos y comas por un salto de línea con el siguiente código. 6. por saltos de linea sTmp = Join( Split(oRangos..createInstance("com. 'Validamos que el rango a remover exista en la colección If oRangos. ”.addRangeAddress( oHojaActiva.star.False ) "B4:B5" ).removeRangeAddress( oHojaActiva. le pasamos un objeto (oHojaActiva) que no necesariamente tiene que corresponder con el nombre de hoja (Hoja1).addRangeAddress( oHojaActiva.".False ) "D10:D11" ).getRangeAddressesAsString() End Sub "A1:A2" ).").getCurrentController.addRangeAddress( oHojaActiva.getCellRangeByName( oRangos. 'Lo unico que hacemos es reemplazar los . si lo quieres mejor presentable.getRangeAddress() .getRangeAddress() .SheetCellRanges") 'Agregamos los rangos que queramos oRangos.getCellRangeByName( oRangos.getRangeAddressesAsString().getCellRangeByName( "D10:D11" ). efectivamente corresponda en nombre con el rango pasado.addRangeAddress( oHojaActiva.D10:D11") y que incluye el nombre de la hoja donde esta el rango.False ) Cuidado. lo mejor es validar antes que existe.False ) "C7:C8" ).getCellRangeByName( "D10:D11" ). pero observa como al método removeRangeAddress. es decir.getRangeAddress()) End If El código anterior tiene un problema que tal vez te pueda causar un pequeño inconveniente.

getActiveSheet() 'Referencia a la columna A oRango = oHojaActiva. en función de hacer referencia a ellas.getCurrentController.2 Referencia a rangos Las filas y columnas de una hoja de calculo siguen siendo rangos de celdas. como en.getCurrentController.select(oRango) .getCurrentController.select(oRango) End Sub Nota como tomamos de la fila 1 y hasta la 65536 que es el número total de filas con que por ahora cuentan las hojas de calculo de Calc.getActiveSheet() 'Referencia a la fila 10 oRango = oHojaActiva.getCurrentController.getCurrentController.186 6.getCurrentController.getCurrentController.getActiveSheet() 'Referencia a la columna A que se nombro previamente oRango = oHojaActiva.select(oRango) End Sub Podemos hacer lo mismo con las filas: Sub AccesoFilas1() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. también es posible acceder por medio de este nombre: Sub AccesoColumna2() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.getCellRangeByName( "Claves" ) 'Y lo seleccionamos ThisComponent.getCurrentController. si la columna completa tienen un nombre.getCellRangeByName( "Registros" ) 'Y lo seleccionamos ThisComponent. lo único que las caracteriza.select(oRango) End Sub Sub AccesoFilas2() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.getCellRangeByName( "A1:A65536" ) 'Y lo seleccionamos ThisComponent. Sub AccesoColumna1() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. es que abarcan la totalidad de celdas que contienen.getActiveSheet() 'Referencia a la fila 15 que se nombro previamente oRango = oHojaActiva.getCellRangeByName( "A10:IV10" ) 'Y lo seleccionamos ThisComponent.

también.getActiveSheet() 'Referencia al rango C5:E10 oRango = oHojaActiva.getActiveSheet() 'Referencia al rango A1:A10 oRango = oHojaActiva. al acceder por medio de estos métodos.getCellRangeByName( "C5:E10" ) 'Mostramos el tipo de objeto MsgBox oRango.getColumns() 'Verificamos el tipo de objeto MsgBox oRango.getCellRangeByName( "A1:E1" ) 'Mostramos el tipo de objeto MsgBox oRango. trata de acceder a la información de depuración como se vio en capítulos anteriores y nota como implementan métodos y propiedades diferentes.Aprendiendo OOo Basic End Sub 187 OOo Basic cuenta con métodos específicos para manipular filas y columnas.getImplementationName() 'Renombramos el objeto oRango accediendo a sus columnas oRango = oRango. Es el mismo caso para las filas: Sub AccesoFilas3() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.getImplementationName() 'Renombramos el objeto oRango accediendo a sus filas oRango = oRango. dejan de ser rangos de celdas y pasan a ser objetos ScTableRowsObj y ScTableColumnsObj respectivamente como lo demostramos a continuación: Sub AccesoColumna3() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.getImplementationName() .getImplementationName() End Sub Trata de seleccionar el rango tal y como queda al final del código y veras que te da un error.getActiveSheet() 'Referencia al rango A1:E1 oRango = oHojaActiva. pero propiamente hablando.getCurrentController.getImplementationName() End Sub Por lo anterior.getRows() 'Verificamos el tipo de objeto MsgBox oRango. la recomendación es que mantengas tu referencia original al rango y uses una segunda variable si necesitas acceder a las filas o columnas completas como te muestro en el siguiente ejemplo: Sub Dim Dim Dim Dim AccesoFilasColumnas1() oHojaActiva As Object oRango As Object oFil As Object oCol As Object oHojaActiva = ThisComponent.getCellRangeByName( "A1:A10" ) 'Mostramos el tipo de objeto MsgBox oRango.getCurrentController.getCurrentController.

siempre (aunque en el rango exista solo una fila o columna) te devolverá un conjunto de Columnas y Filas.getImplementationName() & " .188 'Creamos una nueva referencia a las filas y columnas oCol = oRango.getColumns() oFil = oRango.select(oFil) End Sub Por supuesto.getCellRangeByName( "C5:E10" ) 'Creamos una nueva referencia a la segunda fila del rango la 6 oFil = oRango.getCurrentController.getCurrentController.2 Referencia a rangos 'Verificamos el tipo de objeto MsgBox oCol.sheet. veamos los dos casos: Para seleccionar la primer columna del rango Sub Dim Dim Dim AccesoFilasColumnas2() oHojaActiva As Object oRango As Object oCol As Object oHojaActiva = ThisComponent.getCellRangeByName( "C5:E10" ) 'Creamos una nueva referencia a la primer columna del rango la C oCol = oRango. tenemos que acceder a cada fila o columna de forma individual o construir un contenedor de rangos para acceder a varias filas o columnas." & oFil.select(oCol) End Sub Para seleccionar la primer fila del rango Sub Dim Dim Dim AccesoFilasColumnas3() oHojaActiva As Object oRango As Object oFil As Object oHojaActiva = ThisComponent. así como para poder hacer selecciones.getCurrentController.star.createInstance("com.getByIndex(0) 'Y lo seleccionamos ThisComponent.getImplementationName() End Sub Los métodos getColumns y getRows.getColumns().getRows() 6.getActiveSheet() 'Referencia al rango C5:E10 oRango = oHojaActiva.getActiveSheet() 'Referencia al rango C5:E10 oRango = oHojaActiva.SheetCellRanges") 'Agregamos la columna E y la fila 10 al contenedor .getByIndex(1) 'Y lo seleccionamos ThisComponent.getCurrentController. podemos seleccionar una fila y una columna al mismo tiempo Sub AccesoFilasColumnas4() Dim oHojaActiva As Object Dim oRangos As Object oHojaActiva = ThisComponent.getCurrentController.getRows().sun. para poder tener acceso a los métodos y propiedades disponibles en los rangos.getActiveSheet() 'Creamos el contender para los rangos oRangos = ThisComponent.

en capítulos posteriores.SvxShapeCollection . si lo hiciste en el mismo orden que yo.addRangeAddress( oHojaActiva.sun. podemos acceder directamente a la fila o columna que queramos de cualquier hoja por medio de la colección de estas (getColumns y getRows) y por medio del índice (getByIndex) a la fila o columna deseada: oHojaActiva. seleccionado los siguientes elementos: 1. Varios rangos de celdas 4. con lo que el usuario tenga seleccionado al momento de llamar a una macro.False ) 'Comprobamos que estan correctos seleccionandolos ThisComponent.getByIndex(9) 'Columna E 'Fila 10 Por ahora hemos visto como hacer referencia a diferentes tipos de rangos. es decir.select(oRangos) End Sub Como ya notaste. com. 6.getCurrentSelection() MsgBox oSel.getRows(). insertar.. nuestra selección pueden ser muchas cosas. ScCellObj 2. trataremos de mantener el control de la selección.5 Referencia a la selección actual Trabajar con la selección actual.getImplementationName() End Sub Pero cuidado.getRangeAddress().getByIndex(4). veamos uno muy importante.getByIndex(4) oHojaActiva.Aprendiendo OOo Basic 189 oRangos.getRows(). Una celda 2.getColumns(). veremos como manipular estos rangos. Un rango de celdas 3. es una actividad muy común. mover. teniendo cada vez.2. Para acceder a la selección actual dentro de nuestra hoja de calculo usamos el método getCurrentSelection() de la siguiente manera: Sub SeleccionActual1() Dim oSel As Object oSel = ThisComponent. muy propensa a errores (ya sabes como son los usuarios).star. ScCellRangesObj 4. vuelve a ejecutar la macro anterior. la selección actual.getRangeAddress(). la siguiente lista de mensajes: 1.addRangeAddress( oHojaActiva.False ) oRangos.getColumns().getByIndex(9). Un objeto de dibujo Debes de obtener. y también.drawing. copiar.getCurrentController. siempre que sea posible. etc. ScCellRangeObj 3. para terminar este tema de hacer referencia a rangos.

primer intento: Sub SeleccionActual3() Dim oSel As Object oSel = ThisComponent.getImplementationName() Case "ScCellObj" oCelda = oSel MsgBox oCelda. esto es muy importante para actuar en consecuencia por que son objetos diferentes y por lo tanto implementan métodos y propiedades diferentes.getCurrentSelection() MsgBox oSel. supongamos que nuestra macro requiere que el usuario seleccione una y solo una celda. el método getString() solo esta implementado en celdas individuales.2 Referencia a rangos Observa la diferencia entre una sola celda (1) y un rango (2 y 3). Sub SeleccionActual2() Dim oSel As Object oSel = ThisComponent.getString() End Sub Si seleccionaste una sola celda y esta contenía algo. podemos solo informarle como en el siguiente ejemplo: Sub SeleccionActual4() Dim oSel As Object Dim oCelda As Object oSel = ThisComponent.getCurrentSelection() Select Case oSel. te tuvo que haber dado el error “Propiedad o método no encontrado”. la macro anterior te tiene que mostrar ese contenido. por ello es muy importante discriminar la selección que haya hecho el usuario. en las dos siguientes selecciones. de un rango y varios rangos.getCurrentSelection() Select Case oSel. por ejemplo. pero dependerá de que queramos hacer con la selección para actuar en consecuencia. ejecuta la macro siguiente.getString() Case Else MsgBox "Se requiere seleccionar solo UNA celda" End Select End Sub . por ejemplo.getImplementationName() Case "ScCellObj" MsgBox "Muy bien seleccionaste solo una celda" Case "ScCellRangeObj" MsgBox "Te pasaste un poco" Case "ScCellRangesObj" MsgBox "No tienes remedio" Case Else MsgBox "No se ni que seleccionaste" End Select End Sub Ahora ya sabemos que es lo que el usuario selecciono. y nota también la diferencia en un rango (2) y varios (3). por que efectivamente. teniendo seleccionado cada uno de los tres primeros rangos mencionados.190 6. vamos a tratar de ver el contenido de una celda.

También. que el método a usar esta implementado en los tres. pero siempre. "ScCellRangeObj". .0 ) Case Else MsgBox "Se requiere seleccionar una celda" End Select If Not IsNull(oCelda) Then MsgBox oCelda. tienes que discriminar una u otra cosa. y en un grupo de rangos.getImplementationName() Case "ScCellObj" oCelda = oSel Case "ScCellRangeObj" 'Si es un solo rango. por ello podemos llamarlo sin problemas. no importa si fue el ultimo rango en ser seleccionado.getCellByPosition( 0.clearContents(31) End If End Sub El método clearContents.Aprendiendo OOo Basic 191 O podemos tomar solo la primer celda del rango o de los rangos que haya seleccionado como en: Sub SeleccionActual5() Dim oSel As Object Dim oCelda As Object oSel = ThisComponent. siempre válida los datos. nunca confíes en el usuario. esta implementado en los tres tipos de rangos.0 en relación con la hoja siempre se refiere a la celda A1. recuerda que la posición 0. recuerda que en la interfaz del usuario. el rango 0 también siempre será el que este más arriba y a la izquierda. accedemos a la primer celda oCelda = oSel.getCurrentSelection() Select Case oSel. tal vez sea valido cualquiera de los tres tipos de rangos.getString() End If End Sub Nota que aun tenemos que evaluar que oCelda. puede ser cualquier otra.getCellByPosition( 0. es decir. puede haber más elementos seleccionables.getCurrentSelection() Select Case oSel. siempre válida sus datos. es que.getImplementationName() Case "ScCellObj". dependiendo de tus necesidades. y disculpa la necedad. Es importante que recuerdes que en el caso de un rango. pero en relación al rango seleccionado. En algunos casos. por ejemplo: Sub SeleccionActual6() Dim oSel As Object Dim oRango As Object oSel = ThisComponent. Lo que he querido ilustrarte.0 ) Case "ScCellRangesObj" 'Si son varios rangos. apunte a un rango válido. primero accedemos al primer rango 'con getByIndex(0) y despues a la primer celda oCelda = oSel.getByIndex(0). como recomendación malévola. "ScCellRangesObj" oRango = oSel Case Else MsgBox "Se requiere seleccionar un rango" End Select If Not IsNull(oRango) Then 'Borramos el contenido de las celdas oRango. la primer celda siempre será la superior izquierda. más adelante veremos a detalle este método.

es necesario saber donde estamos ubicados.getCellAddress() 'Mostramos sus datos.EndRow MsgBox sTmp Next 'O podemos acceder a las direcciones de todos los rangos sTmp = Join( Split(oSel. fila y columna. observa como hacemos uso del índice de la hoja 'oDir.getRangeAddress() sTmp = "El rango " & co1 & " esta en la hoja: " & oDir.StartRow & Chr(13) & _ "Columna Fin: " & oDir. en que hoja.2. también.Sheet).StartColumn & Chr(13) & _ "Fila Inicio: " & oDir.getRangeAddress() 'Construimos el texto informativo sTmp = "El rango esta en la hoja: " & oDir.EndRow MsgBox sTmp Case "ScCellRangesObj" 'Si son varios rangos. muchos métodos de manipulación de rangos.getCount()-1 oDir = oSel.StartRow & Chr(13) & _ "Columna Fin: " & oDir.").6 Obteniendo información de rangos En diversas ocasiones. podemos obtener los datos de cada rango For co1 = 0 To oSel. por ello es importante saber cuales son y como están estructuradas.getCurrentSelection() Select Case oSel. es decir.192 6.EndColumn & Chr(13) & _ "Fila Fin: " & oDir.getByIndex(co1).". requieren se les pasen las estructuras correctas de la dirección de los rangos.StartColumn & Chr(13) & _ "Fila Inicio: " & oDir.Row Case "ScCellRangeObj" 'Si es un solo rango.getName() & Chr(13) & "Columna: " & oDir. los rangos cuentas con métodos y estructuras con esta información.Column & Chr(13) & "Fila: " & oDir.Sheet & Chr(13) & _ "Columna Inicio: " & oDir.getImplementationName() Case "ScCellObj" 'Obtenemos la direccion de la celda oDir = oSel. veamos cuales son: Sub Dim Dim Dim Dim InfoRangos1() oSel As Object oDir As Object sTmp As String co1 As Integer oSel = ThisComponent.getRangeAddressesAsString().EndColumn & Chr(13) & _ "Fila Fin: " & oDir.getByIndex(oDir.getSheets(). obtenemos sus datos oDir = oSel.Sheet para obtener el nombre de la hoja MsgBox "Hoja: " & ThisComponent. algunas de ellas ya las hemos usado.Sheet & Chr(13) & _ "Columna Inicio: " & oDir.Chr(13)) 'Mostramos el resultado MsgBox sTmp Case Else MsgBox "Se requiere seleccionar un rango de celdas" End Select End Sub .2 Referencia a rangos 6.

deben estar en el formato (string.Rango. todo desde 0. Observa como en el caso de varios rangos.".FunctionAccess" ) 'Validamos el tipo de rango pasado Select Case Rango.getSpreadsheet. por ejemplo “Datos. pero estos si cuentan con una propiedad de texto (getRangeAddressesAsString) que directamente nos devuelve las direcciones de los rangos en un formato entendible “casi” por cualquier usuario. la hoja por índice donde esta el rango. oDir.getSpreadsheet.getRangeAddress() 'Obtenemos la celda superior izquierda del rango mDatos =Array(oDir. podemos acceder a cada uno.sheet. tal y como sucede en la hoja de calculo.EndRow+1. sino que obtenemos los datos solo con propiedades del rango.getRangeAddressesAsString().Aprendiendo OOo Basic 193 Observa que si es una sola celda se tiene que usar getCellAddress que obtiene.StartColumn+1. pero podemos crearnos nuestra propia función que lo haga por nosotros: Sub InfoRangos2() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() 'Usamos nuestra función personalizada MsgBox DireccionRango(oSel) End Sub 'Que linda quedo esta funcion Function DireccionRango(Rango As Object) As String Dim oSFA As Object Dim oDir As Object Dim mDatos 'Nos apoyamos en la funcion de Calc DIRECCION (ADDRESS) oSFA = createUnoService( "com.Rango. la referencia a la celda. una propiedad o método similar para los casos de una celda y un rango. sino. los argumentos requeridos y estos.A2:E5”.callFunction("ADDRESS". nota que no hacemos uso de ninguna función de hoja de calculo. etc. indicándole la fila.callFunction("ADDRESS".Chr(13)) End Select End Function La función DIRECCION de Calc. reitero.mDatos()) & ":" 'Ahora la celda celda inferior derecha del rango mDatos = Array( oDir.) que “espera” la función. la columna y fila donde empieza y la columna y fila donde termina. si usamos las funciones de Calc desde OOo Basic."). cuando es un rango de celdas se usa getRangeAddress. 4 ) DireccionRango = DireccionRango & oSFA. integer.mDatos()) Case "ScCellRangeObj" 'Si es un rango de celdas usamos getRangeAddress oDir = Rango. la columna y fila. la función te retornara un error.getImplementationName() Case "ScCellObj" 'Si es una sola celda usamos getCellAddress oDir = Rango.mDatos()) Case "ScCellRangesObj" 'Esta ya la vimos DireccionRango = Join( Split(Rango.Column+1. que contiene. no se te olvide que todo empieza en 0.StartRow+1. la hoja donde esta la celda.getCellAddress 'Construimos la matriz de datos para la función mDatos = Array( oDir. nos devuelve en formato de texto.star. es muy importante pasarle.4.Row+1. puede ser la siguiente. desconozco su existe.4.getName()) DireccionRango = oSFA.getName() ) DireccionRango = oSFA.sun. columna.oDir.callFunction("ADDRESS". Una segunda versión de esta función.EndColumn+1. si queremos la referencia absoluta o relativa y la hoja. No he encontrado. oDir. puedes usar indistintamente cualquiera de las dos: . el nombre de estas tenemos que indicarlas en ingles y pasarle los argumentos de la función en forma de matriz de datos. mínimo.

cuentan con una propiedad que nos devuelve la dirección del rango seleccionado.getName() & ".getCurrentSelection() Select Case oSel.getRows(). cuando son varios rangos tienes que ingeniarteles que no es complicado.AbsoluteName End Sub 6.Chr(13) ) End Select DireccionRango2 = sTmp End Function Por ultimo.Row + 1 Case "ScCellRangeObj" sTmp = Rango. podemos saber el número de filas y columnas que tiene un rango usando los métodos getRows y getColumns respectivamente.getColumns().getCount()1).getColumns().getName() & _ Rango.2 Referencia a rangos Select Case Rango.getByIndex(0).").getColumns().getImplementationName() Case "ScCellObj". se llama AbsoluteName y el resultado como su nombre lo indica es con las referencias absolutas.".getColumns().2.getCellAddress." & _ Rango." & _ Rango.7 Trabajando con Cursores .getCount() & Chr(13) & _ "Columnas = " & oSel.getByIndex(Rango.EndRow + 1 Case "ScCellRangesObj" sTmp = Join( Split(Rango.getSpreadsheet."ScCellRangeObj" MsgBox "Filas = " & oSel.getRangeAddress.getRangeAddressesAsString().getName() & _ Rango. estos métodos solo están disponibles cuando el rango es una sola celda y un rango.getColumns().getName() & ".getRangeAddress.194 Function DireccionRango2(Rango As Object) As String Dim sTmp As String 6.getImplementationName() Case "ScCellObj" sTmp = Rango. también. Sub InfoRangos3() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() MsgBox oSel.StartRow + 1 & ":" & _ Rango.getName() & _ Rango.getSpreadsheet. Sub InfoRangos4() Dim oSel As Object oSel = ThisComponent.getCount() End Select End Sub Los rangos.getByIndex(0).

ahora si. útil y poderoso cuando se programa. supongamos la siguiente tabla de datos: Observa que el cursor esta en la celda D8 y que la región actual de este rango de datos es B2:F11. ejecuta la siguiente macro donde obligamos al usuario a seleccionar solo una celda.getSpreadSheet(). al ser un objeto diferente.gotoStart() MsgBox DireccionRango( oCursor ) 'Nos movemos al final oCursor. lo cual sabes.gotoEnd() .Aprendiendo OOo Basic 195 Un cursor. esta trabajara bien. pero muy importante. pero además tiene métodos muy útiles para expandir por ejemplo a la región actual. pero cuando intentemos pasarle un cursor.getCurrentSelection() 'Solo si es una sola celda If oSel. la región actual es un concepto sumamente. "ScCellCursorObj" Observa que ahora evaluara si es un rango de celdas o un cursor.createCursorByRange( oSel ) 'Verificamos que apunten a la misma celda MsgBox DireccionRango( oCursor ) 'Nos movemos al inicio de la region actual oCursor. no necesariamente es así y solo es para fines didácticos. tenemos que agregar el tipo de objeto "ScCellCursorObj". busca y corrige la siguiente línea en dicha función personalizada. cuando le pasemos como argumento una celda. ahora. Case "ScCellRangeObj". te devolverá una cadena vacía. que como sabes. para solucionar esto. nota que usaremos una función creada en tema anterior que se llama DireccionRango. ejecuta la siguiente macro: Sub Cursores1() Dim oSel As Object Dim oCursor As Object 'Partimos de la seleccion oSel = ThisComponent. es un objeto que nos permite movernos por la hoja entera o dentro de un rango especificado sin afectar o modificar al rango a partir del cual se crea. Lo más usual es crearlo a partir de un rango para desplazarse dentro de el. por ello le daremos un poco de énfasis.getImplementationName() = "ScCellObj" Then 'Mostramos la direccion de la celda seleccionada MsgBox DireccionRango( oSel ) 'Creamos un cursor a partir de esta celda oCursor = oSel. es el rango de celdas “con datos” delimitado por filas y columnas en blanco.

al compartir la mayoría de los servicios de las celdas y los rangos.collapseToCurrentRegion() MsgBox DireccionRango( oCursor ) 'Mostramos de nuevo la direccion de la celda seleccionada 'observa que esta no se a movido MsgBox DireccionRango( oSel ) Else MsgBox "Selecciona solo una celda" End If End Sub 6.createCursorByRange( oSel ) 'Nos movemos al final oCursor. "ScCellRangeObj" MsgBox "La siguiente fila libre es la: " & FilaLibre( oSel ) .getCurrentSelection() 'Solo funciona con celdas individuales o rangos de celdas Select Case oSel.gotoEnd() FilaLibre = oCursor.getCurrentSelection() 'Solo si es una sola celda If oSel.2 Referencia a rangos Los cursores. sera esta fila mas 1 MsgBox oCursor. pero sus métodos particulares son lo que los hacen especiales e interesantes.getImplementationName() = "ScCellObj" Then 'Creamos un cursor a partir de esta celda oCursor = oSel. con un cursor. heredan la mayoría de sus métodos y propiedades. esto es muy sencillo: Sub Cursores2() Dim oSel As Object Dim oCursor As Object 'Partimos de la seleccion oSel = ThisComponent.getImplementationName() Case "ScCellObj".getSpreadSheet().gotoEnd() 'La siguiente fila libre. algo muy practico es tener una función personalizada que nos encuentre la siguiente fila libre. es ¿como encuentro la siguiente fila libre?.getSpreadSheet().createCursorByRange( Rango ) oCursor.EndRow + 1 Else MsgBox "Selecciona solo una celda" End If End Sub Por supuesto.196 MsgBox DireccionRango( oCursor ) 'Expandismo el cursor a toda la region actual oCursor.getRangeAddress().EndRow + 1 End Function Y que usamos de una forma muy sencilla: Sub Cursores3() Dim oSel As Object Dim oCursor As Object 'Partimos de la seleccion oSel = ThisComponent. algo como: Function FilaLibre( Rango As Object) As Long Dim oCursor As Object oCursor = Rango.getRangeAddress(). Una pregunta recurrente en las listas de correo.

gotoStart() 'Toma nota de esta direccion MsgBox DireccionRango( oCursor ) oCursor. si te mueves al final de un rango (gotoEnd) y después te desplazas con gotoOffset(3.createCursorByRange( oSel ) oCursor. te saldrás del rango y ya no podrás regresar al inicio (gotoStart).getCurrentSelection() If oSel.gotoOffset(2.createCursorByRange( oSel ) 'Nos movemos a la siguiente celda oCursor. pues puedes “salirte” del rango donde estas trabajando y ya no podrás moverte con otros métodos como gotoStart o gotoEnd. o sea tres columnas a la derecha y tres filas abajo.3) MsgBox DireccionRango( oCursor ) 'Intentamos regresar al inicio. Sub Cursores5() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.getSpreadSheet().getCurrentSelection() If oSel.getImplementationName() = "ScCellObj" Then oCursor = oSel.Aprendiendo OOo Basic End Select End Sub 197 Otros métodos con que cuentan los cursores son: Sub Cursores4() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.gotoOffset(3.gotoEnd() MsgBox DireccionRango( oCursor ) 'Nos movemos tres columnas a la derecha y tres filas abajo oCursor.getSpreadSheet().gotoStart() MsgBox DireccionRango( oCursor ) Else .getImplementationName() = "ScCellObj" Then oCursor = oSel. usa estos métodos con precaución. nota como NO es la 'misma de la primer linea oCursor. por ejemplo.gotoPrevious() MsgBox DireccionRango( oCursor ) 'Nos movemos dos columnas a la derecha y tres filas abajo oCursor.gotoNext() MsgBox DireccionRango( oCursor ) 'Nos movemos a la celda anterior oCursor.3) MsgBox DireccionRango( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub Estos métodos hay que usarlos con cuidado.3).

2 Referencia a rangos Observa atentamente la siguiente imagen. estas se introducen con la combinación de teclas CTRL+SHIFT+ENTER y que ya creada. nota en la barra de formulas que la formula mostrada esta encerrada en unas llaves. no puedes modificar solo una celda de dichas matrices.198 MsgBox "Selecciona solo una celda" End If End Sub 6. sino tienes que hacerlo con toda la matriz. como sabes. estas llaves nos indican que dicha formula forma parte de una formula matricial. . como no es el tema de este libro las formulas matriciales no entraremos en detalle alguno. pero como sabes.

collapseToMergedArea() MsgBox DireccionRango( oCursor ) Else . como lo demostramos en el siguiente ejemplo.getSpreadSheet().createCursorByRange( oSel ) oCursor.getImplementationName() = "ScCellObj" Then oCursor = oSel.getCurrentSelection() If oSel.getSpreadSheet(). probado en los datos mostrados en la imagen anterior: Sub Cursores6() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.getImplementationName() = "ScCellObj" Then oCursor = oSel. cuando establecemos el cursor en celdas combinadas y tratamos de obtener dicha dirección.collapseToCurrentArray() MsgBox DireccionRango( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub En la siguiente imagen.Aprendiendo OOo Basic 199 Con un cursor. pero con un cursor podemos saber el rango completo de estas celdas combinadas: Sub Cursores7() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.getCurrentSelection() If oSel.createCursorByRange( oSel ) 'Comprobamos que solo devuelve una celda MsgBox DireccionRango( oSel ) 'Expandimos el cursor a todas las celdas combinadas oCursor. solo te devolverá la celda superior izquierda de dicho rango. observa las celdas combinadas. podemos saber cual es el rango de una formula matricial.

que no descartes usar un día.createCursorByRange( oSel ) 'Expandimos el cursor a la region actual oCursor.getImplementationName() = "ScCellObj" Then oCursor = oSel.collapseToCurrentRegion() MsgBox DireccionRango( oCursor ) 'Y luego a todas las filas oCursor. lo importante es saber que estas haciendo siempre: Sub Cursores10() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.2 Referencia a rangos Podemos expandir nuestro cursor para que abarque todas las columnas de nuestra región actual: Sub Cursores8() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.getImplementationName() = "ScCellObj" Then oCursor = oSel.expandToEntireRows() MsgBox DireccionRango( oCursor ) 'Nota como devuelve la hoja entera oCursor.getCurrentSelection() If oSel.expandToEntireRows() MsgBox DireccionRango( oCursor ) Ten cuidado cuando uses los dos métodos anteriores. tendrás un cursor con tu hoja completa.getSpreadSheet().expandToEntireColumns() MsgBox DireccionRango( oCursor ) .expandToEntireColumns() MsgBox DireccionRango( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub Intuirás que también es posible hacerlo en las filas: 'Expandimos el cursor a la region actual oCursor.collapseToCurrentRegion() MsgBox DireccionRango( oCursor ) 'Y luego a todas las columnas oCursor.collapseToCurrentRegion() MsgBox DireccionRango( oCursor ) 'Y luego a todas las columnas oCursor.getSpreadSheet().createCursorByRange( oSel ) 'Expandimos el cursor a la region actual oCursor. si los ejecutas uno detrás de otro.200 MsgBox "Selecciona solo una celda" End If End Sub 6.getCurrentSelection() If oSel.

Casi para finalizar.collapseToSize( 2.getRows().getColumns().getCurrentSelection() If oSel.createCursorByRange( oSel ) 'Expandimos el cursor a la region actual oCursor. como en el siguiente ejemplo: Sub Cursores12() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.getSpreadSheet().getImplementationName() = "ScCellObj" Then oCursor = oSel.5 ) MsgBox DireccionRango( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub Nota que estamos “cambiando” el tamaño del cursor.getCount ).Aprendiendo OOo Basic Else 201 MsgBox "Selecciona solo una celda" End If End Sub También puedes ampliar tu cursor el número de columnas y filas que necesites.createCursorByRange( oSel ) 'Expandimos el cursor a la region actual oCursor. esto es posible por que los cursores comparten la mayoría de los servicios con los rangos.getSpreadSheet(). Sub Cursores13() Dim oSel As Object . tienes que sumarle el ancho y alto de la región actual.getCount() + 5 ) MsgBox DireccionRango( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub Nota como hemos usado algunos métodos vistos en el tema anterior ( getColumns().getCount() + 1.collapseToCurrentRegion() MsgBox DireccionRango( oCursor ) 'Y luego cambiamos el cursor a 2 columnas y 5 filas oCursor. toma en cuenta que la celda superior izquierda no cambia: Sub Cursores11() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent. oCursor. veamos dos métodos más de los cursores.collapseToCurrentRegion() MsgBox DireccionRango( oCursor ) 'Y luego ampliamos el cursor 1 columna y 5 filas oCursor.getImplementationName() = "ScCellObj" Then oCursor = oSel. como ya lo mencionamos. si lo que quieres realmente es expandirlo.collapseToSize( oCursor.getCurrentSelection() If oSel.

la cosa cambia en cuanto tienes dos o más celdas usadas. por ejemplo. evita que se 'expanda la selección del rango oCursor.gotoStartOfUsedArea( False ) MsgBox DireccionRango( oCursor ) 'Ahora vamos al final oCursor. será el inicio y el fin de tu área de usuario. esta.202 Dim oCursor As Object oSel = ThisComponent.collapseToCurrentRegion() ThisComponent.getImplementationName() = "ScCellObj" Then oCursor = oSel. el “área de usuario”. un cursor.gotoEndOfUsedArea( False ) MsgBox DireccionRango( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub En una hoja de calculo. y digo que es dinámica. para terminar. es aquel rango “efectivamente” usado. es muy dinámico pues varia de acuerdo a su uso y eliminación.getSpreadSheet().. Ahora si. esta área se ira ajustando conforme a estos cambios. el argumento False. cuentan con unos métodos bastante interesantes (y útiles) para hacer algunas selecciones especiales.getCurrentSelection() If oSel.8 Selecciones especiales Los rangos.. en una hoja nueva el inicio y el final de esta área siempre será el mismo.createCursorByRange( oSel ) 6. 6. como en el ejemplo siguiente donde seleccionamos la región actual del rango: Sub Cursores14() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.select( oCursor ) Else MsgBox "Selecciona solo una celda" End If End Sub Con lo cual observamos que estos cursores con bastante versátiles. la celda A1. por que si eliminas datos o celdas. la regla es: el inicio de tu área de usuario será la celda (“con datos”) que este más cercana al extremo superior izquierdo de la hoja y el final será la celda (“con datos”) que este más cercana al extremo inferior derecho de dicha hoja.getSpreadSheet(). podemos seleccionar las celdas vacías de un rango como en: . también lo puedes usar para establecer una selección.getCurrentController. si tienes “una” sola celda usada.createCursorByRange( oSel ) oCursor.getCurrentSelection() If oSel.2 Referencia a rangos 'Vamos al inicio del area usada.getImplementationName() = "ScCellObj" Then oCursor = oSel.2.

si una celda tiene aunque sea solo un espacio o algún carácter especial no visible (tabuladores.sheet.sheet.select( oSelEsp ) End Sub Ahora.star.select( oSelEsp ) End Sub Los valores posibles para el argumento de este método son los siguientes.CellFlags. ya no será vacía y no la obtendrás por este método.getCurrentSelection() 'Recuperamos las celdas con texto oSelEsp = oSel.star.ANNOTATION Valor 1 2 4 8 .Borrando datos Constante com.getCurrentController. También podemos seleccionar celdas de acuerdo a su contenido.sun.queryEmptyCells() 'Y las seleccionamos ThisComponent.3. no es siempre necesario que selecciones.star.CellFlags.STRING com.star. es que este método siempre retorna un conjunto de rangos (ScCellRangesObj).select( oSelEsp ) End Sub Como hemos visto a lo largo de estas notas.4. esta. puedes manipular el rango obtenido sin que esto sea necesario.CellFlags.FORMULA ) ThisComponent.queryContentCells( 4 ) 'Y las seleccionamos ThisComponent.DATETIME com. saltos de página).CellFlags.sheet.star.getCurrentSelection() 'Recuperamos las celdas con formulas oSelEsp = oSel.getCurrentController.CellFlags. en el siguiente ejemplo seleccionamos las celdas con texto: Sub SeleccionesEspeciales2() Dim oSel As Object Dim oSelEsp As Object 'Accedemos a la seleccion actual oSel = ThisComponent.VALUE com.sheet.sun. valores que también se usan para borrar datos como se ve en el tema 6.getCurrentController.Aprendiendo OOo Basic 203 Sub SeleccionesEspeciales1() Dim oSel As Object Dim oSelEsp As Object 'Accedemos a la selección actual oSel = ThisComponent. los cuales tienes que manipular como ya lo hemos aprendido.sheet.sun. Un punto importante.sun.queryContentCells( com.sun.getCurrentSelection() 'Recuperamos las celdas vacías oSelEsp = oSel. las celdas con formulas: Sub SeleccionesEspeciales3() Dim oSel As Object Dim oSelEsp As Object oSel = ThisComponent.

star.sheet.2 Referencia a rangos Valor 16 32 64 128 256 512 Puedes usar de forma indistinta el valor numérico o su constante como se ve en los dos ejemplos anteriores y también sumar los valores para tener múltiples combinaciones.sun.sun.sun.getCount = 0 Then .star. de acuerdo su resultado.star.sheet.queryFormulaCells( 4 ) If oSelEsp.CellFlags.star.sun.CellFlags.getCurrentController.getCurrentSelection() 'Recuperamos las celdas con texto y valores oSelEsp = oSel. pero informamos si hubo o no celdas con el criterio especificado. estos métodos siempre devuelven un conjunto de rangos (ScCellRangesObj). las celdas que tengan notas.sheet. seleccionemos las celdas que contengan error: Sub SeleccionesEspeciales6() Dim oSel As Object Dim oSelEsp As Object oSel = ThisComponent. que ya hemos usado anteriormente: Sub SeleccionesEspeciales5() Dim oSel As Object Dim oSelEsp As Object oSel = ThisComponent. para este ejemplo.sheet.204 Constante com.STYLES com. observa que usamos una función personalizada (DireccionRango2).sheet.getCurrentSelection() 'Recuperamos las celdas con formulas cuyo resultado sea error oSelEsp = oSel.FORMATTED 6.sun.queryContentCells( 8 ) If oSelEsp.FORMULA com. por ejemplo.HARDATTR com. por lo que es muy sencillo saber si hay o no resultados.CellFlags. pero también podemos seleccionar formulas.star.sun.CellFlags. como en el ejemplo siguiente donde seleccionamos las celdas con texto y valores: Sub SeleccionesEspeciales4() Dim oSel As Object Dim oSelEsp As Object oSel = ThisComponent.getCount = 0 Then MsgBox "No hay celdas con notas" Else 'Mostramos la dirección de los rangos encontrados MsgBox DireccionRango2( oSelEsp ) End If End Sub Ya vimos como seleccionar formulas.star.select( oSelEsp ) End Sub Como ya se menciono.OBJECT com.sheet. en el siguiente ejemplo.CellFlags. ya no seleccionamos.getCurrentSelection() 'Recuperamos las celdas con notas oSelEsp = oSel.EDITATTR com.queryContentCells( 5 ) ThisComponent.CellFlags.

sheet.star.queryFormulaCells( 3 ) If oSelEsp.star.ERROR Valor 1 2 4 Los cuales.star.sheet.STRING com. solo acepta los tres valores siguiente: Constante com.FormulaResult.Aprendiendo OOo Basic MsgBox "No hay celdas con errores" Else MsgBox DireccionRango2( oSelEsp ) End If End Sub 205 El argumento de este método.sun.getCurrentSelection() 'Recuperamos las celdas con formulas cuyo resultado sea texto o valor oSelEsp = oSel.sheet. podemos combinar: Sub SeleccionesEspeciales7() Dim oSel As Object Dim oSelEsp As Object oSel = ThisComponent.sun.VALUE com.getCount = 0 Then MsgBox "No hay celdas con texto o valor" Else MsgBox DireccionRango2( oSelEsp ) End If End Sub Los siguiente métodos requieren una atención especial.sun.FormulaResult.FormulaResult. supongamos la siguiente lista de datos: A 1 2 3 4 5 6 7 8 9 10 3 5 3 1 1 4 1 5 5 3 B 3 2 1 1 5 1 3 1 3 2 C 5 1 2 3 5 4 1 1 3 4 D 3 2 5 4 5 1 1 5 2 5 E 4 4 5 5 4 3 5 3 3 1 Selecciona el rango A1:A10 y ejecuta la siguiente macro: Sub Dim Dim Dim Dim SeleccionesEspeciales8() oHojaActiva As Object oRango As Object oSelEsp As Object oCelda As Object .

queda bastante claro como trabaja este método.getCellRangeByName("A1:A10") 'La celda de comparación oCelda = oHojaActiva. es muy importante entender que.206 oHojaActiva = ThisComponent. después pasale la celda C2 y observa el resultado.getCount = 0 Then MsgBox "No se encontraron celdas" Else ThisComponent.getCellRangeByName("A1:C10") oCelda = oHojaActiva. observa el resultado.getCurrentController().getCurrentController.queryColumnDifferences( oCelda. de la celda de comparación. Con el siguiente ejemplo.getActiveSheet() oRango = oHojaActiva. intenta pasarle a esta misma macro la celda C1. es el valor de la fila respectiva para cada columna: Sub Dim Dim Dim Dim SeleccionesEspeciales9() oHojaActiva As Object oRango As Object oSelEsp As Object oCelda As Object oHojaActiva = ThisComponent. “únicamente toma la fila” de la dirección para la comparación.getActiveSheet() 'El rango a evaluar oRango = oHojaActiva.select( oSelEsp ) End If End Sub 6.getCellAddress ) If oSelEsp. creo.getCellRangeByName("B10") oSelEsp = oRango.getCount = 0 Then MsgBox "No se encontraron celdas" Else 'Las seleccionamos ThisComponent.getCellRangeByName("A1") 'Buscamos las celdas diferentes por columna oSelEsp = oRango.getCellAddress ) If oSelEsp.getCurrentController. el valor comparado.getCurrentController().select( oSelEsp ) End If End Sub Que nos devuelve: . observa el rango pasado y la celda de comparación.2 Referencia a rangos Que te tiene que seleccionar: Observa como seleccionó las celdas con un valor diferente al de la celda de comparación.queryColumnDifferences( oCelda.

Aprendiendo OOo Basic 207 Por ultimo. llamando al rango completo de pruebas.queryColumnDifferences( oCelda.getActiveSheet() oRango = oHojaActiva. como en el siguiente ejemplo.getCount = 0 Then MsgBox "No se encontraron celdas" Else ThisComponent.queryRowDifferences( oCelda. ejecuta la macro.getCellRangeByName("A10:E10") oCelda = oHojaActiva.select( oSelEsp ) End If End Sub Y comprueba que es correcto el resultado. así que solo hagamos un ejemplo más con el rango completo de datos: Sub SeleccionesEspeciales12() Dim oHojaActiva As Object .getCurrentController().getCellRangeByName("A1:E10") oCelda = oHojaActiva.select( oSelEsp ) End If End Sub Y el resultado: La lógica es exactamente la misma de hacerlo por columnas.getActiveSheet() oRango = oHojaActiva. como en: Sub Dim Dim Dim Dim SeleccionesEspeciales10() oHojaActiva As Object oRango As Object oSelEsp As Object oCelda As Object oHojaActiva = ThisComponent.getCurrentController.getCellRangeByName("A3") oSelEsp = oRango.getCellAddress ) If oSelEsp.getCellAddress ) If oSelEsp.getCellRangeByName("C10") 'Buscamos las celdas diferentes por filas oSelEsp = oRango. usando la misma tabla de datos: Sub Dim Dim Dim Dim SeleccionesEspeciales11() oHojaActiva As Object oRango As Object oSelEsp As Object oCelda As Object oHojaActiva = ThisComponent.getCurrentController. con la celda de comparación que quieras. El mismo tipo de comparación lo podemos hacer pero por filas.getCurrentController(). “solo toma la columna” de la celda de comparación.getCount = 0 Then MsgBox "No se encontraron celdas" Else ThisComponent. solo que ahora.

incluyendo formulas.2 Referencia a rangos Que nos selecciona: Lo interesante de estos métodos.getCellAddress ) If oSelEsp. en cuyo caso.getCurrentController().getCellRangeByName("D1") 'Buscamos las celdas diferentes por filas oSelEsp = oRango. puede ser cualquier tipo de dato.getCurrentController. es que los valores de las celdas.getCount = 0 Then MsgBox "No se encontraron celdas" Else ThisComponent.208 Dim oRango As Object Dim oSelEsp As Object Dim oCelda As Object oHojaActiva = ThisComponent.queryRowDifferences( oCelda.select( oSelEsp ) End If End Sub 6. se tomará el tipo de resultado de esta.getCellRangeByName("A1:E10") oCelda = oHojaActiva.getActiveSheet() oRango = oHojaActiva. no tienen que ser necesariamente texto. .

la macro de ejemplo.getCount = 0 Then MsgBox "No hay nada en común" Else ThisComponent.queryIntersection( oRango2. solo las celdas visibles.getCurrentController().getRangeAddress ) If oSelEsp. del rango invocado. nos tiene que seleccionar el rango en verde: Sub Dim Dim Dim Dim SeleccionesEspeciales13() oHojaActiva As Object oRango1 As Object oRango2 As Object oSelEsp As Object oHojaActiva = ThisComponent.getCurrentController. veamos un método muy interesante.getCellRangeByName("B2:I11") oRango2 = oHojaActiva.getActiveSheet() oRango1 = oHojaActiva. nos permite seleccionar.select( oSelEsp ) End If End Sub Para terminar este tema.getCellRangeByName("G8:N17") 'Buscamos las celdas comunes oSelEsp = oRango1. Observa la siguiente imagen: .Aprendiendo OOo Basic 209 El siguiente método nos sirve para saber el rango de celdas comunes a dos rangos. observa la siguiente imagen.

210 6. . puedes hacer tu propia versión de copiado.getCellRangeByName("A1:G243") 'Buscamos las celdas visibles oVisibles = oRango. la copia incluirá aun las celdas ocultas.getActiveSheet() oRango = oHojaActiva. que tenemos muchas filas ocultas.getCount = 0 Then MsgBox "No hay celdas ocultas" Else 'Mostramos la dirección de los rangos visibles MsgBox DireccionRango2( oVisibles ) End If End Sub Cuando haces un filtro automático o especial y cuando calculas subtotales e intentas hacer operaciones de copiado.getCurrentController(). solo contendrá las celdas visibles. pero con este método siempre obtendrás las celdas visibles.2 Referencia a rangos Nota. mostramos la dirección de los rangos visibles: Sub Dim Dim Dim SeleccionesEspeciales14() oHojaActiva As Object oRango As Object oVisibles As Object oHojaActiva = ThisComponent. con la siguiente macro.queryVisibleCells() If oVisibles. que. cuando agrupas u ocultas filas o columnas manualmente. la copia resultante. en los encabezados de fila. en conjunto con los conocimientos del siguiente capitulo.

antes y después de moverse: MsgBox DireccionRango( oOrigen ) 'Movemos el rango oHojaActiva.moveRange( oDestino. que la celda destino “tiene” que ser una celda individual.Aprendiendo OOo Basic 211 6.getRangeAddress() ) MsgBox DireccionRango( oOrigen ) Recuerda que la función DireccionRango. insertarlos.getRangeAddress() ) End Sub Toma en cuenta que el rango origen “tiene” que ser un rango de celdas. este método requiere de dos argumentos. estas. eliminarlos y copiarlos. es personalizada y la hemos usado en los últimos temas vistos. a moverlos. usamos el método moveRange de las hojas de calculo.getCellAddress(). es decir.getActiveSheet() 'Rango a mover oOrigen = oHojaActiva. prueba la siguiente macro: . 6. si el rango contiene formulas. también. Si quieres mover solo una celda.getCellRangeByName( "D10" ) 'Movemos el rango oHojaActiva. que los datos del rango origen se borran y los datos del rango destino son “reemplazados sin preguntarte” por los datos origen y muy importante. ahora. oOrigen.getCurrentController().getCellRangeByName( "A1:B5" ) 'Celda destino oDestino = oHojaActiva. la celda superior izquierda (CellAddress) destino donde se moverá el rango origen (CellRangeAddress) Hoja. “no se actualizan a la nueva posición” aun y cuando las referencias sean relativas.3.3 Manipulando rangos En el capitulo anterior aprendimos a referenciar cualquier rango que nos interese. el rango origen cambia para adaptarse al rango destino. Origen As CellRangeAddress ) El siguiente ejemplo mueve el rango A1:B5 de la hoja activa.moveRange( Destino As CellAddress.1 Moviendo rangos Para mover un rango. aprenderemos a manipular estos rangos. oOrigen. la referencia a dicho rango se actualizara automáticamente como lo puedes comprobar si muestras la dirección del rango origen. principalmente.moveRange( oDestino. a la celda D10 de la misma hoja: Sub Dim Dim Dim MoverRangos1() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent.getCellAddress().

moveRange( oDestino.getActiveSheet() oOrigen = oHojaActiva.getRangeAddress().getRangeAddress() ) Else MsgBox "El rango Origen no es correcto" End If End Sub .3 Manipulando rangos 'Movemos el rango oHojaActiva.getImplementationName() = "ScCellObj" Then oHojaActiva.getCurrentController().getCellAddress().212 Sub Dim Dim Dim MoverRangos2() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent.getRangeAddress() ) End Sub Por supuesto podemos validar que por lo menos el origen y el destino sean efectivamente los argumentos que necesita este método: Sub Dim Dim Dim MoverRangos3() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent. tienes que seleccionar más de una celda es decir.getCurrentController().getCellAddress().EndRow + 2 ) oHojaActiva. aun y con solo seleccionar una celda. oOrigen.moveRange( oDestino.getImplementationName() = "ScCellRangeObj" And oDestino.getCellRangeByName( "F15" ) 'Validamos que los rangos sean correctos If oOrigen.getImplementationName() = "ScCellRangeObj" Then 'Dejamos una columna y una fila en blanco oDestino = oHojaActiva. un rango de celdas. Sub Dim Dim Dim MoverRangos4() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent.getCellAddress().getRangeAddress().getActiveSheet() 'Nota como hacemos la referencia para que sea un rango oOrigen = oHojaActiva.getCellRangeByName( "C5" ) oDestino = oHojaActiva. para que funcione el siguiente código.EndColumn + 2.getRangeAddress() ) Else MsgBox "Los rangos no son correctos" End If End Sub Esta validación es más útil cuando tomamos el rango a mover a partir de la selección actual del usuario.getCellByPosition( oOrigen.getCurrentController().getCellRangeByName( "B2:B2" ) 'Esta tiene que seguir siendo una sola celda oDestino = oHojaActiva.getCurrentSelection() 'Validamos que los rangos sean correctos If oOrigen. oOrigen. te queda de tarea hacer que funcione. oOrigen.getCellRangeByName( "E5" ) 6. oOrigen.getActiveSheet() oOrigen = ThisComponent.moveRange( oDestino. por supuesto.

getCurrentSelection() If oOrigen.getActiveSheet() oOrigen = ThisComponent.moveRange( oDestino. podremos ir moviendo el rango. si seleccionamos el rango cuando se ha movido.getRangeAddress(). por lo que tenemos que evaluar también que esto no suceda: Sub Dim Dim Dim Dim MoverRangos6() oHojaActiva As Object oOrigen As Object oDestino As Object lLimiteCol As Long oHojaActiva = ThisComponent. se queda en el rango origen.getCurrentController(). la selección actual no cambia. no importa si esta tiene 256 como en Openoffice.getRangeAddress().getCount(). y si. oOrigen.x. modifica la macro anterior para que quede así: Sub Dim Dim Dim MoverRangos5() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent.getCurrentController(). puede pasar que en algún momento te un error.getRangeAddress() ) ThisComponent.getCellByPosition( oOrigen. oOrigen.getCount() Then oDestino = oHojaActiva.getImplementationName() = "ScCellRangeObj" Then oDestino = oHojaActiva. por que el destino lo construimos a partir del este. ¿cuando?.getCurrentSelection() If oOrigen.getCellAddress().org 2.getCellByPosition( oOrigen.getColumns().x o 1024 como en Openoffice. en cualquier versión que implemente estas propiedades.EndColumn + 2.EndRow + 2 ) oHojaActiva. .getRangeAddress(). claro que tienes que evaluar también que no pases el limite de filas. pero esa. obtenemos el total de columnas de la hoja activa. tantas veces como llames a la macro.org 3.getCurrentController().getRangeAddress().getRangeAddress().Aprendiendo OOo Basic 213 Nota como solo validamos el origen. cuando el rango destino quede fuera de la hoja de calculo.select( oOrigen ) Else MsgBox "El rango Origen no es correcto" End If End Sub Y llamala (ejecutala) varias veces.getActiveSheet() oOrigen = ThisComponent.moveRange( oDestino. notaras como se va moviendo el rango.getCount() If lLimiteCol <= oHojaActiva. es tu tarea. muy bien.getCellAddress().getRangeAddress() ) 'Seleccionamos el nuevo origen ThisComponent.getColumns().EndColumn + 2 + oOrigen.getColumns().getCurrentController().EndColumn + 2.EndRow + 2 ) oHojaActiva. observa que cuando mueves un rango.getImplementationName() = "ScCellRangeObj" Then 'Garantizamos que no sobre pase el maximo de columnas en la hoja de calculo lLimiteCol = oOrigen. oOrigen. con lo que este código funcionara en las dos versiones. oOrigen. pero cuidado.select( oOrigen ) Else MsgBox "Se llego al limite de la hoja" End If Else MsgBox "Los rangos no son correctos" End If End Sub Nota que con oHojaActiva. de hecho.

pero de forma muy sencilla podemos mover rangos entre hojas. recuerda que una columna no es más que un rango de celdas: Sub Dim Dim Dim MoverRangos9() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent. Nota que el método moveRange.getRangeAddress().getImplementationName() = "ScCellRangeObj" Then oDestino = ThisComponent. oOrigen. solo hay que establecer el destino correctamente y el método se encargará del resto: Sub Dim Dim Dim Dim MoverRangos7() oHojaActiva As Object oOrigen As Object oDestino As Object lLimiteCol As Long oHojaActiva = ThisComponent.getCurrentController(). pero también lo puedes llamar desde cualquier hoja.select( oOrigen ) Else MsgBox "El rango Origen no es correcto" End If End Sub También podemos mover una columna completa. claro que puedes hacerlo a cualquier otra. 0 ) oHojaActiva.getActiveSheet() 'Referenciamos como origen la columna E oOrigen = oHojaActiva.getCurrentController().getRangeAddress() ) ThisComponent.getCurrentSelection() If oOrigen. lo llamamos desde la hoja activa.getColumns(). 0 ) oDestino.214 6. como llamamos al método moveRange desde la hoja del rango destino: Sub Dim Dim Dim Dim MoverRangos8() oHojaActiva As Object oOrigen As Object oDestino As Object lLimiteCol As Long oHojaActiva = ThisComponent. oOrigen.3 Manipulando rangos Hasta ahora hemos movido rangos dentro de la misma hoja.moveRange( oDestino.getCurrentController().select( oOrigen ) Else MsgBox "El rango Origen no es correcto" End If End Sub Observa como el origen lo establecemos en la hoja activa.moveRange( oDestino.getCellByPosition( 0.getCellAddress().getActiveSheet() oOrigen = ThisComponent.getActiveSheet() oOrigen = ThisComponent.getByIndex(0).getByIndex(0).getCurrentController(). pero el destino lo referenciamos a la primer hoja del documento.getCurrentController(). por índice o por nombre como ya lo hemos aprendido.getCellAddress().getSpreadSheet(). es decir.getCellByPosition( 0.getCurrentSelection() If oOrigen.getImplementationName() = "ScCellRangeObj" Then oDestino = ThisComponent.EndColumn + 1.getSheets(). observa en el siguiente ejemplo. el origen y destino estén correctos.getRangeAddress() ) ThisComponent.select( oOrigen ) .moveRange( oDestino.getCellAddress().getCellByPosition( oOrigen.getRangeAddress() ) ThisComponent. oOrigen.getByIndex(4) 'Como destino una columna a la derecha oDestino = oHojaActiva.getCurrentController().getSheets(). 0 ) oHojaActiva. lo importante es que los argumentos.

3.getRangeAddress() ) ThisComponent.getActiveSheet() 'Referenciamos como origen la fila 5 oOrigen = oHojaActiva.getCurrentController().insertCells( Celdas As CellRangeAddress. 6. movemos filas también: Sub Dim Dim Dim MoverRangos10() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent. esta misma consideración hay que tener cuando lo hacemos por código.getRows().getCurrentController(). veamos como: Hoja.getCellByPosition( 0. ten en cuenta las mismas consideraciones vistas en los demás ejemplos. recordaras que Calc. es decir.2 Insertando rangos En la interfaz del usuario. cuando insertamos un rango.getByIndex(4) 'Como destino la fila 10 oDestino = oHojaActiva.moveRange( oDestino.select( oOrigen ) End Sub Cuando muevas columnas y filas completas. oOrigen.getCurrentSelection() .getCurrentController(). no hay ninguna confirmación de sobreescritura en caso de que el destino no este vacío.getCellAddress(). Modo As CellInsertMode) Sub InsertarRangos1() Dim oHojaActiva As Object Dim oSel As Object oHojaActiva = ThisComponent.getActiveSheet() oSel = ThisComponent. 9 ) oHojaActiva. nos muestra un cuadro de dialogo preguntándonos como desplazar las demás celdas. por lo que tu tienes que implementar esta validación y tener cuidado de no salirse de los limites de la hoja de calculo. de las cuales las principales son que los datos se mueven del origen al destino sin preguntar.Aprendiendo OOo Basic End Sub 215 Y ya encarrerados.

StartColumn = 1 . com.Sheet = oHojaActiva.EndColumn = 3 .DOWN com.star.getRangeAddress().sun.CellInsertMode.star. puedes crear una estructura CellRangeAddress vacía del tamaño que quieras como en el siguiente ejemplo: Sub InsertarRangos2() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.star.table. En este segundo ejemplo hemos desplazado las celdas a la derecha.Sheet .sun.star.CellInsertMode.StartRow = 1 .insertCells(oSel. com.sheet.DOWN) End Sub El rango a insertar no tiene por que ser a partir de la selección actual.sun.CellInsertMode.COLUMNS 1 2 3 4 Valor Puedes usar indistintamente la constante o el valor de esta como en el siguiente ejemplo donde insertamos filas completas: Sub InsertarRangos3() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. el valor predeterminado es 0.sheet.RIGHT) End Sub Es muy importante que establezcas la propiedad Sheet (hoja) de esta estructura.StartRow = 1 . en la siguiente tabla resumimos los cuatro valores posibles para este método: Constante com.sun.EndRow = 3 End With 'Insertamos y desplazamos hacia la derecha oHojaActiva.table.sheet.sun. si no lo haces.StartColumn = 1 . con lo que el rango insertado “siempre” lo hará en la primer hoja del documento.RIGHT com.sheet.star.getCurrentController().ROWS com.CellInsertMode.sun. tres filas por tres columnas With oRango . las demás opciones de este método son insertar filas completas o columnas completas.Sheet .CellInsertMode.sun.getActiveSheet() 'Creamos una estructura vacía de dirección de un rango oRango = CreateUnoStruct( "com.star.star.sun.getRangeAddress().star.getCurrentController().Sheet = oHojaActiva.sheet.insertCells(oRango.sheet.CellRangeAddress" ) 'Establecemos los valores del rango.CellInsertMode.3 Manipulando rangos 'Insertamos un rango de celdas igual a la selección actual 'y movemos las celdas hacia abajo oHojaActiva.216 6.getRangeAddress().CellRangeAddress" ) With oRango .getActiveSheet() oRango = CreateUnoStruct( "com.

es decir. que es especifico del conjunto de columnas.Aprendiendo OOo Basic . El método para insertar filas es exactamente igual. en nuestro primer ejemplo. 3 ) End Sub 217 Cuando quieras insertar filas o columnas completas.insertByIndex( 2. por lo que tienes que evaluar que tengas suficiente espacio para la inserción.3 Eliminando rangos Eliminar rangos. puedes usar los métodos vistos hasta ahora o.getRows(). es la operación inversa a insertarlos.getCurrentController().3. excepto por que lo llamamos desde el conjunto de filas (getRows) como en: Sub InsertarRangos5() Dim oHojaActiva As Object oHojaActiva = ThisComponent. como se desplazarán. en este caso.getActiveSheet() 'Insertamos 5 filas a partir de la fila 3 oHojaActiva. el primer argumento de este método es el índice de la columna donde comenzara la inserción y el segundo es el número de columnas que deseamos insertar.insertCells( oRango. por ello primero llamados a getColumns(). tenemos que decidir que hacer con las celdas adyacentes al rango. 6. movemos las celdas hacia arriba: .getActiveSheet() 'Insertamos 2 columnas a partir de la columna E oHojaActiva. puedes usar los métodos específicos del conjunto de filas y columnas como en el siguiente ejemplo donde insertamos 2 columnas a partir de la columna E: Sub InsertarRangos4() Dim oHojaActiva As Object oHojaActiva = ThisComponent. de lo contrario. 2 ) End Sub Nota que ahora usamos el método insertByIndex.insertByIndex( 4.EndRow = 3 End With 'Insertamos filas completas oHojaActiva. te dará un error en tiempo de ejecución.getCurrentController(). recuerda que no puedes desplazar celdas fuera del rango de la hoja de calculo.getColumns().EndColumn = 3 . 5 ) End Sub Para terminar este tema.

. después de confirmar la eliminación: Sub Dim Dim Dim BorrarRangos2() oHojaActiva As Object oRango As Object iRes As Integer oHojaActiva = ThisComponent.getRangeAddress().218 6. es una buena practica de programación que confirmes esta acción con el usuario.CellRangeAddress" ) 'Establecemos el rango E8:F21 oRango = oHojaActiva.sun. com.getRangeAddress.CellDeleteMode.removeRange( oRango.sheet.getActiveSheet() oSel = ThisComponent.getCurrentSelection() 'Borramos la selección actual y movemos las celdas hacia arriba oHojaActiva.star. 4 + 32. "Borrar rango" ) 'Solo borramos si el usuario respondio SI If iRes = 6 Then 'Borramos el rango y movemos las celdas hacia la izquierda oHojaActiva. desplazamos hacia la izquierda.sun. Modo As CellDeleteMode) Sub BorrarRangos1() Dim oHojaActiva As Object Dim oSel As Object oHojaActiva = ThisComponent.LEFT ) End If End Sub En la siguiente tabla puedes ver las posibilidades de este método.3 Manipulando rangos Hoja.star.getActiveSheet() oRango = CreateUnoStruct( "com.star.sheet. En el siguiente ejemplo.getCurrentController().sun.UP ) End Sub Cuando se hace cualquier operación de borrado o eliminación.CellDeleteMode. sobre todo. con aquellas acciones que no es posible deshacer.removeRange( oSel.getCurrentController(). com.table. es casi una regla que lo hagas.removeRange( Celdas As CellRangeAddress.getCellRangeByName( "E8:F21" ) 'Confirmamos la eliminacion iRes = MsgBox( "Estas seguro de borrar el rango". así como sus valores que puedes usar en vez de ellas.

sheet.Aprendiendo OOo Basic 219 Constante com.LEFT com. ¿verdad? Hoja.CellDeleteMode. pero te recomiendo siempre hacerla.star.getActiveSheet() 'Borramos 3 filas a partir de la fila 10 oHojaActiva.removeRange( oRango. 6. en el siguiente ejemplo usamos el valor de la constante en vez de esta.sun.getRows().sheet.CellDeleteMode.CellDeleteMode.sun. veamos como: Sub BorrarRangos4() Dim oHojaActiva As Object oHojaActiva = ThisComponent. cambia el método usado.getActiveSheet() oRango = CreateUnoStruct( "com.sheet. no tienes problemas con ello. 2 ) End Sub No se te olvide siempre confirmar las eliminaciones.4 Copiando rangos Copiar rangos es muy similar a moverlos.sun.removeByIndex( 9. 4 ) End Sub Al igual que con la inserción.sun.copyRange( Destino As CellAddress. al igual que cuando movemos.sheet. Sub Dim Dim Dim BorrarRangos3() oHojaActiva As Object oRango As Object iRes As Integer oHojaActiva = ThisComponent.getRangeAddress.getCellRangeByName( "B2:D2" ) 'Borramos las columnas completas oHojaActiva.UP com.star.getCurrentController().getColumns().3.ROWS com. claro. 3 ) 'Borramos 2 columnas a partir de la A oHojaActiva. para la eliminación de filas y columnas completas.star. pero como ya sabes implementarla. se usan los mismos argumentos. se cuenta con métodos alternativos accesibles desde el conjunto de filas (getRows) y columnas (getColumns).CellDeleteMode.COLUMNS 1 2 3 4 Valor Podemos borrar columnas completas.getCurrentController(). el destino será reemplazado con el origen sin ningún tipo de confirmación.star.CellRangeAddress" ) 'Establecemos el rango B2:D2 oRango = oHojaActiva. Origen As CellRangeAddress) . ya no pedimos confirmación.sun.removeByIndex( 0. un rango origen y una celda destino.table.star.

el siguiente ejemplo.getRangeAddress() ) ThisComponent.getCellAddress().getSheets().EndColumn + 1. oOrigen.getRangeAddress() ) End Sub A diferencia de cuando movemos.copyRange( oDestino.getCurrentController(). oOrigen.EndRow + 1 ) oHojaActiva.select( oDestino ) CopiarRangos3() oHojaOrigen As Object oHojaDestino As Object oOrigen As Object oDestino As Object oHojaOrigen = ThisComponent. oOrigen.getCount() .getCurrentSelection() oDestino = oHojaActiva.copyRange( oDestino.getRangeAddress().getCellRangeByName( "A1:B3" ) 'Celda destino oDestino = oHojaActiva.getRangeAddress().getCellByPosition( oOrigen. las referencias relativas se ajustarán automáticamente a la nueva posición.getActiveSheet() oOrigen = ThisComponent. oOrigen. si el rango contiene formulas.getCurrentController().220 6.getCurrentController().getActiveSheet() 'Rango a copiar oOrigen = oHojaActiva.getCurrentController().getCellRangeByName( "D10" ) 'Copiamos el rango oHojaActiva.select( oOrigen ) End Sub Para copiar en una hoja diferente. copiamos el rango B2:D5 de la ultima hoja del documento a la celda A1 de la primera: Sub Dim Dim Dim Dim ) oHojaDestino = ThisComponent.getSheets(). el origen permanece tal cual y aquí si.getRangeAddress() ) ThisComponent. además de que el rango origen permanece con la referencia original: Sub Dim Dim Dim CopiarRangos2() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent.copyRange( oDestino.getSheets().getByIndex( 0 ) 'Rango a copiar oOrigen = oHojaOrigen.getCellAddress(). solo tienes que establecer el destino correctamente en dicha hoja.getCellAddress().getCellRangeByName( "B2:D5" ) 'Celda destino oDestino = oHojaDestino.getCellRangeByName( "A1" ) 'Copiamos el rango oHojaDestino.3 Manipulando rangos Sub Dim Dim Dim CopiarRangos1() oHojaActiva As Object oOrigen As Object oDestino As Object oHojaActiva = ThisComponent.1 .getByIndex( ThisComponent.

podemos intentar hacer nuestra versión de una herramienta que llamaremos “Copiar solo visibles”.getRangeAddress() ) ThisComponent.getSpreadSheet. cuando copiamos un rango de celdas y este rango tiene filas o columnas ocultas manualmente o por estar agrupadas. las filas y columnas ocultas.getActiveSheet() 'Referencia a la selección actual oSel = ThisComponent. contendrá aun.getCellAddress().getByIndex( 1 ) 'Segunda Hoja oHojaDestino = ThisComponent.getCurrentController().createCursorByRange( oSel ) oCursor.collapseToCurrentRegion() 'Y las celdas visibles oVisibles = oCursor.getSheets(). ¿te parece?.getcurrentSelection() 'Si es una sola celda regresamos la región actual If oSel. claro.getImplementationName() = "ScCellRangesObj" Then oVisibles = oSel End If 'si no hay celdas visibles If IsNull( oVisibles ) Then MsgBox "No hay celdas ocultas" Else .getImplementationName() = "ScCellObj" Then oCursor = oSel. Antes de que sigas leyendo.getCurrentController.getSheets().getCellRangeByName( "E1" ) oHojaDestino.copyRange( oDestino.Aprendiendo OOo Basic End Sub 221 Puedes copiar columnas o filas completas: Sub Dim Dim Dim Dim CopiarRangos4() oHojaOrigen As Object oHojaDestino As Object oOrigen As Object oDestino As Object 'Primer hoja oHojaOrigen = ThisComponent.getByIndex( 0 ) 'Rango a copiar columna B oOrigen = oHojaOrigen. solo con fines didácticos puesto que estamos aprendiendo: Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim CopiarSoloVisibles1() oSel As Object oCursor As Object oVisibles As Object oHojaOrigen As Object oHojaDestino As Object oRangoOrigen As Object oCeldaDestino As New com.queryVisibleCells() ElseIf oSel.select( oDestino ) End Sub Hagamos algo muy interesante.table. después checa mi versión y compáralas.getColumns(). como sabemos.star. oOrigen. con el método para seleccionar solo las celdas visibles (queryVisibleCells) aprendido en el capitulo anterior y el método para copiar rangos. la copia resultante. te invito a que intentes resolverlo por ti mismo primero.sun.getByIndex( 1 ) oDestino = oHojaDestino.CellAddress co1 As Long mDir oHojaOrigen = ThisComponent.

copyRange( oCeldaDestino. oHojaOrigen ) 'Obtenemos una matriz con las direcciones de todos los rangos mDir = oVisibles. Fil As Long.star.insertNewByName( sNombre.getSpreadSheet.getSheets. de nuevo.getByName( sNombre ) End Function Seguro que ya viste que no trabaja muy bien que digamos.queryVisibleCells() End Select If IsNull( oVisibles ) Then MsgBox "No hay celdas ocultas o no es un rango de celdas" .queryVisibleCells() Case "ScCellRangeObj". Col As Long mDir oHojaOrigen = ThisComponent.getRangeAddress.StartRow 'Copiamos el rango oHojaDestino. Vamos a mejorarla.hasByName( sNombre ) co1 = co1 + 1 sNombre = sNombre & " " & Format(co1) Loop oHojas.Column = oRangoOrigen.getCurrentController.getRangeAddresses() 'Iteramos en cada dirección For co1 = LBound(mDir) To UBound(mDir) oRangoOrigen = mDir( co1 ) 'La celda destino tendra la misma dirección del rango pero en la hoja destino oCeldaDestino.CellAddress co1 As Long. Hoja As Object ) As Object Dim oHojas As Object Dim co1 As Integer Dim sNombre As String oHojas = Documento.getSheets() sNombre = "Rangos Copiados" Do While oHojas.getcurrentSelection() Select Case oSel.sun. no es nada practico que use la misma dirección del origen en el destino pues los datos quedan todos dispersos. "ScCellRangesObj" oVisibles = oSel.StartColumn oCeldaDestino.getImplementationName Case "ScCellObj" oCursor = oSel.Sheet = oHojaDestino. oRangoOrigen ) Next co1 'Seleccionamos la nueva hoja con los datos copiados ThisComponent.getActiveSheet() oSel = ThisComponent.Sheet+1 ) getNuevaHoja = Documento.getCurrentController.222 6.collapseToCurrentRegion() oVisibles = oCursor.setActiveSheet( oHojaDestino ) MsgBox "Rangos copiados" End If End Sub 'Devuelve una nueva hoja en Documento.getRangeAddress. a la derecha del argumento Hoja Function getNuevaHoja( Documento As Object.3 Manipulando rangos 'Agregamos una nueva hoja oHojaDestino = getNuevaHoja( ThisComponent. Hoja.table.Sheet oCeldaDestino.createCursorByRange( oSel ) oCursor. intenta corregirla tu y después continuas: Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim CopiarSoloVisibles2() oSel As Object oCursor As Object oVisibles As Object oHojaOrigen As Object oHojaDestino As Object oRangoOrigen As Object oRangoAnterior As Object oCeldaDestino As New com.Row = oRangoOrigen. claro.

Column End If oHojaDestino. oRangoOrigen ) Next co1 End If ThisComponent. tienes que tener presente los diferentes tipos de datos que soporta Calc. También. y digo que es un detalle por que no te dará ningún error y seguirá funcionando.Column = Col + oRangoAnterior.4. oHojaOrigen ) mDir = oVisibles.copyRange( oCeldaDestino.4 Manipulando datos Ya vamos llegando a temas más interesantes y divertidos.Row + oRangoAnterior.setActiveSheet( oHojaDestino ) End If End Sub Ahora si.EndColumn oRangoAnterior. tu tarea es encontrar este caso particular.getCurrentController. hay un caso particular donde el rango no contenga celdas ocultas y nuestra macro no lo informe. pero eso si. oRangoOrigen ) 'Si tenemos más rangos If oVisibles. todavía tiene un “pequeño” detalle. puedes considerar evaluarlo o dejarla así.EndRow oRangoAnterior.Row = oCeldaDestino. pero.getRangeAddress. podrías mejorar esta macro para que copie solo datos o resultados de formulas. 6.StartColumn = oRangoOrigen.StartColumn + 1 oCeldaDestino.getCount() > 1 then For co1 = 1 To UBound(mDir) oRangoOrigen = mDir( co1 ) oRangoAnterior = mDir( co1-1 ) 'Vamos sumando cada ancho y alto de cada rango.Sheet = oHojaDestino.Column = 0 oCeldaDestino.StartRow + 1 Else oCeldaDestino. Para el mejor aprovechamiento de este capitulo.copyRange( oCeldaDestino. esto lo podrás hacer cuando adquieras los conocimientos del próximo capitulo.Row = Fil Col = oCeldaDestino. donde veremos con empezar a interactuar con las celdas de nuestra hoja de calculo. trabaja mucho mejor.Row = 0 oHojaDestino.1 Obteniendo datos .Sheet 'En la celda A1 oCeldaDestino.Aprendiendo OOo Basic Else 223 Fil = 0 Col = 0 oHojaDestino = getNuevaHoja( ThisComponent.StartColumn Then oCeldaDestino.getRangeAddresses() 'Copiamos el primer rango oRangoOrigen = mDir( 0 ) oCeldaDestino. 6. solo cuando cambien If oRangoAnterior.

como SUMA.getCurrentSelection() If oSel. te devolverá este texto.getValue() Else MsgBox "Selecciona solo una celda" End If End Sub También puedes obtener la formula que tenga la celda con el método getFormula. si es texto de nuevo te devolverá 0. este método te devolverá 0. si la celda contiene texto.getImplementationName() = "ScCellObj" Then 'Mostramos el valor de la celda MsgBox oSel. este método te devolverá el nombre de esta función en ingles. se usa el método getValue. BUSCARV. si es un valor. Sub Datos3() Dim oSel As Object oSel = ThisComponent. dependerá del tipo de resultado de esta formula. etc. dicho valor.224 6. incluyendo el signo de igual (=) con que empieza toda formula aun y cuando la formula tenga como resultado un erro.getImplementationName() = "ScCellObj" Then 'Mostramos la formula de la celda MsgBox oSel. si la celda contiene una fecha. si el contenido de la celda es texto. si tiene un valor. también. etc.getString() Else MsgBox "Selecciona solo una celda" End If End Sub Si lo que deseas es devolver el valor de la celda.4 Manipulando datos La forma más simple y directa de obtener el contenido de una celda. de una fecha te devuelve el número de serie y si es formula.getCurrentSelection() If oSel.getCurrentSelection() If oSel. ese valor. si es un valor.getImplementationName() = "ScCellObj" Then 'Mostramos el contenido de la celda MsgBox oSel. te mostrara el resultado de dicha formula y si es fecha y tiene formato. es decir. si contiene una formula. tal y como se ve en la interfaz del usuario. te devuelve dicha formula. si la celda contiene una formula. este valor. si la celda contiene texto. si tiene un error de nuevo será 0.getFormula() Else MsgBox "Selecciona solo una celda" End If . que te devuelve el contenido de la celda. VLOOKUP. te devolverá el número de serie de esta fecha: Sub Datos2() Dim oSel As Object oSel = ThisComponent. es usando el método getString. toma en cuenta que si la formula devuelta contiene alguna función incorporada de Calc. te lo muestra tal cual. SUM. te la devolverá como se ve en pantalla: Sub Datos1() Dim oSel As Object oSel = ThisComponent.

de nuevo. por ello hacemos la validación. y prueba la siguiente macro. Sub Datos5() Dim oSel As Object Dim sTmp As String oSel = ThisComponent. veras claramente las diferencias entres estos métodos. vacía (0).getString & Chr(13) sTmp = sTmp & "getValue : " & oSel. texto (2) o formula (3).getImplementationName() = "ScCellObj" Then 'Mostramos la formula local de la celda MsgBox oSel. texto. . valor (1). si la celda no contiene una formula. excepto en las formulas. fechas y formulas. captura valores en varias celdas.getValue & Chr(13) sTmp = sTmp & "getFormula : " & oSel. este método solo esta disponible es una sola celda: Sub Datos6() Dim oSel As Object oSel = ThisComponent.FormulaLocal 'Mostramos el resultado MsgBox sTmp Else MsgBox "Selecciona solo una celda" End If End Sub También puedes obtener el tipo de contenido de la celda con getType.getCurrentSelection() MsgBox oSel.getImplementationName() = "ScCellObj" Then 'Mostramos las diferencias entre los metodos sTmp = "getString : " & oSel. entonces usa la propiedad FormulaLocal. que te devolverá un entero dependiendo del contenido de la celda.Aprendiendo OOo Basic End Sub 225 Si deseas obtener la formula tal y como se ve en la barra de formulas.getFormula & Chr(13) sTmp = sTmp & "FormulaLocal : " & oSel.getType() End Sub Si la celda contiene una formula y esta devuelve un error. puedes saber que error es con el método getError. toma en cuenta que estos métodos solo los puedes usar en celdas individuales. donde te las devuelve como aparecen en la barra de formulas. números. que se comporta de forma muy similar a getString.FormulaLocal Else MsgBox "Selecciona solo una celda" End If End Sub Si quieres ver las diferencias.getCurrentSelection() If oSel. como en: Sub Datos4() Dim oSel As Object oSel = ThisComponent. en una de las formulas usa la función =ALEATORIO(). este método siempre te devolverá 0.getCurrentSelection() If oSel.

getValue() Case 2 MsgBox oSel. es decir que sea por ejemplo el número de alguna calle o ser el valor de alguna acción y seguir siendo correcto o ser el error 532 y como información. establece este error en una formula cualquiera para que lo compruebes. devuelve el error 532.getError() End If End Select ContenidoCelda = tmp End Function Toma en cuenta que una celda te puede devolver 532 y estar correcto.getCurrentSelection() Select Case oSel.getString() Case 3 If oSel. Podríamos aventurar una primera forma de usar el método correcto.4 Manipulando datos El error división entre cero. seguir siendo correcto.getType() Case 0 : tmp = "La celda esta vacia" Case 1 : tmp = Celda.getString() Case 3 If Celda.getCurrentSelection() MsgBox oSel. normalmente da el error 511.getError() End If End Select End Sub Y si se convierte en función: Function ContenidoCelda(Celda As Object) Dim tmp Select Case Celda.getError() = 0 Then MsgBox oSel.getError() End Sub 6. sino tan solo como una guía para lo que realmente necesites. también puedes probar con el error de cuando a una formula le faltan argumentos.226 Sub Datos7() Dim oSel As Object oSel = ThisComponent. de acuerdo al contenido de la celda: Sub Datos8() Dim oSel As Object oSel = ThisComponent.FormulaLocal Else MsgBox oSel.FormulaLocal Else tmp = Celda.getValue() Case 2 : tmp = Celda.getError() = 0 Then tmp = Celda. Ahora solo nos resta poder llamarla desde la celda: .getType() Case 0 MsgBox "La celda esta vacia" Case 1 MsgBox oSel. así que no tomes la función anterior como definitiva.

getCurrentSelection() Select Case oSel. es en “referencia” a la selección original. co2 As Long oSel = ThisComponent.getColumns(). que te devuelve una matriz de matrices con el contenido de las celdas. getData solo te devuelve las celdas con valores. pero cuidado. obtener lo mismo pero con relación a la hoja completa. la que te devuelve el método getRangeAddress.getCurrentSelection() MsgBox ContenidoCelda ( oSel ) End Sub Y con un poco de ingenio desde cualquier rango de celdas: Sub Datos10() Dim oSel As Object Dim fil As Long.getImplementationName() = "ScCellRangeObj" Then 'Obtenemos SOLO VALORES mDatos = oSel. además.fil) ) Next col Next fil End Select End Sub Toma en cuenta que getCellByPosition.getCellByPosition(col.Aprendiendo OOo Basic Sub Datos9() Dim oSel As Object 227 oSel = ThisComponent.1 MsgBox ContenidoCelda ( oSel. obtiene una referencia a una sola celda. col As Long oSel = ThisComponent.getCount() . te queda de tarea.getImplementationName() Case "ScCellObj" MsgBox ContenidoCelda ( oSel ) Case "ScCellRangeObj" For fil = 0 To oSel. te doy dos pistas. si quieres obtener el contenido de un rango de celdas. pero toma como base de información para los ciclos.getCurrentSelection() If oSel. los métodos usados solo funcionan cuando hacemos referencia a una sola celda. procura seleccionar un rango pequeño por que te mostrará el valor de cada celda: Sub Dim Dim Dim Dim Datos11() oSel As Object mDatos mTmp co1 As Long.1 For col = 0 To oSel. usa el mismo método (getCellByPosition). en las celdas vacías devuelve un valor un tanto “extraño”.getCount() . y esta. usaremos el método getData. puedes verificarlo con el siguiente ejemplo. En todos lo casos anteriores.getRows().getData() For co1 = LBound(mDatos) to UBound(mDatos) 'Asignamos la matriz interna a una temporal mTmp = mDatos(co1) For co2 = LBound(mTmp) to UBound(mTmp) MsgBox mTmp(co2) Next Next End If .

4. usa getDataArray como en: Sub Dim Dim Dim Dim Datos12() oSel As Object mDatos mTmp co1 As Long.getCurrentSelection() If oSel. usa la misma estructura.228 End Sub 6. veamos ahora como introducir información. co2 As Long oSel = ThisComponent.4 Manipulando datos Si quieres obtener el contenido sea cual sea. puedes acceder a cualquier información de una celda o un rango de celdas.getFormulaArray() For co1 = LBound(mDatos) to UBound(mDatos) mTmp = mDatos(co1) For co2 = LBound(mTmp) to UBound(mTmp) MsgBox mTmp(co2) Next Next End If End Sub De la combinación de los métodos vistos en este tema.2 Introduciendo datos . usas getFormulaArray: Sub Dim Dim Dim Dim Datos13() oSel As Object mDatos mTmp co1 As Long.getImplementationName() = "ScCellRangeObj" Then 'Obtenemos todo los datos mDatos = oSel. como si hubieses usado en cada una el método getFormula.getCurrentSelection() If oSel. co2 As Long oSel = ThisComponent. 6. pero en vez de usar getData.getImplementationName() = "ScCellRangeObj" Then 'Obtenemos todo los datos como si se usara getFormula pero en todo el rango mDatos = oSel.getDataArray() For co1 = LBound(mDatos) to UBound(mDatos) mTmp = mDatos(co1) For co2 = LBound(mTmp) to UBound(mTmp) MsgBox mTmp(co2) Next Next End If End Sub Y si lo que quieres es el contenido de las celdas.

pero si lo obtendrás en la interfaz del usuario. usamos setString.getImplementationName() = "ScCellObj" Then 'Insertamos una cadena en la celda oSel. pero en vez de obtenerlos (get) los establecemos (set).getCurrentSelection() If oSel. este método no te dará ningún error. para las formulas podemos usar setFormula. como en el siguiente ejemplo: Sub Introducir4() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() If oSel. simplemente reemplazará el contenido de la celda sin consultarte.setFormula( "=A1+A5" ) Else MsgBox "Selecciona solo una celda" End If End Sub Si introduces una formula no válida. del mismo modo que setString. Para el caso de cadenas de texto. la formula debe estar como una cadena de texto y debe ser una formula válida. Sub Introducir2() Dim oSel As Object oSel = ThisComponent. Sub Introducir1() Dim oSel As Object oSel = ThisComponent. Sub Introducir3() Dim oSel As Object oSel = ThisComponent.getImplementationName() = "ScCellObj" Then 'Insertamos un valor en la celda oSel.getCurrentSelection() If oSel.Aprendiendo OOo Basic 229 Los métodos para introducir datos en celdas.getImplementationName() = "ScCellObj" Then 'Insertamos una formula oSel.setValue( 34 ) Else MsgBox "Selecciona solo una celda" End If End Sub Ya lo habrás intuido.getImplementationName() = "ScCellObj" Then 'Insertamos una formula no valida .setString( "Nadie esta más perdido que quien no sabe a donde va" ) Else MsgBox "Selecciona solo una celda" End If End Sub Para valores usamos setValue. son más o menos los mismos que para obtenerlos. toma en cuenta que este método reemplazará el contenido de la celda sin preguntarte nada.getCurrentSelection() If oSel.

getCurrentSelection() If oSel.12) Array(13.getCurrentSelection() If oSel. también. "debe" 'ser del mismo tamaño en ancho y alto de la matriz oRango = oHojaActiva. hay que tener la precaución de establecer el rango destino. entre español e ingles. en vez de este método.6) Array(7.2. te muestro una lista de equivalencias de las 375 formulas que incorpora Calc.9) Array(10.230 oSel. así.setFormula( "=SUM(A1:A10)" ) End If End Sub Si prefieres usar los nombres de las funciones en español.11.getCurrentController().setData( mDatos ) . Sub Dim Dim Dim Introducir7() oHojaActiva As Object oRango As Object mDatos(4) mDatos(0) mDatos(1) mDatos(2) mDatos(3) mDatos(4) = = = = = Array(1.getImplementationName() = "ScCellObj" Then 'Insertamos una formula con funcion oSel. Sub Introducir5() Dim oSel As Object oSel = ThisComponent. tienes que usar el nombre en ingles de la función a usar.getCellRangeByName("A1:C5") 'Insertamos la matriz completa oRango.getImplementationName() = "ScCellObj" Then 'Insertamos una formula con función oSel. Cuando queramos introducir valores en rangos de celdas.4 Manipulando datos Si hace uso de funciones incorporadas de OpenOffice. los argumentos deben estar correctamente establecidos.15) oHojaActiva = ThisComponent.FormulaLocal = "=SUMA(A1:A10)" End If End Sub En el Apendice C.setFormula( "=C2-C3+" ) End If End Sub 6.org. usa la propiedad FormulaLocal.14. así como los tipos de estos para que no te devuelva ningún error.8.5.getActiveSheet() 'El rango donde se insertaran los valores. el siguiente ejemplo hace lo mismo que el anterior: Sub Introducir6() Dim oSel As Object oSel = ThisComponent. “exactamente” del mismo ancho y alto de la matriz origen. puedes usar el método que quieras.3) Array(4. de lo contrario te dará un error en tiempo de ejecución.

es mejor que uses setFormulaArray: Sub Dim Dim Dim Introducir9() oHojaActiva As Object oRango As Object mDatos(4) mDatos(0) mDatos(1) mDatos(2) mDatos(3) mDatos(4) = = = = = Array("No". "debe" 'ser del mismo tamaño en ancho y alto de la matriz oRango = oHojaActiva.Aprendiendo OOo Basic End Sub 231 También.getCurrentController()."Lidia"."=RAND()") Array(1."=SUM(A2:A4)") Array(4."Lizette"."Lizette"."Gloria".23456789) Array(3."Paola". textos y formulas. este método esta presente en los tres tipos de rangos vistos."Tel") Array(1.3 Borrando datos Para borrar datos de celdas usamos el método clearContents.getCellRangeByName("A1:C5") 'Insertamos la matriz completa oRango.getActiveSheet() 'El rango donde se insertaran los valores.setDataArray( mDatos ) End Sub Si tus datos a introducir incluyen formulas."Gloria". En el siguiente ejemplo. este método la reemplazara por 0. textos (4) o formulas (16). por ejemplo valores (1).87654321) oHojaActiva = ThisComponent. Sub Borrando1() . este método requiere un entero indicándole el tipo de contenido que deseamos borrar."Lidia"."Tel") Array(1. por lo que solo tienes que asegurarte que efectivamente sea un rango de celdas.setFormulaArray( mDatos ) End Sub 6.12345678) Array(1.34567891) Array(4. toma nota de que con el método setData.getActiveSheet() oRango = oHojaActiva."Paola". si la matriz lleva alguna cadena de texto.getCellRangeByName("A1:C5") 'Insertamos la matriz completa oRango. solo puedes introducir valores.4."Nombre"."=RAND()") oHojaActiva = ThisComponent.getCurrentController(). de tres rangos diferentes. para valores y cadenas. se borran solo las celdas con valores. debes usar setDataArray: Sub Dim Dim Dim Introducir8() oHojaActiva As Object oRango As Object mDatos(4) mDatos(0) mDatos(1) mDatos(2) mDatos(3) mDatos(4) = = = = = Array("No"."Nombre"."=A3") Array(3.

clearContents( 16 ) End Sub 6.sun. cuyos valores se listan en la siguiente tabla: Constante com.STRING com.CellFlags.FORMATTED Valor 1 2 4 8 16 32 64 128 256 512 Puedes usar de forma indistinta las constantes o los valores de estas.sheet.CellFlags.star.star. El siguiente ejemplo borra “todo”.CellFlags.sheet.sun.sheet.sheet.EDITATTR com. Sub Borrando3() Dim oSel As Object oSel = ThisComponent.sheet.clearContents( 20 ) End Sub Los valores permitidos para este método.getCurrentSelection() 'Borramos los textos (4) + formulas (16) oSel.4 Manipulando datos Puedes sumar los valores de los tipos a borrar.sun.getCellRangeByName("D2:E10") 'Borramos solo los texto oRango. así como cualquier combinación de estas.VALUE com.DATETIME com.star.getActiveSheet() oRango = oHojaActiva.star.CellFlags.ANNOTATION com.sheet.getCurrentController().star.star.getCellRangeByName("A1:C5") 'Borramos solo los valores oRango.CellFlags.star.CellFlags. te deja la selección como nueva.star.CellFlags.sun.sun.star.sheet.sheet.CellFlags.sun.STYLES com.FORMULA com. en el siguiente ejemplo.HARDATTR com.sun.clearContents( 4 ) oRango = oHojaActiva.getCurrentSelection() .232 Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.CellFlags. se borra los textos y las formulas del rango seleccionado: Sub Borrando2() Dim oSel As Object oSel = ThisComponent.star.clearContents( 1 ) oRango = oHojaActiva.sheet. están condicionados por las constantes del grupo com.sun.CellFlags.CellFlags.sun.star.sun.getCellRangeByName("G1:K100") 'Borramos solo las formulas oRango.sheet.sheet.OBJECT com.sun.

el primero es para indicarle la dirección del llenado en nuestro ejemplo. observa que sencillo: Sub LlenandoSeries1() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent. En la siguiente tabla están las cuatro posibilidades del argumento “dirección” de este método.FillDirection. abajo (TO_BOTTOM = 0) y un entero que le indica. en general la forma automática funcionara.star.sun.Aprendiendo OOo Basic 'Borramos todo oSel.TO_BOTTOM com.sheet.clearContents( 1023 ) End Sub 233 6.FillDirection. Constante com.getCurrentController().4 Llenando series de datos Llenar series es un método muy divertido de introducir datos en nuestra hoja de calculo.getCellRangeByName("A1:A15") 'Llenamos hacia abajo oRango.TO_RIGHT Valor 0 1 .sun.sheet. cuantas celdas del rango tomara como “guías” para determinar el algoritmo de llenado. en la celda A1 tenemos solo un valor y en la columna C como queremos que quede nuestra serie.fillAuto( 0.star. observa la siguiente imagen. si se establecen correctamente los valores iniciales. existen dos formas de hacerlo. 1 ) End Sub El método fillAuto. solo requiere dos argumentos. El código para lograr esto es el siguiente.4.getActiveSheet() oRango = oHojaActiva.

setString( "enero" ) 'Llenamos a la derecha oRango.getCurrentController().star.4 Manipulando datos Constante com.getCellRangeByName("A2").234 6. Donde más me gusta el llenado de series. nota que ahora tomamos dos celdas como guias oRango.getCellRangeByName("A1:L1") 'Establecemos el valor guia oHojaActiva.TO_TOP com.getActiveSheet() oRango = oHojaActiva. dentro de la rama OpenOffice.getCellRangeByName("A1").getCellRangeByName("A1:A15") 'Establecemos los valores guias oHojaActiva.TO_LEFT Valor 2 3 Si quisiéramos llenar el rango con números pares. es en la forma transparente de copiar o llenar un rango con una formula deseada.setValue( 2 ) oHojaActiva.fillAuto( 0. esta y otras listas.FillDirection.fillAuto( 1.sheet.setValue( 4 ) 'Llenamos hacia abajo.org Calc. Sub LlenandoSeries3() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.sun. lo haríamos así: Sub LlenandoSeries2() Dim oHojaActiva As Object Dim oRango As Object oHojaActiva = ThisComponent.org.getCellRangeByName("A1"). observa la siguiente imagen . 2 ) End Sub Por supuesto no solo con números es posible.sheet. 1 ) End Sub Esto es posible por que esta lista viene de forma predeterminada en OpenOffice.getCurrentController().. el siguiente código establece el rango A1:L1 con los meses del año.getActiveSheet() oRango = oHojaActiva. subrama Ordenar listas.sun. por ejemplo.star. las puedes personalizar en el menú Herramientas | Opciones...FillDirection.

En el Apendice C.getRows(). así puedes usar el método que quieras.collapseToCurrentRegion() 'Construimos el rango a llenar oRango = oHojaActiva.getRows().setFormula( "=YEAR(NOW())-C2" ) 'Creamos un cursor a partir de la primer celda oCursor = oHojaActiva.getCellRangeByName("D2"). . observa que los datos terminan en la fila 1001 pero eso no importa. 1 ) End Sub Para establecer la formula.getActiveSheet() oRango = oHojaActiva. puedes usar también la propiedades FormulaLocal.getCurrentController(). pueden terminar en la 1000 o la que sea pues esto lo determinaremos por código.getCount(). solo restando el año actual de la de nacimiento.fillAuto( 0.FormulaLocal = "=AÑO(AHORA())-C2" Observa como obtenemos la ultima fila del rango usado con la ayuda del cursor y el método oCursor.createCursorByRange( oRango ) 'Expandimos a la region actual oCursor. nuestra formula de ejemplo quedaría así: oHojaActiva.getCellRangeByName( "D2:D" & CStr(oCursor. para fines didácticos daremos por buena la edad.getCount()) ) 'Llenamos hacia abajo oRango. entre español e ingles.getCellRangeByName("A1") 'Establecemos la primer formula oHojaActiva. como ya lo vimos.getCellRangeByName("D2"). te muestro una lista de equivalencias de las 375 formulas que incorpora Calc. de la siguiente forma: Sub Dim Dim Dim LlenandoSeries4() oHojaActiva As Object oRango As Object oCursor As Object oHojaActiva = ThisComponent. y con una sola línea más. llenamos todo el rango.Aprendiendo OOo Basic 235 El fin es establecer la formula para calcular la edad de cada persona.

después.4. incluso en todas las hojas. puedes usar listados del tamaño que quieras y los recursos de tu equipo te lo permitan: Nº 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Nombre edgar gloria antonio lidia paola vanessa lizette edgar gloria antonio lidia paola vanessa lizette edgar gloria antonio lidia Año 1975 1976 1965 1966 1974 1976 1975 1969 1971 1969 1973 1975 1975 1967 1975 1965 1967 1980 Edad 33 32 43 42 34 32 33 39 37 39 35 33 33 41 33 43 41 28 En las búsquedas.. nos limitaremos a las opciones más comunes y generales.4 Manipulando datos 6.236 6.. no es restrictiva. que.5 Buscar y reemplazar La búsqueda y reemplazo en OpenOffice. puedes usar la que gustes.getActiveSheet() 'Establecemos el rango donde buscaremos oBuscarEn = oHojaActiva. la forma más sencilla de una búsqueda es la siguiente: Sub Dim Dim Dim Dim Buscar1() oHojaActiva As Object oBuscarEn As Object oEncontrado As Object oSD As Object oHojaActiva = ThisComponent. quedándote de tarea la investigación del resto.getCurrentController().. pero esta pequeña nos permite comprobar rápidamente los resultados para comprobar que funciona correctamente. que es el rango donde queremos hacer la búsqueda. Editar | Buscar y reemplazar. Usaremos para nuestras pruebas la siguiente tabla de datos. se usa un “descriptor de búsqueda” que no es otra cosa que una estructura donde le indicamos las características de la búsqueda y lo que estamos buscando y un lugar para buscar. por supuesto puedes buscar en toda la hoja.createSearchDescriptor . si bien tiene tantas variantes como las que puedes ver en.org es una herramienta muy poderosa.getCellRangeByName( "A1:D19" ) 'Creamos el descriptor de busqueda oSD = oHojaActiva.

la formula de la columna D ya la vimos y contiene la letra buscada. sino acorde a lo que “estas buscando”.getCurrentController. si aparentemente si tenemos valores 33 en nuestros datos?. y todos los 33 que ves en la lista son el “resultado” de una formula.1980). lo que esperas devolver.setSearchString( "33" ) 'Realizamos la busqueda de TODAS las coincidencias oEncontrado = oBuscarEn. devolvemos demasiados resultados. por ello. también tienen la letra “a” entre su texto. Ahora nos pasa al revés. establece el valor buscado en “a” y realiza la búsqueda : oSD. la búsqueda te devuelve todo.findAll( oSD ) 'Si no hay coincidencias oEncontrado = Null If Not IsNull( oEncontrado ) Then 'Si encuentra algo lo seleccionamos ThisComponent. la búsqueda predeterminada se hace por formulas.Aprendiendo OOo Basic 237 'Establecemos lo que estamos buscando oSD. dicha formula es: =AÑO(AHORA())-C2. le diremos que busque por valores. esto lo logramos con la propiedad: searchType. lo cual es correcto. ¿porque.setSearchString( "a" ). para que busque en el “resultado” de las formulas. la búsqueda esta bien. ¿verdad?. y claro. ahora. la formula de la columna C es: =ALEATORIO. ahora. como vez. la respuesta es que la búsqueda predeterminada se hace buscando dentro de las formulas. lo que tenemos que hacer es discriminar un poco más con los criterios de búsqueda. regresemos a nuestro primer ejemplo y agreguemos una propiedad a la búsqueda. la razón es la misma. Sub Buscar3() . no necesariamente tiene que ser más restrictiva.select( oEncontrado ) Else MsgBox "No se encontraron coincidencias" End If End Sub Y nuestra primera búsqueda nos devuelve el mensaje “No se encontraron coincidencias”. no “dentro” de las formulas. observa que selecciono todas las celdas de la columna B que tienen la letra “a” y todas las celdas de la columna C y D.ENTRE(1965.

Como siguiente prueba.setSearchString( "li" ) y observa el resultado: Nota que las búsquedas las puede hacer en partes del texto. cuando y solo te devuelva un solo rango. en el tema Referencia a varios rangos.238 Dim Dim Dim Dim oHojaActiva As Object oBuscarEn As Object oEncontrado As Object oSD As Object oHojaActiva = ThisComponent.select( oEncontrado ) Else MsgBox "No se encontraron coincidencias" End If End Sub 6. es muy importante que sepas que el resultado es una colección de rangos.getCurrentController. formará parte de dicha colección.getActiveSheet() oBuscarEn = oHojaActiva.findAll( oSD ) 'Si no hay coincidencias oEncontrado = Null If Not IsNull( oEncontrado ) Then 'Si encuentra algo lo seleccionamos ThisComponent.getCellRangeByName( "A1:D19" ) 'Creamos el descriptor de busqueda oSD = oHojaActiva.getCurrentController(). pero podemos restringirla a palabras completas con la propiedad searchWords. como en: Sub Buscar3() . establece la búsqueda en oSD. prueba a establecer la búsqueda con la letra “a” o cualquiera que tu quieras y observa los resultados. tratamos como manejar este tipo de rangos.4 Manipulando datos Mucho mejor ¿verdad?.setSearchString( "33" ) 'Realizamos la busqueda de TODAS las coincidencias oEncontrado = oBuscarEn.createSearchDescriptor 'Buscamos por valores oSD. este. aun.searchType = 1 'Establecemos lo que estamos buscando oSD. ahora si. solo las celdas con el valor 33 son seleccionadas.

searchType = 1 .setSearchString( "li" ) oEncontrado = oBuscarEn. Podemos hacerla aun más restrictiva.createSearchDescriptor oSD.getCurrentController.Aprendiendo OOo Basic Dim Dim Dim Dim oHojaActiva As Object oBuscarEn As Object oEncontrado As Object oSD As Object 239 oHojaActiva = ThisComponent.createSearchDescriptor oSD.select( oEncontrado ) Else MsgBox "No se encontraron coincidencias" End If End Sub La búsqueda anterior te tiene que devolver "No se encontraron coincidencias". si establecemos que distinga entre mayúsculas y minúsculas con la propiedad SearchCaseSensitive de la siguiente manera: Sub Dim Dim Dim Dim Buscar4() oHojaActiva As Object oBuscarEn As Object oEncontrado As Object oSD As Object oHojaActiva = ThisComponent.getCellRangeByName( "A1:D19" ) oSD = oHojaActiva. prueba a reemplazar la cadena buscada por el nombre que más de guste de los existentes en nuestra lista.findAll( oSD ) If Not IsNull( oEncontrado ) Then ThisComponent.searchType = 1 'Buscamos por palabras completas oSD.getCurrentController().getActiveSheet() oBuscarEn = oHojaActiva. por ejemplo “lizette” y obtendremos: Por que estamos haciendo la búsqueda por palabras completas.searchWords = True oSD. por que no hay palabras completas que sean “li”.getCellRangeByName( "A1:D19" ) oSD = oHojaActiva.getActiveSheet() oBuscarEn = oHojaActiva.getCurrentController().

en ves de un descriptor de búsqueda (createSearchDescriptor). únicamente te tiene que regresar la celda C1 que contiene la palabra “Año”. Incluso.240 oSD. veamos un ejemplo sencillo y después la explicación.SearchCaseSensitive = True oSD. creamos un descriptor de reemplazo (createReplaceDescriptor). es decir.setSearchString( "A" ) oEncontrado = oBuscarEn. primero se tiene que buscar.createReplaceDescriptor 'Texto a buscar oRD.4 Manipulando datos Observa que hemos vuelto a establecer searchWords en False para que encuentre partes de las palabras. continuamos haciendo uso de nuestra tabla usada en la búsqueda. Sub Dim Dim Dim Dim Reemplazar1() oHojaActiva As Object oBuscarEn As Object lReemplazados As Long oRD As Object oHojaActiva = ThisComponent. puedes realizar búsquedas dentro de las notas de las celdas si estableces la propiedad searchType = 2. teníamos la formula =AÑO(AHORA())-C2. En la columna D de nuestros datos de ejemplo. para para reemplazar algo.getCurrentController. El reemplazo es la continuación de la búsqueda.getActiveSheet() oBuscarEn = oHojaActiva. si es cero no encontró coincidencias. después de ejecutar la macro anterior.setReplaceString( "=mes" ) 'El metodo devuelve el numero de reemplazos que tuvieron exito lReemplazados = oBuscarEn.select( oEncontrado ) Else MsgBox "No se encontraron coincidencias" End If End Sub 6.searchWords = False 'Distinguimos mayusculas de minusculas oSD. establecemos el valor buscado (setSearchString) y el valor por el que se reemplazara (setReplaceString). como lo podemos comprobar en la siguiente imagen: .getCurrentController(). En la búsqueda anterior.findAll( oSD ) If Not IsNull( oEncontrado ) Then ThisComponent.setSearchString( "=año" ) 'Reemplazado por oRD. deberíamos tener en esta columna la formula =MES(AHORA())-C2.getCellRangeByName( "A1:D19" ) 'Creamos el descriptor de reemplazo oRD = oHojaActiva.replaceAll( oRD ) If lReemplazados = 0 Then MsgBox "No se encontraron coincidencias" Else MsgBox "Se realizaron " & lReemplazados & " reemplazos" End If End Sub Observa que ahora. este método (replaceAll) devuelve un entero largo (long) con el número total de reemplazos que tuvieron éxito.

reemplazaremos palabras completas.setReplaceString( "nikole" ) 'Le indicamos que busque palabras completas oRD.CellAddress oHojaActiva = ThisComponent.star. “casi” puedes estar seguro de que el reemplazo lo estará. son muy fáciles de manejar.table.4. 6. mi amigo Edgar no me reclamará nada si lo cambio por Nikole. en las celdas de una hoja de calculo.setSearchString( "edgar" ) oRD. en el siguiente ejemplo.getCurrentController().getActiveSheet() 'Obtenemos la colección de notas de la hoja activa oNotas = oHojaActiva. insertamos una nueva nota en la celda E7: Sub Dim Dim Dim Notas1() oHojaActiva As Object oNotas As Object oDirCelda As New com.6 Trabajando con notas Las notas.getAnnotations() . si tus búsquedas están bien establecidas.searchWords = True lReemplazados = oBuscarEn. de hecho me felicitará: Sub Dim Dim Dim Dim Reemplazar2() oHojaActiva As Object oBuscarEn As Object lReemplazados As Long oRD As Object oHojaActiva = ThisComponent.getCellRangeByName( "A1:D19" ) oRD = oHojaActiva.getActiveSheet() oBuscarEn = oHojaActiva.replaceAll( oRD ) If lReemplazados = 0 Then MsgBox "No se encontraron coincidencias" Else MsgBox "Se realizaron " & lReemplazados & " reemplazos" End If End Sub A veces. es conveniente hacer primero una búsqueda y comprobar que esta correcta para después hacer el reemplazo. con el siguiente código.createReplaceDescriptor oRD.sun.getCurrentController.Aprendiendo OOo Basic 241 Ahora.

getCount() End Sub Para mostrar la dirección de cada una de las celdas con notas y su contenido: Sub Dim Dim Dim Dim Notas3() oHojaActiva As Object oNotas As Object oNota As Object co1 As Long oHojaActiva = ThisComponent.Row = 6 'Insertamos la nota oNotas.mDatos()) End Function Puedes acceder a una celda primero y después a su nota para modificarla: Sub Dim Dim Dim Notas4() oHojaActiva As Object oCelda As Object oNota As Object .Row+1.callFunction("ADDRESS".star.1 'Obtenemos una nota oNota = oNotas.getActiveSheet() oNotas = oHojaActiva.getString() Next co1 Else MsgBox "No hay notas en esta hoja" End If End Sub Function DireccionCelda( DirCelda As Object ) As String Dim oSFA As Object Dim mDatos 'Nos apoyamos en la función de Calc DIRECCION (ADDRESS) oSFA = createUnoService( "com.insertNew( oDirCelda.getCount() > 0 Then For co1 = 0 To oNotas.getAnnotations() If oNotas.sheet.getPosition ) & ": " & oNota.getCurrentController. 4 ) DireccionCelda = oSFA.sun.getActiveSheet() 'Obtenemos la colección de notas de la hoja activa oNotas = oHojaActiva.FunctionAccess" ) 'Construimos la matriz de datos para la función mDatos = Array( DirCelda.Column = 4 oDirCelda.getCount .242 'La celda donde insertaremos la nota oDirCelda.4 Manipulando datos Para saber cuantas notas hay en la hoja activa: Sub Notas2() Dim oHojaActiva As Object Dim oNotas As Object oHojaActiva = ThisComponent.Column+1.getAnnotations() 'Mostramos el total de notas en la hoja MsgBox oNotas.getCurrentController. "Presupuesto aprobado" ) End Sub 6. DirCelda.getByIndex( co1 ) 'Mostramos su posición y su contenido MsgBox DireccionCelda( oNota.

getCellAddress.getPosition.getAnnotations() If oNotas.setString( "Cambio de texto en nota" ) End Sub Si la celda referenciada no tiene una nota.Aprendiendo OOo Basic 243 oHojaActiva = ThisComponent.getActiveSheet() oCelda = oHojaActiva.getCurrentController.getCount() > 0 Then For co1 = 0 To oNotas.getCellAddress.getAnnotation 'Le cambiamos su contenido oNota.1 oNota = oNotas.getActiveSheet() oCelda = oHojaActiva.getCellRangeByName("A1") 'Accedemos a la nota de la celda oNota = oCelda.Column = oCelda.Row = oCelda.getString() ) = 0 Then MsgBox "La celda NO tiene nota" Else MsgBox "La celda tiene nota" End If End Sub También puede recorrer el conjunto de notas y comparar la dirección: Sub Dim Dim Dim Dim Dim Notas6() oHojaActiva As Object oCelda As Object oNotas As Object oNota As Object co1 As Long oHojaActiva = ThisComponent.getCurrentController.getAnnotation If Len( oNota. puedes usar la longitud del contenido de la nota para saberlo: Sub Dim Dim Dim Notas5() oHojaActiva As Object oCelda As Object oNota As Object oHojaActiva = ThisComponent.getByIndex( co1 ) 'Comparamos las direcciones If oNota.getCellRangeByName("E7") oNotas = oHojaActiva. el cambio no se verá reflejado en la interfaz del usuario. por lo que tienes que asegurarte que la celda contienen una nota.getCount .getCellRangeByName("A1") 'Accedemos a la nota de la celda oNota = oCelda.Column And oNota.getPosition.Row Then MsgBox "La celda tiene nota" Exit Sub End If Next co1 MsgBox "La celda NO tiene nota" Else MsgBox "No hay notas en esta hoja" End If End Sub Podemos hacer visible una nota: .getCurrentController.getActiveSheet() oCelda = oHojaActiva.

getCurrentController.getCurrentController. si esta oculta la muestra y si esta visible la oculta: Sub Dim Dim Dim Dim Notas8() oHojaActiva As Object oNotas As Object oNota As Object co1 As Long oHojaActiva = ThisComponent.getCellRangeByName("A1") oNotas = oHojaActiva.getAnnotation 'La hacemos visible oNota.getAnnotations() If oNotas.Column = oCelda.1 oNota = oNotas.getByIndex( co1 ) 'Comparamos las direcciones If oNota.getByIndex( co1 ) 'Intercambiamos su visibilidad oNota.Column And oNota.getCount() > 0 Then For co1 = 0 To oNotas.244 Sub Dim Dim Dim Notas7() oHojaActiva As Object oCelda As Object oNota As Object 6. el siguiente ejemplo te intercambia la visibilidad de las notas de la hoja.setIsVisible( False ) End Sub De nuevo.getIsVisible ) Next co1 Else MsgBox "No hay notas en esta hoja" End If End Sub Nota como hacemos el intercambio.getActiveSheet() oCelda = oHojaActiva.4 Manipulando datos oHojaActiva = ThisComponent.getActiveSheet() oCelda = oHojaActiva. es decir. esta propiedad nos devuelve falso (False) o verdadero (True) según este o no visible la nota. por lo que hay que iterar entre el conjunto de notas: Sub Dim Dim Dim Dim Dim Notas9() oHojaActiva As Object oCelda As Object oNotas As Object oNota As Object co1 As Long oHojaActiva = ThisComponent.getCellRangeByName("E7") oNota = oCelda.getPosition. tampoco te dará ningún error.getPosition.Row = oCelda.getAnnotations() If oNotas.Row Then . con el operador de negación (Not) invertimos este valor y por consiguiente la visibilidad.getCellAddress. es preciso saber el índice de esta.getCount . el código anterior no hará nada. Para borrar una nota.setIsVisible( Not oNota. podemos saber si la nota de la celda es visible (getIsVisible).getCount() > 0 Then For co1 = 0 To oNotas.1 oNota = oNotas.getCellAddress. si la celda no tiene nota.getCount .getCurrentController.getActiveSheet() oNotas = oHojaActiva.

crea una macro que nos haga un informe.getActiveSheet() oCelda = oHojaActiva. Por ahora.getCurrentController.getAnnotation 'La hacemos visible oNota. . en una hoja nueva.setSize( oTam ) 'Cambiamos el color de fondo de forma aleatoria oForma.Height = oTam. tiene decenas de propiedades para manipularse.Rnd()*255) End Sub Esta autoforma. por lo que volveremos a ellas en el capítulo correspondiente a autoformas.Height * 2 'Establecemos el nuevo tamaño oForma.getAnnotationShape 'Obtenemos el tamaño actual oTam = oForma.Width * 2 oTam.getCellRangeByName("E7") 'Accedemos a la nota oNota = oCelda.Width = oTam. tienes todos los elementos para manipular las notas de celdas a tu antojo. ¿vale?.getSize 'Lo duplicamos oTam. nos tiene que devolver la dirección completa y su contenido.Rnd()*255.Aprendiendo OOo Basic 245 'Borramos la nota por su índice oNotas.setIsVisible( True ) 'Accedemos a la forma oForma = oNota. de todas las notas existentes en la hoja activa. De tarea.FillColor = RGB(Rnd()*255.removeByIndex( co1 ) Exit Sub End If Next co1 MsgBox "La celda NO tiene nota" Else MsgBox "No hay notas en esta hoja" End If End Sub También es posible acceder a la autoforma (Shape) de la nota para manipularla: Sub Dim Dim Dim Dim Dim Notas10() oHojaActiva As Object oCelda As Object oNota As Object oForma As Object oTam As Object oHojaActiva = ThisComponent.

CharPosture = 2 'Subrayado . dando formato a los datos se consume una gran cantidad de tiempo y ya sabes.org. no hay muchas variantes entre ellas: Constante com. uno que es bastante flojo esta encantado que se haga de forma automática.5 Dando formato No se si estarás de acuerdo conmigo.awt.awt. 6.CharWeight = 150 'Cursiva o italica .1 subrayado: Sub FormatoCeldas1() Dim oSel As Object Formato de celdas Primero las características más usuales.FontWeight. El estilo negritas se establece por cualquiera de las siguiente constantes. negritas.sun.LIGHT com.SEMILIGHT Valor 0 50 60 75 90 .CharFontName = "Liberation Sans" 'Tamaño de letra . pero a veces. tipo de fuente. usa las macros disponibles en: Listar fuentes en un archivo de Calc El tamaño de la fuente (CharHeight) se establece en puntos.THIN com.FontWeight.5. recordando que un punto es igual a 1/72 de pulgada.FontWeight.sun.star.star. casi siempre. excepto los extremos.sun. de las cuales.CharUnderline = 1 End With End Sub Para saber la lista completa de fuentes (CharFontName) que tienes disponibles en OpenOffice. aproximadamente 0.awt.getCurrentSelection() With oSel 'Tipo de letra .star.star.246 6.star.5 Dando formato 6.DONTKNOW com. tamaño.awt.CharHeight = 20 'Negritas . cursiva y oSel = ThisComponent. es decir.sun.awt.sun.FontWeight. veamos las opciones más comunes de formato por código. así como en un rango de celdas cuando sea necesario.ULTRALIGHT com.3528 mm. pero no se te olvide que siempre es bueno comprobar que estas trabajando en una hoja de calculo.FontWeight. En la mayoría de los ejemplos trataremos de trabajar sobre la selección.

FontWeight.awt.DASH com.DOTTED com.sun.SEMIBOLD com.awt.awt.awt.NONE com.ULTRABOLD com.FontUnderline.FontUnderline.star.FontWeight.sun.awt.sun.DONTKNOW com.sun.sun.awt.awt.OBLIQUE com.sun.FontUnderline.sun.awt.BLACK Valor 100 110 150 175 200 Al estilo cursiva o itálica le corresponden las siguiente constantes: Constante com.sun.awt.FontSlant.sun.ITALIC com.awt.FontWeight.FontWeight.FontUnderline.WAVE com.star.FontSlant.awt.awt.BOLDLONGDASH Valor 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .sun.sun.NONE com.star.star.awt.LONGDASH com.star.DOUBLEWAVE com.BOLD com.FontUnderline.awt.star.NORMAL com.sun.star.SMALLWAVE com.star.awt.FontUnderline.REVERSE_OBLIQUE com.star.sun.awt.sun.DASHDOTDOT com.FontUnderline.awt.sun.sun.awt.FontSlant.star.sun.DASHDOT com.star.sun.Aprendiendo OOo Basic 247 Constante com.sun.FontUnderline.DOUBLE com.FontSlant.FontSlant.sun.star.awt.sun.star.star.awt.FontUnderline.star.star.FontUnderline.DONTKNOW com.awt.star.sun.sun.sun.star.sun.FontUnderline.sun.sun.FontSlant.awt.awt.star.FontUnderline.FontUnderline.SINGLE com.star.awt.BOLD com.star.awt.star.BOLDDOTTED com.star.FontUnderline.BOLDDASH com.REVERSE_ITALIC Valor 0 1 2 3 4 5 El tipo de subrayado esta determinado por las constantes: Constante com.star.FontUnderline.awt.star.FontWeight.star.FontUnderline.awt.star.

sun.CharContoured = True End With End Sub Cuando se subraya la fuente y la propiedad CharWordMode se establece en verdadera (True).star. el color.255 ) 'Estilo de subrayado .0.sun. Las otras dos propiedades creo que son bastante autoexplicativas. Algunos de los valores de estas constantes.BOLDDASHDOTDOT com.248 6. según tu gusto y criterio.getCurrentSelection() With oSel 'Espacios sin subrayar . Algunas otras opciones de formato de fuente son: Sub FormatoCeldas2() Dim oSel As Object oSel = ThisComponent. primero establecemos el estilo (CharUnderline).FontUnderline. Ahora. establezcamos el color de la fuente y del subrayado de esta: Sub FormatoCeldas3() Dim oSel As Object oSel = ThisComponent. te deja los espacios entre palabras sin subrayar.CharUnderlineColor = RGB(255.FontUnderline. establecemos el color de la fuente.BOLDWAVE Valor 16 17 18 Recuerda que puedes usar tanto las constantes como el valor de estas.getCurrentSelection() With oSel 'Color de la fuente azul .star.CharUnderlineHasColor = True End With End Sub Con la propiedad CharColor y la ayuda de la función RGB. para el subrayado.CharColor = RGB( 0.awt.BOLDDASHDOT com.awt.FontUnderline.awt. .CharCrossedOut = True 'Contorno de fuente . si esta propiedad se establece en falso (false).sun.CharWordMode = True 'Tachado de fuente .0.star.0.) 'Si se muestra el color .CharUnderline = 1 'Color de subrayado rojo . el color del subrayado será del mismo color que el de la fuente. los puedes establecer pero no veras ningún efecto aparente.5 Dando formato Constante com. después el color de este (CharUnderlineColor) y por ultimo establecemos si queremos que se muestre el color (CharUnderlineHasColor). veamos algo muy divertido.

star.CellHoriJustify.Rnd()*255. se establece con las propiedades VertJustify para el sentido vertical y HoriJustify para el sentido horizontal de la siguiente forma: Sub FormatoCeldas5() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() 'Alineamos en medio verticalmente oSel.sun.star.CENTER com.getImplementationName = "ScCellRangeObj" Then With oSel For col = 0 To oSel.star.Rnd()*255.table.CENTER com.RIGHT Valor 0 1 2 3 .Aprendiendo OOo Basic 249 Con la siguiente macro.CellVertJustify.sun.table.table.CellHoriJustify.sun.HoriJustify = 2 End Sub Los valores posibles para cada propiedad son: Propiedad VertJustify com. fil ) .sun.getCount .CellVertJustify.Rnd()*255) .CellVertJustify.star.getCount .LEFT com.sun.sun.table.TOP com.table.sun. a cada celda del rango seleccionado se le establecerá un color de fuente y de subrayado aleatorio.table.CellHoriJustify. Sub Dim Dim Dim FormatoCeldas4() oSel As Object col As Long fil As Long oSel = ThisComponent.CharUnderline = 1 .1 With .getCurrentSelection() If oSel.CellVertJustify.CharColor = RGB( Rnd()*255.1 For fil = 0 To oSel.table.CharUnderlineColor = RGB( Rnd()*255.STANDARD com.sun.star.getRows.getColumns.star.BOTTOM Valor 0 1 2 3 Propiedad HoriJustify com.star.table.getCellByPosition( col.CharUnderlineHasColor = True End With Next Next End With End If End Sub La alineación del contenido de la celda.STANDARD com.VertJustify = 2 'Alineamos centrado horizontalmente oSel.star.Rnd()*255 ) .CellHoriJustify.

CellOrientation.star. Si queremos ajustar el texto automáticamente en la celda.STANDARD com.star.BLOCK com.REPEAT Valor 4 5 Con la combinación de estos valores.table.getCurrentSelection() 'Reduccion de texto oSel.table.CellOrientation. prueba a establecer esta propiedad en una celda cuyo contenido sea un punto para que notes su comportamiento.table.CellHoriJustify.sun.table.BOTTOMTOP com.getCurrentSelection() 'Orientacion vertical del texto oSel.CellOrientation. tenemos muchas posibilidades de alineación de una celda.star.sun.sun.TOPBOTTOM com.REPEAT. La constante com.table. usamos: Sub FormatoCeldas7() Dim oSel As Object oSel = ThisComponent.5 Dando formato Propiedad HoriJustify com.star.CellHoriJustify.sun.star.table.sun.star.sun.table. es muy interesante por que te repite el valor de la celda hasta llenar el ancho de ella. usamos: Sub FormatoCeldas6() Dim oSel As Object oSel = ThisComponent.IsTextWrapped = True End Sub Si queremos reducir el texto hasta que quepa en la celda.star.CellOrientation.STACKED O podemos establecer el ángulo de rotación: Sub FormatoCeldas9() Dim oSel As Object Valor 0 1 2 3 .ShrinkToFit =True End Sub Si queremos cambiar la orientación del texto: Sub FormatoCeldas8() Dim oSel As Object oSel = ThisComponent.Orientation = 3 End Sub Los valores para esta propiedad son: Propiedad Orientation com.250 6.CellHoriJustify.sun.getCurrentSelection() 'Ajuste de texto oSel.

200) End Sub La siguiente macro te colorea cada celda de la selección. de los dos ejemplos siguiente. solo el segundo es correcto: Sub FormatoCeldas10() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() oSel.getCurrentSelection() oSel.HoriJustify = 2 oSel.IsTextWrapped = True 'Tamaño de sangria oSel. se autoexcluyen mutuamente. Toma en cuenta que algunas de las propiedades vistas hasta ahora.getCount .1 For fil = 0 To oSel.200. fil ) .RotateAngle = 9000 End Sub El valor del ángulo esta dado en centésimas de ángulo.HoriJustify = 1 oSel. en el ejemplo anterior establecemos el ángulo en 90º (9000) para 180º podemos 18000 y así sucesivamente.ParaIndent = 1000 End Sub También podemos establecer el color de fondo de las celdas: Sub FormatoCeldas12() Dim oSel As Object oSel = ThisComponent.IsTextWrapped = True 'Tamaño de sangria oSel.ParaIndent = 1000 End Sub Sub FormatoCeldas11() Dim oSel As Object oSel = ThisComponent.getCount .getCurrentSelection() oSel.getColumns.getCurrentSelection() 'Color del fondo de la celda (gris) oSel. tanto la fuente como el fondo de la celda de un color aleatorio: Sub Dim Dim Dim FormatoCeldas13() oSel As Object col As Long fil As Long oSel = ThisComponent.Aprendiendo OOo Basic 251 oSel = ThisComponent. es decir.CellBackColor = RGB(200.getImplementationName = "ScCellRangeObj" Then With oSel For col = 0 To oSel.1 With .getCurrentSelection() If oSel.getRows. por lo que tienes que asegurarte que no se contraponen.getCellByPosition( col.

BorderLine) vista en los ejemplos.252 6.InnerLineWidth = 50 'El ancho de la linea interior .TopBorder = oBordeLinea .255) 'El ancho de la linea interior .0.BorderLine oSel = ThisComponent.sun.sun.CharColor = RGB( Rnd()*255. Si deseas establecer también las líneas diagonales.OuterLineWidth = 50 'La distancia entre las lineas .Color = RGB(255.OuterLineWidth = 75 End With . si quieres establecer el borde de solo los extremos del rango.table.star.getCurrentSelection() 'Establecemos las caracteristicas de la linea With oBordeLinea 'El color (rojo) .star. veras una linea simple.5 Dando formato . tienes que establecerles la misma estructura de línea (com.Rnd()*255 ) .Rnd()*255.sun.CellBackColor = RGB( Rnd()*255.RightBorder = oBordeLinea End With End Sub 'Superior 'Inferior 'Izquierdo 'Derecho El ancho de las lineas y la distancia entre ellas esta dada en centésimas de milímetros.star.LeftBorder = oBordeLinea .BottomBorder = oBordeLinea .0.table. usa la propiedad DiagonalTLBR para la línea que va desde la esquina superior izquierda a la inferior derecha y DiagonalBLTR para la que va de la esquina inferior izquierda a la superior derecha.table.sun.table. veamos algunas: Sub FormatoCeldas14() Dim oSel As Object Dim oBordeLinea As New com.LineDistance = 20 End With 'Establecemos los bordes With oSel .getCurrentSelection() 'Establecemos las características de la linea With oBordeLinea 'El color (azul) .Color = RGB(0.BorderLine oBordeTabla As New com.star.0) 'El ancho de la linea exterior . si establecemos solo una de las dos líneas.Rnd()*255.TableBorder oSel = ThisComponent.Rnd()*255 ) End With Next Next End With End If End Sub Los bordes de las celdas tienen muchas posibilidades. tiene que usar la estructura TableBorder: Sub Dim Dim Dim FormatoCeldas15() oSel As Object oBordeLinea As New com. El código anterior te establecerá el borde de cada celda del rango seleccionado.

ParaRightMargin = 800 'Derecha End With End Sub Para dar un formato predeterminado a la celda. usamos la propiedad NumerFormat.IsRightLineValid = True End With 'Establecemos los bordes oSel. Para ello. Para establecer los margenes de la celda. por ejemplo: Sub FormatoCeldas17() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() .TopLine = oBordeLinea . Listar formatos en un archivo de Calc. usamos el método merge. IsBottomLineValid.getCurrentSelection() 'Establecemos la seleccion en el formato Estandar oSel.Aprendiendo OOo Basic 253 'Establecemos las características de la tabla With oBordeTabla .ParaTopMargin = 500 'Arriba . Ahora.IsLeftLineValid = True . la cual es necesario establecer como un entero largo (long) correspondiente a la clave del formato que nos interese. usa la macro que te muestro en.LeftLine = oBordeLinea .ParaLeftMargin = 800 'Izquierda .ParaBottomMargin = 500 'Abajo . IsLeftLineValid y IsRightLineValid. como en el siguiente ejemplo: Sub FormatoCeldas18() Dim oSel As Object oSel = ThisComponent. para ello.TableBorder = oBordeTabla End Sub 'Superior 'Inferior 'Izquierdo 'Derecho Las propiedades IsTopLineValid.NumberFormat = 0 End Sub El numero de clave no es secuencial. usamos: Sub FormatoCeldas16() Dim oSel As Object oSel = ThisComponent. tienes que establecerlas en verdadero (true) si quieres que se vea la línea.RightLine = oBordeLinea .IsBottomLineValid = True .BottomLine = oBordeLinea . por lo que tenemos que saber de antemano la clave del formato que nos interesa. veamos como combinar y separar celdas.getCurrentSelection() 'Para establecer los margenes de la celda With oSel .IsTopLineValid = True . con el argumento verdadero (true).

merge( True ) End Sub 6. no en una colección de rangos así que validalo cuando lo uses. claro. es decir. Sub FormatoCeldas19() Dim oSel As Object oSel = ThisComponent. Sub FormatoCeldas21() Dim oRango As Object Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCellRangeByName( "G19" ). el valor que nos devuelve el consultar su propiedad getIsMerged y observa hasta cuando nos funciona el método para separar las celdas.getActiveSheet() oRango = oHojaActiva.getCurrentController. manualmente y observa que pasa. primero las separamos y después las combinamos. ¿verdad?. ahora..merge( Not oRango.getCellRangeByName( "E15:H20" ) oRango. la macro siguiente te alternara entre combinar y separar la el rango seleccionado.getIsMerged() oHojaActiva.getCellRangeByName( "B2:D10" ) 'Invertimos la combinacion oRango. tienes que poner mucha atención.merge( True ) End Sub Si se puede. es saber que pasa cuando las celdas se combinan.merge( True ) 'Nota que la celda G19 forma parte del rango combiando 'consultamos la propiedad y tratamos de separar Msgbox oHojaActiva.getIsMerged ) End Sub Ahora. separara las celdas de la selección. junto con un área que no. Si estableces el argumento en falso (false).254 'Combinamos las celdas seleccionadas oSel. La siguiente consideración que debes tomar en cuenta. Si seleccionas un rango ya combinado. tratemos de emularlo con código. pero has la prueba en la interfaz del usuario.5 Dando formato Este método solo esta presente en un rango de celdas.getCurrentSelection() 'Separamos las celdas seleccionadas oSel. las celdas en las cuales verificamos si están combinadas. nota como consultamos la propiedad getIsMerged para saber si el rango esta combinado.getCellRangeByName( "G19" ).getActiveSheet() oRango = oHojaActiva.getIsMerged() . en la siguiente macro.. Sub FormatoCeldas20() Dim oRango As Object Dim oHojaActiva As Object oHojaActiva = ThisComponent. haremos unas pruebas ya no con la selección sino con rangos con nombre. por código estoy hablando. para ello.getCurrentController. nota el rango que estamos combinando.merge( False ) 'Las combinamos oSel. este método no hará nada.getCellRangeByName( "F17" ). Este método es sencillo pero debes de tomar en cuenta algunas consideraciones.merge( False ) Msgbox oHojaActiva.

merge( True ) 'Verificamos que este combinada MsgBox oHojaActiva. a partir de otra celda. para hacer esto. cuando se combinan celdas.sun. Sub Dim Dim Dim FormatoCeldas22() oRango As Object oHojaActiva As Object oCursor As Object oHojaActiva = ThisComponent.getIsMerged() oHojaActiva. solo veras el resultado = True oculta el contenido de las celdas .getCellRangeByName( "G19" ) ) 'Expandimos el cursor al area combinada oCursor. veamos como proteger y desproteger celdas. se marcan como “no” combinadas.IsLocked = True 'Determina si se . excepto la de la esquina superior izquierda del rango.getCellRangeByName( "J27:L30" ) With oPC 'Determina si la .getCurrentController.getActiveSheet() oRango = oHojaActiva.merge( False ) Msgbox oHojaActiva.merge( False ) End Sub ¿Lo notaste?.getIsMerged() 'Creamos un cursor a partir de una celda que no sea la de 'la esquina superio izquierda oCursor = oHojaActiva.star.createCursorByRange( oHojaActiva.IsFormulaHidden 'Determina si se .getCellRangeByName( "E15" ). eso nos obliga a buscar y encontrar esta celda a partir de otra cuando intentemos separar celdas.collapseToMergedArea() 'Separamos las celdas oCursor. recuerda que esta protección solo es efectiva si la hoja de calculo esta protegida Sub Dim Dim Dim ProtegerCeldas1() oRango As Object oHojaActiva As Object oPC As New "com. verificalo en la interfaz del usuario y trata de anticipar este caso. nos auxiliaremos de un cursor cuyo uso ya lo hemos visto. Como ultimo tema de este capitulo.CellProtection" oHojaActiva = ThisComponent. nos dice que esta combinada y 'finalmente logramos separarlas Msgbox oHojaActiva.getCellRangeByName( "G19" ).getIsMerged() oHojaActiva.getCellRangeByName( "G19" ).getCellRangeByName( "E16" ).Aprendiendo OOo Basic 255 'Tratamos de separar las celdas oHojaActiva.getCellRangeByName( "E15" ). entonces.getActiveSheet() oRango = oHojaActiva.util. expandimos el cursor a la región combinada y pudimos separar fácilmente. Toma en cuenta que pasa con las celdas que tienen contenido cuando se combinan.merge( False ) End Sub Esta vez.getCurrentController. todas.getCellRangeByName( "E15" ).IsHidden = True celda esta bloqueada para modificarse ocultan las formulas.merge( False ) 'Ahora si.getCellRangeByName( "E15:H20" ) oRango.

IsPrintHidden = True End With oRango.IsHidden = True 'Para ocultar solo para la impresión . IsVisible. si bien no te dará ningún error. para este caso. por supuesto.getRows.CellProtection = oPC End Sub 6.IsFormulaHidden = True 'Determina si se oculta el contenido de las celdas . tampoco veras ningún cambio. usamos la propiedad Height.star.5.Protect("") End Sub 6.getCurrentSelection() 'Establecemos el alto de las filas seleccionadas oSel.sun. estableciendo el valor en la unidad veras que la fila sigue siendo notable. es suficiente con desproteger la hoja.getActiveSheet() oRango = oHojaActiva. es mejor usar la propiedad correspondiente.CellProtection" oHojaActiva = ThisComponent.IsPrintHidden = True End With oRango.IsLocked = True 'Determina si se ocultan las formulas.2 Formato de filas y columnas Para establecer la altura de las filas. por lo que para tener una fila de 0.Height = 500 End Sub Cuando tratas de establecer la altura de las filas en cero (0).util.getCellRangeByName( "J27:L30" ) 'Desprotegemos la hoja oHojaActiva.CellProtection = oPC oHojaActiva. no siempre tienen que estar todas seleccionadas. el valor se establece en centésimas de milímetros. de todos modos puedes deshabilitar las opciones de protección con solo establecer las opciones de protección en falso (False). aun.unProtect("") With oPC 'Determina si la celda esta bloqueada para modificarse . como en: . solo veras el resultado .getCurrentController. tu determinaras el nivel de acceso en cada uno de tus proyecto.5 Dando formato Para desproteger las celdas.50 cm le asignamos un valor de 500 como en el siguiente ejemplo: Sub FormatoFilas1() Dim oSel As Object oSel = ThisComponent. Si lo que deseas es ocultarla.256 'Para ocultar solo para la impresión . por ejemplo: Sub Dim Dim Dim ProtegerCeldas2() oRango As Object oHojaActiva As Object oPC As New "com.

Sub FormatoFilas4() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCurrentSelection() 'Alternamos entre visible y oculta oSel.getCurrentSelection() 'Ocultamos las filas seleccionadas oSel.Aprendiendo OOo Basic Sub FormatoFilas2() Dim oSel As Object 257 oSel = ThisComponent.IsVisible = False End Sub Esta propiedad se establece en falso (false) para ocultar la fila y en verdadero (true) para mostrarla.getRows.getByindex(2).getCurrentSelection() 'Establecemos el color de fondo de las celdas de la fila completa oSel.getActiveSheet() 'Consultamos si la fila 3 esta filtrada MsgBox oHojaActiva.getRows.getCurrentController. adquieren una propiedad particular cuando se les aplica un filtro.getRows. Sub FormatoFilas5() Dim oSel As Object oSel = ThisComponent. esta propiedad se llama IsFiltered. el siguiente ejemplo te alternara en ocultar y mostrar conforme la ejecutes: Sub FormatoFilas3() Dim oSel As Object oSel = ThisComponent. y te devolverá verdadero (true). si tu la ocultas con IsVisible. esta propiedad (IsFiltered) seguirá siendo falsa (false). prueba a hacer un filtro en tu hoja activa y procura que la fila consultada (getByIndex(Indice)) este filtrada. Sub FormatoFilas6() Dim oSel As Object oSel = ThisComponent.getRows.IsFiltered End Sub También podemos establecer el alto optimo de las filas con la propiedad OptimalHeight.getRows.200) End Sub . cuando la fila consultada este oculta como consecuencia de un filtro.IsVisible End Sub Las filas.getRows. debe estar en verdadero (true) para que tenga efecto.getCurrentSelection() 'Establecemos el alto optimo de las filas seleccionadas oSel.OptimalHeight = True End Sub A las filas también es posible cambiarles el color de fondo.IsVisible = Not oSel. toma nota de que “solo” cuando este oculta por un filtro.200.CellBackColor = RGB(200. esto nos permite establecer el color de toda la fila.

aquí una primera aproximación.258 6. Sub FormatoColumnas3() Dim oSel As Object oSel = ThisComponent.getCurrentSelection() 'Ajustamos al contenido oSel.Rnd()*255 ) Next End Sub A las columnas también les podemos establecer el ancho.getColumns.getCount() .1 Step 2 'Establecemos un color aleatorio para las filas impares de la seleccion oSel. Sub FormatoColumnas1() Dim oSel As Object oSel = ThisComponent. pero también podemos implementar nuestras versión.getByIndex( co1 ).getColumns.getCurrentSelection() 'Nos apoyamos en un cursor .getCurrentSelection() 'Ocultamos las columnas seleccionadas oSel.Width = 1000 End Sub Y ocultarlas.IsVisible = False End Sub Ajustar al contenido.getRows. Sub FormatoColumnas2() Dim oSel As Object oSel = ThisComponent. por que como sabes.OptimalWidth = True End Sub Las columnas no tienen una propiedad IsFiltered.getRows.5 Dando formato La siguiente macro te cambiara el color de las filas impares de la selección. Sub FormatoColumnas4() Dim oSel As Object Dim oCursor As Object oSel = ThisComponent.Rnd()*255. pero con un poco de ingenio y usando la propiedad IsVisible.CellBackColor = RGB( Rnd()*255.getCurrentSelection() 'Establecemos el ancho de las columnas seleccionadas oSel. puedes crearte tu versión de filtros horizontales. Sub FormatoFilas7() Dim oSel As Object Dim co1 As Long oSel = ThisComponent.getColumns. no hay filtros horizontales.getCurrentSelection() For co1 = 0 To oSel. Tampoco puedes usar la propiedad CellBackColor para establecer el color de fondo.

los estilos de celda que veremos en este capitulo y los estilos de página que se verán en el siguiente. por lo que se verán en el capitulo correspondiente a impresión.Width = 1000 For co1 = 0 To oSel.getStyleFamilies() 'Accedemos a los estilos de celda oEstilosCelda = oEstilos.230) Next End Sub Las filas y columnas cuentan con algunas propiedades involucradas en la impresión de los documentos. tenemos dos estilos perfectamente definidos.getSpreadSheet.getCount() . después el alto de las filas también en 1 y coloreará alternadamente filas y columnas para hacer un lindo mosaico.0) ) oCursor.210) End Sub La siguiente macro.CellBackColor = RGB(230.createCursorByRange( oSel.expandToEntireColumns() oCursor.getColumns. es decir.Height = 1000 oSel.expandToEntireColumns() oCursor. Sub Dim Dim Dim FormatoFilasColumnas1() oSel As Object oCursor As Object co1 As Long oSel = ThisComponent.230.1 Step 2 oSel.230 ) Next For co1 = 0 To oSel.getSpreadSheet.3 Estilos y autoformato Como buen usuario de OpenOffice.5.getRows.210. en la posibilidad de agrupar bajo un nombre.getColumns. Chr(13) ) . sabemos que una de sus características más ricas esta en sus “estilos”. Dentro de las hojas de cálculo. usamos la siguiente macro: Sub Dim Dim Dim Dim Estilos1() oDoc As Object oEstilos As Object oEstilosCelda As Object oSel As Object 'Accedemos al documento actual oDoc = ThisComponent 'Accedemos a todos los estilos oEstilos = oDoc.CellBackColor = RGB( 230.getCellByPosition(co1. Para ver los estilos de celda actuales. 6.org que somos.1 Step 2 oCursor = oSel.getRows.230.getCurrentSelection() oSel. establecerá el ancho de las columnas en 1 cm.CellBackColor = RGB(210. una serie de características de formato y que podemos aplicar con un solo clic.getRows.getByIndex( co1 ).createCursorByRange( oSel ) oCursor.getCount() .getByName("CellStyles") 'Mostramos sus nombres MsgBox Join( oEstilosCelda.Aprendiendo OOo Basic 259 oCursor = oSel.getElementNames().

un rango de celdas.CharPosture = 2 . los estilos de celda. crea uno con el formato que quieras (tecla F11). En nuestro ejemplo.getCurrentSelection() 'Aplicamos el estilo de celda Domingos a la selección actual oSel. hemos agregado un nuevo estilo de celda que se llama “Domingos”.5 Dando formato Si no tienes ningún estilo de celda personalizado. un grupo de rangos de una forma sumamente sencilla. los podemos establecer a una celda.CharFontName = "Nimbus Sans L" 'Tamaño de letra . veamos como: Sub Estilos2() Dim oSel As Object oSel = ThisComponent.260 End Sub 6.CellStyle = "Domingos" End Sub Veamos la diferencia entre aplicar formato directo a las celdas y usar un estilo.getCurrentSelection() With oSel 'Tipo de letra .CharWeight = 150 'Cursiva o italica . formateamos la selección con las características indicada en cada línea: Sub Estilos3() Dim oSel As Object oSel = ThisComponent. vuelve a correr la macro y tienes que ver listado el nuevo estilo.CharHeight = 15 'Negritas . en la siguiente macro.

mayúsculas y minúsculas. pero (siempre hay un pero).VertJustify = 2 . pasarán a tener el estilo de celda predeterminado. también.204.204) 'Color de la fuente .insertByName( "Resaltado1". el código no te dará ningún error. si el estilo de celda no existe.CharPosture = 2 . verificar que el estilo exista y en caso de que no exista.hasByName( "Resaltado1" ) Then oSel.getCurrentSelection() 'Accedemos a todos los estilos oEstilos = oDoc. crearlo.CellStyle" ) 'Lo agregamos a la colección de estilos oEstilosCelda. pues si intentas agregar un nombre ya existente.255) End With End Sub 261 Ahora. para nuestro ejemplo le llamaremos “Resaltado1” y procedamos a aplicar a la selección: Sub Estilos4() Dim oSel As Object oSel = ThisComponent. el nombre del estilo. al crearlo.CellStyle = "Resaltado1" End Sub No puede ser más fácil.sun.star. las celdas que tengan este estilo. debe estar escrito tal cual se dio de alta incluyendo.CharFontName = "Nimbus Sans L" . es recomendable.VertJustify = 2 'Alineamos centrado horizontalmente . crea un estilo con estas mismas características. que son los únicos que puedes eliminar.CharHeight = 15 .getStyleFamilies() 'Accedemos a los estilos de celda oEstilosCelda = oEstilos. cuando se borra un estilo de celda personalizado. simplemente no hará nada.0.HoriJustify = 2 'Color de fondo de la celda .style.getByName("CellStyles") 'Verificamos que el estilo exista If oEstilosCelda.CharWeight = 150 .CharColor = RGB(0. es recomendable verificar que no exista ya el nombre propuesto.CellStyle = "Resaltado1" Else 'Si no existe lo creamos oEstiloNuevo = oDoc.Aprendiendo OOo Basic 'Alineamos en medio verticalmente .CellBackColor = RGB(204.getCurrentSelection() oSel. te dará un error en tiempo de ejecución. oEstiloNuevo ) 'Establecemos su formato With oEstiloNuevo . Veamos un ejemplo: Sub Dim Dim Dim Dim Dim Estilos5() oDoc As Object oSel As Object oEstilos As Object oEstilosCelda As Object oEstiloNuevo As Object 'Accedemos al documento actual oDoc = ThisComponent 'Accedemos a la selección oSel = ThisComponent. por ello. como sucede en la interfaz del usuario.createInstance( "com.

Sub Dim Dim Dim Dim Estilos6() oDoc As Object oEstilos As Object oEstilosCelda As Object oEstiloNuevo As Object 'Accedemos al documento actual oDoc = ThisComponent 'Accedemos a todos los estilos oEstilos = oDoc.TableAutoFormats") 'Mostramos sus nombres MsgBox Join( oAutoFormatos.CellStyle = "Resaltado1" End If End Sub 6. de tres columnas por tres filas.star. Chr(13) ) End Sub Para aplicar un autoformato se usa el método autoFormat de la siguiente manera: Sub Autoformato2() Dim oSel As Object oSel = ThisComponent. mínimo.sun.getByName("CellStyles") 'Verificamos que el estilo exista If oEstilosCelda. perdiéndose todo el formato.5 Dando formato Para borrar un estilo.hasByName( "Domingos" ) Then If MsgBox("¿Estas seguro de borrar el estilo?". regresaran al estilo predeterminado.255) End With 'Y lo aplicamos oSel.CellBackColor = RGB(204. este servicio esta disponible tanto en hojas de calculo como en tablas de Writer. usamos el método removeByName de la siguiente manera. “todas”.0.autoFormat("Verde") . para ver los autoformatos disponibles usamos: Sub Autoformato1() Dim oAutoFormatos As Object oAutoFormatos = createUnoService("com.sheet.204) ."Borra estilo") = 6 then 'Quitamos el estilo oEstilosCelda.getElementNames(). es que el autoformato siempre se aplica a un rango de celdas.removeByName( "Domingos" ) MsgBox "Estilo de celda borrado" Else MsgBox "NO se borro ningún estilo" End If Else MsgBox "El estilo no existe" End If End Sub El manejo de autoformato. recordando que al borrar el estilo.204. la diferencia.36.getCurrentSelection() oSel.getStyleFamilies() 'Accedemos a los estilos de celda oEstilosCelda = oEstilos. es muy similar al de estilos.262 . las celdas que tengan dicho estilo.CharColor = RGB(0.HoriJustify = 2 .

sheet.getColumns. las celdas establecidas con este.removeByName( "VerdeRojo" ) MsgBox "Autoformato borrado" Else MsgBox "NO se borro nada" End If Else MsgBox "El autoformato no existe" End If End Sub A diferencia de los estilos de celda. cuando borras un autoformato. por ello. lo único es que el autoformato borrado. como siempre. lo mejor. usamos el método removeByName como en: Sub Autoformato4() Dim oAutoFormatos As Object oAutoFormatos = createUnoService("com.hasByName( sNombreAF ) Then oSel = ThisComponent.getRows.TableAutoFormats") 'verificamos que exista el autoformato If oAutoFormatos.getCount > 2 Then oSel. por código. si bien. como en el siguiente ejemplo: Sub Dim Dim Dim Autoformato3() oAutoFormatos As Object oSel As Object sNombreAF As String sNombreAF = "VerdeRojo" oAutoFormatos = createUnoService("com.sun. es validar que la selección es correcta."Borra autoformato") = 6 Then 'Quitamos el autoformato oAutoFormatos. pero a diferencia de los estilos.getCount > 2 And oSel. antes de usarlo. podrás aplicarlo a una sola celda pero te formateará un mínimo de tres fila por tres columnas.sun. como en los estilos. permanecen con dicho formato. te dará un error en tiempo de ejecución. te dará un error pues ese objeto no implementa el método autoFormat.Aprendiendo OOo Basic 263 End Sub Toma en cuenta que el rango seleccionado. si escribes mal el nombre. ya .getImplementationName = "ScCellRangeObj" Then 'de minimo tres filas por tres columnas If oSel.star.TableAutoFormats") 'Verificamos que exista If oAutoFormatos.hasByName( "VerdeRojo" ) Then If MsgBox("¿Estas seguro de borrar el autoformato?".getCurrentSelection() 'Nos aseguramos que la seleccion sea un rango de celdas If oSel. si usas esta técnica.star.autoFormat( sNombreAF ) Else MsgBox "El rango debe ser de minimo. es mejor validar que exista. debe ser exactamente como se llamo al crearlo. 3 columnas por 3 filas" End If Else MsgBox "No es un rango de celdas" End If Else MsgBox "El autoformato no existe" End If End Sub Para eliminar un autoformato. es decir. El nombre del autoformato.36. un rango de celdas.sheet. si seleccionas varios rangos de celdas. “debe” ser un objeto ScCellRangeObj.

observa la siguiente tabla: 1a Columna Encabezado 1a Fila 1a Fila de datos 2a Fila de datos Pie de Tabla Ultima Fila 1a Columna de datos 2a Columna de datos Ultima Columna 0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15 Un autoformato. cada cruce de columna y fila representa un estilo de celda. como es que queremos que quede.264 6. el formato de las columnas de datos se ira duplicando y alternando. Observa la siguiente imagen. si tu rango tiene más área. Como ya lo mencionamos. soy una nulidad para el diseño. Para crear un autoformato. el área mínima para usar un autoformato. como podrás notar. y en la parte inferior. así que no te pongas muy estricto. por lo que tenemos que crearlo de nuevo. es de 3 x 3 celdas. que. en la parte superior. como podrás notar.5 Dando formato no estará disponible para usarse. están nuestros datos sin formato (“pelones” dicen en mi pueblo). . primero hay que saber (y entender) como esta estructurado. no es más que una colección de formatos de celdas individuales. tenemos 16 estilos diferentes que podemos establecer. lo mismo pasará con las filas en el sentido vertical.

Aprendiendo OOo Basic 265 .

5 Dando formato .266 6.

LeftLine = oBordeLinea .star. así que será una macro un poco más larga de las que hemos venido probando. usamos la siguiente macro. pero muy sencilla por que se repite bastante el código.TableBorder oDoc = ThisComponent oSel = oDoc.star. tiene las mismas características de formato de las celdas vistas anteriormente (aunque no es posible aplicar todos los formatos presentes normalmente en celdas).BottomLine = oBordeLinea .star.sun.IsRightLineValid = True End With . te recuerdo que el formato de cada celda (campo) del autoformato.star.createInstance("com.sheet.IsLeftLineValid = True .Aprendiendo OOo Basic 267 Para crear el autoformato anterior.RightLine = oBordeLinea .OuterLineWidth = 60 End With With oBordeTabla .Color = 255 .sun. por lo que no comentaré esa parte.insertByName( sNombreAF. oNuevoAF ) 'Le damos formato a cada celda With oBordeLinea .hasByName( sNombreAF ) Then 'Lo agregamos a la colección de AutoFormatos oAutoFormatos.table.sun.TableAutoFormats") sNombreAF = "MiFormatoNuevo" 'Verificamos que no exista If Not oAutoFormatos.TableAutoFormat") oAutoFormatos = createUnoService("com.sheet.sun.IsTopLineValid = True .BorderLine oBordeTabla As New com.IsBottomLineValid = True .TopLine = oBordeLinea . vamos a formatear 16 celdas.getCurrentSelection() oNuevoAF = oDoc.table. veamos: Sub Dim Dim Dim Dim Dim Dim Dim CrearAutoFormato() oAutoFormatos As Object oNuevoAF As Object sNombreAF As String oDoc As Object oSel As Object oBordeLinea As New com.

IncludeNumberFormat = True . 0. 150. 2621593. 0. 2 ) 'Celda 11 Call FormatearCampoAF( oBordeTabla.getByIndex(5).IncludeFont = True . 2 ) 'Celda 13 Call FormatearCampoAF( oBordeTabla.getByIndex(4). 13. 150.getByIndex(2). 12. 150.getByIndex(0). 150. 16777215. oNuevoAF. 2 ) 'Celda 9 Call FormatearCampoAF( oBordeTabla.getImplementationName = "ScCellRangeObj" Then oSel. "Liberation Sans". 10. 16764057. 12. 13421772. 13421772. 2 ) 'Celda 12 Call FormatearCampoAF( oBordeTabla. 2. 2 ) 'Celda 14 Call FormatearCampoAF( oBordeTabla. 150. 150. "Liberation Sans". 2 ) 'Celda 5 Call FormatearCampoAF( oBordeTabla. 0.getByIndex(1). 16777215. oNuevoAF. 2 ) 'Celda 2 Call FormatearCampoAF( oBordeTabla.5 Dando formato oNuevoAF. 100. 16777215.getByIndex(13). 2 ) 6.autoFormat( sNombreAF ) End If Else 'Si existe el formato lo aplicanos If oSel. "Liberation Sans". "Liberation Sans". oNuevoAF. "Liberation Sans". 0. 13421772. 0.getByIndex(12). 100. 13421772. 16764057.getByIndex(6). 16777215. 16777215. 0. 2 ) 'Celda 8 Call FormatearCampoAF( oBordeTabla. 150. oNuevoAF. oNuevoAF. 0. oNuevoAF.getImplementationName = "ScCellRangeObj" Then oSel. 0. 3. 0. 12. "Liberation Sans".getByIndex(7). 150. oNuevoAF. oNuevoAF. 'De forma predeterminada incluimos todos las opciones With oNuevoAF . 2621593. 2 ) 'Celda 7 Call FormatearCampoAF( oBordeTabla. "Liberation Sans". 10.IncludeJustify = True . 2621593. 3.IncludeWidthAndHeight = True End With 'Solo lo aplicamos si la selección es un rango de celdas If oSel. 2 ) 'Celda 1 Call FormatearCampoAF( oBordeTabla. 150.getByIndex(15). 150. "Liberation Sans". 150. 10. oNuevoAF. "Liberation Sans". 10.getByIndex(9). 16777215. 12.autoFormat( sNombreAF ) . 2. 2. "Liberation Sans". 13. 16711680. oNuevoAF. "Liberation Sans". 150. 16711680. 13421772. 12. 16777215.getByIndex(8). 0.getByIndex(3). 0. 2 ) 'Celda 10 Call FormatearCampoAF( oBordeTabla. 16777215. "Liberation Sans". oNuevoAF. oNuevoAF.getByIndex(14). oNuevoAF.268 'Celda 0 Call FormatearCampoAF( oBordeTabla. 150. 0. 2 ) 'Celda 6 Call FormatearCampoAF( oBordeTabla. 12.IncludeNumberFormat = True . 3. "Liberation Sans". 13. oNuevoAF. 2621593. 2 ) 'Celda 4 Call FormatearCampoAF( oBordeTabla. 13. "Liberation Sans". 2 ) 'Celda 3 Call FormatearCampoAF( oBordeTabla.getByIndex(11). "Liberation Sans". 16711680. 2621593. 2621593. 10. 2 ) 'Celda 15 Call FormatearCampoAF( oBordeTabla. 150. 0. 2. 12. 16711680. oNuevoAF. 16777215. 0. 2621593. "Liberation Sans".getByIndex(10).IncludeBorder = True .IncludeBackground = True .

te dará control completo sobre el formato de página.CharFontName = Fuente . solo tienes que ser un poco observador. Observa que hacemos uso de una subrutina (macro) de apoyo para darle formato a cada campo del autoformato.Aprendiendo OOo Basic End If End If End Sub 269 'Puedes agregar todas las propiedades que consideres Sub FormatearCampoAF(Campo As Object. Bordes As Object. VJ As Byte) With Campo .TableBorder = Bordes . en conjunto con otra serie de propiedades de la hoja donde estés trabajando. así mismo.CharColor = ColorFuente . siempre tiene que establecerse por medio de un estilo de página. Negritas As Integer.CharWeight = Negritas . tiene una pequeña deficiencia que también tienes que encontrar. solo estoy considerando las propiedades más representativas. ColorFondo As Long. este.5. por supuesto. no esta difícil.CellBackColor = ColorFondo .VertJustify = VJ End With End Sub La macro anterior tiene unas pequeñas diferencias con la imagen mostrada al inicio de ella.CharHeight = TamFuente . ColorFuente As Long. puedes complementarla con todas las que necesites pues estos campos tienen más de cuarenta propiedades.getElementNames().HoriJustify = HJ . la lista de formatos de página existentes en el documento desde el cual se ejecuta: Sub Dim Dim Dim FormatoPagina1() oDoc As Object oEstilos As Object oEstilosPagina As Object 'Accedemos al documento actual oDoc = ThisComponent 'Accedemos a todos los estilos oEstilos = oDoc. Fuente As String. HJ As Byte.getByName("PageStyles") 'Mostramos sus nombres MsgBox Join( oEstilosPagina. TamFuente As Integer. La siguiente macro te muestra en un cuadro de mensaje. Chr(13) ) End Sub . 6.4 Formato de página El formato de página. tu tarea es notar las diferencias.getStyleFamilies() 'Accedemos a los estilos de página oEstilosPagina = oEstilos.

getCurrentController. selecciona los estilos de página.getByName("PageStyles") 'Verificamos que el nombre del estilo exista If oEstilosPagina.hasByName( sEstilo ) Then 'Si existe lo aplicamos oHojaActiva.getActiveSheet() oEstilos = oDoc.getCurrentController. Para saber que estilo de página tenemos en nuestra hoja activa.5 Dando formato Verifica que efectivamente sean los estilos que tienes.getActiveSheet() 'Verificamos el nombre del estilo actual MsgBox oHojaActiva.PageStyle End Sub Para aplicar el estilo de página que quieras. mostramos algunas propiedades del estilo de página predeterminado. la lista debería ser igual a la que te devuelve la macro anterior. . usamos: Sub Dim Dim Dim Dim FormatoPagina2() oDoc As Object oHojaActiva As Object oEstilos As Object oEstilosPagina As Object oDoc = ThisComponent oHojaActiva = oDoc.270 6.getStyleFamilies() oEstilosPagina = oEstilos. usamos la siguiente macro: Sub Dim Dim Dim Dim Dim FormatoPagina3() oDoc As Object oHojaActiva As Object oEstilos As Object oEstilosPagina As Object sEstilo As String sEstilo = "Report" oDoc = ThisComponent oHojaActiva = oDoc. ve a tu hoja y presiona la tecla F11 para abrir el cuadro de dialogo “Estilo y Formato”.PageStyle( sEstilo ) Else MsgBox "No se aplico ningún estilo de página" End If End Sub Con el siguiente ejemplo.

getCurrentController. usamos el método removeByName de la siguiente manera: Sub Dim Dim Dim Dim Dim FormatoPagina5() oDoc As Object oHojaActiva As Object oEstilos As Object oEstilosPagina As Object sEstilo As String sEstilo = "Videoteca" oDoc = ThisComponent oHojaActiva = oDoc. si que te quedarás sin estilos. pero.hasByName( sEstilo ) Then If MsgBox("¿Estas seguro de borrar el estilo de página?".hasByName( sEstilo ) Then oEP = oEstilosPagina. al estar basadas en la plantilla predeterminada.Aprendiendo OOo Basic Sub Dim Dim Dim Dim Dim Dim FormatoPagina4() oDoc As Object oHojaActiva As Object oEstilos As Object oEstilosPagina As Object sEstilo As String oEP As Object 271 sEstilo = "Default" oDoc = ThisComponent oHojaActiva = oDoc.RightMargin End If End Sub Para borrar un estilo.LeftMargin & " . borra todos los estilos para verificarlo. los estilos Reporte (Report) y Predeterminado (Default) no se pueden borrar. claro. aunque los borres. puedes volver a crearlos." & oEP. como en el siguiente ejemplo: Sub FormatoPagina6() Dim oDoc As Object Dim oHojaActiva As Object .getCurrentController.BottomMargin 'Margen izquierdo y derecho MsgBox oEP.getByName("PageStyles") If oEstilosPagina.getByName( sEstilo ) 'Ancho y alto de la página MsgBox oEP.TopMargin & " . no obstante.getStyleFamilies() oEstilosPagina = oEstilos.getActiveSheet() oEstilos = oDoc. tendrán de nuevo los estilos predeterminados. si no me crees y te gusta experimentar como a mi. 36) = 6 Then 'Borramos el estilo oEstilosPagina.Width & " .getByName("PageStyles") If oEstilosPagina.getStyleFamilies() oEstilosPagina = oEstilos.getActiveSheet() oEstilos = oDoc. dentro de la interfaz del usuario." & oEP. si llegas a borrar “todos” los estilos. las hojas nuevas. si los borras de la plantilla. pero por código si que se puede.removeByName( sEstilo ) MsgBox "Estilo borrado" Else MsgBox "El estilo no se borro" End If Else MsgBox "No existe el estilo de página" End If End Sub Ten cuidado con la macro anterior." & oEP. ya no podrás hace uso del menú Formato | Página.Height 'Margen superior e inferior MsgBox oEP.

. que.TopMargin = 2000 'Margen superior .style.ScaleToPagesY = 0 'Las que salgan de alto End With End If End Sub Observa las características indicadas dentro de la misma macro.star.getActiveSheet() oEstilos = oDoc. como dicen en mi pueblo -ni están todas las que son.getStyleFamilies() oEstilosPagina = oEstilos.CenterHorizontally = True 'Centrado horizontal del contenido . oEP ) 'Le damos formato With oEp .LeftMargin = 1000 'Margen izquierdo .RightMargin = 1000 'Margen derecho .hasByName( sEstilo ) Then oHojaActiva.createInstance( "com.ScaleToPagesX = 1 'Una página de ancho .. como podrás notar.BottomMargin = 2000 'Margen inferior . son bastantes. ni son todas las que están-.sun.PageStyle( sEstilo ) Else 'Creamos un nuevo estilo oEP = oDoc.insertByName( sEstilo..getByName("PageStyles") If oEstilosPagina.5 Dando formato sEstilo = "Videoteca" oDoc = ThisComponent oHojaActiva = oDoc.272 Dim Dim Dim Dim oEstilos As Object oEstilosPagina As Object sEstilo As String oEP As Object 6.getCurrentController.Height = 21590 'Alto . Las características establecidas son las mismas del menú Formato | Página. veamos las más comunes.IsLandscape = True 'Orientación de la página (horizontal) . .Width = 27940 'Ancho .PageStyle" ) 'Lo agregamos a la colección de estilos oEstilosPagina.

star. este valor esta determinado por la enumeración PageStyleLayout. es decir.IsLandscape = True End With With oEp .Height = 21590 . la segunda no: With oEp . entonces el ancho debe ser mayor que el alto.star.MIRRORED Valor 0 1 2 3 Valor en Interfaz Derecha e izquierda Solo izquierda Solo derecha Reflejado .PageStyleLayout. se refiere al tamaño del papel. hay que establecerlos en centésimas de milímetro. En el siguiente ejemplo.sun. si estableces las páginas derecha e izquierda igual o si las reflejas. cada 100 unidades es igual a 1 milímetro.IsLandscape = False End With 'Ancho 'Alto 'Orientación de la página (horizontal) 'Ancho 'Alto 'Orientación de la página (vertical) Los margenes también están en centésimas de milímetros y se ven afectados por el diseño de página (PageStyleLayout). la primer forma es correcta. si la estableces en falso (False) es decir vertical.Width = 27940 .PageStyleLayout.star.sun.Height = 21590 .style.star. tienes que usarlas correctamente en combinación con la propiedad Orientación (IsLandscape).LEFT com. es decir.PageStyleLayout.RIGHT com.sun. cuyos posibles valores son los siguientes: Propiedad PageStyleLayout com.Aprendiendo OOo Basic 273 El ancho (Width) y alto (Height) de la página. el alto debe ser mayor para que lo veas correctamente.ALL com. estas propiedades. es decir.style.style.PageStyleLayout.Width = 27940 .style. si estableces esta propiedad en verdadero (True) es decir horizontal.sun.

tenemos: .CenterHorizontally = True oEP. oEP.MIRRORED El Formato.NumberingType = 4 En Orientación de la hoja.style.274 6. centrado del contenido.PageStyleLayout = 0 oEP. pues eso es lo que realmente hacen estas propiedades. sus valores van del 0 al 5 y se corresponden al orden mostrado en la interfaz del usuario: oEP.PageStyleLayout.sun.PageStyleLayout = com. para el sentido horizontal (CenterHorizontally) y vertical (CenterVertically). lo correcta seria. son valores booleanos.5 Dando formato Puedes establecer el valor o la constante como en el siguiente ejemplo: oEP.CenterVertically = False En la ficha Borde. se refiere al estilo de numeración que se usará cuando se establece la numeración de páginas en el encabezado o en el pie de página.star.

0) oEP.TopBorder = oBordeLinea oBordeLinea.OuterLineWidth = 50 'Línea exterior .table.LeftBorder = oBordeLinea oBordeLinea.Color = RGB(200.200.star.Color = RGB(0.5 mm oEP. en el siguiente ejemplo. La opción Distancia al texto.0.LineDistance = 100 'Distancia entre líneas End With oEP. las unidades son centésimas de milímetros. usa la propiedad BorderDistance.0) .200. establecemos el borde de cada lado de un color diferente: Dim oBordeLinea As New com.Color = RGB(200.Aprendiendo OOo Basic 275 Para establecer el borde de la página.RightBorder = oBordeLinea Si quieres ver solo una línea.BottomBorderDistance = 1000 oEP. como si estuviera activada la casilla de verificación Sincronizar.200) oEP.200) oEP.BorderDistance = 500 'Para establecer cada borde diferente oEP.LeftBorderDistance = 1500 oEP. se refiere a la distancia entre los bordes y el contenido. usamos al estructura BorderLine. de nuevo.0.Color = RGB(0. establece solo una de las líneas. si quieres la mista distancia para los cuatro bordes.BorderLine With oBordeLinea .sun.TopBorderDistance = 500 oEP.BottomBorder = oBordeLinea oBordeLinea. ya sea la interior (InnerLineWidth) o la exterior (OuterLineWidth) y no establezcas la distancia entre ellas (LineDistance).RightBorderDistance = 2000 . si quieres un distancia diferente para cada lado. ya vista en otros capítulos.InnerLineWidth = 100 'Línea interior . usa las siguientes propiedades: 'Para sincronizar todos los bordes a .

La siguiente ficha se llama Fondo.sun.ShadowFormat.table.240) También podemos establecer una imagen de fondo.ShadowLocation.IsTransparent = False .star.Location = 4 . con las siguiente propiedades: With oSombra .table.ShadowFormat = oSombra 'Donde esta la sombra 'Ancho de la sombra 'Si es transparente 'Color La propiedad Location. aquí puedes ver a mi novia Marion Cotillard: .ShadowWidth = 1000 .BackColor = RGB(200.star.ShadowLocation.table.star.276 6.table. esta determinada por la siguiente enumeración: Propiedad ShadowLocation com. veamos su propiedad que es muy sencilla: oEP.sun.table.220.star.Color = RGB(180.sun.5 Dando formato La sombra se establece con la propiedad ShadowFormat.TOP_LEFT com.sun.ShadowLocation.180) End With oEp.star.BOTTOM_LEFT com.star.table.TOP_RIGHT com. que es una estructura com.BOTTOM_RIGHT Valor 0 1 2 3 4 Valor en Interfaz Ninguna Arriba a la izquierda Arriba a la derecha Abajo a la izquierda Abajo a la derecha Si estableces la propiedad de transparencia (IsTransparent) en verdadero (True).sun. la sombra no se vera.ShadowLocation.NONE com.ShadowLocation.sun.180.

Aprendiendo OOo Basic 277 La ruta de la imagen la establecemos con BackGraphicURL.BackGraphicLocation = 5 La posición (BackGraphicLocation) puede tomar valores de 1 a 11. y veamos la ultima ficha. en la opción Área. si no. y por supuesto que la imagen exista. 'Establecemos la ruta de la imagen oEP. es importante que le pases la ruta en formato URL. no te dará un error pero no te mostrará nada. cuida mucho el tamaño de las imágenes insertadas en documentos. que tiene las siguientes propiedades: . que es lo usual. Hoja. de acuerdo a la siguiente imagen. Nos saltamos el encabezado y pie de página que por su complejidad veremos al final. no requieres ni un gran tamaño ni una gran resolución. si se usara solo en pantalla.jpg" ) 'Y la posición donde la queremos oEP. te cubrirá la hoja completa con la imagen.BackGraphicURL = ConvertToURL( "/home/mau/marion.

Ten cuidado si lo usas en conjunto con el total de hojas.PrintDownFirst = True El valor de Primer núm. oEP. solo es visible en la vista preliminar y a la hora de imprimir.PrintFormulas = False .PrintDrawing = True . de página.278 6. en cada línea te muestro su equivalencia en la interfaz del usuario: With oEP . en tu interfaz de usuario no veras ningún cambio de tamaño.PrintCharts = True .5 Dando formato El orden de impresión (Orden de página) lo establecemos con la propiedad. un valor tipo entero (integer) entre 10 y 400. después hacia la derecha Falso (False) = De izquierda a derecha y hacia abajo oEP. pues te puede dar resultados algo extraños. se ajustará al valor mínimo o máximo más cercano. valor booleano que equivale a: • • Verdadero (True) = De arriba hacia abajo. toma en cuenta que este porcentaje de cambio. esta representado por la propiedad FirstPageNumber. si lo estableces fuera de estos limites.PrintAnnotations = False .PrintZeroValues = True End With 'Imprimir 'Imprimir 'Imprimir 'Imprimir 'Imprimir 'Imprimir 'Imprimir 'Imprimir las notas de celdas los Gráficos los Objetos de dibujo las formulas. valor tipo entero (integer) que establece un inicio de numeración de página diferente de uno. en vez del resultado la cuadrícula de las celdas encabezados de filas y columnas Objetos e imágenes los valores cero La escala de impresión nos puede resolver muy fácilmente problemas de impresión.PrintObjects = True .PrintHeaders = False . como mostrarte Hoja 5 de 3.PrintGrid = False . la primera opción es aumentar o disminuirla según nuestras necesidades con la propiedad PageScale. . PrintDownFirst.FirstPageNumber = 8 Las siguientes propiedades solo determinan que opciones se imprimirán y cuales no.

estamos forzando a usar exactamente una de ancho por las “necesarias” de alto.ScaleToPagesX = 1 oEp. son muy útiles en eso grandes listados de datos.ScaleToPages = 3 Por ultimo la que más me gusta. puedes establecer un determinado número de páginas de ancho por otro de alto.ScaleToPagesY = 2 Pero estas propiedades. por ejemplo: 'Establecemos la impresión en tres de ancho por dos de alto oEp. ya casi para terminar. pues si tienes muchos datos y estableces un valor de páginas muy pequeño.ScaleToPagesX = 3 oEp. el factor de escala se reducirá tanto que los datos no serán legibles. muy comunes donde tienes muchas filas y un determinado número de columnas que caben en el ancho de una hoja. 'Ajustamos a tres páginas de impresión oEP. veamos como modificar el encabezado y el pie de página de nuestro estilo de página. Lo primero que hay que hacer. es activarlos o desactivarlos según nuestras necesidades: .Aprendiendo OOo Basic 279 oEP.ScaleToPagesY = 0 Ahora si. si estableces el ancho en 1 y el alto en 0. ya sea vertical u horizontal. tienes que considerar un ajuste óptimo entre cantidad de datos y este valor. 'Establecemos la impresión en una de ancho por las que salgan de alto oEp.PageScale = 80 'Ajustamos al 80% de escala La segunda opción es ajustar a un determinado número de páginas.

una junto a otra.HeaderBodyDistance = 500 'Ajustamos la distancia del pie de página al cuerpo del documento¡ oEP. junto con la de Diseño de página vista anteriormente.HeaderHeight = 2000 + oEP. Para activarla o desactivarla. usamos: 'Establecemos la altura dinámica para el encabezado oEP.5 Dando formato Como son muy similares las opciones de encabezado y pie de página. esta propiedad es muy útil si establecemos por código el contenido de los encabezados o pies de página.FooterIsShared = True Después tenemos las opciones para establecer los margenes en centésimas de milímetros. se refiere a la distancia entre en el encabezado o pie de página y el contenido del documento: 'Ajustamos la distancia del encabezado al cuerpo del documento¡ oEP. es decir. establecer las opciones de encabezado o pie de página.280 6.FooterBodyDistance La propiedad Ajuste dinámico de la altura. este margen es distinto e independiente del margen de la página. 'Establecemos los margenes del encabezado en 3 cm oEP. Para activarla o desactivarla usamos: 'Lo desactivamos en el encabezado oEP. si esta activada.HeaderOn = True 'y desactivamos el pie de página oEp.FooterBodyDistance = 1000 La propiedad Altura. pero toma en cuenta que dentro de este valor. Para activarlos o desactivarlos usamos: 'Activamos el encabezado oEp. la medida introducida en la propiedad anterior no será tomada en cuenta.FooterOn = False La opción Contenido a la izquierda/derecha igual.HeaderBodyDistance 'Y del pie de página oEP. esta opción.HeaderLeftMargin = 3000 'Establecemos los margenes del pie de página en 2 cm oEP. el espacio disponible para introducir información. esta considerada la distancia entre el encabezado o pie de página y el cuerpo del documento.FooterRightMargin = 2000 oEP.HeaderDynamic = True . nos permite adaptar la altura al contenido del encabezado o pie de página.HeaderRightMargin = 3000 oEP. si esta desactivada. nos permite. debes de sumarle dicho valor. te iré mostrando sus propiedades. por lo que si quieres una distancia absoluta.FooterHeight = 1000 + oEP. de forma diferente para las páginas pares e impares de nuestra impresión.HeaderIsShared = False 'Lo activamos en el pie de página oEP. nos permiten configurar nuestra impresión como si de un libro se tratará. es la altura del encabezado o pie de página. como en: 'Ajustamos la altura del encabezado sumando el espacio al cuerpo oEP.FooterLeftMargin = 2000 La propiedad Espacio.

usamos: 'Establecemos la ruta de la imagen oEP.Color = RGB(150.Aprendiendo OOo Basic 'La desactivamos para el pie de página oEP.FooterDynamic = False 281 Igual que en el estilo de la página.FooterBackColor = RGB ( Rnd()*255. la forma es la misma.HeaderBackGraphicURL = ConvertToURL( "/home/mau/arriba.ShadowWidth = 500 . un color de fondo o una imagen.FooterShadowFormat = oSombra 'Donde esta la sombra 'Ancho de la sombra 'Color Y el color de fondo.HeaderRightBorder = oBordeLinea 'Cambiamos el color para el borde del pie de página With oBordeLinea .HeaderTopBorder = oBordeLinea oEP.jpg" ) 'Y la posición donde la queremos oEP.jpg" ) 'Y la posición donde la queremos oEP.HeaderBackColor = RGB ( Rnd()*255. tenemos las opciones de establecer.Rnd()*255 ) Para agregar una imagen.FooterBackGraphicLocation = 10 .Rnd()*255.HeaderBottomBorder = oBordeLinea oEP.OuterLineWidth = 80 'Línea exterior End With 'Establecemos el mismo para todos oEP.Location = 4 . 'Establecemos el color de fondo del encabezado de forma aleatoria oEP.FooterRightBorder = oBordeLinea Para la sombra aplica igual que en estilo de página: 'Configuramos la sombra With oSombra .150.FooterBottomBorder = oBordeLinea oEP.Rnd()*255.InnerLineWidth = 0 'Línea interior .FooterTopBorder = oBordeLinea oEP.Rnd()*255 ) 'Igual para el pie de página oEP.FooterLeftBorder = oBordeLinea oEP.Color = RGB(150.FooterBackGraphicURL = ConvertToURL( "/home/mau/abajo. una sombra.HeaderBackGraphicLocation = 10 'Ahora en el pie de página oEP.160.170) End With 'Para el encabezado oEP. un borde.0) End With 'Establecemos el mismo para todos oEP.HeaderLeftBorder = oBordeLinea oEP.0) . en el encabezado como en el pie de página.HeaderShadowFormat = oSombra 'Para el pie de página oEP.Color = RGB(0.150. lo que cambia. es a a las propiedades a que se establecen estas: 'Configuramos el tipo de borde With oBordeLinea .

tienes que establecer esta propiedad en vacía. el tipo de letra y su estilo de las tres áreas disponibles. de forma independiente. entonces solo tenemos que modificar el contenido de un lado.282 6. pero no te confundas. tres para el encabezado y tres para el pie de página. aun manipulando solo las de las páginas derechas. pero si esta desactivada.String 'Y de la derecha MsgBox oEP. como se ilustra en la siguiente imagen: Veamos como controlar el contenido de estas secciones. Lo primero que tenemos que tener presente. entonces tenemos que establecer.RightPageHeaderContent. oEP. tenemos acceso a las tres secciones mostradas en la imagen anterior. es muy rico. de la siguiente manera: . si esta propiedad esta seleccionada.HeaderBackGraphicURL = "" El contenido que puede llevar el encabezado o el pie de página.RightPageHeaderContent.String 'Del centro MsgBox oEP.String Vamos a cambiar el texto de mostrado en el ejemplo anterior de las seis secciones accedibles. de este modo. tanto de las páginas pares como de las impares.LeftText. estas propiedades son: • • • • RightPageHeaderContent LeftPageHeaderContent RightPageFooterContent LeftPageFooterContent Para el encabezado de las páginas derechas Para el encabezado de las páginas izquierdas Para el pie de página de las páginas derechas Para el pie de página de las páginas izquierdas Para nuestro ejemplo.CenterText. Contenido a la izquierda/derecha igual. daremos por hecho que las propiedades (HeaderIsShared y FooterIsShared) están seleccionadas.RightText. solo modificamos las propiedades de las páginas derechas.RightPageHeaderContent. que serán iguales a las de la izquierda. veamos como: 'Mostramos el contenido de la izquierda del encabezado MsgBox oEP. puedes establecer. dado que son las mismas opciones para uno y otro.5 Dando formato Para quitar una imagen agregada. tanto el encabezado o pie de página. es la opción vista anteriormente.

CharColor = RGB(0.0. veamos como insertarlos.FooterOn = True 'Accedemos al contenido del encabezado oContenido = oEP.Text.Text.String = "Esta es la derecha" & Chr(13) & "en el encabezado" oTexto.CharColor = RGB(0.getStyleFamilies() oEstilosPagina = oEstilos.0) oEP.0.255.CenterText() oTexto.Text.CharColor = RGB(0.255.RightPageFooterContent() oTexto = oContenido.LeftText() oTexto.HeaderOn = True oEP.String = "Esta es la izquierda" & Chr(13) & "en el encabezado" 'Y el color oTexto.RightPageFooterContent = oContenido End If End Sub Como sabes. campos como.CharColor = RGB(255.Text.Aprendiendo OOo Basic 283 Sub Dim Dim Dim Dim Dim Dim Dim FormatoPagina8() oDoc As Object oEstilos As Object oEstilosPagina As Object sEstilo As String oEP As Object oContenido As Object oTexto As Object sEstilo = "Videoteca" oDoc = ThisComponent oEstilos = oDoc.String = "Esta es la izquierda" & Chr(13) & "en el pie de página" oTexto. la hora.CenterText() oTexto.CharColor = RGB(255.0. .String = "Este es el centro" & Chr(13) & "en el encabezado" oTexto.Text.0.String = "Este es el centro" & Chr(13) & "en el pie de página" oTexto.255) oEP.RightText() oTexto.Text.RightPageHeaderContent = oContenido 'Lo mismo para el centro del encabezado oTexto = oContenido.hasByName( sEstilo ) Then oEP = oEstilosPagina.RightPageFooterContent = oContenido oTexto = oContenido.0) oEP. el número de página y el total de páginas.getByName("PageStyles") If oEstilosPagina.String = "Esta es la derecha" & Chr(13) & "en el pie de página" oTexto.CharColor = RGB(0.RightText() oTexto.0) oEP.255) oEP. hay una serie de campos predeterminados que podemos incluir en cualquier área de un encabezado o de un pie de página.RightPageHeaderContent() 'Accedemos a la parte izquierda oTexto = oContenido. la fecha.RightPageHeaderContent = oContenido 'Ahora modificamos el pie de página oContenido = oEP.LeftText() 'Cambiamos el texto oTexto.0) 'Reasignamos el contenido para ver los cambios oEP.RightPageHeaderContent = oContenido 'Y la derecha oTexto = oContenido.getByName( sEstilo ) oEP.RightPageFooterContent = oContenido oTexto = oContenido.

284

6.5 Dando formato

Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim

FormatoPagina9() oDoc As Object oEstilos As Object oEstilosPagina As Object sEstilo As String oEP As Object oContenido As Object oTexto As Object oCursor As Object oCampo As Object

sEstilo = "Videoteca" oDoc = ThisComponent oEstilos = oDoc.getStyleFamilies() oEstilosPagina = oEstilos.getByName("PageStyles") If oEstilosPagina.hasByName( sEstilo ) Then oEP = oEstilosPagina.getByName( sEstilo ) oEP.HeaderOn = True oEP.FooterOn = True 'Accedemos al contenido del pie de página oContenido = oEP.RightPageFooterContent() 'Creamos una instancia del campo Nombre del archivo oCampo = oDoc.createInstance ("com.sun.star.text.TextField.FileName") 'Limpiamos las tres secciones oContenido.LeftText.String = "" oContenido.CenterText.String = "" oContenido.RightText.String = "" 'Creamos un cursor en esa sección oCursor = oContenido.LeftText.createTextCursor() 'Nos movemos al final oCursor.gotoEnd( False ) 'Insertamos el campo oContenido.LeftText.insertTextContent (oCursor, oCampo, True) 'Creamos el campo Número de página oCampo = oDoc.createInstance ("com.sun.star.text.TextField.PageNumber") 'Creamos un cursor en la sección central oCursor = oContenido.CenterText.createTextCursor() oCursor.gotoEnd( False ) 'Nos movemos oCursor.String = "Página " 'Insertamos un texto oCursor.gotoEnd( False ) 'Nos movemos 'Insertamos el campo oContenido.CenterText.insertTextContent (oCursor, oCampo, True) oCursor.gotoEnd( False ) 'Nos movemos oCursor.String = " de " 'Insertamos más texto oCursor.gotoEnd( False ) 'Nos movemos 'Creamos el campo, Total de páginas oCampo = oDoc.createInstance ("com.sun.star.text.TextField.PageCount") 'Lo insertamos oContenido.CenterText.insertTextContent (oCursor, oCampo, True) 'Creamos el campo de Fecha oCampo = oDoc.createInstance ("com.sun.star.text.TextField.DateTime") oCampo.IsDate = True 'Es una fecha 'Creamos un cursor en la sección derecha oCursor = oContenido.RightText.createTextCursor() oCursor.gotoEnd( False ) 'Nos movemos 'Insertamos el campo oContenido.RightText.insertTextContent (oCursor, oCampo, True) 'Actualizamos el contenido del pie de página oEP.RightPageFooterContent = oContenido End If End Sub

Aprendiendo OOo Basic

285

6.5.5

Formato condicional

El formato condicional nos permite, de acuerdo al resultado de una expresión o formula, formatear una celda con diferentes estilos, esto es importante, solo puedes aplicar estilos de celdas existentes, por lo que asegurate de tener algunos de prueba. Puedes establecer de una a tres condiciones, que se evaluarán una a una, veamos una primer condición sencilla:
Sub Dim Dim Dim Dim Dim FormatoCondicional1() oDoc As Object oHojaActiva As Object oRango As Object oFC As Object mCondiciones(3) As New com.sun.star.beans.PropertyValue

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oRango = oHojaActiva.getCellRangeByName( "A1" ) 'Accedemos al formato condicional oFC = oRango.getPropertyValue("ConditionalFormat") 'Limpiamos cualquier formato existente, si no lo haces, las condiciones 'se agregarán como segunda o terce condición según corresponda oFC.clear() 'Establecemos las condiciones del formato mCondiciones(0).Name = "Operator" 'El operador = mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.EQUAL mCondiciones(1).Name = "Formula1" 'El valor de la formula 1, es decir, si la celda = 100 mCondiciones(1).Value = "100" mCondiciones(2).Name = "StyleName" 'En caso de que se cumpla la condiciones, aplicamos el estilo Resaltado1, 'recuerda que debes de crearlo previamente mCondiciones(2).Value = "Resaltado1" 'Agregamos las condiciones al formato oFC.addNew ( mCondiciones() ) 'Reestablecemos la propiedad para que surtan efecto los cambios oRango.setPropertyValue( "ConditionalFormat", oFC ) End Sub

Acabamos de agregar, a la celda A1, la condición de que, si el valor de la celda es igual a 100, le establezca el estilo de celda Resaltado1, si el estilo no existe, no te dará ningún error, simplemente no aplicará ningún formato, verifiquemos que la agrego correctamente:

286

6.5 Dando formato

Ahora intentemos, agregar dos condiciones en vez de una, por ejemplo, a la celda C1, si es igual a 50 un estilo y si es mayor a 50 otro estilo, que quedaría así:
Sub Dim Dim Dim Dim Dim FormatoCondicional2() oDoc As Object oHojaActiva As Object oRango As Object oFC As Object mCondiciones(3) As New com.sun.star.beans.PropertyValue

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oRango = oHojaActiva.getCellRangeByName( "C1" ) 'Accedemos al formato condicional oFC = oRango.getPropertyValue("ConditionalFormat") oFC.clear() mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.EQUAL mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "50" mCondiciones(2).Name = "StyleName" mCondiciones(2).Value = "Roja" oFC.addNew ( mCondiciones() ) mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.GREATER mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "50" mCondiciones(2).Name = "StyleName" mCondiciones(2).Value = "Azul" oFC.addNew ( mCondiciones() ) 'Reestablecemos la propiedad para que surtan efecto los cambios oRango.setPropertyValue( "ConditionalFormat", oFC ) End Sub

Observa la matriz de propiedades mCondiciones, esta forma de establecer pares de propiedades con un nombre (Name) y un valor (Value), ya la hemos usado anteriormente por lo que no te debe ser desconocida, la propiedad operador (Operator), es una enumeración que puede tener los siguiente valores: com.sun.star.sheet.ConditionOperator
com.sun.star.sheet.ConditionOperator.NONE com.sun.star.sheet.ConditionOperator.EQUAL com.sun.star.sheet.ConditionOperator.NOT_EQUAL com.sun.star.sheet.ConditionOperator.GREATER com.sun.star.sheet.ConditionOperator.GREATER_EQUAL com.sun.star.sheet.ConditionOperator.LESS com.sun.star.sheet.ConditionOperator.LESS_EQUAL com.sun.star.sheet.ConditionOperator.BETWEEN com.sun.star.sheet.ConditionOperator.NOT_BETWEEN com.sun.star.sheet.ConditionOperator.FORMULA

Valor
0 1 2 3 4 5 6 7 8 9

Valor en Interfaz
Ninguna Igual Distinta de Mayor que Mayor o igual Menor que Menor o igual Entre No entre Formula

Aprendiendo OOo Basic

287

Veamos como establecer las condiciones para evaluar entre un par de valores:
Sub Dim Dim Dim Dim Dim FormatoCondicional3() oDoc As Object oHojaActiva As Object oRango As Object oFC As Object mCondiciones(3) As New com.sun.star.beans.PropertyValue

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oRango = oHojaActiva.getCellRangeByName( "B1:B10" ) 'Accedemos al formato condicional oFC = oRango.getPropertyValue("ConditionalFormat") oFC.clear() mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.BETWEEN mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "0" mCondiciones(2).Name = "Formula2" mCondiciones(2).Value = "5" mCondiciones(3).Name = "StyleName" mCondiciones(3).Value = "Reprobado" oFC.addNew ( mCondiciones() ) mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.BETWEEN mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "6" mCondiciones(2).Name = "Formula2" mCondiciones(2).Value = "8" mCondiciones(3).Name = "StyleName" mCondiciones(3).Value = "Suficiente" oFC.addNew ( mCondiciones() ) mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.BETWEEN mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "9" mCondiciones(2).Name = "Formula2" mCondiciones(2).Value = "10" mCondiciones(3).Name = "StyleName" mCondiciones(3).Value = "Excelente" oFC.addNew ( mCondiciones() ) 'Reestablecemos la propiedad para que surtan efecto oRango.setPropertyValue( "ConditionalFormat", oFC ) End Sub

Observa que ahora hemos usado la propiedad Formula1 y Formula2 para dar el intervalo de valores que nos interesa evaluar, entre 0 y 5, entre 6 y 8 y por ultimo entre 9 y 10, también observa que ahora, en vez de aplicar el formato condicional a una sola celda, lo hemos hecho a un rango de celdas, en este caso, “B1:B10. Donde realmente me parece, se ve la nobleza del formato condicional, es con el uso de formulas, pues nos da un margen amplísimo para establecer las condiciones, por ejemplo, supongamos que tenemos un rango de celdas con fechas y queremos que los sábados y domingos se distingan de los demás días, crea dos estilos de celda nuevos, uno para los sábados y otro para los domingos, creamos su formato condicional con el siguiente ejemplo:

288

6.5 Dando formato

Sub Dim Dim Dim Dim Dim

FormatoCondicional4() oDoc As Object oHojaActiva As Object oRango As Object oFC As Object mCondiciones(3) As New com.sun.star.beans.PropertyValue

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oRango = oHojaActiva.getCellRangeByName( "I2:J32" ) 'Accedemos al formato condicional oFC = oRango.getPropertyValue("ConditionalFormat") oFC.clear() mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.FORMULA mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "WEEKDAY(A1)=7" mCondiciones(2).Name = "StyleName" mCondiciones(2).Value = "Sabados" oFC.addNew ( mCondiciones() ) mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.FORMULA mCondiciones(1).Name = "Formula1" mCondiciones(1).Value = "WEEKDAY(A1)=1" mCondiciones(2).Name = "StyleName" mCondiciones(2).Value = "Domingos" oFC.addNew ( mCondiciones() ) 'Reestablecemos la propiedad para que surtan efecto oRango.setPropertyValue( "ConditionalFormat", oFC ) End Sub

Observa como hemos establecido el valor (Value) de la propiedad Formula1, estamos haciendo uso de una función incorporada DIASEM (WEEKDAY) de Calc, que nos devuelve el día de la semana que corresponda a la fecha pasada como argumento; Domingo=1, Lunes=2, etc, nota como, al ser una función de Calc, si esta lleva argumentos, forzosamente hay que proporcionárselos, observa que nuestro rango empieza en I2 y a la función le estamos pasando la celda A1, no te confundas, le decimos que es la celda A1 por que la referencia es “relativa”, el valor que queremos evaluar, es el de la misma celda I2, I3, etc, el formato condicional, ajustará correctamente las referencias a cada celda, por supuesto, compruebalo. Vamos a crear un formato condicional un poco más elaborado, pero más divertido. Observa el par de listas en la imagen siguiente:

Aprendiendo OOo Basic

289

La tarea, es hacer un formato condicional que nos resalte los meses que faltan en una y otra lista. Por supuesto, antes de ver la solución, trata de resolverlo por ti mismo, primero te muestro la imagen con el resultado, para que veas que es posible, después viene la macro con la solución que no tienes que ver hasta que intentes resolverlo, confío en ti. Observa como hemos satisfecho la condición, están resaltados con fondo gris, fuente azul y negritas, los meses que “no” están en cada lista, por supuesto, esto funciona con cualquier par de listas.

Ahora la solución:
Sub Dim Dim Dim Dim Dim FormatoCondicional5() oDoc As Object oHojaActiva As Object oRango As Object oFC As Object mCondiciones(3) As New com.sun.star.beans.PropertyValue

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oRango = oHojaActiva.getCellRangeByName( "B2:B9" ) oFC = oRango.getPropertyValue("ConditionalFormat") oFC.clear() 'Condiciones para la primer lista mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.FORMULA mCondiciones(1).Name = "Formula1" 'Observa como ahora usamos referencia absolutas mCondiciones(1).Value = "COUNTIF($D$2:$D$9;A1)=0" mCondiciones(2).Name = "StyleName" mCondiciones(2).Value = "Faltante" oFC.addNew ( mCondiciones() ) 'Reestablecemos la propiedad para que surtan efecto oRango.setPropertyValue( "ConditionalFormat", oFC ) 'Para la segunda lista oRango = oHojaActiva.getCellRangeByName( "D2:D9" ) oFC = oRango.getPropertyValue("ConditionalFormat") oFC.clear() mCondiciones(0).Name = "Operator" mCondiciones(0).Value = com.sun.star.sheet.ConditionOperator.FORMULA mCondiciones(1).Name = "Formula1" 'Observa como ahora usamos referencia absolutas mCondiciones(1).Value = "COUNTIF($B$2:$B$9;A1)=0" mCondiciones(2).Name = "StyleName" mCondiciones(2).Value = "Faltante"

290
oFC.addNew ( mCondiciones() ) 'Reestablecemos la propiedad para que surtan efecto oRango.setPropertyValue( "ConditionalFormat", oFC ) End Sub

6.5 Dando formato

Y con esto terminamos el tema de los formatos, que, te habrás dado cuenta, muchas veces consume mucho más código que otras necesidades. ¡¡Feliz programación!!

6.6

Imprimiendo

La impresión en OpenOffice.org es sumamente sencilla, pero debes de recordar los elementos que están implicados en ella, por ejemplo, el área de impresión, la impresora disponible, el estilo de página establecido, entre otros elementos que veremos en este capítulo. El método usado para imprimir es print y se usa de la siguiente manera:
Sub Imprimiendo1() Dim mOpc() ThisComponent.Print( mOpc() ) End Sub

Observa que simple, pero !cuidado¡, la línea anterior podría enviarte a imprimir una gran cantidad de hojas, dependiendo de la configuración actual que tengas, usala con cuidado pero mejor aun, controla todas las opciones de impresión que aprenderemos aquí. Para mostrar el nombre de la impresora activa, usamos:
Sub Imprimiendo2() Dim mDI() 'Mostramos el nombre de la impresora activa mDI = ThisComponent.getPrinter() MsgBox mDI(0).Value End Sub

El nombre mostrado dependerá del nombre registrado de tu impresora en tu S.O., para cambiar la impresora a usar, usamos:
Sub Imprimiendo3() 'Matriz para el descriptor de impresión

Aprendiendo OOo Basic

291

Dim mDI(2) As New com.sun.star.beans.PropertyValue Dim mOpc() 'Cambiamos la impresora para imprimir mDI(0).Name = "Name" mDI(0).Value = "HP_PSC_2200" 'Cambiamos la orientación 0 = Vertical, 1 = Horizontal mDI(1).Name = "PaperOrientation" mDI(1).Value = 1 'Establecemos las opciones de la impresora ThisComponent.setPrinter( mDI ) 'Enviamos a imprimir ThisComponent.Print( mOpc() ) End Sub

Si la impresora no esta registrada con dicho nombre, el lenguaje no te dará ni mostrará un error, así que asegurate de usar el nombre correcto. Si bien podemos cambiar la orientación del papel para imprimir desde este descriptor, mi recomendación es que solo uses el descriptor de impresión para cambiar de impresora, y todas las demás opciones las establezcas en un estilo de página donde tenemos más riqueza de opciones y parámetros. En las opciones de impresión tienes algunas características para controlar la cantidad de copias, el orden y las páginas que deseamos imprimir:
Sub Imprimiendo4() 'Matriz para las opciones de impresión Dim mOpc(2) As New com.sun.star.beans.PropertyValue Dim mDI(2) As New com.sun.star.beans.PropertyValue mDI(0).Name = "Name" mDI(0).Value = "HP_LaserJet" mDI(1).Name = "PaperOrientation" mDI(1).Value = com.sun.star.view.PaperOrientation.PORTRAIT mDI(2).Name = "PaperFormat" mDI(2).Value = com.sun.star.view.PaperFormat.LETTER ThisComponent.setPrinter( mDI ) 'El número de copias mOpc(0).Name = "CopyCount" mOpc(0).Value = 1 'Si se imprimen en juegos mOpc(1).Name = "Collate" mOpc(1).Value = True 'Las páginas a imprimir mOpc(2).Name = "Pages" mOpc(2).Value = "1" 'Enviamos a imprimir ThisComponent.Print( mOpc() ) End Sub

De estas opciones, la propiedad Pages, se puede establecer de las siguientes maneras:
• • • •

Una sola página Varias páginas Un rango de páginas Combinación de las anteriores

1 3,8,12 5-10 4,7,10-15

292

6.6 Imprimiendo

Asegurate de pasarle el valor a esta propiedad como una cadena de texto, es decir, entre comillas y el valor de la propiedad CopyCount, como un valor entero, si no, te dará un error al querer establecer las opciones de impresión. Observa que en descriptor de impresión, hemos establecido el formato del papel, para nuestro ejemplo en tamaño carta (LETTER), de nuevo, si no tienes problemas con tu impresión, el tamaño del papel es mejor establecerlo en el estilo de página, en mi experiencia, algunas impresoras “rebeldes”, se niegan a tomar el formato de papel establecido en el formato de página, por ello, se tiene que establecer en el descriptor de impresión, te sugiero hacer tus pruebas respectivas y si no es necesario, solo establece el tamaño en el estilo de página. Los valores que puede tomar esta propiedad son: com.sun.star.view.PaperFormat
com.sun.star.view.PaperFormat.A3 com.sun.star.view.PaperFormat.A4 com.sun.star.view.PaperFormat.A5 com.sun.star.view.PaperFormat.B5 com.sun.star.view.PaperFormat.LETTER com.sun.star.view.PaperFormat.LEGAL com.sun.star.view.PaperFormat.TABLOID com.sun.star.view.PaperFormat.USER

Valor
0 1 2 3 4 5 6 7

Valor en Interfaz
A3 A4 A5 B5 Carta Oficio Doble carta Usuario

Nota que hasta ahora, hemos usado el objeto ThisComponent, es decir, el objeto desde donde se llama a la macro, el método Print esta presente desde cualquier archivo de Calc, por lo que puedes invocarlo desde cualquiera. En las hojas de calculo, tenemos la posibilidad de definir áreas de impresión, que no son más que rangos de celdas con un nombre, pero con algunas características que los hacen especiales, por ejemplo, la posibilidad de repetir una o varias fila o columnas en cada hoja de la impresión. Las opciones de las áreas de impresión que aprenderemos a usar y manipular, son las mismas presentes en el menú Formato | Imprimir Rangos ->. Para obtener las áreas de impresión actuales usamos:
Sub Imprimiendo5() Dim mAI() Dim sMensaje As String mAI = ThisComponent.getCurrentController.getActiveSheet.getPrintAreas() sMensaje = "La hoja activa tiene " & Format( UBound( mAI() ) + 1 ) & " áreas de impresión" MsgBox sMensaje End Sub

Observa que estamos obteniendo (getPrintAreas) las áreas de impresión desde la hoja activa pues este método esta implementado en las hojas del archivo, este método te devolverá una matriz con todos las áreas de impresión establecidas en la hoja desde donde se invoque, cada elemento de esta matriz, tendrá la estructura de la dirección de un rango de celdas, visto múltiples veces a lo largo de este libro, definido por com.sun.star.table.CellRangeAddress. En el siguiente ejemplo, mostramos la dirección de cada área de impresión si las hay:

Aprendiendo OOo Basic

293

Sub Dim Dim Dim

Imprimiendo6() mAI() sMensaje As String co1 As Integer

mAI = ThisComponent.getCurrentController.getActiveSheet.getPrintAreas() If UBound( mAI() ) > -1 Then For co1 = LBound(mAI) To UBound(mAI) sMensaje = DireccionRango( mAI(co1) ) MsgBox sMensaje Next Else MsgBox "No hay área de impresión definidas en la hoja activa" End If End Sub Function DireccionRango( DirRango As Object) As String Dim sTmp As String Dim oRango As Object oRango = ThisComponent.getCurrentController.getActiveSheet.getCellRangeByPosition( _ DirRango.StartColumn, DirRango.StartRow, DirRango.EndColumn, DirRango.EndRow) sTmp = oRango.getSpreadsheet.getName() & "." & _ oRango.getColumns().getByIndex(0).getName() & _ oRango.getRangeAddress.StartRow + 1 & ":" & _ oRango.getColumns().getByIndex(oRango.getColumns().getCount()-1).getName() & _ oRango.getRangeAddress.EndRow + 1 DireccionRango = sTmp End Function

Si no tienes ningún área de impresión definida, Calc tomará todas las hojas con datos como disponibles para impresión, mi recomendación es que siempre establezcas tus áreas de impresión, esto te permite tener siempre el control de lo que se imprimirá, además de poder combinar áreas de diferentes hojas que al ser impresas quedan como si de un solo estilo se tratara. Para borrar las áreas de impresión de una hoja, usamos:
Sub Imprimiendo7() Dim mAI() 'Borramos todas las áreas de impresión de la hoja activa ThisComponent.getCurrentController.getActiveSheet.setPrintAreas( mAI() ) End Sub

Observa como simplemente pasándole una matriz vacía, todas las áreas de impresión serán borrados, nota que ahora estamos usando el método setPrintAreas, si la hoja no tiene ningún área actual, este método no te dará error. Como supongo lo habrás deducido, para agregar áreas de impresión, solo tenemos que llenar dicha matriz con direcciones de rango validos como en el siguiente ejemplo:
Sub Imprimiendo8() Dim mAI(1) As New com.sun.star.table.CellRangeAddress 'Rango A1:E5 mAI(0).Sheet = 0 mAI(0).StartColumn = 0 mAI(0).StartRow = 0

en la propiedad Sheet. en verdadero (True). de forma predeterminada.CellRangeAddress oHojaActiva = ThisComponent. no serán tomadas en cuenta. para nuestro ejemplo.setPrintAreas( mAI() ) End Sub 6. que. si estableces setPrintTitleRows. la propiedad setPrintTitleRows.EndRow = 15 'Agregamos las áreas de impresión ThisComponent.StartRow = 0 mAI(0).setPrintAreas( mAI() ) 'Le decimos que queremos títulos de fila a repetir oHojaActiva. se establece en verdadero (True). vamos a establecer las filas que queremos repetir en cada hoja de impresión: Sub Dim Dim Dim Imprimiendo9() oHojaActiva As Object mAI(0) As New com.sun. esto no afecta el “destino” de las áreas de impresión. Para repetir las columnas es similar: .sun. deben estar dentro de rangos válidos y en el orden correcto.setTitleRows( oFilR ) End Sub Nota que solo hacemos uso de la fila de inicio y fin. del mismo modo. Cuando haces uso del método setTitleRows.CellRangeAddress oFilR As New com.294 mAI(0).EndColumn = 4 mAI(0). si estableces en setTitleRows.EndColumn = 3 mAI(0).EndRow = 4 'Rango K11:P16 mAI(1).table.getActiveSheet.table. Ahora. tanto de columna como de fila. la fila 1 será establecida. en esta misma propiedad puse 1.StartColumn = 10 mAI(1). te sustituye las existentes. pero no estableces un rango con setTitleRows.6 Imprimiendo Si. tu tarea es modificar la macro para agregar nuevas sin borrar las existentes.EndRow = 18 oHojaActiva.getCurrentController.star.setPrintTitleRows(True) 'Establecemos el rango de filas oFilR. se establecerá la fila 1 como titulo a repetir. pero como ya sabes manejar matrices.Sheet = 0 mAI(0). ya lo notaste.StartColumn = 0 mAI(0).StartRow = 2 OFilR.EndColumn = 15 mAI(1). puse 0 y en el segundo rango. automáticamente. también. Esta forma de agregar áreas de impresión. pues estas se agregarán a la hoja desde donde es invocado el método setPrintAreas. es la hoja activa. pero no esta de más que lo establezcas primero.getActiveSheet() mAI(0). nota que en el primer rango. en teoría. no esta de más recordarte que los valores de inicio y fin. asegurate de establecer un rango de filas valido. una estructura vacía. hice un poco de “trampita”.EndRow = 3 'Las establecemos oHojaActiva.StartRow = 10 mAI(1).getCurrentController. las demás propiedades de la estructura CellRangeAddress.Sheet = 1 mAI(1).star.

getCurrentController.EndColumn = 1 oTitulosR. tu puedes establecer la fila o columna que desees como un salto de página manual.getByIndex(4).getActiveSheet() oTitulosR.getByIndex(4).getActiveSheet() 'Quitamos el salto de página . si vas a repetir filas y columnas. los métodos respectivos omitirán las propiedades no necesarias para ellos.EndColumn = 1 'Las establecemos oHojaActiva.sun. estamos insertando un salto de página manualmente. por supuesto.getCurrentController. IsStartOfNewPage.EndRow = 2 'Los establecemos oHojaActiva. Salto de fila y Salto de columna.setTitleColumns( oTitulosR ) oHojaActiva.StartRow = 2 oTitulosR.getActiveSheet() 'Le decimos que queremos titulos de columna a repetir oHojaActiva. veras que tienes dos opciones.table. al establecer esta propiedad en verdadero (True).getActiveSheet() 'Establecemos la fila 5 como salto de página oHojaActiva. solo tienes que establecerla en falso (False): Sub Imprimiendo13() Dim oHojaActiva As Object oHojaActiva = ThisComponent. veamos como hacerlo.table.sun. como en: Sub Imprimiendo11() Dim oHojaActiva As Object Dim oTitulosR As New com. estas forzando un salto de página.getRows. para quitarlo.star.setTitleRows( oTitulosR ) End Sub Si vas al menú Insertar | Salto Manual ->.CellRangeAddress oHojaActiva = ThisComponent.StartColumn = 0 OColR. lo cual verificamos con la propiedad.setTitleColumns( oColR ) End Sub Estos métodos tienen las mismas consideraciones vistas para las filas.IsManualPageBreak Then MsgBox "La fila es un salto de página" End If End Sub Nota como estamos accediendo a una fila (la 5) y la establecemos como inicio de una nueva página con la propiedad.CellRangeAddress oHojaActiva = ThisComponent.Aprendiendo OOo Basic 295 Sub Imprimiendo10() Dim oHojaActiva As Object Dim oColR As New com.star. puedes hacer uso de una sola estructura CellRangeAddress. IsManualPageBreak.IsStartOfNewPage = True 'Verificamos que se haya establecido If oHojaActiva. Sub Imprimiendo12() Dim oHojaActiva As Object oHojaActiva = ThisComponent.StartColumn = 1 oTitulosR.setPrintTitleColumns(True) 'Establecemos el rango de Columnas A:B oColR.getCurrentController. es decir.getRows.getCurrentController.

getActiveSheet() 'Obtenemos todos los saltos de página.ManualBreak Next co1 End Sub .IsStartOfNewPage = True 'Lo verificamos If oHojaActiva.6 Imprimiendo Lo mismo para las columnas: Sub Imprimiendo14() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getRows.getCurrentController. tenemos dos tipos de saltos de página.getByIndex(2).IsManualPageBreak Then MsgBox "La columna NO es un salto de página" End If End Sub En las hojas de Calc.getCurrentController.ManualBreak Next co1 'Ahora los de columna mSP = oHojaActiva.IsManualPageBreak Then MsgBox "La columna es un salto de página" End If End Sub Sub Imprimiendo15() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getColumnPageBreaks() For co1 = LBound( mSP ) To UBound( mSP ) MsgBox "El salto de página esta en la columna: " & mSP(co1). de acuerdo.getByIndex(2). al formato de la página y su contenido. mostramos todos los saltos de página.getByIndex(4). de la hoja activa mSP = oHojaActiva.296 oHojaActiva.getByIndex(2).Position + 1 & Chr(13) & _ "Es salto manual: " & mSP(co1). con el siguiente ejemplo. los segundos los establecemos nosotros.getColumns. por filas.IsStartOfNewPage = False 'Lo verificamos If Not oHojaActiva.getColumns.getRowPageBreaks() 'Mostramos los salto de fila For co1 = LBound( mSP ) To UBound( mSP ) MsgBox "El salto de página esta en la línea: " & mSP(co1).IsManualPageBreak Then MsgBox "La fila NO es un salto de página" End If End Sub 6.getColumns.getRows.getActiveSheet() 'Establecemos un salto de página de columna oHojaActiva.getByIndex(4).getColumns. los primeros se insertan automáticamente.getByIndex(2).IsStartOfNewPage = False 'Lo verificamos If Not oHojaActiva. tanto de fila como de columna que tenga la hoja activa e informamos si es manual o no: Sub Dim Dim Dim Imprimiendo16() oHojaActiva As Object mSP() co1 As Integer oHojaActiva = ThisComponent.Position + 1 & Chr(13) & _ "Es salto manual: " & mSP(co1).getActiveSheet() 'Quitamos un salto de página de columna oHojaActiva.getCurrentController. los automáticos y los manuales.

se seleccionaran las hojas que los contienen.1 Step 2 oSel. y agregarlos a un contenedor de rangos que ya aprendimos a usar. procura no tener una selección muy grande y sobre todo no mandar a imprimir que te podrían salir muchas hojas. "".getRows. 0.getCurrentSelection() 'Insertamos un salto de página cada dos filas For co1 = 2 To oSel. ".sun.. al seleccionar rangos de diferentes hojas. puede ser solo una celda.getByIndex(co1). se enviaba todas las hojas del documento. de forma predeterminada. como creo. y seleccionarlos.removeAllManualPageBreaks() End Sub El siguiente ejemplo. solo se envían las hojas seleccionadas.IsStartOfNewPage = True Next End Sub Por ultimo. esto siempre lo puedes cambiar desde el cuadro de dialogo imprimir en el menú Archivo | Imprimir.executeDispatch(oDocF. los saltos de páginas. que no me gusta pero por ahora es la única forma que conozco: Sub Imprimiendo19() Dim oDocF As Object Dim oDH As Object oDocF = ThisComponent. para ver tu vista previa. Array()) End Sub En versiones anteriores de OOo.getCount() . te inserta un salto de página cada 2 filas en la selección actual.getActiveSheet() 'Quitamos TODOS los saltos de páginas manuales oHojaActiva. después. ahora.Frame oDH = createUnoService("com. claro. debe ser.getCurrentController. podemos enviar a imprimir como en el siguiente ejemplo: Sub Dim Dim Dim Dim Imprimiendo20() oDoc As Object oHojas As Object mOpc() oRangos As Object oDoc = ThisComponent oHojas = oDoc. tanto de fila como de columna. cuando enviabas a imprimir.star. ve el resultado en tu vista preliminar: Sub Imprimiendo18() Dim oSel As Object Dim co1 As Integer oSel = ThisComponent.DispatchHelper") 'Mostramos la vista previa oDH.. con el siguiente método: Sub Imprimiendo17() Dim oHojaActiva As Object oHojaActiva = ThisComponent..getRows.Aprendiendo OOo Basic 297 Puedes quitar “todos”.getSheets() 'Creamos el contender para los rangos . solo tienes que seleccionar un rango de cada una de ellas. como consecuencia.getCurrentController.frame.uno:PrintPreview". Para seleccionar varias hojas a imprimir. usa el siguiente método.

SheetCellRanges") 6. según mi experiencia.addRangeAddress( oHojas.sheet. veras que tema tan interesante es. con los que puedes definir en el cuadro de nombres de la barra de formulas.getRangeAddress() . estamos seleccionando dichas hojas oDoc. automatizando estos procesos.298 oRangos = oDoc. ya que son distintos. presentes en Calc.False ) 'Al seleccionar las celdas de diferentes hojas.getCellRangeByName("A1"). Trata de que tus datos sean “consistentes”.print( mOpc() ) End Sub La recomendación general. entre esta y los datos. Así mismo. es decir. pero una base de datos se hace para llenarse de datos. son áreas rectangulares de rangos de celdas delimitados por. efectivamente se capturen números.getRangeAddress() . son las presentes en el menú Datos.getRangeAddress() . es mucho mejor tenerla. campo. y cada fila de estos. es.addRangeAddress( oHojas. ahora. los registros. de tarea.addRangeAddress( oHojas. y no es gratuito. esto no es indispensable. las herramientas disponibles para trabajar con datos estructurados de esta manera. es recomendable. una fila y una columna en blanco. registros. imagínate lo que se puede hacer. con lo cual. se establecen los “títulos de campo”.sun. a las cuales se les establece un nombre y tienen características especiales que facilitan su uso como si de una base de datos se tratara.getByIndex(7). sin hacer uso de macros.False ) oRangos. no dejar ninguna fila en blanco. También. En la actualidad hay una amplia fuente de información para una buena construcción de tus bases de datos. así como el estilo de página con la configuración deseada. El uso de hojas de calculo con datos tratados como bases de datos. lo podemos llamar. de nuevo. aunque esta primer fila no es indispensable. al menos.star. Si bien este libro no es de bases de datos explícitamente. que todos sus campos contienen datos. te ayudará mucho recordar que cada columna de tu rango de datos. es decir. el uso más cotidiano dado a esta herramienta. puede ser cualquier celda oRangos.getCellRangeByName("A1").getCurrentController. la impresión se facilitará enormemente.7 Rangos de datos Los rangos de datos.getCellRangeByName("A1"). busca algo acerca del siguiente tema: “normalización de bases de datos”. de la interfaz del usuario. No confundas estos nombres.getByIndex(8). esto quiere decir que si una columna (campo) lo llamas Edad. en la primer fila de estos.select( oRangos ) 'Enviamos a imprimir oDoc. 6. es bastante amplio. o fechas si la calculas. poderoso y versátil. las filas. es que siempre establezcas tus áreas de impresión correctamente. es mejor si están completos. Las mayor parte de las opciones que estudiaremos en este capitulo. . normalmente en un formato diferente del resto de los datos.6 Imprimiendo 'Agregamos la primer celda de cada hoja.createInstance("com.False ) oRangos. Tampoco es recomendable dejar filas completas en blanco.getByIndex(6).

en la primer hoja del documento.getImplementationNAme = "ScCellRangeObj" Then 'Solicitamos el nuevo nombre sNombre = Trim( InputBox("Escribe el nombre del nuevo rango") ) 'Si no esta vacío If sNombre <> "" Then oRangosBD = oDoc.MoveCells = True 'Para que se actualice al insertar o eliminar celdas . en el rango A1:D24.table.getRangeAddress() ) oRBD = oRangosBD. Sub Dim Dim Dim Dim Dim RangoDeDatos1() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDir As New com.EndColumn = 3 'La columna final .Sheet = 0 'La hoja .DataBaseRanges() 'Verificamos que no exista el nombre If Not oRangosBD.CellRangeAddress oDoc = ThisComponent oSel = oDoc.sun.addNewByName( sNombre.getByName( sNombre ) With oRBD .DataBaseRanges() 'El nombre del nuevo rango sNombre = "Direcciones" 'La dirección del nuevo rango With oDir .sun.star. solicitamos al usuario el nombre del rango de datos y tomamos la selección actual como dirección para el nuevo rango de datos.StartColumn = 0 'La columna de inicio .getCurrentSelection() 'Nos aseguramos de que sea un rango de celdas If oSel. en el siguiente ejemplo. oDir ) 'Regresamos el rango recién agregado oRBD = oRangosBD.1 Definiendo rangos En el siguiente ejemplo.getByName( sNombre ) With oRBD .Aprendiendo OOo Basic 299 6. también.EndRow = 23 'La fila final End With 'Lo agregamos a la colección oRangosBD.star. verificamos que no exista el nuevo nombre: Sub Dim Dim Dim Dim Dim Dim RangoDeDatos2() oDoc As Object oSel As Object oRangosBD As Object sNombre As String oRBD As Object oDir As New com. oSel.hasByName( sNombre ) Then 'Y lo agregamos. Observa como tomamos la dirección de la selección oRangosBD. definimos un rango de bases de datos.StartRow = 0 'La fila de inicio .CellRangeAddress oDoc = ThisComponent 'Accedemos al conjunto de los rangos de bases de datos oRangosBD = oDoc.MoveCells = True .7.KeepFormats = True 'Para que mantenga los formatos End With End Sub El nombre del nuevo rango no debe de existir o te dará un error.table.addNewByName( sNombre.

KeepFormats = True End With Else MsgBox "Ya existe el nombre del rango" End If Else MsgBox "El nombre no puede estar vacío" End If Else MsgBox "No es un rango de celdas" End If End Sub 6.7 Rangos de datos Para borrar un rango de datos usamos el método removeByName.star.CellRangeAddress .sun.hasByName( sNombre ) Then 'Lo removemos de la colección oRangosBD.DataBaseRanges() 'El nombre del rango a modificar sNombre = "Pruebas" If oRangosBD.setName ("Nuevo nombre") Else MsgBox "El rango de datos no existe" End If End Sub Sub Dim Dim Dim Dim Dim RangoDeDatos5() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDir As New com.removeByName( sNombre ) MsgBox "Rango de datos borrado" Else MsgBox "El rango de datos no existe" End If End Sub Podemos cambiar las propiedades de un rango de datos existente: Sub Dim Dim Dim Dim RangoDeDatos4() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDoc = ThisComponent oRangosBD = oDoc.getByName( sNombre ) 'Le cambiamos el nombre oRBD.DataBaseRanges() 'El nombre del rango a borrar sNombre = "Pruebas" 'Si el nombre no existe obtendrás un error If oRangosBD.table. toma en cuenta que lo único que se borra es el nombre del rango de datos y sus propiedades.300 .hasByName( sNombre ) Then oRBD = oRangosBD. las celdas y sus valores se mantienen: Sub Dim Dim Dim RangoDeDatos3() oDoc As Object oRangosBD As Object sNombre As String oDoc = ThisComponent oRangosBD = oDoc.

puede suceder que acabe apuntando a un rango vacío de celdas sin querer.StartColumn = 2 'La columna de inicio .7.StartRow = 5 'La fila de inicio .Sheet = 0 'Cambiamos la hoja . los siguientes: Nº 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Nombre nikole gloria antonio lidia paola vanessa paola paola paola lizette lizette lizette nikole gloria antonio lidia paola vanessa Año 1976 1976 1977 1967 1979 1974 1972 1968 1968 1978 1978 1978 1977 1975 1979 1977 1968 1978 Edad 33 33 32 42 30 35 37 41 41 31 31 31 32 34 30 32 41 31 .2 Ordenar datos Para ordenar datos. 6. por supuesto.setDataArea( oDir ) Else MsgBox "El rango de datos no existe" End If End Sub En el primer caso le cambiamos el nombre y en el segundo.EndRow = 19 'La fila final End With oRBD. la dirección del rango. veamos como ordenar un rango de celdas con y sin nombre de rango de datos.DataBaseRanges() 'El nombre del rango a modificar sNombre = "Direcciones" If oRangosBD.getByName( sNombre ) 'Cambiamos la dirección With oDir . no necesitas forzosamente un rango de datos con nombre.hasByName( sNombre ) Then oRBD = oRangosBD.Aprendiendo OOo Basic 301 oDoc = ThisComponent oRangosBD = oDoc. Tomaremos como datos de ejemplo.EndColumn = 5 'La columna final . cambia la dirección de un rango con cuidado.

estos no serán tomados en cuenta y se ordenaran en relación con el resto de tus datos. puede tomar los siguientes valores: com.star.IsCaseSensitive = False 'Tipo de campo AUTOMATICO mCamposOrden(0).Field = 1 'Orden ascendente mCamposOrden(0). y tu rango de datos efectivamente tiene títulos de campo.TableSortField mDescriptorOrden() 'La hoja donde esta el rango a ordenar oHoja = ThisComponent.FieldType = com. En el descriptor de orden.TableSortFieldType. no me ha dado muchas variantes en velocidad. o sea.Name = "SortFields" mDescriptorOrden(3).Value = mCamposOrden 'Ordenamos con los parámetros establecidos oRango.Value = True 'La matriz de campos a ordenar mDescriptorOrden(3).table.NUMERIC com.sun.TableSortFieldType. por que he hecho pruebas con pocos datos. el "como" mDescriptorOrden = oRango.table.sun.TableSortFieldType.7 Rangos de datos Vamos a ordenar los datos por nombre: Sub Dim Dim Dim Dim OrdenarDatos1() oHoja As Object oRango As Object mCamposOrden(0) As New com.sort( mDescriptorOrden ) End Sub Los puntos a los que debes poner atención son. si estableces la propiedad.sun.star.star. o sea.Name = "ContainsHeader" mDescriptorOrden(1).table.TableSortFieldType.getSheets.ALPHANUMERIC Valor 0 1 2 Valor en Interfaz Automático Numérico Alfanumérico En mis pruebas.IsAscending = True 'Sensible a MAYUSCULAS/minusculas mCamposOrden(0). establecer en uno y en otro. habría que hacer pruebas de rendimiento con grandes datos para ver su desempeño pues no creo que esta propiedad este de adorno. el "que" 'Los campos empiezan en 0 mCamposOrden(0).sun.getCellRangeByName("A1:D24") 'Descriptor de ordenamiento.AUTOMATIC com.302 19 20 21 22 23 lizette nikole gloria antonio lidia 1969 1970 1971 1973 1968 40 39 38 36 41 6.star.getByName("agosto") 'El rango a ordenar oRango = oHoja. el tipo de campo FieldType.table.AUTOMATIC 'Indicamos si el rango contiene títulos de campos mDescriptorOrden(1).createSortDescriptor() 'Los campos a orden.sun. ContainsHeader.TableSortFieldType com.table.star. en falso (False).table.sun.star. supongo. esto es. mi recomendación es que siempre .

createSortDescriptor() mCamposOrden(0).Aprendiendo OOo Basic 303 establezcas esta propiedad en verdadero (True) y efectivamente te asegures de tenerlos.table. claro.star.star.TableSortField mDescriptorOrden() oHoja = ThisComponent.getSheets.createSortDescriptor() mCamposOrden(0).Value = True mDescriptorOrden(3). a menos de que no te sea indispensable o de plano no los necesites.getCellRangeByName("A1:D24") oDestino = oHoja.star.Name = "SortFields" mDescriptorOrden(3).Value = mCamposOrden 'Ordenamos con los parámetros establecidos oRango.IsAscending = True mCamposOrden(0).Value = True mDescriptorOrden(3).star.getCellRangeByName("G1") mDescriptorOrden = oRango.getSheets.table.table.AUTOMATIC mDescriptorOrden(1). Si quieres ordenar por más de un campo (por ahora el limite es tres).Field = 1 mCamposOrden(0).TableSortFieldType.sun.Field = 3 'Este es descendente mCamposOrden(1).FieldType = com.Name = "ContainsHeader" mDescriptorOrden(1).table.sun.TableSortFieldType.IsCaseSensitive = False mCamposOrden(0).table.getByName("agosto") oRango = oHoja.IsAscending = False mCamposOrden(1).sun.getCellRangeByName("A1:D24") mDescriptorOrden = oRango.Value = mCamposOrden 'Establecemos que queremos copiar el resultado a otro lado .FieldType = com.Field = 1 mCamposOrden(0).AUTOMATIC mDescriptorOrden(1).TableSortField oDestino As Object mDescriptorOrden() oHoja = ThisComponent.FieldType = com.Name = "ContainsHeader" mDescriptorOrden(1).sun.star.IsAscending = True mCamposOrden(0).sun. como en el ejemplo siguiente que ordenamos por nombre ascendente y después por edad descendente: Sub Dim Dim Dim Dim OrdenarDatos2() oHoja As Object oRango As Object mCamposOrden(1) As New com. es la posibilidad de enviar el resultado a un destino diferente como en el siguiente ejemplo: Sub Dim Dim Dim Dim Dim OrdenarDatos3() oHoja As Object oRango As Object mCamposOrden(0) As New com.sort( mDescriptorOrden ) End Sub Una opción muy interesante.IsCaseSensitive = False mCamposOrden(1).IsCaseSensitive = False mCamposOrden(0). no hay más que agregar el segundo criterio a la matriz de campos.AUTOMATIC 'Agregamos un segundo campo mCamposOrden(1).getByName("agosto") oRango = oHoja.Name = "SortFields" mDescriptorOrden(3).TableSortFieldType.

Name = "CopyOutputData" mDescriptorOrden(5).sun.hasByName( sNombre ) Then 'Referencia al rango oRBD = oRangosBD.Value = mCamposOrden oRango.Value = oDestino. Ahora.table.getCellAddress() 'Ordenamos con los parámetros establecidos oRango. . pero accediendo desde un rango de datos: Sub Dim Dim Dim Dim Dim Dim Dim OrdenarDatos4() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oRango As Object mCamposOrden(0) As New com.IsCaseSensitive = False mCamposOrden(0).7 Rangos de datos Observa como establecemos el destino con una estructura getCellAddress.FieldType = com.createSortDescriptor() mCamposOrden(0). que te da acceso al rango origen de los datos. estos serán totalmente reemplazados sin preguntarte nada. por ejemplo.getReferredCells() mDescriptorOrden = oRango.star.Name = "OutputPosition" mDescriptorOrden(6).Name = "SortFields" mDescriptorOrden(3).Field = 1 mCamposOrden(0).304 mDescriptorOrden(5). Si en el rango destino existen datos.Value = True mDescriptorOrden(3). esta solo incluye la hoja destino.table.AUTOMATIC mDescriptorOrden(1). getReferredCells.TableSortFieldType.TableSortField mDescriptorOrden() oDoc = ThisComponent oRangosBD = oDoc. puedes aplicarle un autoformato de tabla a los datos. esta propiedad te devuelve un objeto ScCellRangeObj.DataBaseRanges() sNombre = "Direcciones" 'Verificamos que exista el nombre del rango de datos If oRangosBD.Value = True 'Establecemos el destino de la copia mDescriptorOrden(6).Name = "ContainsHeader" mDescriptorOrden(1). ordenamos.sun. por lo que puedes tener acceso a todas las propiedades de manipulación y formato vistas de este objeto.IsAscending = True mCamposOrden(0).star.sort( mDescriptorOrden ) End Sub 6.sort( mDescriptorOrden ) Else MsgBox "El rango de datos no existe" End If End Sub La propiedad importante es.getByName( sNombre ) 'Referencia al origen del rango oRango = oRBD. la columna y la fila de inicio.

te agrega un control de lista desplegable en el encabezado de campo de tus datos.Aprendiendo OOo Basic 305 6.hasByName( sNombre ) Then 'Referencia al rango . como en: Para hacer lo mismo por código. veamos como establecerlas por código. usamos: Sub Dim Dim Dim Dim FiltrarDatos1() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDoc = ThisComponent oRangosBD = oDoc. solo la establecemos en falso (False) Sub Dim Dim Dim Dim FiltrarDatos2() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDoc = ThisComponent oRangosBD = oDoc. Doy por hecho que no tienes problemas. y seguiremos usando los datos del tema anterior. la más sencilla. Primero.DataBaseRanges() sNombre = "Direcciones" If oRangosBD. adivinaste. muy bien. son las presentes en el menú Datos | Filtro ->.getByName( sNombre ) 'Mostramos el autofiltro oRBD.7. con cada una de estas opciones. el filtro automático.hasByName( sNombre ) Then 'Referencia al rango oRBD = oRangosBD.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.3 Filtrar datos Las opciones que estudiaremos en este capitulo.AutoFilter = True Else MsgBox "El rango de datos no existe" End If End Sub ¿Y para quitarlos?. como usuario.

AutoFilter = False Else MsgBox "El rango de datos no existe" End If End Sub 6.star.TableFilterField oDoc = ThisComponent oRangosBD = oDoc.sheet. para eliminar completamente un filtro.sun.hasByName( sNombre ) Then oRBD = oRangosBD.sun.getByName( sNombre ) oDesFiltro = oRBD.star.FilterOperator.getByName( sNombre ) 'Mostramos el autofiltro oRBD.StringValue = "lizette" .getRows.EQUAL 'Si es un número mCamposFiltro(0). solo te quitará las flechas para desplegar el filtro del campo. eliminar el filtro y después mostrar las filas ocultas como te muestro en el siguiente ejemplo: Sub Dim Dim Dim Dim Dim Dim FiltrarDatos3() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro() As New com. tienes que hacer dos cosas. podemos filtrar directamente como en el siguiente ejemplo: Sub Dim Dim Dim Dim Dim Dim FiltrarDatos4() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(0) As New com.IsVisible = True Else MsgBox "El rango de datos no existe" End If End Sub Entonces.hasByName( sNombre ) Then oRBD = oRangosBD.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.getFilterDescriptor() 'El campo por el que queremos filtrar mCamposFiltro(0).AutoFilter = False 'Mostramos las filas ocultas oRBD.Operator = com. primero.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.306 oRBD = oRangosBD.TableFilterField oDoc = ThisComponent oRangosBD = oDoc. la macro anterior. cuando filtramos por código.sheet.star.sheet.Field = 1 'El tipo de comparación mCamposFiltro(0). si tienes establecido un filtro automático.IsNumeric = False 'El valor de comparación mCamposFiltro(0). no es indispensable mostrar las flechas de los campos del filtro.FilterFields = mCamposFiltro 'Quitamos las flechas oRBD. este permanecerá.getReferredCells().sun.getFilterDescriptor() 'Le pasamos una matriz vacía con una estructura de campo de filtro oDesFiltro.getByName( sNombre ) 'Obtenemos la descripción del filtro oDesFiltro = oRBD.7 Rangos de datos Pero cuidado.

sun.FilterOperator.star.Operator = com.FilterFields = mCamposFiltro 'Refrescamos el rango para ver el resultado del filtro oRBD. para obtener el resultado deseado.StringValue = "paola" oDesFiltro.sun. es muy importante establecer correctamente esta.hasByName( sNombre ) Then oRBD = oRangosBD. veamos como filtrar un campo con dos condiciones: Sub Dim Dim Dim Dim Dim Dim FiltrarDatos5() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(1) As New com.Field = 1 mCamposFiltro(0).FilterOperator.getFilterDescriptor() mCamposFiltro(0).refresh() Else MsgBox "El rango de datos no existe" End If End Sub Que comprobamos que lo hace correctamente: Ahora.sheet.TableFilterField oDoc = ThisComponent oRangosBD = oDoc.FilterConnection. muchos errores de filtros incorrectos.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.sun.sheet.StringValue = "lizette" 'Agregamos la segunda condición al mismo campo mCamposFiltro(1).star.Connection = com.sheet.OR mCamposFiltro(1).FilterFields = mCamposFiltro oRBD. solo tiene dos posibilidades.EQUAL mCamposFiltro(1).sun.star.IsNumeric = False mCamposFiltro(0).sheet.refresh() Else MsgBox "El rango de datos no existe" End If End Sub Observa muy bien la propiedad Connection.Field = 1 'Establecemos la relación con la condición anterior mCamposFiltro(1).Aprendiendo OOo Basic 307 'Le pasamos los campos oDesFiltro.getByName( sNombre ) oDesFiltro = oRBD. una “O” (OR) o una “Y” (AND).EQUAL mCamposFiltro(0). son por la incorrecta aplicación de este sencillo parámetro.star. y veamos más ejemplos: . comprobamos que nuestro filtro esta correcto.Operator = com.IsNumeric = False mCamposFiltro(1).

sun.star.sun.FilterOperator. dando por entendido.FilterConnection.Field = 3 'Establecemos la relación con la condición anterior (Y) mCamposFiltro(1).IsNumeric = False mCamposFiltro(0).sun.Operator = com. ya no te mostraré el resultado.EQUAL 'Ahora si buscamos por número mCamposFiltro(1).FilterFields = mCamposFiltro oRBD.star.AND mCamposFiltro(1).TableFilterField oDoc = ThisComponent oRangosBD = oDoc. que estas comprobando.EQUAL mCamposFiltro(0). que el resultado esperado es el correcto.7 Rangos de datos Ahora filtraremos con condiciones en dos campos diferentes: Sub Dim Dim Dim Dim Dim Dim FiltrarDatos6() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(1) As New com.refresh() Else MsgBox "El rango de datos no existe" End If End Sub Y una vez más lo comprobamos En los siguientes ejemplos.sheet.Field = 1 mCamposFiltro(0). filtramos a todos los que tengan entre 30 y 35 años: Sub Dim Dim Dim Dim Dim FiltrarDatos7() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object .star.getFilterDescriptor() mCamposFiltro(0).DataBaseRanges() sNombre = "Direcciones" If oRangosBD.NumericValue = 32 oDesFiltro.hasByName( sNombre ) Then oRBD = oRangosBD.Connection = com.getByName( sNombre ) oDesFiltro = oRBD.sheet.StringValue = "lidia" 'Agregamos la segunda condición a otro campo mCamposFiltro(1).sheet.star.Operator = com.sheet.308 6.sun.IsNumeric = True mCamposFiltro(1).FilterOperator. En el siguiente ejemplo. como yo.

sun.star.NOT_EMPTY com.IsNumeric = True mCamposFiltro(1).star.star.sun.star.sheet.LESS_EQUAL com.FilterFields = mCamposFiltro oRBD.star.getFilterDescriptor() mCamposFiltro(0).sun.star.Connection = com.FilterOperator.Aprendiendo OOo Basic 309 Dim mCamposFiltro(1) As New com.star.sheet.sheet.sun.FilterOperator.sheet.BOTTOM_VALUES com.Field = 3 mCamposFiltro(0).sheet. los posibles valores para esta propiedad.sun.GREATER_EQUAL com.star.FilterOperator.sun.FilterOperator.EQUAL com.FilterOperator.sheet.star.sun.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.TableFilterField oDoc = ThisComponent .sun.EMPTY com.NumericValue = 30 'Agregamos la segunda condición a otro campo mCamposFiltro(1).sheet.star.star.star.IsNumeric = True mCamposFiltro(0).LESS_EQUAL mCamposFiltro(1).Operator = com.star.sun.FilterOperator.star.FilterOperator.FilterConnection.sheet.getByName( sNombre ) oDesFiltro = oRBD.sun.Field = 3 mCamposFiltro(1).refresh() Else MsgBox "El rango de datos no existe" End If End Sub Observa como hemos cambiado la propiedad operador (Operator) para satisfacer la condición.sun.Operator = com. cuyos valores son: com.sun.sheet.sun.FilterOperator.sheet.FilterOperator.FilterOperator.star.FilterOperator.sun.sun. viene condicionados por la enumeración com.hasByName( sNombre ) Then oRBD = oRangosBD.FilterOperator.star.sheet. seleccionamos los cinco registros con más edad: Sub Dim Dim Dim Dim Dim Dim FiltrarDatos8() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(0) As New com.NOT_EQUAL com.star.sun.sheet.FilterOperator com.FilterOperator.BOTTOM_PERCENT Valor 0 1 2 3 4 5 6 7 8 9 10 11 Valor en Interfaz Vacío No vacío Igual No igual Mayor que Mayor o igual que Menor que Menor o igual que El mayor valor El mayor porcentaje El menor valor El menor porcentaje En el siguiente ejemplo.star.TOP_VALUES com.LESS com.sheet.sun.sheet.GREATER com.sun.sheet.GREATER_EQUAL mCamposFiltro(0).TableFilterField oDoc = ThisComponent oRangosBD = oDoc.FilterOperator.TOP_PERCENT com.sheet.star.FilterOperator.sheet.NumericValue = 35 oDesFiltro.AND mCamposFiltro(1).sheet.sheet.sun.

filtremos todos los nombres que comiencen por la letra “L”: Sub Dim Dim Dim Dim Dim Dim FiltrarDatos9() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(0) As New com.refresh() Else MsgBox "El rango de datos no existe" End If End Sub 6. Otra posibilidad bastante interesante de los filtros.sheet.Operator = com.sheet.sheet.sun.star.TOP_VALUES mCamposFiltro(0).sun.EQUAL mCamposFiltro(0).7 Rangos de datos Ahora.StringValue = "l.getFilterDescriptor() mCamposFiltro(0).IsNumeric = False 'Observa el parametro de la condición mCamposFiltro(0).Field = 3 mCamposFiltro(0). del descriptor del filtro para que tenga efecto nuestra condición.star.refresh() Else MsgBox "El rango de datos no existe" End If End Sub Observa como hemos establecido la propiedad para usar expresiones regulares (UseRegularExpressions).310 oRangosBD = oDoc.TableFilterField oDestino As Object .getFilterDescriptor() mCamposFiltro(0).star.NumericValue = 5 oDesFiltro.getByName( sNombre ) oDesFiltro = oRBD.FilterFields = mCamposFiltro oRBD.UseRegularExpressions = True oDesFiltro.*" 'Establecemos que use expresiones regulares oDesFiltro.sun.FilterOperator.Field = 1 mCamposFiltro(0).FilterFields = mCamposFiltro oRBD.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.hasByName( sNombre ) Then oRBD = oRangosBD.Operator = com.getByName( sNombre ) oDesFiltro = oRBD.FilterOperator.star.TableFilterField oDoc = ThisComponent oRangosBD = oDoc.IsNumeric = True 'Los cinco de más edad mCamposFiltro(0). veamos como: Sub Dim Dim Dim Dim Dim Dim Dim FiltrarDatos10() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(0) As New com.sun.sheet. es poder copiar el resultado en otra posición y dejar el origen intacto.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.hasByName( sNombre ) Then oRBD = oRangosBD.

Field = 1 mCamposFiltro(0).DataBaseRanges() sNombre = "Direcciones" If oRangosBD.sheet. copia varios registros iguales para que notes la diferencia. estas.Column = oDestino.sheet.Column + oRBD.Aprendiendo OOo Basic 311 oDoc = ThisComponent oRangosBD = oDoc.ReferredCells().IsNumeric = False mCamposFiltro(0).sheet.EQUAL mCamposFiltro(0).star.hasByName( sNombre ) Then oRBD = oRangosBD.getByName( sNombre ) oDesFiltro = oRBD.sun.StringValue = "gloria" 'Le indicamos que queremos el resultado en otro lugar oDesFiltro.Field = 0 'Seleccionamos los registros NO vacíos mCamposFiltro(0).0).TableFilterField oDestino As Object oDoc = ThisComponent oRangosBD = oDoc.FilterFields = mCamposFiltro oRBD.FilterOperator.getCellAddress() 'Despues sumamos el ancho del rango y uno para dejar una columan en blanco oDestino.getCount + 1 oDesFiltro.Operator = com.hasByName( sNombre ) Then oRBD = oRangosBD.SaveOutputPosition = True 'Y le indicamos donde. es la posibilidad de filtrar los registros.getByName( sNombre ) oDesFiltro = oRBD.FilterFields = mCamposFiltro oRBD.Column = oDestino. observa como obtenemos la dirección de la primer celda del rango oDestino = oRBD. Otra característica muy poderosa de los filtros.getCellByPosition(0.getCellByPosition(0. se hace de la siguiente manera: Sub Dim Dim Dim Dim Dim Dim Dim FiltrarDatos11() oDoc As Object oRangosBD As Object sNombre As String oRBD As Object oDesFiltro As Object mCamposFiltro(0) As New com. omitiendo los duplicados.star.star. para evaluar esto y se lo notifiques al usuario.ReferredCells().ReferredCells().FilterOperator.getCount + 1 'Establecemos el destino oDesFiltro. modifica la macro.ReferredCells().SkipDuplicates = True oDesFiltro.getCellAddress() oDestino.Column + oRBD.OutputPosition = oDestino oDesFiltro.0).SaveOutputPosition = True oDestino = oRBD.refresh() Else MsgBox "El rango de datos no existe" End If End Sub .getFilterDescriptor() mCamposFiltro(0).NOT_EMPTY 'Le indicamos que solo queremos registros únicos oDesFiltro.DataBaseRanges() sNombre = "Direcciones" If oRangosBD.getColumns().sun.getFilterDescriptor() mCamposFiltro(0).getColumns().Operator = com.refresh() Else MsgBox "El rango de datos no existe" End If End Sub Si las celdas destino no están vacías.OutputPosition = oDestino oDesFiltro.sun. serán reemplazadas sin preguntarte nada.

nos permite establecer un rango como origen de los criterios para el filtro.SkipDuplicates = True oDesFiltro. al ser un método de rango de celdas (ScCellRangeObj). preparate una buena tabla de datos.sun. no refrescamos el rango.star. hemos aplicados filtros. pasándole como parámetro el descriptor de filtro creado. lo que nos da la posibilidad de poder llegar a usar como criterios “todos” los campos de nuestra base de datos. la siguiente macro. y por ultimo.filter( oDesFiltro ) Else MsgBox "No es un rango de celdas" End If End Sub Hay diferencias importantes en comparación con los filtros en rango de datos.getImplementationName = "ScCellRangeObj" Then 'Creamos un nuevo descriptor de filtro vacio (True) oDesFiltro = oSel.TableFilterField oDestino As Object oDoc = ThisComponent oSel = oDoc. si lo prefieres.getRangeAddress().7 Rangos de datos Hasta ahora.getCellByPosition(0. puedes aplicar un filtro a cualquier rango de celdas.sheet.FilterFields = mCamposFiltro 'Y lo aplicamos oSel.getCurrentSelection() 'Nos aseguramos de que sea un rango de celdas If oSel. este tipo de filtro. si el destino contiene datos. Para demostrar el poder y versatilidad de esta opción. . toma el rango de celdas seleccionado y filtra los datos únicos dos columnas a la derecha.star. también cambia la propiedad para decirle que queremos copiar el resultado (CopyOutputData) en otra posición. dándonos absoluto control sobre los registros filtrados. la primera es la forma de crear el descriptor de filtro. si no que aplicamos el filtro (filter).EndColumn + 2 'Establecemos las propiedades del filtro oDesFiltro. esta macro es muy útil para dejar listados únicos de lo que sea.sheet. serán reemplazados sin consultarte.Operator = com. con al menos cinco campos y varias decenas de registros. presente en los ejemplos que acompañan a estos apuntes y que será la que yo use.OutputPosition = oDestino oDesFiltro. verificalo: Sub Dim Dim Dim Dim Dim FiltrarDatos12() oDoc As Object oSel As Object oDesFiltro As Object mCamposFiltro(0) As New com. observa que también hemos establecido que este rango no tiene encabezados de campos (ContainsHeader). para un rango de celdas se usa el método createFilterDescriptor.Field = 0 mCamposFiltro(0).Column = oSel.createFilterDescriptor(True) 'Establecemos los campos mCamposFiltro(0).FilterOperator. al cual se le pasa el parámetro verdadero (True) si queremos que el nuevo descriptor este vacío y falso (False) si toma el existente en dicho rango de celdas.312 6.0). puedes usar la hoja llamada “Peliculas”.NOT_EMPTY 'Establecemos el destino oDestino = oSel.ContainsHeader = False oDesFiltro.CopyOutputData = True oDesFiltro. pero los filtros no están limitados a estas áreas.getCellAddress() oDestino. Veamos como usar las opciones del filtro especial. Al igual que con los rango de datos. desde un rango de datos.sun.

. todo lo anterior puedes hacerlo por código que ya sabes hacerlo.getByName( "Videoteca" ).createFilterDescriptorByObject( oVideoteca ) 'Sin duplicados oDesFiltro. con esta macro en especifico. La definición de criterios para el filtro especial.UseRegularExpressions = True 'Queremos el resultado en otra posición oDesFiltro.DataBaseRanges() 'Nos aseguramos de que existen nuestros tres rangos If oRangosBD. por ultimo. después.hasByName( "Destino" ) Then 'Obtenemos una referencia a los rangos origen oVideoteca = oRangosBD.getByName( "Destino" ). se puede hacer como lo hemos venido aprendiendo.getByName( "Criterios" ). concentrándonos en estudiar la forma de establecer estos criterios desde un rango de datos con nombre. selecciona la celda “A260” y la bautizamos como “Destino”.ReferredCells() oCriterios = oRangosBD. Recuerda que esta definición de nombres es en el menú Datos | Definir rango.SkipDuplicates = True 'Que pueda usar expresiones regulares oDesFiltro. asignarle una combinación de teclas o un botón en alguna barra de herramientas con la finalidad de que podamos ejecutarla varias veces desde la interfaz del usuario e ir viendo en vivo y en directo los resultados que nos arrogue. Te sugiero. “Videoteca” si te parece.ReferredCells. ¿verdad?. selecciona el rango “A250:G255” y nombrala como “Criterios”.getCellAddress() 'Obtenemos el descriptor del filtro del rango de criterios a partir del rango de datos oDesFiltro = oCriterios.0 ).Aprendiendo OOo Basic 313 El rango de nuestros datos es: “A1:G243”.ReferredCells() oDestino = oRangosBD. Nuestra tabla debe verse más o menos así. establecemos un nombre a este rango.hasByName( "Criterios" ) And oRangosBD. Aquí la macro: Sub Dim Dim Dim Dim Dim Dim FiltrarEspecial1() oDoc As Object oRangosBD As Object oVideoteca As Object oDestino As Object oCriterios As Object oDesFiltro As Object oDoc = ThisComponent oRangosBD = oDoc. por lo que no lo repetiremos aquí.hasByName( "Videoteca" ) And oRangosBD.getCellByPosition( 0. copia los títulos de los campos a la fila 250..CopyOutputData= True 'Le indicamos donde . si es de tu agrado.

Ahora. Nº Titulo Director Genero Año 1974 País Duración Si quieres establecer más de un criterio y lo haces en una misma fila. usamos: Ejecuta la macro y vemos el resultado: Recuerda que la finalidad de establecer criterios y realizar filtros. por ejemplo.filter( oDesFiltro ) Else MsgBox "El rango de datos no existe" End If End Sub 6. establece la condición y ejecuta la macro para responderla.314 oDesFiltro. para responder la pregunta. pasándole como argumento. el rango de datos (oVideoteca).OutputPosition = oDestino 'El rango contiene encabezados de campos oDesFiltro. como la respuesta a la pregunta. es la de responder preguntas como por ejemplo. realizadas en Japón realizadas en 1980? Nº Titulo Director Genero Año País 1980 Japón Duración Si usas diferentes filas. para saber que películas tenemos de mi director favorito. estas usando el operador “Y” (And). ¿cuantas películas tenemos del año 1974?. ¿cuantas películas tenemos de la India o del director Peter Greenaway? . ¿cuantas películas tenemos. que se invoca desde el rango de criterios (oCriterios). estas usando el operador “O” (Or). las restantes propiedades usadas en el ejemplo ya las hemos tratado. los criterios tienes que establecerlos en las celdas correspondientes. por ejemplo.7 Rangos de datos Es importante notar que para el filtro especial usamos en nuevo método llamado createFilterDescriptorByObject.ContainsHeader = True 'Filtramos con las opciones seleccionadas oVideoteca.

EnableSort = True oDesSubTotal.* Director Genero Año País Duración Como habrás notado. y ya casi te dije todo. obtenemos la cantidad de títulos por director: Sub Dim Dim Dim Dim Dim Dim Subtotales1() oDoc As Object oRangosBD As Object oPeliculas As Object oRango As Object oDesSubTotal As Object mCamposSubTotal(0) As New com.SubTotalColumn oDoc = ThisComponent oRangosBD = oDoc.Aprendiendo OOo Basic Nº Titulo Director Peter Greenaway 315 Genero Año País India Duración Como declaramos en el descriptor de filtro.7.Column = 1 .4 Subtotales Los subtotales nos permiten obtener información de las áreas de datos. ¿cuantas películas empiezan con la letra “D”? Nº Titulo d. tienes que usar el operador “Y” (AND) para resolverlo.sun. nota que estamos solicitando un rango especifico. la primer pista es.SortAscending = True 'La columna en la que se usara la función especificada mCamposSubTotal(0). las posibilidades son enormes. que se usarán expresiones regulares.star. Te queda de tarea. con lo que ya te resolví la tarea.getByName( "Peliculas" ) 'Referencia al rango de celdas origen oRango = oPeliculas. agrupar y realizar una operación determinada en un grupo de datos. puedes responder preguntas como. establecer las condiciones para responder la siguiente pregunta. ¿cuales películas duran entre 60 y 90 minutos?.DataBaseRanges() 'Nos aseguramos de que existe el rango If oRangosBD.ReferredCells() 'Creamos un nuevo subtotal oDesSubTotal = oRango. por lo tanto. recuerda que el rango de criterios es solo eso un rango y no estamos limitados a cambiar lo que queramos en este rango.hasByName( "Peliculas" ) Then 'Obtenemos una referencia a los rangos origen oPeliculas = oRangosBD. a trabajar: Nº Titulo Director Genero Año País Duración ?? 6. en el siguiente ejemplo y continuando trabajando con nuestra base de datos de películas.createSubTotalDescriptor( True ) 'Que ordene de forma ascendente el grupo seleccionado oDesSubTotal.sheet.

te creara un nuevo descriptor vacío.star. si es falso (False).star.GeneralFunction. si es ascendente o descendente. que puede tomar los siguientes valores: com. te puede dar resultados incorrectos.sun.SUM com. a su vez.MAX com. borra cualquier subtotal existente en el rango del área de datos: Sub Subtotales2() Dim oDoc As Object Dim oRangosBD As Object .star. si lo hay.sun.star.COUNTNUMS com.sun.sheet.sheet.sun. True ) End If End Sub 6.GeneralFunction. pero si no ordenas el grupo. La siguiente macro.sun.GeneralFunction. la matriz de campos de columna del subtotal donde hemos establecido que campos y que operación haremos con ellos.star.addNew( mCamposSubTotal.VAR com.COUNT 'Agregamos la operación.star.sun.GeneralFunction.GeneralFunction. si al método del rango de celdas para crear el descriptor del subtotal (createSubTotalDescriptor). aplicamos (applySubTotals) los subtotales.sheet. determinada por la propiedad función (Function).sheet. le indicamos por que campo queremos agrupar. solo la utilizamos para acceder (ReferredCells) al rango de celdas origen. pues si agregas criterios “inconsistentes”. ahí mismo. En la matriz de columnas del subtotal (com.GeneralFunction.Function = com.sun.316 mCamposSubTotal(0). establecemos el campo (Column) en el cual queremos hacer una operación. y dependiendo de como estén tus datos origen. el resultado puede ser impreciso y desastroso visualmente hablando.sheet.GeneralFunction.sun.sun. Es importante que establezcas que ordene el grupo. con el segundo parámetro.sun. tomará el existente.star.2 ) 'Aplicamos el subtotal oRango.sheet.star.GeneralFunction.star.sun. si lo hay.star.sheet.applySubTotals( oDesSubTotal.STDEVP com.sun. al grupo deseado oDesSubTotal.GeneralFunction.GeneralFunction com.star.SubTotalColumn).sheet.GeneralFunction.MIN com. queda a tu criterio y necesidades.sheet.sun.sun.sheet.star.sun.NONE com. basada en la enumeración com. le pasamos como parámetros.star. el descriptor de subtotal y un valor booleano indicándole si deseamos reemplazar el subtotal actual (True).VARP Valor 0 1 2 3 4 5 6 7 8 9 10 11 12 Valor en Interfaz Ninguna Automático Suma Cuenta Promedio Máximo Mínimo Producto Cuenta solo números Desviación estándar (Muestra) Desviación estándar (Población) Varianza (Muestra) Varianza (Población) Al añadir los campos (addNew) al descriptor de subtotal.GeneralFunction.sheet.sheet.sheet.GeneralFunction. del rango seleccionado.AUTO com.GeneralFunction. por último. usa con cuidado este parámetro.STDEV com. cuyos parámetros son.PRODUCT com.GeneralFunction. o agregamos al existente (False).GeneralFunction. se le pasa como argumento un valor verdadero (True).sheet.sheet.sheet.star.sheet.star.star.AVERAGE com.7 Rangos de datos El área de datos (DataBaseRanges).sun.sun.star.COUNT com.

sheet. “dentro” de cada país tenemos: Sub Dim Dim Dim Dim Subtotales4() oDoc As Object oSel As Object oDesSubTotal As Object mCamposSubTotal(0) As New com.GeneralFunction. La siguiente macro.getCurrentSelection() 'Si es una sola celda o un rango de celdas . no es indispensable usar un área de datos para hacer uso de los subtotales.sheet.star.3 ) oSel.getImplementationName = "ScCellRangeObj" Or oSel.sun.applySubTotals( oDesSubTotal.SubTotalColumn oDoc = ThisComponent oSel = oDoc.DataBaseRanges() If oRangosBD.Column = 1 mCamposSubTotal(0).COUNT 'Columna de minutos mCamposSubTotal(1).addNew( mCamposSubTotal.getCurrentSelection() 'Si es una sola celda o un rango de celdas If oSel.getByName( "Peliculas" ) oRango = oPeliculas.sun.Column = 6 mCamposSubTotal(1).ReferredCells() 'Quitamos el subtotal oRango. podemos invocarlos desde cualquiera de estos. Sub Dim Dim Dim Dim Subtotales3() oDoc As Object oSel As Object oDesSubTotal As Object mCamposSubTotal(1) As New com.createCursorByRange(oSel) 'Expandimos a la región actual oSel. nos da el total de títulos por genero y suma la cantidad de minutos del mismo.Aprendiendo OOo Basic Dim oPeliculas As Object Dim oRango As Object 317 oDoc = ThisComponent oRangosBD = oDoc.SortAscending = True 'Columna de titulos mCamposSubTotal(0).star.Function = com.createSubTotalDescriptor( True ) oDesSubTotal.getSpreadSheet. y después otro subtotal nos indica cuantos títulos por genero.hasByName( "Peliculas" ) Then oPeliculas = oRangosBD.star.removeSubTotals() End If End Sub Como se muestra en el siguiente ejemplo.EnableSort = True oDesSubTotal.star. nos muestra cuantos títulos tenemos por país.sun.sheet.sun.SubTotalColumn oDoc = ThisComponent oSel = oDoc.SUM 'Aplicamos al genero oDesSubTotal.GeneralFunction. True ) Else MsgBox "No es un rango de celdas" End If End Sub El siguiente ejemplo.collapseToCurrentRegion() 'Creamos el descriptor a partir de la selección oDesSubTotal = oSel. al ser métodos implementados en rangos de celda.getImplementationName = "ScCellObj" Then oSel = oSel.sheet.Function = com.

con cuadros de mensaje para ayudarle a introducir la información correctamente. informando.applySubTotals( oDesSubTotal. espacios vacíos de más. y cuéntame cual es el error. a capturar dados válidos en el programa.Column = 1 mCamposSubTotal(0).createCursorByRange(oSel) oSel. si lo deseas. por lo que te podrás dar cuenta si tienes campos con.sun. Solo puedes sacar subtotales por hasta un máximo de tres grupos.star. revisa los registros que solo tengan un solo registro.7.Function = com. . presente en el menú Datos. que nos permite establecer criterios en celdas para la captura de información por parte del usuario y limitarlo en la medida de lo posible.Column = 1 mCamposSubTotal(0). será el orden de precedencia de los subtotales. que hemos establecido la matriz de campos dos veces y usado el método addNew también dos veces para lograr el resultado deseado. sobre todo cuando haces uso de la función cuenta. al realizar la operación establecida en algún campo. La obtención de subtotales. busca y observa los géneros “Comedia” y “Drama”.7 Rangos de datos If oSel.sheet.GeneralFunction.5 Validando datos A estas alturas del libro. te habrás dado cuenta de la importancia de validar la información que el usuario le proporciona a un programa.getSpreadSheet. una gran cantidad de programas. fallan en este tema de. alta prioridad. tiene un valor agregado bastante útil. con los subtotales te podrás dar cuenta de forma visual muy fácilmente. Para ejemplificar esto. si un registro tiene solo un error de “dedo”.5 ) 'Columna de títulos mCamposSubTotal(0).GeneralFunction.sheet.getImplementationName = "ScCellObj" Then oSel = oSel. Calc cuenta con una herramienta llamada Validez.addNew( mCamposSubTotal.318 6. True ) Else MsgBox "No es un rango de celdas" End If End Sub Observa.addNew( mCamposSubTotal.collapseToCurrentRegion() oDesSubTotal = oSel. por ejemplo. Esa es tu tarea que no es mucha.COUNT 'Aplicamos al genero oDesSubTotal.createSubTotalDescriptor( True ) oDesSubTotal.getImplementationName = "ScCellRangeObj" Or oSel. tu debes determinar si es correcto o no. la herramienta hace una comparación “exacta” de cada valor.3 ) oSel. o en el caso de tener valores de campo muy similares. por supuesto.EnableSort = True oDesSubTotal.SortAscending = True 'Columna de títulos mCamposSubTotal(0).star. 6. al principio o al final de el. El orden en que establezcas y agregues los campos.COUNT 'Aplicamos al país oDesSubTotal.sun.Function = com. saca un subtotal por genero. creo yo. si estas usando la misma base de datos que yo.

oValidacion) End If .STOP 'El titulo del mensaje de error .getImplementationName = "ScCellRangeObj" Then 'Obtenemos la estructura validación oValidacion = oSel.IgnoreBlankCells = True 'Que muestre un mensaje al seleccionar la celda . es decir.getPropertyValue("Validation") 'Establecemos sus propiedades With oValidacion 'El tipo de validación .sheet.ValidationType.star.ErrorMessage = "El valor introducido no es un número entre 1 y 12" End With 'Reinsertamos la propiedad para que surtan efecto los cambios oSel.ConditionOperator.setOperator ( com.star. solo puedan aceptar números enteros del 1 al 12.InputTitle = "Introduce el mes del año" 'El mensaje . En el siguiente ejemplo.setFormula1 ( "1" ) 'Establecemos la segunda .ShowErrorMessage = True 'El estilo del mensaje de alerta .sheet.WHOLE 'El operador de la validación .star.sheet.sun.getImplementationName = "ScCellObj" Or oSel.setPropertyValue("Validation".getCurrentSelection() 'Validamos que sea una celda o un rango de celdas If oSel.Aprendiendo OOo Basic 319 Veamos como establecer estas opciones por código.InputMessage = "Captura un número entre 1 y 12" 'Que muestre un mensaje si la condición no se cumple . un entero correspondiente a un mes del año: Sub Dim Dim Dim ValidarDatos1() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.ErrorAlertStyle = com.sun.ValidationAlertStyle.BETWEEN ) 'Establecemos la primer condición .ErrorTitle = "Dato erroneo" 'El mensaje de error .sun.Type = com.setFormula2 ( "12" ) 'Que ignore las celdas en blanco .ShowInputMessage = True 'El titulo del mensaje . establecemos que las celdas seleccionadas.

320 End Sub 6. pero debes de saber que esta propiedad no determina el validar celdas vacía o no.ValidationType com.ValidationType.sun.star.sun.sheet.star.ValidationType.star.star.ValidationType.sheet. establecemos el operador (setOperator).star.sheet. y el mensaje que verá (InputMessage).ANY com.NOT_BETWEEN com.sheet. las celdas en blanco (IgnoreBlankCells).sun.ConditionOperator.ValidationType.ConditionOperator. determinará la acción a tomar con el valor capturado. y “no entre” (NOT_BETWEEN). puede que necesites establecer el primer valor de comparación (setFormula1).sun. si no que trabaja en conjunto la utilidad Detective del menú Herramientas. podemos mostrar un mensaje de error (ShowErrorMessage).sheet.sun.star.sheet.TIME com. este estilo. para evaluar la condición. el nombre de la propiedad que nos interesa.sun.sun.TEXT_LEN com.sun.ConditionOperator.sheet. son los que requieren los dos valores. se refiere al tipo de validación que haremos y esta condicionado por la enumeración com. pasándole como argumento.sheet.sun.LIST com.GREATER_EQUAL com. Las restantes propiedades son: el tipo (Type).star.NONE com.LESS com. esta propiedad puede tomar los siguientes valores: com.ConditionOperator com.sheet.sun.ValidationType.ConditionOperator.star.sun.star.FORMULA Valor 0 1 2 3 4 5 6 7 8 9 Valor en Interfaz Ninguna Igual Distinta de Mayor que Mayor o igual Menor que Menor o igual Entre No entre Formula Dependiendo de que operador selecciones.GREATER com. cuyos posibles valores son: com. este texto orienta al usuario sobre los valores a introducir.7 Rangos de datos Observa como estamos obteniendo la estructura de validación (getPropertyValue). establecer su titulo (InputTitle).sun.sheet.star. y también el segundo (setFormula2).sheet.sheet. Podemos determinar si la validación ignora o no. En caso de que el valor capturado por el usuario.sheet.sun.sun.star.ConditionOperator. para determinar si una celda vacía se considera error o no.sheet.ValidationType.sun. Podemos mostrar un mensaje (ShowInputMessage).star.ValidationType.sheet.DATE com. no satisfaga las condiciones de la validación.sheet.star.EQUAL com.star.sun.sun.sheet.star. este estilo esta determinado por los siguientes valores: .star.star.star.BETWEEN com.ConditionOperator.sheet. comúnmente los operadores “entre” (BETWEEN).ValidationType.sun.sheet.sun. de determinado estilo (ErrorAlertStyle).DECIMAL com.star.star.sun.ValidationType.sun.star.LESS_EQUAL com.ConditionOperator.ConditionOperator.WHOLE com.NOT_EQUAL com.ConditionOperator.sheet. cuando el usuario seleccione una celda.ConditionOperator.sheet.CUSTOM Valor 0 1 2 3 4 5 6 7 Valor en Interfaz Cualquier valor Entero Decimal Fecha Hora Longitud de texto Lista Formula Después.

sheet.sun.InputMessage = "Puedes usar decimales" .sun. mostrar un mensaje más elaborado o realizar una operación más compleja.star.ValidationAlertStyle com.INFO com.ShowErrorMessage = True .setOperator ( com.setFormula2 ( "10" ) . puedes escoger una macro a ejecutar.sheet. por ejemplo.sheet.star.sun.sheet. Sub Dim Dim Dim ValidarDatos2() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.sheet.IgnoreBlankCells = True . es importante. quedará a criterio del usuario si acepta o no el nuevo valor aun y cuando no cumpla la condición y en el caso de la opción “macro” (MACRO).ValidationAlertStyle.setPropertyValue("Validation". la celda regresará al valor inmediato anterior.DECIMAL .WARNING com.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.ValidationType.Type = com.getImplementationName = "ScCellObj" Or oSel.star.ConditionOperator.sheet. en los casos de “advertencia” ( WARNING) e “información” (INFO).STOP com.star.sheet. oValidacion) End If End Sub El tipo decimal. al aceptar.ValidationAlertStyle.ValidationAlertStyle.ANY 'Que muestre un mensaje al seleccionar la celda oValidacion.sun.ValidationAlertStyle. para.getImplementationName = "ScCellRangeObj" Then 'Obtenemos la estructura validación oValidacion = oSel. “reinsertar” (setPropertyValue) la propiedad al objeto para que los cambios surtan efecto. te permite capturar números con decimales: Sub Dim Dim Dim ValidarDatos3() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.getImplementationName = "ScCellObj" Or oSel.getCurrentSelection() 'Validamos que sea una celda o un rango de celdas If oSel.sun.sun. Por ultimo.MACRO Valor 0 1 2 3 Valor en Interfaz Stop Advertencia Información Macro Si estableces el valor en “stop” (STOP).sheet. solo establece el tipo (Type) en cualquier valor (ANY) y deshabilita el mensaje de entrada (ShowInputMessage). Para quitar una validación.star.star.star.ShowInputMessage = False 'Reinsertamos la propiedad para que surtan efecto los cambios oSel.BETWEEN ) .getPropertyValue("Validation") 'El tipo de validación oValidacion.ValidationType.getPropertyValue("Validation") With oValidacion .ShowInputMessage = True .Aprendiendo OOo Basic 321 com.setFormula1 ( "0" ) . se mostrara al usuario un mensaje (ErrorMessage) con un titulo (ErrorTitle) para informarle del error.InputTitle = "Introduce la calificacion" .sun.sun.getCurrentSelection() If oSel.Type = com.star.

ValidationAlertStyle.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.LESS_EQUAL ) 'Usamos una formula como condición . solo puede capturar una hora que no sea entre 1 p.sheet.sheet.setFormula1 ( "TIME(13.ErrorTitle = "Dato erroneo" .sun.sheet.getPropertyValue("Validation") With oValidacion .setOperator ( com.sheet.sheet.IgnoreBlankCells = True .sheet. Sub Dim Dim Dim ValidarDatos4() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.0.ErrorAlertStyle = com.: Sub Dim Dim Dim ValidarDatos5() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.WARNING .star.IgnoreBlankCells = True .Type = com.InputMessage = "La fecha no puede ser futura" .ShowInputMessage = True .star. oValidacion) End If End Sub Ahora.DATE .STOP .getImplementationName = "ScCellObj" Or oSel.star. nota el uso de la función incorporada de Calc.InputTitle = "Hora de salida" .star.322 .NOT_BETWEEN ) 'Introducir una hora que no sea entre 1 y 3 p.ErrorMessage = "El valor introducido no es válido" End With oSel.Type = com.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.getCurrentSelection() If oSel.InputMessage = "La hora de salir" .ValidationType.0. validamos que no sea una fecha futura.ErrorAlertStyle = com.0" ) .ErrorTitle = "Dato erroneo" . 3 p.sheet.ErrorAlertStyle = com.ErrorTitle = "Dato erroneo" .InputTitle = "Fecha de Nacimiento" .sun.getPropertyValue("Validation") With oValidacion .sun.ConditionOperator.ValidationAlertStyle.0" ) .m.ValidationType.star.setFormula2 ( "TIME(15.7 Rangos de datos En el siguiente ejemplo.m.ShowInputMessage = True .ShowErrorMessage = True .star.TIME .sun.setOperator ( com.sun.setFormula1 ( "TODAY()" ) .ErrorMessage = "El valor introducido no es válido" End With 'Reinsertamos la propiedad para que surtan efecto los cambios oSel.INFO .setPropertyValue("Validation".ConditionOperator.sun.setPropertyValue("Validation".sun.ShowErrorMessage = True .getCurrentSelection() If oSel.m. oValidacion) End If End Sub 6.star.getImplementationName = "ScCellObj" Or oSel. .ValidationAlertStyle.

LIST 'Introducir valores desde un rango de celdas .ShowErrorMessage = True .getImplementationName = "ScCellRangeObj" Then oValidacion = oSel. o por código.ErrorTitle = "Dato erroneo" .ErrorMessage = "El valor introducido no es válido" End With oSel.sun. establecemos que los valores los tome desde un rango de celdas.setFormula1 ( "valores" ) .ValidationType.getCurrentSelection() If oSel. desde el cuadro de nombres de la barra de formulas. observa que las referencias al rango son absolutas: Sub Dim Dim Dim ValidarDatos6() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.ValidationAlertStyle.Type = com.LIST 'Introducir valores desde un rango de celdas .star.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.ShowErrorMessage = True .getCurrentSelection() If oSel.ErrorTitle = "Dato erroneo" .getPropertyValue("Validation") With oValidacion .getPropertyValue("Validation") With oValidacion . En el siguiente ejemplo.setPropertyValue("Validation".getImplementationName = "ScCellObj" Or oSel.sun.Type = com.ShowList = 2 . como hemos aprendido en .setPropertyValue("Validation".sun. que te devuelve el número de serie de la hora pasada. en la interfaz del usuario.Aprendiendo OOo Basic 323 .star. por ejemplo: Sub Dim Dim Dim ValidarDatos7() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.setPropertyValue("Validation".star.ValidationType.ErrorMessage = "El valor introducido no es válido" End With oSel.ErrorAlertStyle = com.sheet.ErrorAlertStyle = com. oValidacion) End If End Sub Observa que estamos haciendo uso de la función de Calc.sun.getImplementationName = "ScCellObj" Or oSel. oValidacion) End If End Sub Recuerda que los rangos con nombre los establecemos.sheet.setFormula1 ( "$I$2:$I$8" ) .sheet. esto es necesario para establecer los limites correctamente.sheet.STOP .star. NSHORA (TIME).STOP .ValidationAlertStyle.ErrorMessage = "El valor introducido no es válido" End With oSel. oValidacion) End If End Sub Pero también podemos establece el rango desde un rango de celda con nombre.

el valor 2 determina que se muestre con los valores ordenados de forma ascendente. este en una hoja diferente. pues desde código la podemos actualizar siempre que queramos. puedes usar cualquier texto o formula que te devuelva un rango de celdas válido.star.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.star. El poder de hacerlo con funciones o desde código.sun. nos devuelve una referencia en forma de texto.sun.7 Rangos de datos este libro. Como a la función DIRECCION se le pueda establecer entre sus parámetros el nombre de una hoja. no te dará el rango correcto: Sub Dim Dim Dim ValidarDatos8() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.star.star.324 6. establecemos el origen de celdas con formulas de Calc. Estos valores corresponden a: com.Type = com.LIST 'Introducir valores desde un rango de celdas . una lista de clientes que va creciendo confirme vamos agregando registros o cualquier otro listado que vaya creciendo en sentido vertical.star. esta formula debe estar bien construida.TableValidationVisibility. veamos como: .sun.ErrorMessage = "El valor introducido no es válido" End With oSel. Observa que hemos usado una nueva propiedad (ShowList). y el valor 0 que no se muestre la lista de selección. es introducir una lista fija de valores. podemos determinar si mostramos la flecha de lista de selección.getCurrentSelection() If oSel. que los muestre tal y como están en el origen.ShowList = 2 . después.getImplementationName = "ScCellObj" Or oSel.ErrorAlertStyle = com.sheet. Otra posibilidad.sheet..STOP .setFormula1 ( "INDIRECT(ADDRESS(1. la función INDIRECTO (INDIRECT).1))" ) . es que la lista de validación la puedes actualizar dinámicamente.sun..sheet.UNSORTED com.sheet.TableValidationVisibility com.star. aunque también puedes usar un nombre de área de datos definida en el menú Datos | Definir. el valor 1 que se muestre pero que no ordene los valores.sheet.sun.SORTEDASCENDING Valor 0 1 2 Valor en Interfaz No mostrar lista Mostrar desordenada Mostrar ordenada ascendente En el siguiente ejemplo.ValidationAlertStyle.sun. te queda de tarea modificar la macro anterior para que el rango de celdas de la validación. si no.. si el rango de celdas tiene más de una columna. oValidacion) End If End Sub Recuerda que la función DIRECCION (ADDRESS). la referencia a dicha celda.ErrorTitle = "Dato erroneo" . solo se usara la primer columna.TableValidationVisibility.sheet. por ejemplo. de hecho.1)&"":""&ADDRESS(10. o semifija.ShowErrorMessage = True . algo no muy recomendable cuando se usa una lista. de una cadena de texto que tenga un rango de celda válido.getPropertyValue("Validation") With oValidacion .ValidationType. nos devuelve.INVISIBLE com.TableValidationVisibility. cuando el tipo de la validación esta establecida en “lista” (LIST).setPropertyValue("Validation". de acuerdo a los parámetros pasados.

ValidationAlertStyle.ShowErrorMessage = True . que esta forma de introducir los datos fijos.Aprendiendo OOo Basic Sub Dim Dim Dim ValidarDatos9() oDoc As Object oSel As Object oValidacion As Object 325 oDoc = ThisComponent oSel = oDoc."&"""VALOR3""" ) . tienes que pasarle cada valor como una cadena.sun. lo cual es incorrecto.ShowList = 2 .Type = com.VALOR2.sun.ErrorAlertStyle = com.ErrorMessage = "El valor introducido no es válido" End With oSel.ShowList = 2 .sheet. oValidacion) End If End Sub Pero ve que cantidad de comillas.ValidationType.sheet.VALOR3" ) .STOP . desde Datos | Validez.ValidationAlertStyle.setPropertyValue("Validation".Type = com. la detecta como si fuera un intervalo de celdas.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.sun.setFormula1 ( "VALOR1.. como en el siguiente ejemplo: Sub Dim Dim Dim Dim ValidarDatos11 sTmp As String m oDoc As Object oSel As Object .getCurrentSelection() If oSel.sun.getImplementationName = "ScCellObj" Or oSel.ShowErrorMessage = True .getPropertyValue("Validation") With oValidacion .star. como en el siguiente ejemplo: Sub Dim Dim Dim ValidarDatos10() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc. cuando nosotros los agregamos en mayúsculas.ErrorAlertStyle = com.sheet.ErrorTitle = "Dato erroneo" . podemos hacer una función que agregue las comillas por nosotros.getImplementationName = "ScCellObj" Or oSel.. oValidacion) End If End Sub Ve a la interfaz del usuario y observa como “aparentemente”. ¿y son muchos valores?.setFormula1 ( """VALOR1"""&".ValidationType.star. pero observa que están en minúsculas."&"""VALOR2"""&".star. si agrego los valores.ErrorTitle = "Dato erroneo" .star.LIST 'Introducir valores fijos .sheet.getPropertyValue("Validation") With oValidacion .setPropertyValue("Validation"..LIST 'Introducir valores fijos .getCurrentSelection() If oSel. para que realmente la detecte como una lista “fija” de valores.ErrorMessage = "El valor introducido no es válido" End With oSel. verifica desde la interfaz de usuario.STOP .

" ) End Function Ahora si." Function JuntarEnLista( ByVal m ) As String Dim co1 As Long For co1 = LBound(m) To UBound(m) m(co1) = """" & m(co1) & """" Next JuntarEnLista = Join( m.ShowList = 2 .STOP .sun."Cinco") 'Los juntamos sTmp = JuntarEnLista(m) . no lo tomes como un tema menor.setPropertyValue("Validation".star.setOperator ( com."Dos".star.sheet."Cuatro".ValidationAlertStyle.setFormula2 ( "10" ) .sheet.ErrorTitle = "Longitud erronea" .sheet.setFormula1( sTmp ) End With oSel.ConditionOperator.setFormula1 ( "5" ) .sun. y aun más desde código. solo letras o alfanuméricas: Sub Dim Dim Dim ValidarDatos12() oDoc As Object oSel As Object oValidacion As Object oDoc = ThisComponent oSel = oDoc.getPropertyValue("Validation") With oValidacion ."Tres". El siguiente ejemplo te limita la entrada a una palabra de entre 5 y 10 letras.ErrorAlertStyle = com. la validación de datos es un tema central en la programación. no te acepta solo números.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.getImplementationName = "ScCellRangeObj" Then oValidacion = oSel.ValidationType. separados por ".getImplementationName = "ScCellObj" Or oSel.getCurrentSelection() If oSel.ErrorMessage = "La palabra debe ser de entre 5 y 10 caracteres" End With 'Reinsertamos la propiedad para que surtan efecto los cambios oSel.getCurrentSelection() If oSel.star.Type = com. oValidacion) End If End Sub 'Toma una matriz y le agrega comillas a cada elemento 'Devuelve una cadena con los elementos.326 Dim oValidacion As Object 6. ".sun.LIST .setPropertyValue("Validation".BETWEEN ) .ValidationType.TEXT_LEN . es preferible agregar unas cuantas líneas más de código a correr el riesgo de que un dato inconsistente nos devuelva .ShowErrorMessage = True . es un poco más fácil agregar valores a una lista.star.getImplementationName = "ScCellObj" Or oSel.sheet.sun.IgnoreBlankCells = True .getPropertyValue("Validation") With oValidacion 'Valores a agregar m = Array("Uno".Type = com. oValidacion) End If End Sub Tanto en la interfaz del usuario.7 Rangos de datos oDoc = ThisComponent oSel = oDoc.

group( oRango. vista muchas veces en este libro y como segundo argumento. imaginación.Sheet = oHojaActiva. 0 = por columnas oHojaActiva.table. sentido común. 6.getRangeAddress.sun. estamos verificando el ¿porque? de esto.Sheet = oHojaActiva.getActiveSheet() With oRango .Sheet 'Ahora establecemos el rango de filas .getActiveSheet() 'Establecemos las propiedades del grupo With oRango 'La hoja donde se creará .Sheet 'La columna de inicio .StartColumn = 0 'La columan de fin .star. estén dentro de rangos válidos.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc.EndColumn = 4 End With 'Creamos el grupo. son herramientas que pueden apoyarnos. si no. podemos probar lo siguiente: Sub Dim Dim Dim Agrupar1() oDoc As Object oHojaActiva As Object oRango As New com. inteligencia. que no es más que ocultarlas. 0 ) End Sub La macro anterior nos agrupará las columnas 1 a 5 en la interfaz del usuario. le pasamos una estructura de dirección de un rango (CellRangeAddress). puede ser la diferencia entre eficiencia e ineficiencia. que el índice de hoja exista.table. 1 = por filas . cuando simplemente necesitemos agrupar por un rango de columnas o filas.sun.Aprendiendo OOo Basic 327 información inconsistente. Ahora.StartRow = 0 . pero sobre todo. puedes provocar una caída de la aplicación. si queremos que se agrupe por columnas (0) o por filas (1). Observa como al agrupar (group).7. agrupamos las primeras diez filas de la hoja activa: Sub Dim Dim Dim Agrupar2() oDoc As Object oHojaActiva As Object oRango As New com. por ejemplo. los filtros.EndRow = 9 End With 'Y agrupamos.getCurrentController. el ordenar y los subtotales. encontrar una manera simple y rápida de agrupar datos.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc. es muy importante que validez que la hoja y el rango de columnas establecidas.getCurrentController. Tienes instrucciones limitadas pero suficientes para evitarlo y tienes algo ilimitado.6 Agrupando datos Cuando se maneja una gran cantidad de información.star. explotalos.getRangeAddress.

Sheet = oHojaActiva. lo que borrara cualquier grupo creado. la segunda: .getCurrentController.star.getCurrentController.table. 0 ) oHojaActiva.328 oHojaActiva. puedes establecer. desde la hoja donde estés haciendo estas pruebas.getRangeAddress.getRangeAddress.StartRow = 9 .EndRow = 9 End With 'Deagrupamos filas y columnas oHojaActiva. 0 ) 'Agrupamos por filas 10 a 20 oHojaActiva.getActiveSheet() With oRango . 1 ) End Sub El rango usado para desagrupar (ungroup).EndRow = 19 End With 'Agrupamos por columnas 10 a la 20 oHojaActiva.ungroup( oRango. ve al menú Datos | Agrupar y Esquema | Eliminar.Sheet . Sub Dim Dim Dim Agrupar4() oDoc As Object oHojaActiva As Object oRango As New com.ungroup( oRango.EndColumn = 19 . no tiene que coincidir exactamente. con la misma estructura.group( oRango.table. con que este “dentro” del rango con que se agrupo. tanto las columnas como las filas. es suficiente. 1 ) End Sub 6. 1 ) End Sub Desagrupar (ungroup) es trivial.sun.sun.getActiveSheet() With oRango .StartColumn = 0 .Sheet .group( oRango.Sheet = oHojaActiva.StartColumn = 9 . después. en tamaño.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc. al rango original de agrupamiento.StartRow = 0 .EndColumn = 4 .star. ejecuta la primer macro siguiente e inmediatamente después.7 Rangos de datos Por supuesto. usa los mismos argumentos que para agrupar. antes de comprobarlo.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc.group( oRango. como en el siguiente ejemplo: Sub Dim Dim Dim Agrupar3() oDoc As Object oHojaActiva As Object oRango As New com.

Sheet 'Solo indicamos la primer columna y fila . pero asegurate.Sheet = oHojaActiva.StartRow = 0 . contrae el grupo para ocultar su contenido. ejecuta la macro para desagrupar. si el grupo esta contraído.table. Cuando eliminas los grupos desde la interfaz del usuario.getCurrentController. 0 ) oHojaActiva.getRangeAddress.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc. 1 ) End Sub Observa como agrupamos por un rango y desagrupamos por otro.getActiveSheet() With oRango .sun. este “dentro” del rango agrupado. asegurate de mostrar el detalle del rango como en el siguiente ejemplo: Sub Dim Dim Dim Agrupar7() oDoc As Object oHojaActiva As Object oRango As New com. para evitar esto.StartColumn = 0 .table. 1 ) End Sub Sub Dim Dim Dim Agrupar6() oDoc As Object oHojaActiva As Object oRango As New com.sun.StartRow = 0 . ahora sí.Sheet = oHojaActiva.Sheet .CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc.group( oRango.StartColumn = 0 . vuelve a realizar la prueba anterior.EndRow = 19 End With 'Agrupamos filas (1-20) y columnas (1-10) oHojaActiva.EndColumn = 0 .getRangeAddress.getRangeAddress. donde solo nos tenemos que asegurar que.group( oRango.getActiveSheet() With oRango .star.sun. antes de desagrupar.star.Aprendiendo OOo Basic Sub Dim Dim Dim 329 Agrupar5() oDoc As Object oHojaActiva As Object oRango As New com. 0 ) oHojaActiva.EndRow = 0 End With 'Desagrupamos filas y columnas oHojaActiva.Sheet = oHojaActiva.getCurrentController.getCurrentController.EndColumn = 9 . notaras que el rango usado seguirá oculto. no sucede lo mismo cuando lo haces por código.Sheet . el rango a desagrupar.ungroup( oRango.getActiveSheet() With oRango . las columnas o filas ocultas. de que.star.ungroup( oRango. antes de desagrupar.table.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc. se mostrarán inmediatamente.

getCurrentController. podría no ser tan fácil de conocer. dependiendo de si exista o no previamente uno en el rango pasado. sucederá cualquiera de las siguientes acciones. Cuando agregas grupos.StartRow = 0 . el rango agrupado (group).sun.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc.getActiveSheet() 'Eliminamos cualquier grupo de la hoja oHojaActiva.StartColumn = 0 .getCurrentController.StartColumn = 0 .Sheet . lo cual.330 'Solo indicamos la primer columna y fila .clearOutline() With oRango . 0 ) oHojaActiva.StartColumn = 0 .sun.EndColumn = 9 .table. veamoslo con ejemplos.ungroup( oRango. se agregará al mismo nivel. si el rango ya contiene un grupo. en el primero comprobamos que se agregan los grupos en niveles: Sub Dim Dim Dim Agrupar9() oDoc As Object oHojaActiva As Object oRango As New com.getActiveSheet() oHojaActiva.EndColumn = 3 End With 'Agrupamos las columnas 1-4 . puedes crear hasta ocho niveles de ellos.EndColumn = 1 End With 'Agrupamos las columnas 1-2 oHojaActiva. siempre y cuando.EndRow = 19 End With 'Expandimos el grupo contenido en el rango oHojaActiva.clearOutline() End Sub Con lo cual.group( oRango. es mucho más sencillo. Si lo que quieres es eliminar cualquier grupo existente en una hoja.Sheet = oHojaActiva. 1 ) End Sub 6. este.star. eliminar cualquier grupo y volver a crear el necesario. corresponda “exactamente” con el rango mostrado (showDetail) y con el rango desagrupado (ungroup).7 Rangos de datos El ejemplo anterior funcionará.getRangeAddress. usamos: Sub Dim Dim Dim Agrupar8() oDoc As Object oHojaActiva As Object oRango As New com. se creará un nuevo nivel de agrupamiento. 0 ) With oRango .table.showDetail( oRango ) 'Desagrupamos filas y columnas oHojaActiva. en ocasiones.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc.star.ungroup( oRango. si el rango no contiene un grupo.

0 ) With oRango .EndColumn = 5 End With 'Agrupamos las columnas 1-6 oHojaActiva.group( oRango.StartColumn = 0 .Aprendiendo OOo Basic oHojaActiva.group( oRango. 0 ) End Sub 331 .

332

6.7 Rangos de datos

Aprendiendo OOo Basic

333

334

6.7 Rangos de datos

Aprendiendo OOo Basic

335

336

6.7 Rangos de datos

Ahora, veamos como agregar al mismo nivel:
Sub Dim Dim Dim Agrupar10() oDoc As Object oHojaActiva As Object oRango As New com.sun.star.table.CellRangeAddress

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oHojaActiva.clearOutline() With oRango .Sheet = oHojaActiva.getRangeAddress.Sheet .StartRow = 0 .EndRow = 3 End With 'Agrupamos la fila 1 a 4 oHojaActiva.group( oRango, 1 ) With oRango .StartRow = 5 .EndRow = 8 End With 'Agrupamos la fila 4 a 7 oHojaActiva.group( oRango, 1 ) With oRango .StartRow = 10 .EndRow = 13 End With 'Agrupamos la fila 9 a 12 oHojaActiva.group( oRango, 1 ) End Sub

Y lo comprobamos:

Puedes crear un grupo y ocultarlo inmediatamente, como en:
Sub Agrupar11() Dim oDoc As Object Dim oHojaActiva As Object

Aprendiendo OOo Basic

337

Dim oRango As New com.sun.star.table.CellRangeAddress oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() With oRango .Sheet = oHojaActiva.getRangeAddress.Sheet .StartColumn = 0 .EndColumn = 9 End With oHojaActiva.group( oRango, 0 ) 'Ocultamos el grupo contenido en el rango oHojaActiva.hideDetail( oRango ) End Sub

A diferencia de mostrar un grupo (showDetail), cuando lo ocultas (hideDetail), el rango no necesariamente debe ser del mismo tamaño, con que apunte a cualquier celda dentro del rango a ocultar, funcionará. También tienes la posibilidad de mostrar cualquier nivel de agrupamiento, los demás niveles hacia arriba, si los hay, se cerraran:
Sub Dim Dim Dim Agrupar12() oDoc As Object oHojaActiva As Object oRango As New com.sun.star.table.CellRangeAddress

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() With oRango .Sheet = oHojaActiva.getRangeAddress.Sheet .StartRow = 0 .EndRow = 4 End With oHojaActiva.group( oRango, 1 ) With oRango .StartRow = 0 .EndRow = 9 End With oHojaActiva.group( oRango, 1 ) With oRango .StartRow = 0 .EndRow = 14 End With oHojaActiva.group( oRango, 1 ) With oRango .StartRow = 0 .EndRow = 19 End With oHojaActiva.group( oRango, 1 ) 'Mostramos el nivel 2 oHojaActiva.showLevel( 2, 1 ) End Sub

El método para mostrar un nivel especifico (showLevel), solo usa dos parámetros, el nivel a mostrar como primero y como segundo parámetro, si el nivel a mostrar esta en columnas (0) o en filas (1). Para terminar este tema, veamos un ejemplo practico bastante útil, para que veas su uso, procura llamarla, teniendo el cursor dentro de un rango de celdas que tenga al

338

6.7 Rangos de datos

menos dos pantallas de datos en sentido vertical, es decir, de filas, si tienes más filas, es mucho mejor pues se paginara más:
Sub Dim Dim Dim Dim Dim Dim Dim Agrupar13() oDoc As Object oHojaActiva As Object oSel As Object oCursor As Object iNumFilPag As Integer oRango As New com.sun.star.table.CellRangeAddress co1 As Long

oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController.getActiveSheet() oSel = oDoc.getCurrentSelection() 'Obligamos a seleccionar solo una celda If oSel.getImplementationName = "ScCellObj" Then 'Creamos un cursor a partir de la celda seleccionada oCursor = oHojaActiva.createCursorByRange( oSel ) 'Expandimos a la región actual oCursor.collapseToCurrentRegion() 'Obtenemos el número de filas visibles por página iNumFilPag = oDoc.getCurrentController.getVisibleRange.EndRow oDoc.getCurrentController.getVisibleRange.StartRow - 1 'Establecemos el primer nivel de agrupamiento en el total de filas With oRango .Sheet = oHojaActiva.getRangeAddress.Sheet .StartRow = 0 .EndRow = oCursor.getRangeAddress.EndRow End With oHojaActiva.group( oRango, 1 ) 'Agregamos un segundo nivel de agrupamiento, página por página For co1 = 0 To oCursor.getRangeAddress.EndRow Step iNumFilPag oRango.StartRow = co1 + 1 oRango.EndRow = co1 + iNumFilPag - 1 oHojaActiva.group( oRango, 1 ) Next 'Para el ultimo rango si no es exacto If co1 > oCursor.getRangeAddress.EndRow Then oRango.StartRow = co1 - iNumFilPag + 1 oRango.EndRow = oCursor.getRangeAddress.EndRow oHojaActiva.group( oRango, 1 ) End If oHojaActiva.ShowLevel( 1, 1 ) Else MsgBox "Selecciona solo una celda" End If End Sub

Y mira que bien queda:

Aprendiendo OOo Basic

339

Claro que el área no esta limitada a que tenga datos, puedes establecer tus criterios pero sobre todo tus necesidades particulares para agrupar.

6.8

Bases de datos

La manipulación y administración de datos, es una de las necesidades más recurrentes en usuarios de hoja de cálculo, esto no es gratuito, pues las herramientas presentes en ellas, facilitan enormemente esta tarea. Para el mejor aprovechamiento de este capitulo, sería deseable que conocieras los siguientes conceptos: base de datos, tabla, campo, registro, consulta, SQL, clave primaria, índice, relaciones e integridad referencial. Dada la amplia documentación existente en castellano de estos temas, no duplicaremos esfuerzos y te queda de tarea investigar un poco acerca de ello, si no los dominas. También, es indispensable que las bases de datos que usemos, al menos en este capitulo, estén registradas en OOo, para registrar una base de datos, seguimos los siguientes pasos, ve al menú Herramientas | Opciones..., selecciona la rama OpenOffice.org Base y después la subrama Bases de datos, donde tienes que ver las siguientes opciones:

340

6.8 Bases de datos

Da clic en el botón de comando Nuevo..., para ve el siguiente cuadro de dialogo:

En el cual, le darás clic al botón de comando Examinar..., que te mostrará el conocido cuadro de dialogo para seleccionar archivos, navega hasta la ruta donde hayas guardado la base de datos o este localizada la base de datos que quieras registrar y selecciónala, por ultimo da un clic en el botón de comando Abrir.

Al dar clic en el botón de comando Abrir, tienes que regresar al cuadro de dialogo anterior, pero, ahora, tienes que ver la ruta completa del archivo que acabas de seleccionar, así como el nombre propuesto con el que se registrará la base de datos, este nombre puedes

Aprendiendo OOo Basic

341

personalizarlo a tu gusto pues acepta espacios incluso, pero mi recomendación es que no uses ni espacios ni caracteres “extraños”, para nuestro ejemplo, dejaremos el propuesto:

Da un clic en el botón de comando Aceptar para regresar al primero cuadro de dialogo, donde, ahora, tendrás que ver la nueva base de datos registrada.

Agrega de una vez la otra base de datos que acompaña a estos apuntes, se llama “Videoteca” y también la usaremos para nuestros ejemplos. Solo te resta cerrar este cuadro de dialogo con el botón de comando Aceptar.

6.8.1

Importando datos

Importa datos desde bases de datos registradas en OpenOffice.org, es trivial, solo tienes que presionar la tecla F4, que te mostrará estas bases en la ventana “Fuente de datos”, junto con todos sus objetos; tablas y consultas, seleccionar la base de datos de nuestro interés, expandir para mostrar su contenido, seleccionar la tabla o consulta que quieras, el contenido de dicho objeto, te lo mostrará en el panel derecho del examinador de fuentes de datos, solo te resta seleccionar todo con el botón de seleccionar todo, arrastrar a tu documento y listo, tienes que tener los datos seleccionados, como en la siguiente imagen:

Name = "SourceObject" . con el cual. por ejemplo: Sub Dim Dim Dim Dim BasesDeDatos1() oHojaActiva As Object sBaseDatos As String sTabla As String mOpcBD(2) As New "com. a este método.star.sun.PropertyValue" 'El nombre de nuestra base de datos sBaseDatos = "Directorio" 'La tabla que nos interesa traer sTabla = "tblContactos" 'La hoja activa oHojaActiva = ThisComponent.DataImportMode. de bases de datos previamente registradas en OpenOffice.org. con las indicaciones de que queremos importar. tenemos posibilidades “casi” ilimitadas para importar datos. Para importar datos.Name = "SourceType" mOpcBD(1).getCurrentController. se le pasa una matriz de propiedades.sun.Value = sBaseDatos 'El tipo de objeto fuente mOpcBD(1). podrás comprobarlo más adelante.Value = com. aprenderemos a hacer esto mismo. usamos el método doImport.star. por código.beans. pero claro. primero el nombre de la base de datos mOpcBD(0).Name = "DatabaseName" mOpcBD(0).getActiveSheet() 'Las propiedades de la importación. presente en rangos de datos.TABLE 'El nombre del objeto fuente mOpcBD(2).8 Bases de datos En este capitulo.sheet.342 6.

por lo que tienes que ser muy cuidadoso de como nombrarlos y usar exactamente este nombre al importar.sheet. de lo contrario te puede alguno de los siguientes errores: Cuando el nombre de la base de datos no corresponde: Cuando la tabla este incorrecta: En el siguiente ejemplo.sheet.sun. consultas.DataImportMode.sun.star.sun.sheet.DataImportMode com. tablas.star.QUERY Valor 0 1 2 3 Valor en Interfaz Vacio Instrucción SQL Tabla Consulta Si estableces el tipo de objeto fuente en 0 ( NONE).star.getCellRangeByName("A1").star. después. El tipo de objeto esta determinado por la enumeración: com. luego.sheet. campos) distingue mayúsculas de minúsculas.star. el nombre del objeto (SourceObject) que queremos importar.sheet.beans.Value = sTabla 'Importamos la tabla. Todos los nombres de objetos (bases de datos. a partir de la celda A1 oHojaActiva. por ultimo aplicamos la importación (doImport).star.sun.doImport( mOpcBD() ) End Sub Nota como estamos usando el nombre con que registramos la base de datos (DatabaseName).DataImportMode.PropertyValue" 'El nombre de nuestra base de datos sBaseDatos = "Directorio" 'La tabla que nos interesa traer sTabla = "tblPaises" 'La hoja activa .sun. de lo contrario te dará error al importar. importamos una tabla diferente en una celda diferente: Sub Dim Dim Dim Dim BasesDeDatos2() oHojaActiva As Object sBaseDatos As String sTabla As String mOpcBD(2) As New "com.NONE com.DataImportMode.DataImportMode. entonces tienes que pasarle una instrucción SQL. le estamos indicando el tipo de objeto (SourceType) que queremos importar.SQL com.Aprendiendo OOo Basic 343 mOpcBD(2).sun.TABLE com.

Name = "DatabaseName" mOpcBD(0).beans. a partir de la celda A1 oHojaActiva. importamos una consulta (QUERY) en vez de una tabla (TABLE).PropertyValue" sBaseDatos = "Directorio" .sun.QUERY 'El nombre del objeto fuente mOpcBD(2).getCurrentController.sheet.sun.Name = "SourceType" mOpcBD(1). si no.star.star.Value = sConsulta 'Importamos la tabla.getCellRangeByName("A1").TABLE 'El nombre del objeto fuente mOpcBD(2).DataImportMode.344 oHojaActiva = ThisComponent.DataImportMode.Name = "DatabaseName" mOpcBD(0). Sub Dim Dim Dim Dim BasesDeDatos3() oHojaActiva As Object sBaseDatos As String sConsulta As String mOpcBD(2) As New "com.getActiveSheet() 'Las propiedades de la importación.Value = sBaseDatos 'El tipo de objeto fuente mOpcBD(1).Name = "SourceType" mOpcBD(1).Value = com.Name = "SourceObject" mOpcBD(2).doImport( mOpcBD() ) End Sub 6.star. el método te devolverá un error: Importamos una consulta diferente: Sub Dim Dim Dim Dim BasesDeDatos4() oHojaActiva As Object sBaseDatos As String sConsulta As String mOpcBD(2) As New "com.beans. primero el nombre de la base de datos mOpcBD(0).sun.Value = com.getCurrentController.Value = sTabla 'Importamos la tabla. a partir de la celda A10 oHojaActiva.getActiveSheet() mOpcBD(0).8 Bases de datos Ahora.PropertyValue" sBaseDatos = "Directorio" 'Ahora una consulta sConsulta = "qryCiudades" 'La hoja activa oHojaActiva = ThisComponent.doImport( mOpcBD() ) End Sub Tienes que tener la precaución de que el nombre del objeto corresponda a su tipo.sheet.getCellRangeByName("A10"). una consulta mOpcBD(1).Name = "SourceObject" mOpcBD(2).sun.Value = sBaseDatos 'El tipo de objeto fuente.star.

getCurrentController. es decir.star. me limitaré a darte muestras de instrucciones SQL que sean lo suficientemente ilustrativas del poder y versatilidad de este lenguaje. hace exactamente lo mismo que el primer ejemplo.getActiveSheet() . SQL es un lenguaje estructurado de consultas.getActiveSheet() mOpcBD(0).Value = sSQL oHojaActiva. nos permite recuperar “casi” cualquier dato de cualquier base de datos con soporte para SQL.Name = "SourceType" mOpcBD(1). podemos limitarnos exclusivamente a los datos que necesitamos.star..Value = sConsulta oHojaActiva. Paterno y Materno) campos de la tabla (tblContactos): Sub Dim Dim Dim Dim BasesDeDatos6() oHojaActiva As Object sBaseDatos As String sSQL As String mOpcBD(2) As New "com.Name = "SourceObject" mOpcBD(2).sun.sheet.Name = "DatabaseName" mOpcBD(0). así que. ¿que es SQL?.sun.Aprendiendo OOo Basic 345 'Una consulta sConsulta = "qryContactos" oHojaActiva = ThisComponent.Value = com. es que estamos usando una instrucción SQL para importar los datos.Name = "SourceObject" mOpcBD(2).getCellRangeByName("A1"). SQL es un estándar.Name = "DatabaseName" mOpcBD(0).Name = "SourceType" 'Observa como hemos cambiado el tipo de fuente a SQL mOpcBD(1).getCurrentController.getCellRangeByName("A1").star.Value = sBaseDatos mOpcBD(1).star. la respuesta sencilla. estas.getActiveSheet() mOpcBD(0). la primera.DataImportMode.sheet..QUERY mOpcBD(2). en “teoría”. el siguiente ejemplo.beans.PropertyValue" sBaseDatos = "Directorio" 'Establecemos la consulta SQL sSQL = "SELECT * FROM tblContactos" oHojaActiva = ThisComponent.PropertyValue" sBaseDatos = "Directorio" 'Establecemos la consulta SQL sSQL = "SELECT Nombre. Cuando importamos tablas o consultas.Value = sBaseDatos mOpcBD(1). en el siguiente ejemplo.getCurrentController. se importan con todo su contenido.SQL mOpcBD(2).beans.doImport( mOpcBD() ) End Sub Cambiemos de tipo de objeto fuente. Materno FROM tblContactos" oHojaActiva = ThisComponent.doImport( mOpcBD() ) End Sub Entonces.sun. con SQL. En los siguiente ejemplos. la respuesta compleja nos podría llevar una libro completo. es obvio.sun.DataImportMode. Paterno.Value = com. nos importa la tabla “tblContactos”: Sub Dim Dim Dim Dim BasesDeDatos5() oHojaActiva As Object sBaseDatos As String sSQL As String mOpcBD(2) As New "com. cualquier documentación de el “debería” servirte. pero. solo importamos tres (Nombre. ¿cual es la diferencia?.

Name = "SourceObject" mOpcBD(2).getCellRangeByName("A1").Value = sSQL oHojaActiva.sun.Name = "DatabaseName" mOpcBD(0).star.346 6. Las instrucciones SQL. por uno de más fácil lectura para el usuario.getCellRangeByName("A1").sun. el método te devolverá un error: Nota como claramente nos esta diciendo que el campo no existe.sheet. si el campo no existe. de nuevo.getActiveSheet() mOpcBD(0). Materno FROM tblContactos ORDER BY Paterno" oHojaActiva = ThisComponent. en este segundo ejemplo.sun.8 Bases de datos mOpcBD(0).doImport( mOpcBD() ) End Sub El nombre de los campos.Name = "SourceType" mOpcBD(1). Paterno.sheet. ordenamos (ORDER BY) los datos importados: Sub Dim Dim Dim Dim BasesDeDatos7() oHojaActiva As Object sBaseDatos As String sSQL As String mOpcBD(2) As New "com.Name = "SourceObject" mOpcBD(2).star.Value = com.beans. para estos casos. filtrar y ordenar entre otras acciones a los datos importados. tenemos una clausula para cambiar el nombre original del campo.doImport( mOpcBD() ) End Sub Observa como en el primer ejemplo de instrucción SQL.SQL mOpcBD(2).SQL mOpcBD(2).Name = "SourceType" mOpcBD(1).Value = sBaseDatos mOpcBD(1). pero muchas veces este nombre no le dice mucho al usuario. ten mucho cuidado con los nombres de tus campos.Value = com.DataImportMode. le indicamos explícitamente que campos queremos importar. limitar. estas no permiten complementar.Name = "DatabaseName" mOpcBD(0). tiene unos modificadores que se llaman “clausulas”. veamos como: Sub BasesDeDatos8() Dim oHojaActiva As Object .Value = sSQL oHojaActiva. casi siempre se establece de forma que sea fácil de recordar y de manipular por el programador.getCurrentController.Value = sBaseDatos mOpcBD(1). recuerda que en los nombres se distingue entre mayúsculas y minúsculas.star.PropertyValue" sBaseDatos = "Directorio" 'Establecemos la consulta SQL sSQL = "SELECT Nombre. le indicamos que queremos todo (*) con el asterisco. En el siguiente ejemplo.DataImportMode.

para hacer consultas sobre campos de fechas.sun.DataImportMode.doImport( mOpcBD() ) End Sub . para consultar una fecha especifica.Value = sBaseDatos mOpcBD(1). si estableces correctamente este criterio. Paterno As ""Apellido Paterno"".sheet. deben ser exactamente las necesarias.star.Name = "DatabaseName" mOpcBD(0). nota el uso de la letra D (de Date) y las comillas en la fecha. el orden tiene que ser precisamente así añomes-día.Name = "SourceObject" mOpcBD(2). Cumple As Cumpleaños FROM tblContactos ORDER BY Paterno" oHojaActiva = ThisComponent.Value = com.getActiveSheet() mOpcBD(0).Value = sBaseDatos mOpcBD(1).getCurrentController.Aprendiendo OOo Basic 347 Dim sBaseDatos As String Dim sSQL As String Dim mOpcBD(2) As New "com. Materno As ""Apellido Materno"". esto es indispensable cuando el nombre usado (AS) contenga espacios como en nuestro ejemplo. usamos la base de datos “Videoteca”.beans.PropertyValue" sBaseDatos = "Videoteca" 'Establecemos la consulta SQL sSQL = "SELECT * FROM tblVideo ORDER BY Genero ASC.beans.star.getCellRangeByName("A1"). en el siguiente ejemplo.star.Name = "DatabaseName" mOpcBD(0). tienes que usar una sintaxis muy singular.star.Name = "SourceType" mOpcBD(1).Value = sSQL oHojaActiva.Name = "SourceType" mOpcBD(1).doImport( mOpcBD() ) End Sub Nota el uso de las dobles comillas.sun. ni una más ni una menos. no tendrás problemas con el manejo de fechas.DataImportMode.SQL mOpcBD(2).sun.getCurrentController. Director DESC" oHojaActiva = ThisComponent. por ejemplo.SQL mOpcBD(2).PropertyValue" sBaseDatos = "Directorio" 'Establecemos la consulta SQL sSQL = "SELECT Nombre. ten cuidado con su uso.Value = com. y estas. Cambiemos de base de datos.getCellRangeByName("A1"). usamos: sSQL = "SELECT * FROM tblContactos WHERE Cumple={ D '1974-01-15' }" Observa como todo el criterio de la fecha va encerrado entre llaves.Name = "SourceObject" mOpcBD(2). además.sheet.Value = sSQL oHojaActiva.getActiveSheet() mOpcBD(0). Si revisas la estructura de la tabla “tblContactos” notaras que el campo “Cumple” es de tipo fecha (Date). y mostramos como podemos ordenar de forma ascendente (ASC) por un campo y de forma descendente (DESC) por otro: Sub Dim Dim Dim Dim BasesDeDatos9() oHojaActiva As Object sBaseDatos As String sSQL As String mOpcBD(2) As New "com.sun.

8 Bases de datos Como en los ejemplos siguiente solo cambia la instrucción SQL. nos importa todos los títulos que comiencen por la letra “V”.348 6. La siguiente instrucción. nos permite obtener un listado con registros únicos (DISTINCT). con esta clausula te darás cuenta cuales de ellos pueden tener este caso. solo que ahora hacemos uso de la clausula IN para establecer los años deseados: sSQL = "SELECT * FROM tblVideo WHERE Año IN(1974. tenemos una nueva clausula para importar datos entre dos valores (BETWEEN) junto con el operador “y” (AND): sSQL = "SELECT * FROM tblVideo WHERE Duracion BETWEEN 60 AND 90 ORDER BY Duracion" Ahora. todos los directores que tenemos en nuestra videoteca. esto. es importante. solo te mostraré esta. En el siguiente ejemplo. por ejemplo. observa que volvemos a hace uso de la forma CAMPO=CRITERIO: sSQL = "SELECT * FROM tblVideo WHERE Año=1974 OR Año=1986 OR Año=2000" Nuestro siguiente ejemplo.1986. es una buena alternativa para encontrar campos mal capturados. importamos todas las películas que “contengan” la palabra “anillos”: sSQL = "SELECT * FROM tblVideo WHERE Titulo LIKE '%anillos%'" Con la siguiente instrucción. observa el uso de una nueva clausula LIKE sin signo igual y con el símbolo de porcentaje después de la letra deseada sin olvidar el uso de las comillas simples: sSQL = "SELECT * FROM tblVideo WHERE Titulo LIKE 'V%'" Ahora. además. importamos todas las películas que duren entre 60 y 90 minutos ordenados por duración. seguiremos usando la base de datos “Videoteca”. por ejemplo. hace exactamente lo mismo que el anterior. si algún campo tiene un solo espacio de más. mientras no se indique lo contrario. como hacemos uso de comillas simples para el parámetro del criterio.2000)" El siguiente ejemplo es muy interesante. filtramos los datos importados por el campo Pais. sSQL = "SELECT * FROM tblVideo WHERE Pais='México'" Siempre que quieras establecer un criterio de filtrado usa WHERE en donde estableces el CAMPO=CRITERIO deseado y nota también. ya que los considerará como dos registros diferentes: sSQL = "SELECT DISTINCT Director FROM tblVideo" . lo que nos da la posibilidad de importar. 1974 o 1986 o 2000. importamos las películas que sean de cualquiera (OR) de los siguientes años.

usamos una nueva clausula que nos sirve para agrupar (GROUP BY) el resultado por algún campo. después. en vez de regresar los distintos países que tenemos. este valor. obtenemos la máxima duración (SELECT MAX(Duracion) FROM tblVideo). ahora si. y después los contamos (COUNT). SUM(Duracion) AS ""Duración por Genero"" FROM tblVideo GROUP BY Genero" Observa como en los ejemplos para obtener la película de máxima (MAX) y mínima (MIN) duración. solo el valor. nota que primero obtenemos los países (DISTINCT Pais). usamos la siguiente instrucción SQL: sSQL = "SELECT Genero. que no es otra cosa que consultas anidadas. sumando (SUM) los minutos de duración de todas las películas: sSQL = "SELECT SUM(Duracion) AS ""Total Minutos"" FROM tblVideo" U obtener el promedio (AVG) de duración por película: sSQL = "SELECT AVG(Duracion) AS ""Promedio en Minutos"" FROM tblVideo" O la duración máxima: sSQL = "SELECT MAX(Duracion) AS ""Duración Máxima"" FROM tblVideo" O la mínima: sSQL = "SELECT MIN(Duracion) AS ""Duración Mínima"" FROM tblVideo" En el siguiente ejemplo. lo establecemos como criterio (WHERE) de la consulta exterior. vamos a realizar una “subconsulta”. obtenemos todos los datos de la película de máxima duración en nuestra videoteca: sSQL = "SELECT * FROM tblVideo WHERE Duracion=(SELECT MAX(Duracion) FROM tblVideo)" No te confundas. para saberlo. el total de minutos de nuestra videoteca. es muy importante el uso de los paréntesis para la consulta interior. primero. son solo una muestra ínfima de su poder y versatilidad. en donde. también nos permite hacer algunas operaciones sobre los campos.Aprendiendo OOo Basic 349 El lenguaje SQL. le establecemos un nombre a este resultado (AS ""Total Países""): sSQL = "SELECT COUNT(DISTINCT Pais) AS ""Total Países"" FROM tblVideo" Podemos obtener. el resultado de la consulta interior. pero creo. con en el siguiente ejemplo. Los ejemplos de instrucciones SQL vistas en todos los ejemplos anteriores. suficientes para tengas mucho para . donde si devolvemos todos los campos. por ejemplo. es el criterio de filtro para la exterior. pero no sabes que título es este. solo los contamos (COUNT). efectivamente obtenemos el valor. para obtener al suma de minutos por genero. además.

el nombre de los campos. el siguiente código. no es el único método para consultar datos en bases de datos pero si el más sencillo. 6.getCellRangeByName("A1"). son datos indispensables para insertar nuevos datos.beans. tiene que haberte devuelto algo muy similar a: Pero el método para importar (doImport). no puede faltar. lo más probable es que la instrucción no tenga éxito y te devuelva un error.getActiveSheet() mOpcBD(0). de no cumplir con algún requerimiento especifico o no coincidir el tipo de dato que se desea insertar con el tipo del campo de la tabla.PropertyValue" sBaseDatos = "Directorio" sTabla = "tblPaises" oHojaActiva = ThisComponent. ya que. es la clave primaria y su inserción es automática.star.TABLE mOpcBD(2). hace exactamente solo eso. el tipo de campo y si es requerido o no. la estructura de la tabla. el segundo es un campo tipo texto y es requerido.sheet. El método doImport. también nos sirven para insertar nuevos datos en las tablas de nuestra base de datos.350 6. por lo que para insertar nuevos datos usaremos una técnica diferente.Name = "SourceObject" mOpcBD(2). te mostrará todas las bases de datos “registradas” en OpenOffice.Name = "DatabaseName" mOpcBD(0). y el tercero. Si revisas la estructura de la tabla “tblPaises”.sun. “Id”. el primero es un campo tipo entero.2 Insertando nuevos datos Las instrucciones SQL. importar. es decir. “Pais” y “LDPais”. Antes de empezar con los ejemplos propios de inserción de datos.Value = sBaseDatos mOpcBD(1). observaras que esta formada por tres campos.Name = "SourceType" mOpcBD(1).DataImportMode.star. esto. En el siguiente ejemplo.doImport( mOpcBD() ) End Sub La importación anterior.Value = sTabla oHojaActiva.8 Bases de datos practicar y probar.8.getCurrentController. no solo sirven para importar datos. es un entero que puede o no puede estar. importamos los países dados de alta en nuestra tabla “tblPaises” de nuestra base de datos “Directorio”: Sub Dim Dim Dim Dim BasesDeDatos10() oHojaActiva As Object sBaseDatos As String sTabla As String mOpcBD(2) As New "com. veamos la nueva forma de acceder a nuestra base de datos.Value = com.org: .sun.

sdb.DatabaseContext") 'Obtenemos los nombres de las bases de datos registradas mNombresBD = oDBC. accedemos por el nombre oBD = oDBC.getByName( sBaseDatos ) 'Creamos una conexion a la base de datos oConexion = oBD.DatabaseContext") 'Nos aseguramos de que exista la base de datos If oDBC. nos ilustra una nueva forma de hacer una consulta (executeQuery).sun.hasByName( sBaseDatos ) Then 'Si existe.getByName( sBaseDatos ) 'Mostramos la ruta de la base de datos MsgBox ConvertFromURL( oBD.star. diferente al método doImport.star.Name ) End If End Sub El siguiente ejemplo.getElementNames() 'Mostramos el nombre de cada una For co1 = LBound( mNombresBD ) To UBound ( mNombresBD ) MsgBox mNombresBD(co1) Next End Sub Para acceder a la base de datos de nuestro interés. accedemos por el nombre oBD = oDBC.sdb.star. Sub Dim Dim Dim Dim Dim Dim Dim BasesDeDatos13() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object oResultado As Object sBaseDatos As String sSQL As String 'El nombre de la base de datos sBaseDatos = "Directorio" sSQL = "SELECT * FROM tblPaises" 'Creamos el servicio para acceder y manipular las bases de datos oDBC = createUnoService("com. este nuevo método.hasByName( sBaseDatos ) Then 'Si existe. pues nos da acceso al resultado de la consulta para manipular cada registro y cada campo según nuestras necesidades.DatabaseContext") 'Nos aseguramos de que exista la base de datos If oDBC.sun. tienen muchas variantes y posibilidades.sdb."") 'Creamos un objeto para las instrucciones SQL .getConnection("". usamos: Sub Dim Dim Dim BasesDeDatos12() oDBC As Object oBD As Object sBaseDatos As String 'El nombre de la base de datos sBaseDatos = "Directorio" 'Creamos el servicio para acceder y manipular las bases de datos oDBC = createUnoService("com.Aprendiendo OOo Basic Sub Dim Dim Dim BasesDeDatos11() oDBC As Object mNombresBD() As String co1 As Integer 351 'Creamos el servicio para acceder y manipular las bases de datos oDBC = createUnoService("com.sun.

""Pais"") VALUES (11. es posible insertarlo si lo deseas. usamos una nueva instrucción SQL (INSERT INTO). estas “no admiten duplicados”. por lo que si el valor indicado ya existe.createStatement() 'Ejecutamos la consulta oResultado = oDeclaracion. después la clausula para indicar los valores (VALUES) y por ultimo."") 'Creamos un objeto para las instrucciones SQL oDeclaracion = oConexion. Nota que en la tabla y los campos.executeQuery( sSQL) 'Si hay resultados If Not IsNull( oResultado ) Then Do While oResultado. será automáticamente insertado.next 'Mostramos el contenido del campo MsgBox oResultado. el primero se llama “Id” y es un entero. Para insertar registros.star. que además es clave primaria y de inserción automática. tanto el campo como el valor.'Honduras')" Observa como indicamos el nombre del campo (Id) y su valor (11).createStatement() 'Ejecutamos la insercion de datos oDeclaracion. por que este.getString( 2 ) Loop End If End If End Sub 6.sdb. seguida de la tabla donde insertaremos los nuevos datos. si estos son texto. al ser este campo una clave primaria. veamos como insertar un nuevo registro en nuestra base de datos: Sub Dim Dim Dim Dim Dim Dim BasesDeDatos14() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object sBaseDatos As String sSQL As String 'El nombre de la base de datos sBaseDatos = "Directorio" sSQL = "INSERT INTO ""tblPaises"" (""Pais"") VALUES ('Honduras')" 'Creamos el servicio para acceder y manipular las bases de datos oDBC = createUnoService("com. pero. Recordemos que la tabla “tblPaises” esta conformada por tres campos. usamos doble comilla y en los valores a insertar. .8 Bases de datos Ahora si. por ello omitimos. usamos comillas simples.hasByName( sBaseDatos ) Then 'Si existe. accedemos por el nombre oBD = oDBC.352 oDeclaracion = oConexion.getConnection("".executeUpdate( sSQL) End If End Sub Es importante que notes que estamos usando un nuevo método (executeUpdate) para ejecutar la instrucción SQL.DatabaseContext") 'Nos aseguramos de que exista la base de datos If oDBC.getByName( sBaseDatos ) 'Creamos una conexion a la base de datos oConexion = oBD. los valores a insertar entre paréntesis. los nombres de los campos.sun. entre paréntesis. no obstante. como en: sSQL = "INSERT INTO ""tblPaises"" (""Id"".

usaremos el segundo método. claro que no. “no debería” haber información repetida en una base de datos.10. intentando insertar valores duplicados para la columna (campo) Id.close() MsgBox "El país: " & sPais & " ya existe en la base de datos" . una.hasByName( sBaseDatos ) Then oBD = oDBC. como lo vimos en el capitulo 4. tienes dos posibles soluciones. Aunque este error en tiempo de ejecución es interceptable y manipulable. obtendrás un error interceptable en tiempo de ejecución.executeUpdate( sSQL) MsgBox "El país: " & sPais & " se inserto correctamente en la base de datos" Else oResultado. la recomendación es que permitas al motor de bases de datos."") oDeclaracion = oConexion. que consiste en consultar si el país ya existe o no. la idea de una base de datos es tener la menor cantidad de información repetida.sdb.createStatement() 'Verificamos que el país no exista oResultado = oDeclaracion.next() If oResultado. ¿es esto correcto?.star. donde claramente nos indica que estamos violando la unicidad del índice. tenemos varias veces el país recién insertado. tienes que modificar la tabla desde Base y agregar el índice manualmente (o por código) lo cual aprenderemos más adelante.getRow = 0 Then 'Si no existe lo insertamos sSQL = "INSERT INTO ""tblPaises"" (""Pais"") VALUES ('" & sPais & "')" oDeclaracion.sun.executeQuery( sSQL) oResultado. puedes crear un índice en este campo. una primera aproximación a este solución seria: Sub Dim Dim Dim Dim Dim Dim Dim Dim BasesDeDatos15() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object oResultado As Object sBaseDatos As String sSQL As String sPais As String sPais = Trim( InputBox( "Introduce el nombre del nuevo país" ) ) If sPais <> "" Then sBaseDatos = "Directorio" sSQL = "SELECT Pais FROM ""tblPaises"" WHERE Pais='" & sPais & "'" oDBC = createUnoService("com. se encargue de insertar el valor siguiente como en nuestro ejemplo.getByName( sBaseDatos ) oConexion = oBD. y actuar en consecuencia. ejecuta varias veces para que notes que efectivamente. Control de errores. notaras que ahora. de hecho. si tienes un campo que es clave primaria y de inserción automática como el campo “Id” de nuestra tabla. si ejecutaste la macro varias veces y haces la consulta de la tabla o la abres desde Base.DatabaseContext") If oDBC. Para evitar la duplicidad de datos en otro campo que no sea la clave primaria. en el cual se le indica que solo contenga datos únicos con lo cual. por ahora. Después tenemos el campo “Pais”. si se intentan agregar datos duplicados.getConnection("". inserta el valor automáticamente.Aprendiendo OOo Basic 353 te dará un error como el siguiente. para ello. que.

por lo que.sdb. tienes la ultima palabra.""Paterno"". por lo que puedes omitirlo como lo hemos hecho hasta ahora. el valor devuelto con el valor nuevo todo en mayúsculas o minúsculas según prefieras. en el orden año-mes-día. salvo en contadas excepciones.""IdCiudad"") VALUES ('Juan'. “todos” llevan sus comillas dobles. tienes dos alternativas. Sub Dim Dim Dim Dim Dim Dim BasesDeDatos16() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object sBaseDatos As String sSQL As String sBaseDatos = "Directorio" sSQL = "INSERT INTO ""tblContactos"" (""Nombre"". la primero es obvia. “MÉXico” o “MÉXICO”.DatabaseContext") . una base de datos ideal.close() 'Liberamos la memoria oResultado = Nothing oDeclaracion = Nothing oConexion = Nothing End If Else MsgBox "El campo no puede estar vacío" End If End Sub 6. como en el siguiente ejemplo: sSQL = "INSERT INTO ""tblPaises"" (""Pais"". la cual.""Materno"". o puedes insertarlo. esto es por que el campo distingue mayúsculas de minúsculas.8 Bases de datos Aun con esta validación. aunque no sea obligatorio. tal vez podrías plantearte la posibilidad de eliminarlo de la tabla. su contenido y estructura y evitar en lo posible cambios constantes durante la implementación de tu código. haces la consulta y comparas (si hay resultado).sun. te dará un error en tiempo de ejecución. no así el campo. practica y segura y como siempre.2)" oDBC = createUnoService("com. Para terminar este tema. ""LDPais"") VALUES ('Venezuela'. te evitaras algunos dolores de cabeza. no “debería” tener campos vacíos. veamos un ejemplo donde se inserta una fecha.354 End If 'Cerramos las conexiones oDeclaracion. si un campo esta casi siempre vacío. El ultimo campo de nuestra tabla es: “”LDPais”. es mucho mejor y más eficiente. esta segunda opción es más rápida.'1981-01-31'. anticipando lo mejor posible.'Gomez'. de nuevo. debe ir entre comillas simples y muy importante.45)" Observa que al ser un número. En “teoría”. si no. “MÉxico”. “diseñar” tus tablas. es posible que haya todavía datos duplicados cuando intentemos introducir variantes como “México”. procura dejar vacíos la menor cantidad de campos posible.""Cumple"". es modificar la estructura de la tabla para que ignore esta distinción. pero el campo no es requerido. aunque no es muy recomendable estar eliminando o insertando campos. que es un entero. no lleva comillas. la otra. en algunas ocasiones.close() oConexion.'Perez'.star. Modifica la macro anterior para que no distinga mayúsculas de minúsculas y permite al usuario seguir introduciendo países hasta que quiera presionando el botón Cancelar del cuadro de dialogo.

executeUpdate( sSQL) oDeclaracion. por último.sun. la condición (WHERE) para actualizar solo los registros deseados. cuida de que no falte ningún campo requerido y cuida los campos que tienen alguna “relación” con un campo de otra tabla. mostramos el país y la clave lada de cada uno. el campo a actualizar y el nuevo valor.close() oDeclaracion = Nothing oConexion = Nothing End Sub Para actualizar. te actualizará “todos” los registros de tu tabla.executeUpdate( sSQL) oDeclaracion. no veras ningún mensaje."") oDeclaracion = oConexion.getConnection("". En el siguiente ejemplo. actualiza el campo “LDPais” de la tabla “tblPaises” pero solo el registro que cumple la condición: Sub Dim Dim Dim Dim Dim Dim BasesDeDatos17() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object sBaseDatos As String sSQL As String sBaseDatos = "Directorio" 'Construimos la instrucción de actualización sSQL = "UPDATE ""tblPaises"" SET ""LDPais""=57 WHERE ""Pais""='Colombia'" oDBC = createUnoService("com."") oDeclaracion = oConexion. es una acción recurrente en la manipulación de bases de datos. usamos una nueva instrucción SQL (UPDATE). Veamos como hacerlo. si hay más campo se separan por comas. simplemente no hará ningún cambio en la tabla.getConnection("". 6.getByName( sBaseDatos ) oConexion = oBD.DatabaseContext") oBD = oDBC.Aprendiendo OOo Basic oBD = oDBC. con la posibilidad de cambiarlo: .star. si no estableces un criterio.8. Si el criterio no devuelve ningún resultado.sdb.3 Actualizando datos La actualización de datos en una tabla.createStatement() oDeclaracion.createStatement() oDeclaracion.close() oConexion. el siguiente ejemplo. cuidado.getByName( sBaseDatos ) oConexion = oBD. después establecemos (SET).close() oConexion.close() oDeclaracion = Nothing oConexion = Nothing End Sub 355 Las recomendaciones generales al insertar datos son: ten cuidado con el tipo de datos del campo destino.

pues se ven afectadas una por la otra.getConnection("".sdb. LDPais FROM tblPaises" oDBC = createUnoService("com.getString(1) & "'" oDeclaracion1.star.Next sInfo = "El pais: " & oResultado.getString(2) & Chr(13) & Chr(13) & "Introduce la nueva clave lada" sClave = Val(Trim(InputBox(sInfo))) If sClave > 0 Then sSQL = "UPDATE ""tblPaises"" SET ""LDPais""=" & sClave & " WHERE ""Pais""='" & oResultado.createStatement() oResultado = oDeclaracion.createStatement() oDeclaracion.sun.DatabaseContext") oBD = oDBC.close() .getByName( sBaseDatos ) oConexion = oBD."") oDeclaracion = oConexion.356 Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim BasesDeDatos18() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object oDeclaracion1 As Object oResultado AS Object sBaseDatos As String sSQL As String sInfo As String sClave As String 6.close() oConexion.sdb.executeUpdate( sSQL) oDeclaracion.close() oDeclaracion1.executeQuery( sSQL) Do While oResultado.executeUpdate( sSQL) End If Loop oResultado.8 Bases de datos sBaseDatos = "Directorio" sSQL = "SELECT Pais.close() oDeclaracion."") oDeclaracion = oConexion.getConnection("".star.DatabaseContext") oBD = oDBC.sun.getString(1) & " tiene como clave Lada: " & _ oResultado.close() oResultado = Nothing oDeclaracion = Nothing oDeclaracion1 = Nothing oConexion = Nothing End Sub Observa que creamos dos declaraciones (createStatement). En nuestro siguiente ejemplo. actualizamos la fecha del contacto con Id = 0: Sub Dim Dim Dim Dim Dim Dim BasesDeDatos19() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object sBaseDatos As String sSQL As String sBaseDatos = "Directorio" 'Construimos la instrucción de actualización sSQL = "UPDATE ""tblContactos"" SET ""Cumple""='1980-02-28' WHERE ""Id""=0" oDBC = createUnoService("com. no puedes usar la misma.getByName( sBaseDatos ) oConexion = oBD.createStatement() oDeclaracion1 = oConexion. una es para la consulta de selección y la otra para la actualización.

Aprendiendo OOo Basic
oConexion.close() oDeclaracion = Nothing oConexion = Nothing End Sub

357

Al igual que en la inserción, la fecha debe cumplir el orden año-mes-día y estar entre comillas simples. Cuida, respetar el tipo de dato del campo a actualizar.

6.8.4

Borrando datos

Borrar datos es sumamente simple, por ello, ten mucho cuidado cuando uses esta instrucción, el siguiente ejemplo borra un país de la tabla:
Sub Dim Dim Dim Dim Dim Dim BasesDeDatos20() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object sBaseDatos As String sSQL As String

sBaseDatos = "Directorio" 'Construimos la instrucción de borrado sSQL = "DELETE FROM ""tblPaises"" WHERE ""LDPais""=57" oDBC = createUnoService("com.sun.star.sdb.DatabaseContext") oBD = oDBC.getByName( sBaseDatos ) oConexion = oBD.getConnection("","") oDeclaracion = oConexion.createStatement() oDeclaracion.executeUpdate( sSQL) oDeclaracion.close() oConexion.close() oDeclaracion = Nothing oConexion = Nothing End Sub

¡Cuidado!, si no estableces la condición, “borraras toda el contenido de la tabla”, es recomendable, en cualquier operación de borrado, así sea un campo, una tabla, un archivo o lo que sea, preguntarle al usuario si esta seguro de realizar la acción e informarle que esta no se puede deshacer. Las instrucciones de borrado, pueden afectar a tablas que estén “relacionadas”, tanto la actualización como el borrado, están ligados con un concepto en bases de datos que se llama “integridad referencial”, tema que sale de los propósitos de este libro, pero que si quieres profundizar en ello, tienes que conocerlo, estudiarlo, comprenderlo y aplicarlo en tus bases de datos, por ahora, con que tengas el cuidado de no dejar “huérfanos” a tus datos es más que suficiente. En el siguiente ejemplo, borramos todos los contactos que se llamen 'Juan':
Sub Dim Dim Dim Dim Dim Dim BasesDeDatos21() oDBC As Object oBD As Object oConexion As Object oDeclaracion As Object sBaseDatos As String sSQL As String

358

6.8 Bases de datos

sBaseDatos = "Directorio" 'Construimos la instrucción de borrado sSQL = "DELETE FROM ""tblContactos"" WHERE ""Nombre""='Juan'" oDBC = createUnoService("com.sun.star.sdb.DatabaseContext") oBD = oDBC.getByName( sBaseDatos ) oConexion = oBD.getConnection("","") oDeclaracion = oConexion.createStatement() oDeclaracion.executeUpdate( sSQL) oDeclaracion.close() oConexion.close() oDeclaracion = Nothing oConexion = Nothing End Sub

Los temas vistos en este capitulo, son solo una pequeña parte de ese enorme tema que son las bases de datos, volveremos a ellos en el capitulo referente a Base, aunque procurando mantener el nivel básico que venimos manejando, no obstante, tienes ya, herramientas suficientes para obtener mucho provecho de tus datos y tus conocimientos.

6.9

Graficando datos

Dicen que una imagen vale más que mil palabras, la verdad es que yo prefiero las mil palabras, no obstante, daré por cierta la aseveración anterior y veremos como darle “imagen” a nuestros datos, que de eso se trata cuando hacemos gráficos. Vamos a crear el siguiente gráfico de la población de cinco países de América Latina.

Aprendiendo OOo Basic

359

360

6.9 Graficando datos

Aprendiendo OOo Basic

361

El cual creamos con la siguiente macro:
Sub Dim Dim Dim Dim Dim Dim Graficando1() oHojaActiva As Object oGraficos As Object mRangos(0) sNombre As String oRec As New com.sun.star.awt.Rectangle oDir As New com.sun.star.table.CellRangeAddress

'Acceso a la hoja activa oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'El nombre de nuestro gráfico sNombre = "Grafico01" 'El tamaño y la posición del nuevo gráfico, todas las medidas 'en centésimas de milímetro With oRec .X = 5500 'Distancia desde la izquierda de la hoja .Y = 0 'Distancia desde la parte superior .Width = 10000 'El ancho del gráfico .Height = 10000 'El alto del gráfico End With 'La dirección del rango de datos para el gráfico With oDir .Sheet = oHojaActiva.getRangeAddress.Sheet .StartColumn = 0 .EndColumn = 1 .StartRow = 0 .EndRow = 5 End With 'Es una matriz de rangos, pues se pueden establecer más de uno mRangos(0) = oDir 'Accedemos al conjunto de todos los gráficos de la hoja oGraficos = oHojaActiva.getCharts() 'Verificamos que no exista el nombre If oGraficos.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico, escoge otro" Else 'Si no existe lo agregamos oGraficos.addNewByName(sNombre, oRec, mRangos, True, True) End If

362

6.9 Graficando datos

End Sub

El método para agregar un nuevo gráfico (addNewByName), consta de cinco argumentos:
addNewByName(Nombre, Rectangulo, Rangos, EncabezadoColumna, EncabezadoFila)

1. Nombre: es el nombre del objeto a nivel código, este nombre es diferente del que puede establecer el usuario en la interfaz de la aplicación, es indispensable que no exista otro gráfico con este valor. 2. Rectángulo: es una estructura com.sun.star.awt.Rectangle que permite establecer el tamaño y la posición del gráfico, las unidades están especificadas en centésimas de milímetro, 1000 = 1 cm 3. Rangos: es una matriz de rangos, es decir, de estructuras com.sun.star.table.CellRangeAddress que guardan la dirección del rango para los datos de origen del gráfico. 4. EncabezadoColumna: valor booleano, establecido en verdadero (True) sirve para indicar si la fila superior se usara como titulo de etiquetas para eje o leyenda. 5. EncabezadoFila: valor booleano, establecido en verdadero (True) sirve para indicar si se usará la columna de la izquierda como etiquetas de eje o leyenda. Ya creado el gráfico, podemos personalizarlo completamente a nuestro gusto. En el siguiente ejemplo, creamos tres nuevos gráficos, de tres estilos diferentes: columnas, barras y circular, uno al lado de otro, teniendo como origen de datos, el mismo del ejemplo anterior:
Sub Dim Dim Dim Dim Dim Dim Dim Graficando2() oHojaActiva As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.sun.star.awt.Rectangle oDir As New com.sun.star.table.CellRangeAddress

'Acceso a la hoja activa oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'El nombre de nuestro gráfico sNombre = "GraficoA" 'El tamaño y la posición del nuevo gráfico, todas las medidas 'en centésimas de milímetro With oRec .X = 0 'Distancia desde la izquierda de la hoja .Y = 4000 'Distancia desde la parte superior .Width = 10000 'El ancho del gráfico .Height = 10000 'El alto del gráfico End With 'La dirección del rango de datos para el gráfico With oDir .Sheet = oHojaActiva.getRangeAddress.Sheet .StartColumn = 0 .EndColumn = 1 .StartRow = 0 .EndRow = 5 End With 'Es una matriz de rangos, pues se pueden establecer más de uno mRangos(0) = oDir 'Accedemos al conjunto de todos los gráficos de la hoja

Aprendiendo OOo Basic

363

oGraficos = oHojaActiva.getCharts() 'Verificamos que no exista el nombre If oGraficos.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico, escoge otro" Else 'Si no existe lo agregamos, de forma predeterminada se crea 'un gráfico de columnas oGraficos.addNewByName(sNombre, oRec, mRangos, True, True) End If 'Cambiamos el nombre y la posición para un segundo gráfico sNombre = "GraficoB" With oRec .X = 10000 .Y = 4000 End With If oGraficos.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico, escoge otro" Else oGraficos.addNewByName(sNombre, oRec, mRangos, True, True) 'Accedemos al nuevo gráfico oGrafico = oGraficos.getBYName( sNombre ).getEmbeddedObject() 'Establecemos que sean barras en vez de columnas oGrafico.getDiagram.Vertical = True End If 'Volvemos a cambiar el nombre y la posición para un tercer gráfico sNombre = "GraficoC" With oRec .X = 20000 .Y = 4000 End With If oGraficos.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico, escoge otro" Else oGraficos.addNewByName(sNombre, oRec, mRangos, True, True) oGrafico = oGraficos.getBYName( sNombre ).getEmbeddedObject() oGrafico.setDiagram( oGrafico.createInstance("com.sun.star.chart.PieDiagram")) End If End Sub

Los gráficos de columnas y barras son el mismo tipo de gráfico, excepto por la orientación, uno es vertical y otro es horizontal, para el tercer gráfico, cambiamos completamente su tipo (setDiagram), lo establecemos circular, toma en cuenta, que cada gráfico esta pensado para un determinado tipo de datos, los tipos de gráficos que puedes establecer son: com.sun.star.chart
com.sun.star.chart.BarDiagram com.sun.star.chart.AreaDiagram com.sun.star.chart.LineDiagram com.sun.star.chart.PieDiagram com.sun.star.chart.DonutDiagram com.sun.star.chart.NetDiagram com.sun.star.chart.XYDiagram com.sun.star.chart.StockDiagram

Tipo
Barras (y columnas) Áreas Líneas Circular Dona Red Dispersión XY Stock

364

6.9 Graficando datos

Cada uno de estos tipos, tiene variantes que multiplican las posibilidades para graficar la información, por ejemplo, representaciones en 3D, agregar líneas y puntos, entre otras características que veremos más adelante. La mayor parte de los elementos de un gráfico, son en realidad una forma (Shape), a la cual le puedes establecer sus propiedades, principalmente; el estilo de letra (tipo de fuente, color, negritas, tamaño, etc), el estilo de fondo (estilo, color, etc), y el estilo de borde (tipo de línea, color, ancho, etc), entre otras más, vamos a mostrar como modificar los principales elementos de un gráfico, los siguientes ejemplos manipulan el gráfico seleccionado, pero todas las propiedades que veremos, las puedes establecer perfectamente al crearlo de modo que tu gráfico este configurado completamente a tu gusto y necesidad a la primera. Vamos a hacer uso de las siguientes subrutinas para dar formato:
'Subrutina para formatear el texto de una forma, si no quieres cambiar alguna 'propiedad, solo pasa una cadena vacía en los textos y un 0 en los números Sub FormatoTexto(Obj As Object, Texto As String, Fuente As String, Neg As Integer, Tam As Integer, Color As Long) Dim oTexto As Object Dim mTexto(0) 'El titulo del gráfico es algo especial If Obj.supportsService("com.sun.star.chart2.Title") Then 'Requiere un objeto "Cadena Formateada" (FormattedString) oTexto = createUnoService("com.sun.star.comp.chart.FormattedString") 'Y agregarse a una matriz mTexto(0) = oTexto 'Establecer el texto Obj.setText( mTexto ) Else oTexto = Obj End If 'Cambiamos el formato del texto With oTexto If Texto <> "" Then .String = Texto If Fuente <> "" Then .CharFontName = Fuente If Neg > 0 Then .CharWeight = Neg If Tam > 0 Then .CharHeight = Tam If Color > 0 Then .CharColor = Color End With End Sub 'Subrutina para cambiar el fondo de una forma, si no quieres ningún fondo 'establece el estilo en 0 Sub FormatoFondo(Obj As Object, Estilo As Integer, Color As Long) With Obj .FillBackground = True .FillStyle = Estilo If Color > 0 Then .FillColor = Color End With End Sub 'Subrutina para cambiar la línea de una forma, si no quieres línea, 'establece el estilo en 0 Sub FormatoLinea(Obj As Object, Estilo As Integer, Color As Long, Ancho As Integer) With Obj .LineStyle = Estilo If Color > 0 Then .LineColor = Color If Ancho > 0 Then .LineWidth = Ancho End With End Sub

Aprendiendo OOo Basic

365

'Función para devolver el gráfico activo 'devuelve NULL si no es un gráfico Function getGrafico() As Object Dim oHojaActiva As Object Dim oGraficos As Object Dim oGrafico As Object Dim oSel As Object Dim sNombre As String Dim sInfo As String oSel = ThisComponent.getCurrentSelection() If oSel.getImplementationName = "com.sun.star.drawing.SvxShapeCollection" Then oSel = oSel.getByIndex(0) If oSel.supportsService("com.sun.star.drawing.OLE2Shape") Then sNombre = oSel.PersistName oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() oGraficos = oHojaActiva.getCharts() If oGraficos.hasByName( sNombre ) Then getGrafico = oGraficos.getByName( sNombre ).getEmbeddedObject() End If End If End If End Function

En el siguiente ejemplo, agregamos y damos formato al titulo y al subtitulo del gráfico, observa que si no existe el titulo lo creamos, el subtitulo siempre existe, solo hay que determinar si lo mostramos o no, como se indica en los comentarios:
Sub Dim Dim Dim Graficando3() oGrafico As Object oTitulo As Object oSubTitulo As Object

'Accedemos al gráfico seleccionado oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Si hay un gráfico, seleccionamos el título oTitulo = oGrafico.getTitleObject() If IsNull(oTitulo) Then 'Si no existe el título lo creamos oTitulo = createUnoService("com.sun.star.chart2.Title") End If 'Le damos formato al texto del título Call FormatoTexto( oTitulo, "Habitantes Por País", "Liberation Serif", 150, 15, RGB(255,0,0) ) 'Le damos formato al fondo del titulo Call FormatoFondo( oTitulo, 1, RGB(220,220,220) ) 'Le damos formato a la línea Call FormatoLinea( oTitulo, 1, RGB(100,50,25), 100 ) 'Si estableces la línea, tal vez sea buena idea, establecer los margenes 'al texto para que no se vea tan pegado With oTitulo .ParaLeftMargin = 300 .ParaRightMargin = 300 .ParaTopMargin = 200 .ParaBottomMargin = 200 End With 'Y lo establecemos oGrafico.setTitleObject( oTitulo ) 'Establecemos que se muestre el subtitulo

366

6.9 Graficando datos

oGrafico.HasSubTitle = True 'Accedemos al subtitulo oSubTitulo = oGrafico.SubTitle 'Le damos formato al texto, fondo y línea Call FormatoTexto( oSubTitulo, "América Latina", "Liberation Serif", 150, 12, RGB(255,150,0) ) Call FormatoFondo( oSubTitulo, 1, RGB(240,240,240) ) Call FormatoLinea( oSubTitulo, 2, RGB(100,50,25), 50 ) Else MsgBox "Selecciona un gráfico" End If End Sub

Los margenes del borde al texto, solo existen en el título, no así en el subtítulo. Si usas normalmente un conjunto de fuentes, podrías usar una matriz de texto (string) con los nombres de las fuentes que más uses, por ejemplo:
Dim mFuentes(4) As String mFuentes(0) mFuentes(1) mFuentes(2) mFuentes(3) mFuentes(4) = = = = = "Liberation Serif" "Liberation Sans" "Liberation Mono" "FreeMono" "FreeSans"

Y mira que bien nos va quedando, bueno, no tan bien, ya sabes que soy muy malo para el diseño, así que no te me pongas exigente.

Aprendiendo OOo Basic 367 .

fondo y línea Call FormatoTexto( oLeyenda. "". 10. que claro. así como su formato. pues es una sola serie de datos. esto es muy importante. 3. como en este ejemplo.50.HasLegend = False 'Accedemos al titulo del eje X . 50 ) Else MsgBox "Selecciona un gráfico" End If End Sub En algunos casos. Nota que en la llamada a la subrutina FormatoTexto. intento de circulo) rojo en la imagen anterior. no tiene mucho sentido mostrar la leyenda.240) ) Call FormatoLinea( oLeyenda. 150.100) ) Call FormatoFondo( oLeyenda. el circulo (bueno. le pasamos una cadena vacía.9 Graficando datos Ahora. pues la leyenda no implementa la propiedad String. ahora. 1.25). puedes interceptar y manipular.150. RGB(100. así que mejor la ocultamos y establecemos el titulo de el eje X y el eje Y. por lo que si intentas establecerla. te dará un error en tiempo de ejecución. RGB(255.368 6.Legend() 'Le damos formato al texto. Sub Graficando5() Dim oGrafico As Object Dim oTituloEje As Object oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Ocultamos la leyenda oGrafico. cambiaremos el formato de la leyenda. Sub Graficando4() Dim oGrafico As Object Dim oLeyenda As Object oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Accedemos a la leyenda oLeyenda = oGrafico. RGB(240. que nos sirve para establecer el título y el subtítulo.240. el argumento Texto. "Liberation Sans".

RGB(150. 10. 50 ) 'Mostramos las líneas secundarias oGrafico.50. 25 ) Else MsgBox "Selecciona un gráfico" End If End Sub Modificamos las propiedades de toda el área del gráfico Sub Graficando7() .255).getDiagram. RGB(0.240. 20 ) Else MsgBox "Selecciona un gráfico" End If End Sub El punto importante.0. 150.240) ) Call FormatoLinea( oTituloEje. "Liberation Sans".0). 30 ) 'Rotamos 60º el texto oEje. 1. RGB(240. pero también “dentro” de un forma que se llama diagrama.50) ) Call FormatoLinea( oEje.50.getDiagram. "Liberation Sans".YMainGrid Call FormatoLinea( oEje. RGB(200.getDiagram. RGB(200.0. 1. "Países". RGB(255. "".50) ) Call FormatoLinea( oEje. 150.HasYAxisHelpGrid = True oEje = oGrafico.0.getDiagram.StepHelpCount = 5 'Líneas del eje principal oEje = oGrafico.240. 1.200).0). "Liberation Sans". 11.150.getDiagram. están contenidos “dentro” del gráfico.getDiagram.100) ) Call FormatoFondo( oTituloEje.200. RGB(0.150.getDiagram. RGB(240.240) ) Call FormatoLinea( oTituloEje. es la forma en que accedemos a los títulos de los ejes (getDiagram). 11. que es propiamente el área donde se muestra el gráfico. 1. 1.TextRotation = 6000 'Accedemos al eje Y oEje = oGrafico. "Habitantes". 1. 1. 20 ) 'Accedemos al titulo del eje Y oTituloEje = oGrafico.255).100) ) Call FormatoFondo( oTituloEje.YHelpGrid Call FormatoLinea( oEje. 150.getYAxis Call FormatoTexto( oEje.getDiagram. RGB(50.HasYAxisTitle = True Call FormatoTexto( oTituloEje.XAxisTitle 'Establecemos que se muestre oGrafico.200). RGB(50.HasXAxisTitle = True Call FormatoTexto( oTituloEje.Aprendiendo OOo Basic 369 oTituloEje = oGrafico.Max = 200000000 'Establecemos el intervalo superior oEje.YAxisTitle 'Establecemos que se muestre oGrafico. estos. 30 ) 'Establecemos el limite superior del eje oEje. RGB(100. Sub Graficando6() Dim oGrafico As Object Dim oEje As Object oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Accedemos al eje X oEje = oGrafico.0. 10.getDiagram.getXAxis Call FormatoTexto( oEje. RGB(100. 150. "Liberation Sans". "". 1.StepMain = 50000000 'El número de marcas secundarias oEje.200.

370 Dim oGrafico As Object Dim oArea As Object oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Seleccionamos el área del gráfico oArea = oGrafico.0.getDataRowProperties(0) Call FormatoTexto( oDatos. Sub Graficando8() Dim oGrafico As Object Dim oFondo As Object oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Seleccionamos el fondo del gráfico oFondo = oGrafico. tienes que hacerlo como si fuera una forma (shape) como te muestro en el siguiente ejemplo: Sub Dim Dim Dim Graficando10() oGrafico As Object oSel As Object oTam As New com. 11. Sub Graficando9() Dim oGrafico As Object Dim oDatos As Object oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'La primer serie de datos oDatos = oGrafico.255. por ahora.getDiagram.sun. 150. 9 ) Else MsgBox "Selecciona un gráfico" End If End Sub Modificamos la serie de datos.awt. RGB(0.50).DataCaption = 1 Else MsgBox "Selecciona un gráfico" End If End Sub Para cambiar de tamaño un gráfico.star.250) ) Call FormatoFondo( oDatos.9 Graficando datos Ahora. 2.Size . 2.getArea() Call FormatoFondo( oArea. 11 ) Call FormatoLinea( oArea.getDiagram. 5 ) 'Establecemos que se muestren los valores de cada punto oDatos. el área efectiva donde se muestran los datos. RGB(50. 1. solo del fondo del gráfico. 20 ) Else MsgBox "Selecciona un gráfico" End If End Sub 6. "Liberation Sans".getWall Call FormatoFondo( oFondo. "". solo tenemos una. 4.

cambiara el rango de datos origen.star. hay que hacerlo como si fuera una forma (shape) oSel = ThisComponent.getCurrentController.table.Height = 15000 oSel. algo sumamente necesario para tener realmente un gráfico dinámico y podamos actualizarlo cuando sea necesario.Aprendiendo OOo Basic 371 oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Aquí.getByIndex(0) 'Establecemos el nuevo tamaño oTam. al fin que no es curso de diseño. esta horrible.Width = 15000 oTam. Sub Dim Dim Dim Dim Graficando11() oGrafico As Object oHojaActiva As Object mRangos(0) oDir As New com.setSize( oTam ) Else MsgBox "Selecciona un gráfico" End If End Sub Si has probado cada una de las macros de ejemplo sobre el mismo gráfico.getActiveSheet() 'Accedemos al gráfico . La siguiente macro. repetimos lo que hace la función que nos regresa el gráfico 'esto es por que ya estamos seguros de que es un gráfico y por que. 'para cambiar de tamaño. tienes que tener algo así: Si lo se.sun.getCurrentSelection() oSel = oSel.CellRangeAddress oHojaActiva = ThisComponent.

EndRow = 10 End With mRangos(0) = oDir 'Establecemos el nuevo rango oGrafico. puedes establecerle ejes a un gráfico circular.drawing. accede directamente al gráfico (getByName).star.getCurrentController.getByName( sNombre ) End If End If End If End Function La diferencia.star.getCharts() If oGraficos.getImplementationName = "com. debes de cuidar la correspondencia de tus datos con el tipo de gráfico.SvxShapeCollection" Then oSel = oSel.sun.getByIndex(0) If oSel.StartRow = 0 . Veamos algunos ejemplos más de creación de gráficos. esta segunda forma. por ejemplo.setRanges( mRangos ) Else MsgBox "Selecciona un gráfico" End If End Sub 6.9 Graficando datos Nota que estamos usando una segunda versión de la función para regresar el gráfico seleccionado.getRangeAddress.hasByName( sNombre ) Then getGrafico2 = oGraficos.sun.getActiveSheet() oGraficos = oHojaActiva. pero dejaría de ser un gráfico circular y te aseguro que no obtendrías el resultado previsto.supportsService("com. El siguiente ejemplo. con el cual tenemos acceso a todos los objetos dentro del gráfico. cuando personalices un gráfico.drawing. así mismo. asegurate de que el tipo de gráfico es correcto.EndColumn = 1 . es que la primera te devuelve el objeto (no me gusta la palabra pero así es) “embebido” (getEmbeddedObject). Sub Graficando12() Dim oGrafico As Object .getCurrentSelection() If oSel.Sheet = oHojaActiva. modifica nuestro gráfico para que se vea en 3D. Function getGrafico2() As Object Dim oHojaActiva As Object Dim oGraficos As Object Dim oGrafico As Object Dim oSel As Object Dim sNombre As String Dim sInfo As String oSel = ThisComponent. como ya lo mencionamos.Sheet . la función es casi idéntica.PersistName oHojaActiva = ThisComponent.372 oGrafico = getGrafico2() If Not IsNull( oGrafico ) Then 'El nuevo rango de datos With oDir .StartColumn = 0 . cuando grafiques.OLE2Shape") Then sNombre = oSel.

Aprendiendo OOo Basic 373 oGrafico = getGrafico() If Not IsNull( oGrafico ) Then 'Establecemos el gráfico en 3D oGrafico. tanto el rango de datos como la posición.createCursorByRange( oSel ) 'Expandimos el cursor a la región actual oCursor.getSelection() If oSel.getDiagram.getRangeAddress.getRangeAddress.SolidType = 1 Else MsgBox "Selecciona un gráfico" End If End Sub Observa el siguiente gráfico. para obtenerlo.getCurrentController. es indispensable que el cursor este en “una sola celda” de los datos.getCellByPosition( oCursor. oCursor.awt.star.getDiagram.sun.getCurrentController.getActiveSheet() oSel = ThisComponent.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.getRangeAddress sNombre = "Grafico10" 'Celda para la posición del gráfico oCelda = oHojaActiva.Dim3D = True 'Mostramos cilindros en vez de columnas oGrafico.StartColumn.EndRow + 2 ) With oRec .Rectangle oCelda As Object oHojaActiva = ThisComponent.collapseToCurrentRegion() mRangos(0) = oCursor. lo demás se calcula. Sub Dim Dim Dim Dim Dim Dim Dim Dim Graficando13() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object mRangos(0) sNombre As String oRec As New com.

Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando14() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.star.Position.Rectangle oCelda As Object oHojaActiva = ThisComponent.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.Y = oCelda.getCharts() If oGraficos.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.createCursorByRange( oSel ) 'Expandimos el cursor a la región actual oCursor. True) End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub 6.X . oRec. True.getCurrentController.Position.Width = 11500 'El ancho del gráfico .collapseToCurrentRegion() mRangos(0) = oCursor.374 .getSelection() If oSel.addNewByName(sNombre.awt.getCurrentController.X = oCelda.getActiveSheet() oSel = ThisComponent.sun.Height = 7000 'El alto del gráfico End With oGraficos = oHojaActiva.9 Graficando datos El mismo gráfico. escoge otro" Else oGraficos.getRangeAddress sNombre = "Grafico10" 'Celda para la posición del gráfico . pero ahora lo hacemos de barras.Y . mRangos.

Width = 11500 'El ancho del gráfico . mRangos.getRangeAddress. oCursor.Y .getCellByPosition( oCursor.star.X .getCurrentController. True.Height = 7000 'El alto del gráfico End With oGraficos = oHojaActiva.addNewByName(sNombre.Y = oCelda.Aprendiendo OOo Basic 375 oCelda = oHojaActiva.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.StartColumn. escoge otro" Else oGraficos.Rectangle oCelda As Object oDatos As Object oHojaActiva = ThisComponent.getDiagram.getSelection() .getRangeAddress. True) oGrafico = oGraficos.getActiveSheet() oSel = ThisComponent.Position.getEmbeddedObject. oRec.getByName( sNombre ) oGrafico.awt.getCharts() If oGraficos.getCurrentController.X = oCelda.sun.Vertical = True End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub Los gráficos circulares nos dan la imagen de la relación de cada punto respecto al total.EndRow + 2 ) With oRec .Position. Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando15() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.

sun.Dim3D = True oGrafico.Width = 10000 . destacan la magnitud de un cambio en el tiempo.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.collapseToCurrentRegion() mRangos(0) = oCursor.HasColumnHeaders = True oGrafico.getRangeAddress sNombre = "Grafico15" oCelda = oHojaActiva.createInstance("com.setRanges( mRangos ) oDatos.LabelPlacement = 0 Call FormatoTexto( oDatos. "Liberation Sans".getDataRowProperties(0) oGrafico.getRangeAddress.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.X = oCelda. . RGB(55.EndRow + 2 ) With oRec . mRangos.Y .setDiagram( oGrafico.createCursorByRange( oSel ) oCursor.getDiagram.Position.376 6.getCharts() If oGraficos.X . 15.getEmbeddedObject.Y = oCelda. escoge otro" Else oGraficos.DataCaption = 2 oDatos.StartColumn.getEmbeddedObject. oCursor.getRangeAddress.9 Graficando datos If oSel.getEmbeddedObject. True) oGrafico = oGraficos.getByName( sNombre ) 'Cambiamos el tipo de gráfico oGrafico.HasRowHeaders = True 'Hay que reasignar el rango de datos. 150.55) ) End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub Los gráficos de área.PieDiagram") ) oDatos = oGrafico. oRec. True.addNewByName(sNombre.getEmbeddedObject.55.star.getDiagram.chart. lo pierde al cambiar de tipo de gráfico oGrafico.Height = 7000 End With oGraficos = oHojaActiva. "".getCellByPosition( oCursor.Position.

True) oGrafico = oGraficos.Y = oCelda.getByName( sNombre ) 'Cambiamos el tipo de gráfico oGrafico.getRangeAddress sNombre = "Grafico16" oCelda = oHojaActiva.StartColumn.getCurrentController.Width = 10000 .addNewByName(sNombre. escoge otro" Else oGraficos. mRangos.Aprendiendo OOo Basic Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando16() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.Position.getEmbeddedObject. .getCurrentController.collapseToCurrentRegion() mRangos(0) = oCursor.createCursorByRange( oSel ) oCursor.getSelection() If oSel.EndRow + 2 ) With oRec .getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.Rectangle oCelda As Object oDatos As Object 377 oHojaActiva = ThisComponent.sun.star.createInstance("com.getEmbeddedObject.awt.star.X .hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.getCellByPosition( oCursor.getCharts() If oGraficos. True. oCursor.chart.getActiveSheet() oSel = ThisComponent.AreaDiagram") ) End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub Los gráficos de líneas muestran principalmente los cambios de valor en el tiempo y su relación con otros valores.X = oCelda.Height = 7000 End With oGraficos = oHojaActiva.getRangeAddress.getRangeAddress.setDiagram( oGrafico.Y .Position.sun. oRec.

378 6.9 Graficando datos .

getCharts() If oGraficos.star.Height = 7000 End With oGraficos = oHojaActiva.EndRow + 2 ) With oRec .chart.Y = oCelda. escoge otro" Else oGraficos.getCurrentController.collapseToCurrentRegion() mRangos(0) = oCursor.Y .getRangeAddress. oCursor.Position.X .Rectangle oCelda As Object oDatos As Object oHojaActiva = ThisComponent. oRec.getRangeAddress sNombre = "Grafico17" oCelda = oHojaActiva.getEmbeddedObject.getByName( sNombre ) 'Cambiamos el tipo de gráfico oGrafico.getEmbeddedObject.getEmbeddedObject.Position.star.getSelection() If oSel.awt.StartColumn.Width = 12000 . True) oGrafico = oGraficos.createCursorByRange( oSel ) oCursor.SymbolType = 1 End If Else MsgBox "Selecciona solo una celda con datos" .setDiagram( oGrafico.createInstance("com.Aprendiendo OOo Basic 379 Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando17() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.getActiveSheet() oSel = ThisComponent. mRangos.getRangeAddress.sun. True.LineDiagram") ) oGrafico.addNewByName(sNombre.getDiagram.X = oCelda.getCurrentController.sun.getCellByPosition( oCursor.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.

StartColumn.getByName( sNombre ) 'Cambiamos el tipo de gráfico oGrafico.createCursorByRange( oSel ) oCursor.addNewByName(sNombre.collapseToCurrentRegion() mRangos(0) = oCursor.Width = 12000 .setDiagram( oGrafico.Y .awt. aun así.getEmbeddedObject.getCurrentController. creo.sun.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.9 Graficando datos Los gráficos de anillo.getSelection() If oSel. mRangos. True.getEmbeddedObject.Rectangle oCelda As Object oDatos As Object oHojaActiva = ThisComponent.X . no son una buena elección.getCellByPosition( oCursor.star.DonutDiagram") ) End If Else MsgBox "Selecciona solo una celda con datos" .X = oCelda.getCurrentController.getRangeAddress sNombre = "Grafico18" oCelda = oHojaActiva.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.Height = 7000 End With oGraficos = oHojaActiva.Position.getRangeAddress.getCharts() If oGraficos. oRec. Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando18() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.380 End If End Sub 6.sun.EndRow + 2 ) With oRec . escoge otro" Else oGraficos. son parecidos a los circulares.Y = oCelda.getActiveSheet() oSel = ThisComponent.getRangeAddress.star.Position. oCursor.chart. pero pueden representar más de una serie de datos. True) oGrafico = oGraficos.createInstance("com.

Y .chart.getRangeAddress. mRangos.getActiveSheet() oSel = ThisComponent.X .star.getCurrentController.createCursorByRange( oSel ) oCursor.getRangeAddress.createInstance("com. Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando19() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.getEmbeddedObject.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.NetDiagram") ) End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub .Position.getSelection() If oSel.Y = oCelda.EndRow + 2 ) With oRec .getRangeAddress sNombre = "Grafico19" oCelda = oHojaActiva. oRec.getCurrentController.star. oCursor.getCharts() If oGraficos.sun.collapseToCurrentRegion() mRangos(0) = oCursor.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.getCellByPosition( oCursor.Width = 12000 .Aprendiendo OOo Basic End If End Sub 381 Lo confieso.StartColumn.awt. pero ahí esta el ejemplo.Height = 7000 End With oGraficos = oHojaActiva. True) oGrafico = oGraficos.sun.getByName( sNombre ) 'Cambiamos el tipo de gráfico oGrafico.getEmbeddedObject.addNewByName(sNombre.Rectangle oCelda As Object oDatos As Object oHojaActiva = ThisComponent. no le hayo mucho sentido a un gráfico radial.setDiagram( oGrafico. escoge otro" Else oGraficos.X = oCelda.Position. True.

Rectangle oCelda As Object oDatos As Object oHojaActiva = ThisComponent.getRangeAddress.createInstance("com.getByName( sNombre ) 'Cambiamos el tipo de gráfico oGrafico.sun.star.382 6. el orden de los datos es importante.9 Graficando datos Para un gráfico de stock.getCurrentController. mRangos.StartColumn.getRangeAddress sNombre = "Grafico20" oCelda = oHojaActiva. Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando20() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.Y .getActiveSheet() oSel = ThisComponent.getCurrentController.awt.getRangeAddress. True) oGrafico = oGraficos.chart.getCharts() If oGraficos.getEmbeddedObject.Height = 7000 End With oGraficos = oHojaActiva.getSelection() If oSel.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.Position.Width = 12000 .addNewByName(sNombre.star. True.EndRow + 2 ) With oRec . escoge otro" Else oGraficos. oRec.StockDiagram") ) End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub El gráfico XY (dispersión) muestra la relación de un valor en función de otro.Position.X .getCellByPosition( oCursor.createCursorByRange( oSel ) oCursor.Y = oCelda.setDiagram( oGrafico.X = oCelda.getEmbeddedObject. .collapseToCurrentRegion() mRangos(0) = oCursor.sun. oCursor.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.

X .getCurrentController. inmediatamente que agregues el gráfico.star.addNewByName(sNombre.collapseToCurrentRegion() mRangos(0) = oCursor.Rectangle oCelda As Object oDatos As Object oHojaActiva = ThisComponent.getActiveSheet() oSel = ThisComponent.star.getRangeAddress.HasLegend = False End If Else MsgBox "Selecciona solo una celda con datos" End If End Sub Cada tipo de gráfico tiene sus particularidades que tendrás que considerar a la hora de graficar. estableces todas las propiedades que quieras.X = oCelda.createInstance("com. True) oGrafico = oGraficos.getRangeAddress sNombre = "Grafico21" oCelda = oHojaActiva.getCellByPosition( oCursor. mRangos.createCursorByRange( oSel ) oCursor.Y = oCelda. True.XYDiagram") ) oGrafico.getImplementationName = "ScCellObj" Then oCursor = oHojaActiva.Height = 7000 End With oGraficos = oHojaActiva.Aprendiendo OOo Basic 383 Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Graficando21() oHojaActiva As Object oSel As Object oCursor As Object oGraficos As Object oGrafico As Object mRangos(0) sNombre As String oRec As New com.getRangeAddress. oRec. la recomendación general es.chart.getCharts() If oGraficos.StartColumn.getSelection() If oSel.Width = 12000 .Position.getEmbeddedObject 'Cambiamos el tipo de gráfico oGrafico.awt.setDiagram( oGrafico.getCurrentController. oCursor.Position. cambia su tipo al que necesites y solo al final.Y .sun. escoge otro" Else oGraficos.hasByName( sNombre ) Then MsgBox "Ya existe este nombre de gráfico.getByName( sNombre ).EndRow + 2 ) With oRec .sun. .

por ende.9 Graficando datos Si sumas la importación de bases de datos. tan variadas y ricas con que cuentan las aplicaciones actuales.createInstance( "com.GraphicURL = sRuta 'La agregamos a la página de dibujo.add( oImagen ) 'Establecemos el tamaño de la imagen. podemos hacer uso de esas características extras. 6. si no 'se insertará con un tamaño mínimo casi invisible 'la unidad es centésimas de milímetro oTam. soporta la inclusión de una amplia variedad de formatos de imágenes.sun.GraphicObjectShape" ) 'Establecemos la ruta de la imagen oImagen. siempre establece un tamaño. .10 Trabajando con elementos gráficos No se si estarás de acuerdo conmigo.star.384 6. en uno y en otro podemos hacer muchas tareas similares. pero poco a poco se ha ido diluyendo la frontera entre aplicaciones. insertamos una imagen PGN en la hoja activa.getCurrentController.1 Trabajando con imágenes Calc. soy de la opinión de seguir usando cada aplicación especifica para la tarea que fue diseñada.png") oDoc = ThisComponent 'Pagina de dibujo de la hoja activa oPaginaDibujo = oDoc.drawing. el método para abrir un archivo lo usamos casi al principio de estos apuntes.Width = 10000 oTam. Sub Dim Dim Dim Dim Dim Imagenes1() oDoc As Object oPaginaDibujo As Object oImagen As Object sRuta As String oTam As New com. es decir.getDrawPage() 'Para crear y manipular imagenes oImagen = oDoc.Height = 7500 oImagen. en el siguiente ejemplo. no obstante.getActiveSheet. pero aquí lo recordamos. lo cual aprenderemos en este capitulo. 6.setSize( oTam ) End Sub Ahora permitimos al usuario seleccionar una imagen. entre un procesador de textos y una hoja de calculo por ejemplo.awt.sun. tienes un combinación bastante poderosa y eficiente para representar tus datos en informes. al conjunto de formas oPaginaDibujo. con el gráfico de datos.10.Size 'La ruta de la imagen sRuta = ConvertToURL("/home/mau/globo.star.

ui.*.getActiveSheet. "*.Execute() mostramos el cuadro de dialogo 'Si el usuario presiona Abrir el metodo devuelve 1 que podemos evaluar como Verdadero (True) 'Si presiona Cancelar devuelve 0 If oDlgAbrirArchivo.GraphicObjectShape" ) oImagen.star.setTitle("Selecciona la imagen a insertar") If oDlgAbrirArchivo.*.Execute() Then 'De forma predeterminada.sun.appendFilter( "Imagenes JPG".awt.Height = 7500 oImagen.*.appendFilter( "Todos los formatos".sun.jpg.bmp.*.appendFilter( "Todos los formatos de imagen". pero tu puedes mejorarla.star.getFiles() SelecionarImagen = mArchivos(0) End If End Function Comprueba que funciona como se espera. "*.sun.png. pasándole el título del dialogo y los filtros que soporte.FilePicker") oDlgAbrirArchivo. 'Función para devolver la imagen a insertar Function SelecionarImagen() As String Dim oDlgAbrirArchivo As Object Dim mArchivos() oDlgAbrirArchivo = CreateUnoService ("com. por ejemplo.*.appendFilter( "Imagenes PNG".tiff") oDlgAbrirArchivo.dialogs.jpge. "*.star.Size 385 'Creamos el servicio necesario oDlgAbrirArchivo = CreateUnoService ("com. "*.star.getFiles() 'El primer elemento de la matriz es el archivo seleccionado sRuta = mArchivo(0) 'Insertamos la imagen oPaginaDibujo = ThisComponent.appendFilter( "Imagenes PNG".jpge.*.GraphicURL = sRuta oPaginaDibujo. .getCurrentController.setTitle("Selecciona la imagen") 'Con el metodo .drawing.add( oImagen ) oTam.png.jpg") oDlgAbrirArchivo.sun.Execute() Then mArchivos() = oDlgAbrirArchivo.Width = 10000 oTam. "*.FilePicker") 'Establecemos los filtros de archivo oDlgAbrirArchivo.appendFilter( "Imagenes JPG". podrías convertirla en una función para que te devuelva el nombre o nombres de los archivos abiertos.setSize( oTam ) Else 'Si el usuario presiona Cancelar MsgBox "Proceso cancelado" End If End Sub El método para abrir archivos.Aprendiendo OOo Basic Sub Dim Dim Dim Dim Dim Dim Imagenes2() oDlgAbrirArchivo As Object mArchivo() sRuta As String oPaginaDibujo As Object oImagen As Object oTam As New com.bmp.*.createInstance( "com.getDrawPage() oImagen = ThisComponent.ui.png") oDlgAbrirArchivo.jpg") 'Establecemos el titulo del cuadro de dialogo oDlgAbrirArchivo.*.tiff") oDlgAbrirArchivo.jpg. solo se puede seleccionar un archivo 'pero devuelve una matriz de todos modos con la ruta completa 'del archivo en formato URL mArchivo() = oDlgAbrirArchivo.png") oDlgAbrirArchivo. "*.dialogs. aquí te muestro una primer forma que nos servirá para nuestros siguientes ejemplos.

drawing. puedes mejorarla pasándole la hoja donde se insertará.getActiveSheet.sun.sun. 'Subrutina para insertar la imagen en la hoja activa Sub InsertaImagen(RutaImagen As String) Dim oDoc As Object Dim oPaginaDibujo As Object Dim oImagen As Object Dim oTam As New com. inserta la imagen pasada como argumento en la hoja activa.createInstance( "com.10 Trabajando con elementos gráficos Sub Imagenes3() Dim sRuta As String sRuta = SelecionarImagen() MsgBox sRuta End Sub La siguiente subrutina.Height = 7500 oImagen. de este modo. Nota que en la función no establecemos el tamaño de la imagen.star.add( oImagen ) oTam.awt.386 6.GraphicURL = RutaImagen oPaginaDibujo. por ahora.getActiveSheet. la posición y el tamaño.getDrawPage() oImagen = oDoc.GraphicObjectShape" ) oImagen. devuelve la imagen 'nota que no establecemos el tamaño Function getImagen(RutaImagen As String) As Object Dim oDoc As Object Dim oPaginaDibujo As Object Dim oImagen As Object oDoc = ThisComponent oPaginaDibujo = oDoc. Sub Imagenes4() Dim sRuta As String sRuta = SelecionarImagen() If sRuta <> "" Then Call InsertarImagen( sRuta ) End If End Sub La subrutina la puedes convertir en función y devolver una referencia a la imagen insertada.star. así nos sirve.getCurrentController. para nuestro ejemplos.setSize( oTam ) End Sub Y la probamos.drawing.Size oDoc = ThisComponent oPaginaDibujo = oDoc. 'Función para insertar la imagen en la hoja activa. por lo que es importante que lo hagas después de llamar a esta función.add( oImagen ) .getDrawPage() oImagen = oDoc.createInstance( "com.getCurrentController.GraphicObjectShape" ) oImagen.sun.Width = 10000 oTam.star.GraphicURL = RutaImagen oPaginaDibujo. puedes seguir manipulándola.

sun.Size sRuta = SelecionarImagen() If sRuta <> "" Then oImagen = getImagen( sRuta ) oTam.9 ) oImagen.Height = Alto Obj.star.awt.awt.setSize( oTam ) End If End Sub Y ya encarrerados. Sub CambiaTam( Obj As Object.setSize( oTam ) End Sub Hasta ahora.getActiveSheet.Anchor = oCelda End If End Sub El ancla también la puedes establecer a la hoja. siempre lo hacen ancladas (Anchor) a la celda A1. al modificar esta se modifica la posición oCelda = ThisComponent.sun. vamos a cambiar esto y por consiguiente la posición de la imagen.Width = Ancho oTam. crea la subrutina para establecer el tamaño. las imágenes insertadas.getCellByPosition( 4. 7500 ) 'Establecemos la celda de anclaje. Sub Imagenes7() Dim sRuta As String Dim oImagen As Object .Width = 10000 oTam.star. Alto As Long ) Dim oTam As New com.getCurrentController.Height = 7500 oImagen. Sub Dim Dim Dim Imagenes6() sRuta As String oImagen As Object oCelda As Object sRuta = SelecionarImagen() If sRuta <> "" Then oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. 10000. Sub Dim Dim Dim Imagenes5() sRuta As String oImagen As Object oTam As New com. Ancho As Long.Size oTam.Aprendiendo OOo Basic getImagen = oImagen End Function 387 Y la prueba. que servirá para cualquier objeto que soporte estas propiedades.

IsMirrored = True End With End If End Sub .388 6.getActiveSheet End If End Sub Como ya lo comprobamos. pero también puedes establecer esta posición. 7500 ) 'Establecemos la hoja como ancla oImagen.awt. 10000.sun. 7500 ) With oImagen 'Nombramos la imagen .MoveProtect = True 'Que cambie su tamaño .Point sRuta = SelecionarImagen() If sRuta <> "" Then oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.X = 15000 oPos. Sub Imagenes8() Dim sRuta As String Dim oImagen As Object Dim oPos As New com. 7500 ) 'Establecemos la posición de la imagen oPos.Name = "Imagen09" 'Evitamos que la muevan .SizeProtect = True 'Que se imprima . puedes evitarlo protegiendo su tamaño (SizeProtect).setPosition( oPos ) End If End Sub Algunas propiedades interesantes.getCurrentController. si cambias el ancla de la imagen a una celda. cuando insertas o eliminas filas o columnas. la imagen se verá afectada en su tamaño.Printable = False 'Puedes reflejar la imagen . no importando si el ancla esta a la hoja o a una celda. la imagen cambia a la posición de dicha celda. 10000. también puedes evitar que se mueva (MoveProtect) y que se imprima (Printable).Anchor = ThisComponent. 10000. Sub Imagenes9() Dim sRuta As String Dim oImagen As Object sRuta = SelecionarImagen() If sRuta <> "" Then oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.10 Trabajando con elementos gráficos sRuta = SelecionarImagen() If sRuta <> "" Then oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.y = 5000 oImagen.star.

es importante que lo asignes. es el que puede establecer con el menú contextual de la imagen. así mismo.Aprendiendo OOo Basic 389 El nombre asignado a la imagen (Name). es el nombre que aparecerá en el navegador. . sobre todo si manejas muchas imágenes para que se muestre en el navegador.

inserta la imagen varias veces son los diferentes modos.drawing. 0 ) 'Cambiamos el modo de color a escala de grises oImagen.star.ColorMode. 5000.ColorMode.GraphicColorMode = com.ColorMode.STANDARD com.ColorMode.MONO oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.WATERMARK .awt. 3750 ) Call CambiaPos( oImagen.star.WATERMARK Valor 0 1 2 3 Valor en Interfaz Predeterminado Escala de grises Blanco y negro Filigrana El siguiente ejemplo.sun. 5000.Point sRuta = SelecionarImagen() If sRuta <> "" Then 'Insertamos la imagen normal oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.GraphicColorMode = com. 0 ) 'Cambiamos el modo de color a marca de agua oImagen. 15000. 3750 ) Call CambiaPos( oImagen.GREYS oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.10 Trabajando con elementos gráficos Puedes tener varias imágenes con el mismo nombre. 5000.sun.sun.star. 3750 ) 'Insertamos la misma imagen oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.390 6.star.drawing. según la siguiente enumeración: com.sun.ColorMode.star.ColorMode.sun.sun.star.ColorMode. 5000.drawing.sun.drawing. 10000. 5000.star. A las imágenes.star.drawing.drawing.MONO com. 0 ) 'Cambiamos el modo de color a blanco y negro oImagen.sun.drawing. 3750 ) Call CambiaPos( oImagen.star.sun.drawing. Sub Dim Dim Dim Imagenes10() sRuta As String oImagen As Object oPos As New com.ColorMode com.GraphicColorMode = com. les puedes cambiar el modo de color (GraphicColorMode).GREYS com.

0 ) oImagen.setPosition( oPos ) End Sub El resultado.Transparency = 25 oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.Aprendiendo OOo Basic 391 End If End Sub 'Cambia la posición del objeto Sub CambiaPos( Obj As Object. Sub Dim Dim Dim Imagenes11() sRuta As String oImagen As Object oPos As New com.Point oPos. sin transparencia y 100 totalmente transparente. 3750 ) Call CambiaPos( oImagen.awt.Transparency = 75 End If End Sub . Puedes cambiar la transparencia (Transparency) de la imagen. 10000.X = X oPos. 15000. donde 0 es el valor predeterminado. X As Long.star. 3750 ) oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.sun. 3750 ) Call CambiaPos( oImagen. 5000. 0 ) oImagen. no veras la imagen por lo que procura no establecerlo tan alto. 0 ) 'Cambiamos el nivel de transparencia oImagen. este valor va de 0 a 100. 3750 ) Call CambiaPos( oImagen. 5000. si estableces esta valor en 100 y pierdes la selección.sun. 5000. 5000.Point sRuta = SelecionarImagen() If sRuta <> "" Then 'Insertamos la imagen normal oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. Y As Long ) Dim oPos As New com.star.Transparency = 50 oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. 5000.awt.Y = Y Obj.

verde (AdjustGreen) y azul (AdjustBlue). pero cambia oImagen. 15000. 3750 ) Call CambiaPos( oImagen.AdjustGreen = 50 . 0 ) 'Cambiamos el nivel de verde oImagen.sun. 5000. 5000. 5000. Sub Dim Dim Dim Imagenes13() sRuta As String oImagen As Object oPos As New com. Sub Dim Dim Dim Imagenes12() sRuta As String oImagen As Object oPos As New com.Point sRuta = SelecionarImagen() If sRuta <> "" Then 'Insertamos la imagen normal oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. 0 ) 'Cambiamos el canal gamma.AdjustLuminance = 50 oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.10 Trabajando con elementos gráficos Puedes manipular completamente los colores de una imagen (si sabes por que yo no).sun. 3750 ) Call CambiaPos( oImagen. 5000.awt. 10000. 10000. 0 ) 'Cambiamos el nivel de luminosidad oImagen.star.awt. 3750 ) Call CambiaPos( oImagen. toman valores de 0 a 100. que no se que sea. 3750 ) Call CambiaPos( oImagen. 3750 ) Call CambiaPos( oImagen. 3750 ) oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. 5000. tanto la luminosidad (AdjustLuminance). 3750 ) oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. de la siguiente manera.AdjustRed = 50 oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. el canal gamma. La luminosidad y el contraste. también puedes cambiar los canales rojo (AdjustRed). 0 ) 'Cambiamos el nivel de rojo oImagen.AdjustContrast = 50 oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. de 0.star. 0 ) 'Cambiamos el contraste oImagen. como el contraste (AdjustContrast). 5000. 5000. 5000. 5000.1 a 10.Gamma = 5 End If End Sub Y por supuesto.Point sRuta = SelecionarImagen() If sRuta <> "" Then 'Insertamos la imagen normal oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.392 6. el canal gamma (Gamma).

como en: Sub Imagenes14() Dim sRuta As String Dim oImagen As Object sRuta = SelecionarImagen() If sRuta <> "" Then oImagen = getImagen( sRuta ) Call CambiaTam( oImagen.CharColor = RGB(255.255.CharHeight = 30 .Aprendiendo OOo Basic 393 oImagen = getImagen( sRuta ) Call CambiaTam( oImagen. la posibilidad de agregarles texto. 15000. pero al ser consideradas formas (shapes) comparten con ellas muchas de sus propiedades. Las imágenes insertadas tienen propiedades particulares.255) . 7500 ) 'Insertamos texto en la imagen y le cambiamos sus propiedades With oImagen .CharWeight = 150 . por ejemplo. como las que hemos visto hasta ahora. 5000. Hidalgo" & Chr(13) & "México" .AdjustBlue = 50 End If End Sub Mira que divertido queda. 3750 ) Call CambiaPos( oImagen.String = "Apulco. 0 ) 'Cambiamos el nivel de azul oImagen. 10000.ParaAdjust = 3 End With End If End Sub .

sun. cuando abras tu archivo.GraphicObjectShape") ThisComponent. por lo que si cambias el nombre de la imagen origen.star.sun.beans.sun.graphic. 10000. en todos los ejemplos anteriores. Sub Dim Dim Dim Dim Imagenes16() sRuta As String oSel As Object oGP As Object mOpc(1) As New com. pero esa.GraphicProvider") 'Establecemos la ruta mOpc(0).star. Sub Dim Dim Dim Dim Dim Imagenes15() sRuta As String oImagen As Object oForma As Object oGP As Object mOpc(0) As New com.getCurrentController. 7500 ) End If End Sub El cual. toma la selección y determina si es o no una imagen. al insertar la imagen.star.10 Trabajando con elementos gráficos Otras propiedades las veremos en el siguiente apartado. El siguiente ejemplo es muy divertido.sun. te quedará solo un marco vacío. en formato “jpg”.getDrawPage(). usa el siguiente código. para insertar la imagen incrustada en el documento.drawing.PropertyValue .createInstance("com.queryGraphic( mOpc ) 'Cambiamos el tamaño Call CambiaTam( oForma.Name = "URL" mOpc(0).Value = sRuta 'Trae la imagen y la carga en la forma oForma.beans. por supuesto.PropertyValue sRuta = SelecionarImagen() If sRuta <> "" Then 'Agregamos una forma a la hoja activa oForma = ThisComponent. es tu tarea. por supuesto puedes exportar a otros formatos.star. puedes convertir en una función o subrutina para llamarla cuando quieras. la mueves o borras. solicita una ruta y nombre donde guardar y la guarda si el usuario no cancela la operación.Graphic = oGP.394 6.getActiveSheet. para terminar este tema.add(oForma) 'Servicio para manipulacion de gráficos oGP = createUnoService("com. la estás vinculando.

GraphicObjectShape") Then 'Si es una imagen.getCurrentController. que puedes complementar perfectamente con los conocimientos de nuestro próximo apartado.Value = "image/jpeg" 'Guardamos la imagen oGP.star. el limite. "*.drawing. tiene .sun.sun.getFiles() RutaGuardarImagen = mArchivo(0) End If End Function Y con esto terminamos el tema de imágenes. porqué.AppendFilter( "Imagen JPG (.GraphicProvider") 'Establecemos las propiedades mOpc(0). siempre es la primera oSel = oSel.SvxShapeCollection" Then 'Si es una forma.getSelection iF oSel. obtenemos la ruta y nombre para guardar sRuta = RutaGuardarImagen() If sRuta <> "" Then oGP = createUnoService("com.getByIndex(0) If oSel.supportsService("com.setTitle("Guardar como") oDlgGuardarArchivo.jpg" ) If oDlgGuardarArchivo.star.Execute() Then mArchivo() = oDlgGuardarArchivo.graphic.Name = "MimeType" mOpc(1).getImplementationName = "com.storeGraphic( oSel.sun.Initialize ( mDlgOpciones() ) oDlgGuardarArchivo. pues muchas de las propiedades y métodos que veremos. es tu imaginación.star.Value = sRuta mOpc(1).drawing.dialogs. Cada hoja de nuestro archivo.Name = "URL" mOpc(0).FilePicker") oDlgGuardarArchivo.Aprendiendo OOo Basic 395 'La selección actual oSel = ThisComponent. son soportados por las imágenes.jpg)".sun.Graphic. 6.star.2 Trabajando con autoformas Con las herramientas de dibujo incluidas en la aplicación.ui. se podría dibujar casi cualquier cosa. veamos. mOpc ) Else MsgBox "Proceso cancelado" End If Else MsgBox "La selección es una forma pero no una imagen" End If Else MsgBox "La selección no es una imagen" End If End Sub La función para devolver la ruta es: 'Función para devolver la ruta y nombre del archivo a guardar 'Puedes mejorarla pasándole los filtros que quieras Function RutaGuardarImagen() As String Dim oDlgGuardarArchivo As Object Dim mArchivo() Dim mDlgOpciones() mDlgOpciones() = Array(2) oDlgGuardarArchivo = CreateUnoService ("com.10.

donde están todos los elementos gráficos.getActiveSheet() 'Accedemos a la página de dibujo oPaginaDibujo = oHojaActiva. Como con las imágenes. no cuando pongas el cursor sobre la celda. es importante que al menos cambies el tamaño de la nueva forma. hay elementos.getActiveSheet() 'Accedemos a la página de dibujo oPaginaDibujo = oHojaActiva. Sub Dim Dim Dim Dim Dim AutoFormas2() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oForma As Object co1 As Long oDoc = ThisComponent oHojaActiva = oDoc. 0. si no cuando la muestres permanentemente. si no. entonces.getByIndex(co1) 'Cambiamos su tamaño Call CambiaTam( oForma.getCount End Sub La cuenta de los objetos gráficos. cambia el tamaño y la posición de “todos” los objetos gráficos de la hoja y los posiciona en la esquina superior izquierda de la hoja. que siempre muestra las notas cerca de esta. otras veces. por ejemplo. las subrutinas “CambiaTam” y “CambiaPos”. una polilínea no puedes agregarla. por lo que si te muestra un número y aparentemente no hay nada en la hoja. incluye. incluso. 3000 ) 'Y su posición Call CambiaPos( oForma.getCurrentController. estas se cambiaran de tamaño pero el cambio de posición solo lo veras reflejado cuando muestres la nota. ya las hemos usado anteriormente. 0 ) Next End Sub Si en tu hoja hay notas.396 6. bueno.getCurrentController. las notas de las celdas.1 oForma = oPaginaDibujo. como imágenes. lo cual si puedes hacer en Draw o Impress. El siguiente ejemplo. que tienen un tamaño mínimo y no se notan o están posicionadas en zonas de la hoja muy separadas. no necesariamente la activa). se creará del tamaño .10 Trabajando con elementos gráficos una “página de dibujo virtual” (DrawPage). 3000. para acceder a esta hoja. le estableces sus propiedades y al final la agregas a la página de dibujo. casi de la que quieras por que en las hojas de calculo no puedes agregar todos los tipos de formas. después de agregar la forma soportada en Calc.getDrawPage() 'Iteramos en cada forma For co1 = 0 To oPaginaDibujo. primero creas una instancia de la forma que quieras.getDrawPage() 'Mostramos el número de elementos en la página MsgBox oPaginaDibujo. tal vez sea este tu caso.getCount . usamos: Sub Dim Dim Dim AutoFormas1() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oDoc = ThisComponent oHojaActiva = oDoc. Para agregar una forma a la página de dibujo y por consiguiente a la hoja activa (puede ser a la hoja que quieras.

Rnd()*255 ) 'La transparencia de la línea .drawing.EllipseShape") Call CambiaTam( oForma. Sub AutoFormas4() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent. aprenderemos a cambiar aquí.getDrawPage() 'Creamos una elipse oForma = ThisComponent. veamos las principales que comparten entre si y después las particulares de algunas.Rnd()*255.drawing.LineStyle. 5000 ) oPaginaDibujo. tienes un cuadrado. 5000.getDrawPage() 'Creamos un rectangulo oForma = ThisComponent.LineTransparence = 50 'El ancho de la línea .RectangleShape") Call CambiaTam( oForma. etc).LineWidth = 500 End With oPaginaDibujo. comparten casi todas las mismas propiedades (línea. es obvia la respuesta.add( oForma ) End Sub La mayoría de las formas. las cuales.getDrawPage() 'Creamos un circulo oForma = ThisComponent.sun.getCurrentController.createInstance("com.star. 10000.createInstance("com.getCurrentController. sombra. texto. relleno.createInstance("com. la nueva forma se crea con las propiedades predeterminadas.drawing. 5000.add( oForma ) End Sub ¿Adivina que pasa si estableces el mismo alto y ancho?.getActiveSheet.star.Aprendiendo OOo Basic 397 mínimo. 6.LineStyle = com. 5000 ) With oForma 'El estilo de línea .getActiveSheet.sun. en vez de un rectángulo.star. 3000 ) oPaginaDibujo.LineColor = RGB( Rnd()*255. Sub AutoFormas3() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.drawing.getActiveSheet.2. Sub AutoFormas5() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.add( oForma ) .1 Principales propiedades de línea.getCurrentController. agregamos un rectángulo a la hoja.SOLID 'El color de la línea . lo mismo pasa con las elipses. En el siguiente ejemplo.sun.10.EllipseShape") Call CambiaTam( oForma.star. obtienes un circulo.sun. si establece el mismo ancho y alto.

LineDashName = "Fine Dashed" End Sub Los nombres que puedes establecer son: Si las vas a usar seguido. Si estableces el estilo en guiones (DASH). si establece el valor en cero la línea no se verá como si establecieras el estilo en oculta (NONE).sun. si estableces este valor en cero.star.sun.sun.10 Trabajando con elementos gráficos El estilo de línea.LineStyle.star.drawing. el ancho de la línea se establece en centésimas de milímetro y se reparte de forma equidistante del dentro hacia afuera y dentro de la forma.sun.star. esta determinado por la siguiente enumeración. lo más practico es crear una matriz con los nombres.star. queda visible aun.drawing.getCurrentController.drawing. estableces el nombre de estilo como en: Sub AutoFormas6() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.LineStyle = com.DASH Valor 0 1 2 Valor en Interfaz Oculta Solida Guiones El color (LineColor) de la línea es un valor tipo largo (long).star.getActiveSheet.LineStyle com. por ello.getByIndex(0) 'Establecemos el estilo en guiones oForma.getDrawPage() 'Seleccionamos el primero objeto de dibujo oForma = oPaginaDibujo.LineStyle.LineStyle.drawing. mejor usa el estilo si lo que quieres es no mostrar la línea. la primera más sencilla. Sub Dim Dim Dim AutoFormas7() oPaginaDibujo As Object oForma As Object mEstilos() .398 End Sub 6. la transparencia (LineTransparence) puede tomar valores de 0 (menos transparencia) a 100 (más transparencia).DASH 'Establecemos el estilo oForma. no desaparece completamente.sun.drawing.LineStyle. com.NONE com.SOLID com. puedes establecer el estilo de este de dos maneras.

creando un estilo completamente nuevo y personalizado. usamos el siguiente código.star. Sub Dim Dim Dim AutoFormas8() oPaginaDibujo As Object oForma As Object oLineaGuion As Object oLineaGuion = createUnoStruct("com.getActiveSheet.sun.getDrawPage() 'Seleccionamos el primero objeto de dibujo oForma = oPaginaDibujo.drawing.star."Fine Dashed". son completamente personalizables desde la interfaz del usuario.DASH 'Establecemos el estilo oForma."3 Dashes 3 Dots (var)".getCurrentController. de lo contrario. con el nombre de la interfaz.LineStyle.sun.Style = 0 .getActiveSheet.drawing.Aprendiendo OOo Basic 399 mEstilos = Array("Ultrafine Dashed".LineDash = oLineaGuion End Sub .star.drawing.LineDash") 'Todas las medidas en centésimas de milímetro With oLineaGuion . esta estructurado de la siguiente manera.getDrawPage() oForma = oPaginaDibujo. Si quieres asegurate de que no haya error.DASH 'Establecemos el estilo oForma. el cual.LineDashName = mEstilos(4) End Sub Recuerda que los estilos de línea. 1) 2) 3) 4) 5) Número de puntos (Dots) Número de guiones (Dashes) Ancho del punto (DotLen) Distancia en elementos (Distance) Ancho del guión (DashLen) Para crear un estilo similar al anterior."Line Style 9".getByIndex(0) 'Establecemos el estilo en guiones oForma.Dashes = 2 . minúsculas.getCurrentController. por lo que estos nombres pueden cambiar. te dará un error en tiempo de ejecución.Distance = 250 End With oPaginaDibujo = ThisComponent."2 Dots 1 Dash") oPaginaDibujo = ThisComponent.getByIndex(0) oForma. puedes usar la otra forma de establecer el estilo.sun. incluso sus mayúsculas.LineStyle.DotLen = 500 ."Fine Dotted".Dots = 3 .LineStyle = com. el nombre debe corresponder exactamente. números y espacios."Line with Fine Dots"."Ultrafine 2 Dots 3 Dashes".LineStyle = com."Fine Dashed (var)"."Ultrafine Dotted (var)".DashLen = 2000 .

sun. Sub AutoFormas10() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.BITMAP Valor 0 1 2 3 4 Valor en Interfaz Invisible Color Gradiente Trama Bitmap (Imagen) Establecemos un color aleatorio en la primer forma de la hoja. La primera y más simple.HATCH com.DashStyle.getActiveSheet.ROUNDRELATIVE Valor 0 1 2 3 Valor en Interfaz Rectangulo Punto Rectangulo.drawing. establece la línea en un acho bastante visible y nota como cambia.DashStyle.sun.drawing. sin relleno.drawing.getCurrentController.sun.star.getByIndex(0) 'Establecemos el relleno en color oForma.getDrawPage() oForma = oPaginaDibujo.FillStyle.FillStyle.star.getByIndex(0) 'Establecemos el relleno en invisible oForma.RECTRELATIVE com.star.sun.2.sun.star.star.RECT com.SOLID com.FillStyle.star. es.FillStyle com.drawing.sun.drawing.sun.drawing.GRADIENT com.FillStyle.sun.10 Trabajando con elementos gráficos Observa que también aquí tenemos un estilo (Style).sun.star.drawing.star.FillStyle. com.sun.FillStyle = 0 End Sub El estilo de fondo (FillStyle).2 Principales propiedades de relleno Ahora veamos las principales propiedades de relleno.FillStyle.drawing.DashStyle.sun. esta determinado por la enumeración.star.drawing.drawing. de acuerdo a la enumeración.drawing.getActiveSheet.drawing.star.star. 6. relativo a la longuitud de la línea Para que notes las diferencias de estos estilos.10.DashStyle com. Sub AutoFormas9() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.NONE com. com.400 6.SOLID . relativo a la longuitud de la línea Punto.star.getDrawPage() oForma = oPaginaDibujo.DashStyle.getCurrentController.ROUND com.sun.FillStyle = com.

Sub AutoFormas12() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent. si lo haces con la transparencia.getActiveSheet.getByIndex(0) 'Establecemos el relleno en gradiente oForma.Rnd()*255 ) End Sub Puedes establecer el porcentaje (0 a 100) de transparencia.FillTransparence = 50 End Sub Para establecer el fondo en un gradientes.drawing.SOLID 'Un color aleatorio oForma. los gradientes predeterminados.FillStyle = com.star.Rnd()*255. la diferencia será que si lo estableces con el estilo.getCurrentController. será similar a establecer el estilo de fondo en invisible (NONE). usamos.FillColor = RGB( Rnd()*255. el fondo se “quita” y puedes seleccionar las celdas que esten debajo de la forma.getDrawPage() oForma = oPaginaDibujo.getActiveSheet. un valor de 100.sun.Rnd()*255. te dará un error en tiempo de ejecución.drawing.FillStyle. si no.Aprendiendo OOo Basic 401 'Un color aleatorio oForma.Rnd()*255 ) 'La transparencia del color oForma. al dar clic dentro de la forma.getCurrentController.GRADIENT 'El nombre del gradiente oForma. seleccionas la forma.sun.FillStyle = com.FillColor = RGB( Rnd()*255. si no los ha cambiado el usuario son: .getByIndex(0) 'Establecemos el relleno en color oForma. Sub AutoFormas11() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.star.getDrawPage() oForma = oPaginaDibujo.FillGradientName = "Rectangular red/white" End Sub El nombre es el usado por la interfaz del usuario y debe ser exacto.FillStyle.

getActiveSheet.FillGradientName = mGradiente(4) End Sub Cambiamos de tipo de fondo y establecemos el estilo en trama (HATCH).10 Trabajando con elementos gráficos Con una matriz para los nombres.FillStyle."Gradient 3".getDrawPage() oForma = oPaginaDibujo."Blue Crossed 45 Degrees". es más sencillo establecerlos.getByIndex(0) 'Establecemos el relleno en trama oForma.FillStyle = com.drawing.FillStyle.FillStyle.drawing.getCurrentController."Linear yellow/brown"."Square yellow/white". Sub Dim Dim Dim AutoFormas15() oPaginaDibujo As Object oForma As Object mTramas() 'Matriz con los nombres de las tramas predeterminadas mTramas = Array("Black 0 Degrees".HATCH 'El nombre de la trama oForma.sun.star."Linear blue/white"."Gradient 6".FillHatchName = "Black 45 Degrees Wide" End Sub Al igual que con los nombres de los gradientes.FillHatchName = mTramas(5) End Sub Que corresponden a. también."Gradient 5"."Gradient 2".GRADIENT 'El nombre del gradiente oForma.FillStyle = com.getActiveSheet."Radial red/yellow"."Rectangular red/white"."Linear magenta/green"."Black 45 Degrees".getByIndex(0) 'Establecemos el relleno en gradiente oForma."Ellipsoid blue grey/light blue".drawing."Gradient 4"."Red Crossed 45 Degrees"."Axial light red/white") oPaginaDibujo = ThisComponent. Sub AutoFormas14() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent."Blue Triple 90 Degrees"."Black 90 Degrees".sun.getActiveSheet.getByIndex(0) 'Establecemos el relleno en trama oForma.sun.402 6.getDrawPage() oForma = oPaginaDibujo."Blue Crossed 0 Degrees"."Black 45 Degrees Wide") oPaginaDibujo = ThisComponent.FillStyle = com."Black -45 Degrees".star. son suceptibles de ser modificados por el usuario desde la interfaz del usuario.star.getCurrentController.getCurrentController. Sub Dim Dim Dim AutoFormas13() oPaginaDibujo As Object oForma As Object mGradiente() 'Matriz con los nombres de los gradientes mGradiente = Array("Gradient 1"."Red Crossed 0 Degrees"."Radial green/black". estos deben establecerse exactamente como se muestran a continuación y.getDrawPage() oForma = oPaginaDibujo.HATCH 'El nombre de la trama oForma. .

getByIndex(0) 'Establecemos el relleno en Imagen oForma.star."Marble".FillBitmapName = mImagen(10) End Sub Estos nombres corresponden a."Leaves".getActiveSheet."Space".getCurrentController."Daisy".getActiveSheet.sun.sun.drawing.star."Wet". debe estar escrito correctamente y puede ser cambiado por el usurio desde la interfaz.FillStyle = com.Rnd()*255."Coarse".BITMAP 'El nombre de la imagen oForma."Roses") oPaginaDibujo = ThisComponent. Sub Dim Dim Dim AutoFormas17() oPaginaDibujo As Object oForma As Object mImagen() mImagen = Array("Empty"."Pattern"."Pebbles". ."Wall"."Orange". tienes que cambiar el estilo y establecer el nombre de la imagen."Linen"."Space Metal".getDrawPage() oForma = oPaginaDibujo."Lawn Artificial".getDrawPage() oForma = oPaginaDibujo."Red Wall".Aprendiendo OOo Basic 403 Puedes combinar el uso de una trama con un fondo de color.HATCH 'El nombre de la trama oForma.FillColor = RGB( Rnd()*255.FillHatchName = "Black 45 Degrees Wide" 'Tambien con color oForma. Sub AutoFormas16() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.FillStyle = com. procura establecer un color de fondo claro.Rnd()*255 ) End Sub Para establecer una imagen como fondo de una forma.getCurrentController.drawing."Fiery".FillStyle.getByIndex(0) 'Establecemos el relleno en trama oForma.FillBackground = True oForma."Sky".FillStyle."Metal". que como en los demás estilos."Stone"."Aqua". para que se distinga la trama.

BITMAP 'El nombre de la imagen oForma."Space"."Linen".FillStyle = com.FillStyle.getDrawPage() oForma = oPaginaDibujo."Daisy"."Orange"."Wet".getByIndex(0) oForma.FillStyle."Marble"."Wall"."Stone". y al mismo tiempo el nivel de transparencia.FillBitmapURL = ConvertToURL( "/home/mau/fondo.FillStyle = com."Red Wall".star.FillBitmapName = mImagen(15) oForma.404 6."Roses") oPaginaDibujo = ThisComponent.getActiveSheet.sun."Space Metal".drawing."Fiery".drawing.getByIndex(0) 'Establecemos el relleno en Imagen oForma.sun. tomado de un archivo oForma."Metal".10 Trabajando con elementos gráficos Puedes establecer una imagen.FillBitmapMode = com."Lawn Artificial"."Pebbles".star.getActiveSheet.BITMAP 'El nombre de la imagen.drawing."Aqua"."Coarse".sun.star.getDrawPage() oForma = oPaginaDibujo."Sky".BitmapMode."Pattern".REPEAT .getCurrentController. desde un archivo de imagen.jpg" ) 'Es modo con que se muestra oForma.getCurrentController.FillTransparence = 50 End Sub Puedes establecer la imagen. Sub Dim Dim Dim AutoFormas18() oPaginaDibujo As Object oForma As Object mImagen() mImagen = Array("Empty". Sub AutoFormas19() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent."Leaves".

no necesariamente tiene que estar en tu equipo. com.getCurrentController.drawing.sun.getByIndex(0) oForma.BitmapMode.sun.png" ) End Sub 6.star.getDrawPage() oForma = oPaginaDibujo.NO_REPEAT Valor 0 1 2 Valor en Interfaz Repetir Ajustar No repetir El mismo fondo en una forma. no te dará error.2.drawing.getActiveSheet.universolibre.drawing.FillStyle.FillBitmapURL = ConvertToURL( "http://www.star.BitmapMode com.10. La imagen.star.getActiveSheet.sun.REPEAT com. no te mostrará la imagen.drawing.drawing.star.FillStyle = com. si la ruta no existe.BitmapMode.getCurrentController.getDrawPage() .BITMAP 'El nombre de la imagen.3 Principales propiedades de sombra Ahora veamos las principales propiedades de la sombra de una forma.Aprendiendo OOo Basic End Sub 405 El modo de imagen. Sub AutoFormas21() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.sun. esta determinado por la enumeración. puede estar al otro lado del mundo.star. pero obvio.BitmapMode.org/archivos/favicon.sun.STRETCH com. Sub AutoFormas20() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent. tomado de un archivo de internet oForma. con los tres modos diferentes.

Shadow = True 'Establecemos el color de la sombra oForma.getByIndex(0) oForma.getDrawPage() oForma = oPaginaDibujo. Puedes posicionar la imagen.Rnd()*255. por ejemplo.ShadowXDistance = -500 oForma.Rnd()*255 ) 'Establecemos el nivel de transparencia de la sombra oForma. donde quieras. si se puede mover o no y si se puede cambiar el tamaño o no. para establecer la forma en otra posición de la forma. para posicionarla en el extremo inferior izquierdo.Shadow = True 'Establecemos el color de la sombra oForma.ShadowTransparence = 50 End Sub 6. estableces los valores en. Sub AutoFormas23() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent. por ejemplo.Rnd()*255 ) 'Establecemos la distancia X .ShadowColor = RGB( Rnd()*255.getByIndex(0) 'Establecemos que queremos mostrar la sombra oForma.Shadow = True oForma.ShadowYDistance = 300 End Sub 6.ShadowXDistance = 300 oForma. usamos. para establecer la sombra a 3 milímetros de la forma. en relación a la forma.ShadowColor = RGB( Rnd()*255.Rnd()*255.2.getActiveSheet.Rnd()*255 ) 'Establecemos la distancia X .Y de la sombra en centésimas de milímetro oForma. Sub AutoFormas24() .406 oForma = oPaginaDibujo.getCurrentController.10 Trabajando con elementos gráficos Si no quieres mostrarla solo establece la sombra (Shadow) en falso (False).Rnd()*255. con las siguientes propiedades. puedes establecer estas propiedades en valores negativos. el color y la transparencia tienen las mismas particularidades ya vistas.ShadowYDistance = 300 End Sub Si establecemos la posición (ShadowXDistance y ShadowYDistance) en 0.getActiveSheet.4 Otras propiedades de las autoformas Podemos establecer si la forma se va a imprimir o no.getByIndex(0) 'Establecemos que queremos mostrar la sombra oForma.Y de la sombra en centésimas de milímetro oForma.getCurrentController.getDrawPage() oForma = oPaginaDibujo.ShadowColor = RGB( Rnd()*255.10. la sombra queda “detras” de la forma y es “como” si la ocultaras. Sub AutoFormas22() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.

getCurrentController.SizeProtect = True End Sub Podemos establecer el ángulo de rotación de la forma. el siguiente ejemplo intercambia la posición de las dos primeras formas. asegurate de tener al menos dos formas en tu hoja y de preferencia formas estándar. pero no todas las formas lo soportan. esta propiedad.MoveProtect = True 'Que no cambie el tamaño oForma.getActiveSheet. rectángulos o círculos para que veas el efecto. algunas formas especiales como rombos o corazones no la soportan.getCurrentController. Sub AutoFormas25() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent. Sub Dim Dim Dim AutoFormas27() oPaginaDibujo As Object oForma1 As Object oForma2 As Object . es decir.getByIndex(0) 'Establecemos que no se imprima la forma oForma.getActiveSheet. La unidad de esta valor son centésimas de grado y el sentido de rotación es inverso al giro de las manecillas del reloj.RotateAngle = 4500 End Sub También podemos modificar la inclinación de la forma. la unidad también son centésimas de grado.getDrawPage() oForma = oPaginaDibujo.ShearAngle = 1500 End Sub También podemos cambiar el orden de las formas.getDrawPage() oForma = oPaginaDibujo.getByIndex(0) 'Establecemos el ángulo de rotación en 45º 'unidades en centésimas de grado oForma. Sub AutoFormas26() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.getActiveSheet.getCurrentController.getDrawPage() oForma = oPaginaDibujo. quien esta delante de quien. este valor solo puede estar comprendido entre 0º y 89º.Printable = False 'Que no se pueda mover oForma.getByIndex(0) 'Establecemos el ángulo de inclinación oForma.Aprendiendo OOo Basic Dim oPaginaDibujo As Object Dim oForma As Object 407 oPaginaDibujo = ThisComponent.

2.getActiveSheet.getByIndex(0) 'Establecemos el nombre de la forma oForma.getActiveSheet. Sub AutoFormas28() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.getDrawPage() oForma = oPaginaDibujo.getByIndex(0) oForma2 = oPaginaDibujo.10 Trabajando con elementos gráficos oPaginaDibujo = ThisComponent.group( oGrupoFormas ) Else MsgBox "Agrega más formas para poder agrupar" End If End Sub Si el elemento a agregar no existe te dará un error en tiempo de ejecución.getCurrentController. .5 Agrupando y desagrupando formas Para agrupar formas. En un grupo puedes editar cada elemento que lo contiene de la siguiente manera.ZOrder Pos2 = oForma2.getActiveSheet.getDrawPage() oGrupoFormas = createUnoService("com. usamos el siguiente código.getCurrentController.getByIndex(0) ) oGrupoFormas. es importante que lo establezcas para que puedas verlo en el navegador (F5) de contenido del archivo.408 Dim Pos1 As Integer Dim Pos2 As Integer 6.getCurrentController.sun.add( oPaginaDibujo.drawing. Sub Dim Dim Dim AutoFormas29() oPaginaDibujo As Object oGrupoFormas As Object oForma As Object oPaginaDibujo = ThisComponent.getDrawPage() oForma1 = oPaginaDibujo.getByIndex(1) Pos1 = oForma1.10.ZOrder oForma1.add( oPaginaDibujo.ZOrder = Pos1 End Sub Puedes cambiar el nombre de la forma.Name = "Circulo Azul" End Sub 6.getCount >= 2 Then 'Agregamos las dos primeras oGrupoFormas.ZOrder = Pos2 oForma2.ShapeCollection") 'Necesitamos al menos dos formas para agrupar If oPaginaDibujo.getByIndex(1) ) 'Las agrupamos oPaginaDibujo.star.

Sub Dim Dim Dim Dim AutoFormas32() oPaginaDibujo As Object oForma As Object co1 As Long bHayGrupo As Boolean oPaginaDibujo = ThisComponent.FillColor = RGB( Rnd()*255.getByIndex(co1) If oForma.getCurrentController.getDrawPage() 'Accedemos a la primer forma de la hoja oForma = oPaginaDibujo. el siguiente ejemplo. por eso.supportsService("com.getCurrentController.Rnd()*255 ) Call CambiaTam( oForma.getDrawPage() oForma = oPaginaDibujo.star.sun. Rnd()*5000+1000) Next End If End Sub El ejemplo anterior.drawing.getDrawPage() If oPaginaDibujo. el número de elementos que contenía el grupo. puedes deducirlo a partir de lo que se comenta en el ejemplo 32 y mejorar este ejemplo para que funcione en todos los casos.ungroup( oForma ) 'Reiniciamos la cuenta para empezar de cero co1 = 0 Else co1 = co1 + 1 End If . Para desagrupar un grupo.supportsService("com.getCount . te dará un error en un caso determinado. usamos el siguiente código. tu tarea es averiguar en cual.star.Rnd()*255. este número varia en función de agrupar o desagrupar formas.GroupShape") Then 'Recorremos todas las formas que contiene For co1 = 0 To oForma.getActiveSheet.GroupShape") Then 'Si es un grupo.star. toma en cuenta esto cuando trates de recorrer todas las formas de la página de dibujo. Sub AutoFormas31() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.drawing. te desagrupa “todos” los grupos existentes.getByIndex(0) 'Checamos que sea un grupo If oForma. Rnd()*10000+1000.getActiveSheet.getByindex(co1).sun. se suma a la cuenta de formas de la página de dibujo.getCount > 0 Then Do oForma = oPaginaDibujo.getByindex(co1).1 'Cambiamos el color y el tamaño de cada forma aleatoriamente oForma.Aprendiendo OOo Basic Sub Dim Dim Dim AutoFormas30() oPaginaDibujo As Object oForma As Object co1 As Integer 409 oPaginaDibujo = ThisComponent.sun.getCurrentController. lo desagrupamos oPaginaDibujo.ungroup( oForma ) End If End Sub Toma en cuenta que cuando desagrupas.drawing.supportsService("com.getActiveSheet.getByIndex(0) If oForma.GroupShape") Then oPaginaDibujo.

PropertyValue oPaginaDibujo = ThisComponent.add( oForma ) 'Establecemos el texto de la forma oForma.sun.CustomShape") 'Cambiamos algunas propiedades conocidas Call CambiaTam( oForma. por lo que salimos. este valor.PropertyValue mOpc(1) As New com. Sub FontWork2() Dim oPaginaDibujo As Object Dim oForma As Object . debe estar “exactamente” escrito.getCurrentController. no te dará ningún error pero la forma no se insertará.sun.FillStyle.Rnd()*255.Name = "TextPath" mProp(0).10 Trabajando con elementos gráficos 'Cuando co1 = número de formas.sun. usamos.FillStyle = com.star.SOLID oForma.getActiveSheet.star. si combinas el tamaño.beans. 15000.Name = "Type" mOpc(0). tienes muchas.Value = True 'Establecemos el tipo de FontWork mOpc(0). el tipo (Type) de la forma. el color y estilo de relleno. En el siguiente ejemplo.FillColor = RGB( Rnd()*255.value = mProp() 'Aplicamos estas propiedades personalizadas oForma. determinará el estilo del FontWork insertado. el color y estilo de línea.getCount End If End Sub 6.Value = "fontwork-wave" 'Establecemos las propiedades de la ruta del texto mOpc(1). Sub Dim Dim Dim Dim FontWork1() oPaginaDibujo As Object oForma As Object mProp(0) As New com.org Basic" 'Esta propiedad es importante. si no. significa que recorrió todas 'las formas sin encontrar más grupos. que es una cadena (string). tienes cuarenta estilos para escoger.410 6. 4000 ) oForma.Name = "TextPath" mOpc(1).6 Trabajando con FontWork Para insertar un texto con FontWork. insertamos una forma.setPropertyValue("CustomShapeGeometry".drawing.beans. le decimos que use una ruta para el texto 'que es lo que le da su particularidad a FontWork mProp(0). se establecen como una matriz de propiedades.star.getDrawPage() 'Agregamos una forma personalizada (CustomShape) oForma = ThisComponent.String = "OpenOffice.createInstance("com.2.sun. muchas posibilidades para personalizar las formas.10. Loop While co1 < oPaginaDibujo.Rnd()*255 ) oPaginaDibujo. mOpc() ) End Sub La mayoría de las propiedades con las formas FontWork.star. pero seleccionamos aleatoriamente el tipo del FontWork.drawing.

star."fontworkcurve-up"."fontwork-triangle-down".sun."fontwork-circle-curve"."fontwork-slant-up"."fontwork-circle-curve".getCurrentController."fontwork-arch-leftcurve"."msospt158"."fontwork-arch-leftcurve"."fontwork-circle-pour".Rnd()*255 ) oPaginaDibujo."fontworkarch-up-pour"."mso-spt175") Call CambiaTam( oForma."fontwork-arch-right-curve".sun."fontwork-arch-up-curve".Aprendiendo OOo Basic 411 Dim mProp(0) As New com.getCurrentController."fontwork-faderight".sun."mso-spt164".add( oForma ) oForma.drawing."mso-spt165".beans.createInstance("com."mso-spt157"."mso-spt167".PropertyValue Dim mOpc(1) As New com.beans.sun."mso-spt143".Name = "Type" mOpc(0)."mso-spt162"."mso-spt161"."fontwork-open-circle-pour"."fontwork-arch-rightpour"."fontwork-stop".Rnd()*255.Value = mTipoFW( Rnd()*UBound(mTipoFW) ) mOpc(1).PropertyValue mOpc(2) As New com.FillStyle = com."fontwork-arch-down-pour"."fontwork-slant-up"."mso-spt159".star.sun.Name = "TextPath" mOpc(1).PropertyValue mTipoFW() oPaginaDibujo = ThisComponent.star."fontworkchevron-down".Value = True 'Establecemos el tipo de FontWork aleatoriamente mOpc(0)."fontwork-circle-pour"."fontwork-curve-down"."fontwork-fade-up-and-left".value = mProp() oForma.drawing.FillColor = RGB( Rnd()*255."fontwork-inflate".PropertyValue Dim mTipoFW() oPaginaDibujo = ThisComponent."fontwork-inflate"."fontwork-chevron-up".setPropertyValue("CustomShapeGeometry"."fontwork-fade-left"."fontworkchevron-down"."mso-spt159".sun."mso-spt163".Rnd()*255 ) .FillColor = RGB( Rnd()*255."fontwork-fade-left".Rnd()*255.star."mso-spt142"."mso-spt142"."fontwork-chevron-up"."fontworkslant-down"."fontwork-arch-up-curve".SOLID oForma."mso-spt143".beans."fontwork-open-circle-curve"."mso-spt162"."fontwork-fade-up-and-right"."fontwork-fade-up"."mso-spt167"."fontwork-triangle-up"."fontwork-open-circle-pour".String = "OpenOffice."fontwork-stop"."mso-spt164"."fontwork-arch-down-pour".beans."msospt166".star."mso-spt174"."fontwork-curve-down"."fontwork-fade-down". 15000.FillStyle. 15000."mso-spt165"."mso-spt161"."fontwork-fade-up-and-left".FillStyle = com."fontwork-arch-down-curve".sun.createInstance("com.star.getActiveSheet.getActiveSheet."fontworkarch-up-pour"."fontworkslant-down"."fontwork-fade-down"."msospt158". mOpc() ) End Sub En el siguiente ejemplo."mso-spt175") Call CambiaTam( oForma.Name = "TextPath" mProp(0)."fontwork-arch-right-curve"."fontwork-wave"."fontwork-arch-down-curve".drawing.PropertyValue mPropEx(0) As New com.sun."fontwork-arch-rightpour".star."fontwork-wave"."fontwork-fade-up".FillStyle.getDrawPage() oForma = ThisComponent.CustomShape") mTipoFW = Array("fontwork-plain-text".SOLID oForma."fontwork-open-circle-curve".beans. 4000 ) oForma."fontwork-triangle-up". insertamos una forma FontWork en 3D.CustomShape") mTipoFW = Array("fontwork-plain-text"."mso-spt163"."fontwork-faderight". Sub Dim Dim Dim Dim Dim Dim FontWork3() oPaginaDibujo As Object oForma As Object mProp(0) As New com."fontworkcurve-up"."mso-spt157".drawing. 4000 ) oForma."fontwork-arch-left-pour".star."fontwork-arch-left-pour".sun.org Basic" mProp(0)."mso-spt174"."fontwork-fade-up-and-right"."fontwork-triangle-down".getDrawPage() oForma = ThisComponent.star."msospt166".

FillStyle. te confieso que hice varios intentos hasta que salio esta que me gusto.setPropertyValue("CustomShapeGeometry". 6.412 oPaginaDibujo.7 Propiedades particulares de algunas formas Los rectángulos y los marcos de texto.Name = "Type" mOpc(0).10.Name = "Extrusion" mPropEx(0).star. Sub AutoFormasEspeciales1() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.Rnd()*255 ) .value = mPropEx() oForma. establecer el radio de las esquinas y personalizar el comportamiento del texto que contiene. tienes varias propiedades más para personalizarce completamente.star.getDrawPage() 'Creamos un marco de texto oForma = ThisComponent.Value = mTipoFW( CInt(Rnd()*UBound(mTipoFW)) ) mOpc(1).String = "OpenOffice. por ejemplo.sun.Name = "TextPath" mOpc(1).Value = True 'Establecemos el tipo de FontWork aleatoriamente mOpc(0). son formas muy similares. Tanto las propiedades de la ruta del texto (TextPath).FillStyle = com.setString("Marco con texto" & Chr(13) & "Otra línea") oForma.FillColor = RGB( Rnd()*255.add( oForma ) oForma.org Basic" mProp(0).getCurrentController.createInstance("com.SOLID oForma. describirlas todas sale del propósito de este tema.Rnd()*255.Value = True mPropEx(0).add( oForma ) oForma.2.value = mProp() mOpc(2). como de la configuración en 3D (Extrusion).sun.10 Trabajando con elementos gráficos Y mira que linda quedo.drawing. los dos soportan casi las mismas propiedades. pero esperamos abordarlas a profundidad en Draw. 5000 ) oPaginaDibujo. 10000.drawing. mOpc() ) End Sub 6.TextShape") Call CambiaTam( oForma.Name = "TextPath" mProp(0). claro.Name = "Extrusion" mOpc(2).getActiveSheet.

tu tarea es decirme que distancia tiene la línea. con un cuadro a 45º.LineColor = RGB( Rnd()*255.add( oForma ) oForma.getActiveSheet. y.TextFitToSize = 1 End Sub Reemplaza TextShape por RectangleShape y veras que sigue funcionando. agregamos una línea vertical y otra horizontal. como la posibilidad de establecer el inicio y el final de forma diferente.sun. 5000.LineShape") Call CambiaTam( oForma. establecemos el inicio y el final de la línea. Sub AutoFormasEspeciales4() Dim oPaginaDibujo As Object Dim oForma As Object . 0 ) oPaginaDibujo.LineColor = RGB( Rnd()*255.createInstance("com.LineShape") Call CambiaTam( oForma.getActiveSheet.Aprendiendo OOo Basic 413 'Establecemos el radio de las esquinas oForma. como valor Y establecemos 0.add( oForma ) oForma. Las líneas tienes propiedades únicas. Sub AutoFormasEspeciales2() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.Rnd()*255. lo que te permite acotar otros elementos.LineWidth = 200 End Sub En el siguiente ejemplo.sun.createInstance("com.star. tan solo pasándole el valor X para cambiar el tamaño. 10000.LineWidth = 200 'Ahora una vertical oForma = ThisComponent.getCurrentController.star.star.drawing.drawing.createInstance("com. 5000 ) oPaginaDibujo. En el siguiente ejemplo.CornerRadius = 1000 'Establecemos que el texto se adapte al tamaño de la forma oForma. El siguiente ejemplo agrega una línea ¿de?.Rnd()*255 ) oForma.drawing.sun.add( oForma ) oForma.getDrawPage() 'Creamos una línea oForma = ThisComponent.LineColor = RGB( Rnd()*255. lo contrario para la línea vertical.getDrawPage() 'Creamos una línea horizontal oForma = ThisComponent.Rnd()*255 ) oForma. 0.Rnd()*255.Rnd()*255. 5000 ) oPaginaDibujo.Rnd()*255 ) oForma. Sub AutoFormasEspeciales3() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent.LineShape") Call CambiaTam( oForma.getCurrentController.LineWidth = 200 End Sub Observa como hemos logrado dibujar una línea horizontal.

LineWidth = 300 'Establecemos el ancho de inicio y final de línea oForma.star.CustomShape") Call CambiaTam( oForma.Rnd()*255. veamos como insertar otros tipos de formas.LineWidth = 300 'Establecemos el ancho de inicio y final de línea oForma.drawing.getCurrentController.LineStartWidth = 1000 oForma.Rnd()*255.FillStyle.LineColor = RGB( Rnd()*255.createInstance("com. 0 ) oPaginaDibujo.drawing.star.PropertyValue oPaginaDibujo = ThisComponent.SOLID .Rnd()*255 ) oForma.10 Trabajando con elementos gráficos oPaginaDibujo = ThisComponent.getActiveSheet.star. solo algunos. 0 ) oPaginaDibujo.LineShape") Call CambiaTam( oForma.createInstance("com.SOLID oForma.setPropertyValue("CustomShapeGeometry".getCurrentController.Rnd()*255.drawing.LineColor = RGB( Rnd()*255. 5000 ) oPaginaDibujo.star.sun.Rnd()*255.add( oForma ) oForma.LineWidth = 300 oForma.star.LineEndName = "Square 45" End Sub Ahora.add( oForma ) oForma.createInstance("com.LineWidth = 300 oForma.FillStyle = com.Rnd()*255 ) 'Agregamos un hexágono mOpc(0).getDrawPage() oForma = ThisComponent.LineEndName = "Arrow" End Sub Para terminar este tema.LineStartName = "Square 45" oForma.getActiveSheet.star.getCurrentController. 5000 ) oPaginaDibujo.add( oForma ) oForma. 10000.Value = "hexagon" oForma.LineEndWidth = 1000 'Establecemos el tipo de inicio y fin de línea oForma.FillStyle = com.sun.getActiveSheet. 5000.drawing.getDrawPage() oForma = ThisComponent.add( oForma ) oForma.Rnd()*255 ) oForma.sun.sun.sun.LineStartWidth = 1000 oForma.414 6. mOpc() ) oForma = ThisComponent.Rnd()*255.CustomShape") Call CambiaTam( oForma.Rnd()*255 ) oForma.beans.drawing.star.sun.getDrawPage() oForma = ThisComponent.LineColor = RGB( Rnd()*255.Name = "Type" mOpc(0).LineStartName = "Arrow" oForma.FillColor = RGB( Rnd()*255.FillStyle.LineShape") Call CambiaTam( oForma.createInstance("com.sun.LineEndWidth = 1000 'Establecemos el tipo de inicio y fin de línea oForma. 5000.Rnd()*255 ) oForma. Sub AutoFormasEspeciales5() Dim oPaginaDibujo As Object Dim oForma As Object oPaginaDibujo = ThisComponent. establecemos flechas como final de línea.LineColor = RGB( Rnd()*255.drawing. Sub Dim Dim Dim AutoFormasEspeciales6() oPaginaDibujo As Object oForma As Object mOpc(0) As New com. 10000.

"mso-spt104". mOpc() ) End Sub Como ya lo notaste. "flowchart-sort". "fontwork-curve-up". "mso-spt143".Rnd()*255. "mso-spt27". "mso-spt101".Rnd()*255. "isosceles-triangle". "mso-spt182". "mso-spt165". "mso-spt64". "mso-spt46". "flowchartalternate-process". "flowchartconnector". "flowchart-terminator". "down-arrow-callout". "quad-arrow". "flowchart-or". "mso-spt199". "left-arrow-callout". "ellipse". "down-arrow". 5000 ) oPaginaDibujo. "mso-spt174". "fontwork-triangle-up". "flowchart-manual-input".PropertyValue mTipoFormas mTipoFormas = Array("rectangle".Name = "Type" mOpc(0).Value = "heart" oForma. "mso-spt103". "pentagon-right". "bracket-pair". "fontwork-fade-left".beans. "right-arrow-callout". "mso-spt52". "mso-spt18". "mso-spt17". "quad-bevel". "mso-spt34". "notched-right-arrow". "flowchart-document". "mso-spt45". "fontwork-stop". "mso-spt42". "flowchart-internal-storage". "fontwork-open-circle-pour". "ring". "flowchart-directaccess-storage". "mso-spt25". "mso-spt175". Sub Dim Dim Dim Dim AutoFormasEspeciales7() oPaginaDibujo As Object oForma As Object mOpc(0) As New com. "mso-spt75". "line-callout-1". "msospt89".sun. "flowchart-collate". "mso-spt31". mOpc() ) oForma = ThisComponent.add( oForma ) oForma. "mso-spt107". 5000. "mso-spt190". "msospt166". "star24". "mso-spt201".Aprendiendo OOo Basic 415 oForma. "mso-spt163". "vertical-scroll". "diamond". "striped-right-arrow". "mso-spt71". "mso-spt191".sun.createInstance("com. "flowchart-extract". "star4".star.FillStyle = com. "fontwork-chevron-down". "mso-spt49". "fontwork-triangle-down". "fontwork-arch-down-curve". "mso-spt200". "mso-spt39". "msospt44". "flowchart-merge". "fontwork-fade-right". "mso-spt197". "mso-spt90". "mso-spt179". "mso-spt26". "mso-spt194". "quadarrow-callout". "right-bracket". "mso-spt40". "mso-spt33". "mso-spt195". "can". "mso-spt193". "chevron".drawing. "round-callout". "left-right-arrow-callout". "mso-spt129". la cantidad de formas es grande. "cube". "mso-spt60". "pentagon". "brace-pair". "linecallout-3". "up-arrow". "msospt29". "flowchart-card". "flowchart-delay". "fontwork-arch-down-pour". "horizontal-scroll". "mso-spt35". "mso-spt30". "fontwork-fade-up". "hexagon". "mso-spt105". "mso-spt41". "left-arrow". "fontworkfade-down". "mso-spt38". "msospt59".star.sun. "mso-spt91".Rnd()*255 ) oForma. "flowchart-decision". "mso-spt198". "mso-spt157".Value = "flowchart-sort" oForma. compruébalo tu mismo con el siguiente código donde agregamos una forma aleatoria de las diferentes doscientas un posibles. "mso-spt14". "mso-spt43". "left-bracket". "line-callout-2".LineWidth = 300 oForma. "flowchart-off-page-connector". "fontwork-curve-down". "mso-spt28". "mso-spt19". "star5".setPropertyValue("CustomShapeGeometry". "mso-spt188". "flowchart-magnetic-disk". "fontwork-fadeup-and-right". "flowchart-stored-data".setPropertyValue("CustomShapeGeometry". "circular-arrow". "fontwork-plain-text". "msospt189". "mso-spt20". "blockarc". "flowchart-display". "mso-spt142".FillStyle. "right-triangle". "mso-spt161". "rightarrow". "flowchart-data". "fontwork-chevron-up". "mso-spt24". "up-down-arrow-callout". "rectangular-callout". "cross". "fontwork-open-circle-curve". "lightning". "flowchart-multidocument".SOLID oForma. "mso-spt164".Rnd()*255. "fontwork-arch-up-pour". "paper". "sun".LineColor = RGB( Rnd()*255. "fontwork-inflate". "left-right-arrow". "bang". "mso-spt21". "trapezoid". "mso-spt53". "flowchart-summing-junction".Rnd()*255 ) 'Agregamos un corazón mOpc(0). "fontwork-arch-up-curve". "parallelogram". "mso-spt100". "left-brace". "right-brace".star. "fontwork-slant-up". hay que indicarle el nombre de la forma especial que queremos agregar.FillColor = RGB( Rnd()*255. "round-rectangle". "flowchart-preparation". "octagon". "cloud-callout". "mso-spt50". "fontwork-slant-down". "flowchart-predefined-process". "flowchart-sequential-access". "mso-spt202" ) . "msospt196". "mso-spt37". "msospt51". "flowchart-process".FillColor = RGB( Rnd()*255. "star8". "mso-spt192".drawing. "up-arrow-callout". "moon". "mso-spt180". "heart". "fontwork-circlecurve". "flowchart-punched-tape". "mso-spt158".CustomShape") Call CambiaTam( oForma.Rnd()*255 ) 'Agregamos el simbolo de ordenar en un diagrama de flujo mOpc(0). "mso-spt32". "mso-spt159". "mso-spt102". "forbidden". "up-down-arrow". "mso-spt108". "fontwork-fade-up-and-left".Name = "Type" mOpc(0). "round-rectangular-callout". "mso-spt36". "mso-spt178". "fontwork-wave". "flowchart-manual-operation". "fontworkcircle-pour". "mso-spt162". "mso-spt167". "smiley". "mso-spt54".

sun.createInstance("com.416 6. mOpc() ) End Sub 6.Rnd()*255 ) 'Agregamos una forma aleatoria mOpc(0). que tengas muy claro.sun.FillStyle. es una de las características más ricas de una hoja de calculo.Rnd()*255.star.11 Funciones personalizadas La posibilidad de implementar nuestras propias funciones. por ejemplo. que estas pueden o no necesitar argumentos.Rnd()*255.getActiveSheet. que las funciones siempre devuelven un valor. suponiendo que el radio este en la celda A2 las formulas serían. Diámetro Perímetro Área = A2 * 2 = PI() * A2 * 2 = PI() * POTENCIA(A2.CustomShape") Call CambiaTam( oForma. 5000 ) oPaginaDibujo. el perímetro y el área de un circulo Donde: r D P A = radio = Diámetro = Perímetro = Área radio D= 2∗ r P= ∗ D A= ∗ r2 En Calc.10 Trabajando con elementos gráficos oPaginaDibujo = ThisComponent.Rnd()*255 ) oForma.SOLID oForma.LineWidth = 300 oForma. y cuando este sea un error.Name = "Type" mOpc(0).star. aun. asumo que no tienes problemas con la implementación de formulas y funciones en Calc.getDrawPage() oForma = ThisComponent. que los argumentos son de un tipo y el valor devuelto puede ser de otro.LineColor = RGB( Rnd()*255.setPropertyValue("CustomShapeGeometry".drawing.getCurrentController.2) En OOo Basic. 5000.FillStyle = com. para todo este capitulo. supongamos las triviales formulas para obtener el diámetro. estas funciones podrían quedar así: Option Explicit .Value = mTipoFormas( CInt(Rnd()*UBound(mTipoFormas)) ) oForma.drawing.FillColor = RGB( Rnd()*255.add( oForma ) oForma. es muy útil.

ahora ahora. solo el radio. Observa la siguiente imagen. ahora. la diferencia. los hemos venido usando a lo largo de los temas vistos.1416 PerimetroCirculo = Radio * 2 * PI End Function 'Función para obtener el área de un circulo Function AreaCirculo( Radio As Single ) As Double Const PI As Single = 3. QueDato As Byte ) As Double Const PI As Single = 3.Aprendiendo OOo Basic 417 'Función para obtener el diámetro de un circulo Function DiametroCirculo( Radio As Single ) As Double DiametroCirculo = Radio * 2 End Function 'Función para obtener el perímetro de un circulo Function PerimetroCirculo( Radio As Single ) As Double Const PI As Single = 3. solo “llamábamos” a las funciones desde otras macros. podemos crear nuestra función para que nos devuelva el valor deseado de los tres. se usan exactamente igual que cualquier otra función de Calc. 'Función para devolver un dato de un círculo 'QueDato puede tener los valores ' 1 = Diámetro ' 2 = Perímetro ' 3 = Área Function Circulo( Radio As Single.141592 Dim dTmp As Double . por los dos métodos. donde estamos calculando estos valores. Pero las funciones personalizadas son mucho más versátiles. es que. las estamos usando desde la hoja de calculo. y con nuestras funciones personalizadas.1416 AreaCirculo = PI * Radio ^ 2 End Function Estas funciones. no te son desconocidos. escribiendo su nombre correctamente y pasándole los argumentos correctos. La forma como establecemos los argumentos y el valor devuelto de la función. simplemente pasándole un segundo argumento para indicárselo. con formulas y funciones incorporadas de Calc. usamos el mismo argumento. es decir. nota como en las tres formulas.

trata de hacerla tu mismo. b y c = son los lados del triángulo S = Semiperímetro. lo que realmente toma la función es el valor de estas celdas. cuya formula es. Las funciones personalizadas. vamos a obtener el área de un triángulo. Donde: b = Base h = Altura A = Área altura base Nuestra función para calcular el área. es decir. H As Single ) As Double AreaTriangulo = (B * H) / 2 End Function A= b∗ h 2 El asunto cambia bastante cuando lo que conocemos son la longitud de los lados del triángulo. las relacionadas con el correcto paso de argumentos y el tipo de valor devuelto. 'Función para calcular el área de un triángulo Function AreaTriangulo( B As Single. usamos la famosa formula de Herón. Te pongo la formula y antes de que veas la respuesta. Cuando le pasas un argumento a una función desde una hoja de calculo (generalmente una referencia a una o varias celdas). Nuestro siguiente ejemplo también es muy simple. quedaría así.418 Select Case QueDato Case 1 dTmp = Radio * 2 Case 2 dTmp = Radio * 2 * PI Case 3 dTmp = PI * Radio ^ 2 End Select Circulo = dTmp End Function 6. principalmente. . tienen las mismas consideraciones presentes en las funciones incorporadas de Calc. el perímetro entre dos A = Área Como función.11 Funciones personalizadas Y el resultado. Donde: A= S− a b c S∗  ∗ S− ∗ S− a. para estos casos.

significa que la renovación ya paso. usamos una fecha como argumento. c As Single ) As Double Dim S As Double S = ( a + b + c ) / 2 AreaTrianguloHeron = Sqr( S*(S-a)*(S-b)*(S-c) ) End Function Por supuesto.MES(A2). con Year obtenemos el año FechaActual = DateSerial( Year(Now()). la fecha de contratación del servicio.AÑO(HOY()). cuidado. devuelve la fecha actual. la función Now. por lo que se tiene 'que aumentar un año a la fecha actual para obtener la correcta de renovación FechaActual = DateSerial( Year(Now())+1.Aprendiendo OOo Basic 419 'Función para calcular el área de un triángulo 'con la formula de Herón Function AreaTrianguloHeron( a As Single. Month(FechaInicial). observa como obtenemos 'el año actual. no importa el número de años que lleva contratado. y los problemas. en el siguiente ejemplo. entre más sencillos. Day(FechaInicial) ) End If 'Restamos la fecha futura con el día de hoy. pero es un buen ejemplo de lo que hay que hacer cuando queremos hacer una función personalizada. no es una pregunta ligera. 'Función para saber cuantos días faltan para renovar Function DiasParaRenovar( FechaInicial As Date ) As Integer Dim FechaActual As Date Dim iDiferencia As Integer 'Lo primero que necesitamos es tener la misma fecha inicial 'mismo día y mes. se contrato un servicio anual.DÍA(A2))>HOY(). es resolver problemas. una primera aproximación sería. es mayor o menor al día de hoy If FechaActual < Now() Then 'Si es menor. b As Single.MES(A2). ¿que es lo que haces para saber cuantos días faltan para la renovación?. Month(FechaInicial). tomate con calma la respuesta de la pregunta. no solo puedes manejar números como argumentos. En la solución de la función comentamos paso a paso la respuesta. nos pide un poco más de esfuerzo para comprenderla. tenemos que tener muy claro que es lo que queremos obtener y que datos de origen tenemos. el planteamiento es el siguiente. Celda A2 = Fecha de contratación Celda B2 = Días que faltan para renovar La formula de la columna B es: =FECHA(SI(FECHA(AÑO(HOY()). Day(FechaInicial) ) 'El siguiente paso. pero con el año actual. queremos mostrar en otra celda. es saber si esta fecha actual. solo queremos saber cuantos días faltan para la próxima renovación. para saber cuantos días faltan 'Usamos Fix para eliminar las horas y evitar el redondeo . recuerda que el trabajo de programador. así que.DÍA(A2))-HOY() Esta formula ya es un poco más compleja. en este caso. el número de días que faltan para renovar el servicio. solo tenemos una fecha.AÑO(HOY()) +1). es decir. son más fáciles de resolver.

Fix(Now()) 'Asignamos el resultado DiasParaRenovar = iDiferencia End Function 6. lo que logramos con la siguiente función.420 iDiferencia = FechaActual . 'Función para dar formato a valores sexagesimales Function AnguloFormateado( Gra As Integer. minutos o segundos. te pongo el esqueleto de la función y tu la desarrollas. aquí es bastante notable la comodidad de una función personalizada: =FECHA(SI(FECHA(AÑO(HOY()).DÍA(A2))HOY() =DIASPARARENOVAR(A2) En nuestro siguiente ejemplo.DÍA(A2))>HOY(). grados. QueValor As Byte ) As Integer 'Esta es tu tarea End Function Otro ejemplo donde tenemos como argumento un número y regresamos una cadena. regresar cualquiera de los tres valores. la tarea es mostrar el valor de un ángulo. 'Función para convertir un número en texto Function NumeroTexto( Num As Byte ) As String Dim sTmp As String Select Case Num Case 0 : sTmp Case 1 : sTmp Case 2 : sTmp Case 3 : sTmp Case 4 : sTmp Case 5 : sTmp Case 6 : sTmp Case 7 : sTmp = = = = = = = = "Cero" "Uno" "Dos" "Tres" "Cuatro" "Cinco" "Seis" "Siete" .MES(A2). Tu tarea es hacer la operación inversa.AÑO(HOY()).AÑO(HOY())+1). puede tomar los valores ' 1 = Devuelve los grados ' 2 = Devuelve los minutos ' 3 = Devuelve los segundos Function DatoAngulo( Angulo As String. configurado correctamente. Seg As Byte ) As String Dim sTmp As String sTmp = Str(Gra) & "º " & Str(Min) & "' " & Str(Seg) & "''" AnguloFormateado = sTmp End Function Observa como estamos regresando una cadena (String).MES(A2). por ejemplo: 125º 45' 35''. según el argumento pasado. 'Función para devolver un valor de una ángulo 'El argumento QueValor.11 Funciones personalizadas Comparando. es el siguiente. a partir de la cadena. tenemos como argumentos números y regresamos un texto. Min As Byte.

te invito a que intentes desarrollarla. donde se cuenta con sus coordenadas. sumamente útil y muy usada en áreas administrativas.. los tomará como una matriz de dos dimensiones. dada la extensión de la misma..1 ) 'Iteramos en la segunda dimensión de la matriz For co2 = LBound( Rango. pero si en los archivos de ejemplo que acompañan a este libro. nuestra versión de la función SUMA.. para hacer la famosa función que convierte números a letras. forzosamente tiene que ser tipo variante (Variant). . Veamos un ejemplo practico donde pasamos como argumento un rango de celdas. espero sea bastante claro en la siguiente imagen.Aprendiendo OOo Basic Case 8 : sTmp = "Ocho" Case 9 : sTmp = "Nueve" End Select NumeroTexto = sTmp End Function 421 ¿Y para que crees que sirve eso?.1 ) To UBound( Rango. co2 As Long 'Iteramos en la primer dimensión de la matriz For co1 = LBound( Rango. se puede calcular el área de un terreno o de cualquier poligonal cerrada cualquiera. pero también puedes pasarle rangos de celdas. En topografía. al ser una matriz. cuyo algoritmo. han sido celdas individuales. por varios métodos. esta.2 ) 'Vamos sumando los valores dTmp = dTmp + Rango( co1. donde. no la incluimos aquí. todos los argumentos que le hemos pasado a nuestras funciones. Hasta ahora.2 ) To UBound( Rango. es la siguiente. exactamente. es que los valores de este rango. 'Función para sumar los valores de un rango Function SumarRango( Rango ) As Double Dim dTmp As Double Dim co1 As Long. uno de ellos se llama por “Productos Cruzados”. co2 ) Next co2 Next co1 'Asignamos el resultado SumarRango = dTmp End Function Observa como no establecemos el tipo del argumento Rango. lo único que tienes que tener en cuenta. esto es por que.

IsValueHighlightingEnabled = True . cuyo código es el siguiente. por ejemplo lo que queremos ver y lo que no. 'Función para obtener el área de un polígono irregular 'por medio de coordenadas y el método de productos cruzados Function AreaPoligono( Rango ) As Double Dim Suma1 As Double Dim Suma2 As Double Dim co1 As Long 'Calculamos las suma de los productos cruzados For co1 = LBound( Rango. 6. tenemos el mismo resultado. es la única excepción que me he encontrado con el uso de matrices. observa que para acceder a la segunda dimensión de la matriz. tenemos el calculo del área.12 Configuración global de Calc En este capitulo.1 ) .getCurrentController() 'Mostramos las formulas en vez de su resultado 'el valor "normal" es falso (False) oCC.1) * Rango(co1.showZeroValues = False 'Podemos automáticamente diferenciar los valores de 'formulas con esta propiedad.1) * Rango(co1+1. los valores los pone 'en azul y las formulas en verde. veremos algunas opciones que afectan a la configuración global de Calc.422 6.showFormulas = True 'Ocultamos los valores cero 'el valor normal es verdadero (True) oCC. pero usando la función mostrada en la celda D218. pero usando todo el desarrollo del método.1 Suma1 = Suma1 + Rango(co1.11 Funciones personalizadas En la celda D214. recuerdalo. en la celda D216 (en rojo). no se cual sea la razón de que al acceder a los valores de un rango de celdas por medio de una función. estamos empezando en 1.2) Suma2 = Suma2 + Rango(co1+1. Sub ConfigurarCalc1() Dim oDoc As Object Dim oCC As Object oDoc = ThisComponent oCC = oDoc. el limite inferior sea siempre 1 (por ahora). pero ten cuidado 'no podrás establecer el color de fuente mientras 'esta propiedad este en verdadera (True) oCC.2) Next co1 'Asignamos el resultado AreaPoligono = Abs(Suma1 .Suma2) / 2 End Function Muy importante.1 ) To UBound( Rango.

por ejemplo. establecelo en verdadero para volver 'a ver este pequeño cuadro oCC. cambiamos el color de las líneas de división de las celdas y establecemos el zoom con un porcentaje.showGrid 'Las líneas de ayuda cuando se mueve un objeto gráfico oCC. En el siguiente ejemplo.showCharts = Not oCC. la nota 'sigue existiendo. si ocultas las etiquetas de las hojas. el usuario puede cambiarse aun con la combinación de teclas CTRL+RePag (AvPag).HasColumnRowHeaders 'Las líneas de división de las celdas oCC.HasHorizontalScrollBar 'Las etiqueas de las hojas oCC. así como los gráficos.showHelpLines = Not oCC. alternamos el valor de las propiedades.showCharts 'Las formas oCC.ShowAnchor 'Los saltos de página oCC.HasHorizontalScrollBar = Not oCC.ShowPageBreaks 'Los objetos e imagenes oCC.IsOutlineSymbolsSet End Sub Ten cuidado con ocultar algunos elementos.showObjects 'Los gráficos oCC. . los saltos de página se ocultan.showDrawing = Not oCC.HasVerticalScrollBar oCC. solo oculta el pequeño cuadro rojo 'que nos indica que una celda tiene una nota.HasColumnRowHeaders = Not oCC. objetos.showGrid = Not oCC. pero siguen existiendo.HasSheetTabs 'Los encabezados de filas y columnas oCC.HasSheetTabs = Not oCC. si están visibles se ocultan y viceversa: Sub ConfigurarCalc2() Dim oDoc As Object Dim oCC As Object oDoc = ThisComponent oCC = oDoc. en todos los ejemplos siguientes.getCurrentController() 'Ocultamos o mostramos las barras de desplazamiento 'tanto vertical como horizontal oCC.IsOutlineSymbolsSet = Not oCC.ShowHelpLines 'El icono de anclaje cuando se selecciona un objeto gráfico oCC.showObjects = Not oCC.HasVerticalScrollBar = Not oCC. formas y símbolos de esquema.showNotes = False End Sub También podemos mostrar u ocultar otros elementos de la hoja de calculo.showDrawing 'Los símbolos de esquema y agrupamiento oCC.showAnchor = Not oCC.showPageBreaks = Not oCC.Aprendiendo OOo Basic 423 'Esta propiedad. es decir.

getVisibleRange() 'Mostramos su dirección MsgBox DireccionRango( oRangoVisible ) 'Cambiamos el zoom oCC.ZoomType = 3 'Si lo establece en 3 (valor).gridColor = RGB(Rnd()*255.ZoomType = 3 .setFirstVisibleRow( 50 ) oCC.getFirstVisibleRow & Chr(13) & "Columna: " & oCC.getFirstVisibleColumn 'Lo interesante.getCurrentController() 'Obtenemos el rango visible oRangoVisible = oCC. puedes establecer 'el porcentaje de zoom entre 20% y 400% oCC. Sub Dim Dim Dim ConfigurarCalc5() oDoc As Object oCC As Object oRangoVisible As Object oDoc = ThisComponent oCC = oDoc. solo tiene efecto sobre una sola hoja. este rango se ve afectado por el nivel de zoom establecido en la hoja.getCurrentController() 'La primer fila y columna visible actuales MsgBox "Fila: " & oCC. como mostramos en el ejemplo.setFirstVisibleColumn( 10 ) End Sub Podemos obtener el rango visible.Rnd()*255) 'Establecer el tipo de Zoom ' 1 = Ancho de página ' 2 = Ajustar al ancho y alto ' 3 = Valor oCC.ZoomValue = 130 End Sub 6. Podemos consultar y establecer la primer fila y columna visible. Sub ConfigurarCalc4() Dim oDoc As Object Dim oCC As Object oDoc = ThisComponent oCC = oDoc. es que podemos establecerlas para que el usuario 'vea lo que queramos que vea oCC. Las siguientes propiedades. este se ajustará al más cercano. pero me parece que son interesantes de ver.12 Configuración global de Calc Si estableces el porcentaje fuera de sus limites (20% a 400%).getCurrentController() 'Puedes cambiar el color de las líneas de división de celdas 'el valor predeterminado es gris claro = 12632256 oCC.Rnd()*255.424 Sub ConfigurarCalc3() Dim oDoc As Object Dim oCC As Object oDoc = ThisComponent oCC = oDoc.

getName() & _ DirRango.getColumns.ZoomValue + 25 'Volvemos a consultar el rango visible oRangoVisible = oCC.getActiveSheet sTmp = oHA.getSplitColumn & " y en la fila: " & oCC.getSplitRow MsgBox sInfo Else MsgBox "La ventana no esta dividida" End If End Sub Por supuesto podemos establecer la división donde quieras.getVisibleRange() MsgBox DireccionRango( oRangoVisible ) End Sub 425 Function DireccionRango( DirRango As Object) As String Dim oHA As Object Dim sTmp As String oHA = ThisComponent.EndColumn).StartRow + 1 & ":" & _ oHA.ZoomValue = oCC.getByIndex(DirRango.getCurrentController.getColumns.300 ) End If End Sub .splitAtPosition( 500.StartColumn). Sub Dim Dim Dim ConfigurarCalc7() oDoc As Object oCC As Object sInfo As String oDoc = ThisComponent oCC = oDoc.getIsWindowSplit Then 'Las unidades son pixeles oCC.getByIndex(DirRango.getCurrentController() 'Si no esta dividida la dividimos If Not oCC.getSplitHorizontal & " pixeles de la izquierda y" & Chr(13) & _ oCC.Aprendiendo OOo Basic oCC.getName() & _ DirRango. Sub Dim Dim Dim ConfigurarCalc6() oDoc As Object oCC As Object sInfo As String oDoc = ThisComponent oCC = oDoc.getSplitVertical & " pixeles de la parte superior" & Chr(13) & _ "En la columna: " & oCC.EndRow + 1 DireccionRango = sTmp End Function Podemos saber si la ventana esta dividida.getIsWindowSplit Then 'Mostramos la información sInfo = "La ventana esta dividida a: " & Chr(13) & _ oCC.getCurrentController() 'Consultamos si la ventana esta dividida If oCC.

splitAtPosition( 0. aquí se usa la columna y fila deseada.12 Configuración global de Calc Si quieres establecer solo un división.0 ) Para la horizontal: oCC. establece el otro en cero.freezeAtPosition( 5. por ejemplo.300 ) Para eliminar la división: oCC.426 6. si quiere establecer solo un sentido. no eliminaras la división. si que la ventana se fijara en la posición actual del cursor de celda.splitAtPosition( 0.getCurrentController() 'Establecemos la división en la columna 5 y fila 10 oCC. Sub Dim Dim Dim ConfigurarCalc8() oDoc As Object oCC As Object sInfo As String oDoc = ThisComponent oCC = oDoc. establece la que no quieras en cero. si estableces los dos argumentos en ceros. oCC.hasFrozenPanes Then MsgBox "La ventana esta fija" Else MsgBox "La ventana no esta fija" End If End Sub Y establecer la posición de esta. Sub Dim Dim Dim ConfigurarCalc9() oDoc As Object oCC As Object sInfo As String oDoc = ThisComponent oCC = oDoc.0 ) También podemos saber si la ventan esta fija.splitAtPosition( 500. 10) End Sub Al igual que con la ventana dividida. 0) Si quieres quitarla.getCurrentController() 'Consultamos si la ventana esta fija If oCC. si solo quieres la división vertical usas: oCC. usa el mismo método visto anteriormente: .freezeAtPosition( 0.

1 'Obtenemos acceso a cada panel oPanel = oCC.getName() & _ Rango. y puedes tener acceso a cada rango de cada panel.getColumns(). estás pueden tener 2 o cuatro partes. "ScCellCursorObj" sTmp = Rango.getIsWindowSplit Or oCC.hasFrozenPanes Then For co1 = 0 To oCC.getRangeAddress.Aprendiendo OOo Basic oCC.getImplementationName() Case "ScCellObj" sTmp = Rango.getCurrentController() 'La ventans debe estar fija o dividida If oCC.getColumns().getByIndex(0).splitAtPosition( 0.getName() & ".").getColumns().getColumns().getSpreadsheet.getName() & _ Rango. como se muestra en el siguiente ejemplo: Sub Dim Dim Dim Dim Dim ConfigurarCalc10() oDoc As Object oCC As Object oPanel As Object co1 As Byte sInfo As String oDoc = ThisComponent oCC = oDoc.getReferredCells ) Next co1 End If End Sub Function DireccionRango2(Rango As Object) As String Dim sTmp As String Select Case Rango.". y con esto damos por terminado un nuevo tema.getByIndex( co1 ) 'Mostramos su dirección MsgBox "La dirección del Panel " & co1+1 & " es: " & DireccionRango2( oPanel.getCount()1).Row + 1 Case "ScCellRangeObj".getByIndex(Rango.getCellAddress. aquí la repetimos por si no la tienes a mano.getRangeAddress.StartRow + 1 & ":" & _ Rango.getName() & ".getRangeAddressesAsString().0 ) 427 Si divides la ventana por cualquiera de los dos métodos vistos.EndRow + 1 Case "ScCellRangesObj" sTmp = Join( Split(Rango.getName() & _ Rango." & _ Rango.getCount . .getSpreadsheet.getByIndex(0)." & _ Rango. cada una de estas partes se llama panel.Chr(13) ) End Select DireccionRango2 = sTmp End Function La función anterior ya la hemos usado anteriormente.

con el uso de los formularios. veremos como manipular las propiedades más importantes de estos. con código OOo Basic. en tiempo de ejecución. El formulario y la mayoría de los controles.getCount() . como usuario.1 MsgBox oFormularios. a los que tienen poca experiencia con la hoja de calculo ya que nos permite convertir una hoja de Calc. también pueden servir para ayudar al usuario con la manipulación de datos.1 Formularios (Forms) Los formularios y sus controles.getCurrentController. como en el siguiente ejemplo. a través de esta hay que acceder a ellos. que sabes agregar los controles a la interfaz del usuario y manipular sus propiedades en tiempo de diseño. es decir. puedes acceder a un formulario por su índice o por su nombre. 7. se colocan sobre la capa de dibujo. debes de validarlo como en: Sub Dim Dim Dim Dim Dim Dim Formularios2() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object iNum As Integer sNombre As String . aunque se pueden usar sin ellas. múltiples tareas. aun más.getByIndex(co1). tiene propiedades especiales para enlazarse y manipular bases de datos.428 7 Trabajando con formularios 7 Trabajando con formularios Los formularios. nos permiten interactuar con el usuario por medio de controles. que son objetos de dibujo con características especiales y la capacidad de poder asociarles la ejecución de macros. es decir. en una nueva y completamente personalizada interfaz de usuario. sobre todo. Asumo que no tienes problemas. donde mostramos los nombres de los formularios existentes en la hoja activa.getName() Next co1 End Sub Como en el ejemplo anterior. aquí.getDrawPage() 'Todos los formularios oFormularios = oPaginaDibujo.getActiveSheet() 'La página de dibujo oPaginaDibujo = oHojaActiva.getForms() 'Iteramos en cada uno mostrando su nombre For co1 = 0 To oFormularios. en los dos casos el formulario “debe” de existir. El uso de formularios permite automatizar. por lo que. Sub Dim Dim Dim Dim Dim Formularios1() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object co1 As Integer 'El archivo desde donde se llama esta macro oDoc = ThisComponent 'La hoja activa oHojaActiva = oDoc.

getForms() oFormulario = oFormularios.getCurrentController.Aprendiendo OOo Basic 429 'El archivo desde donde se llama esta macro oDoc = ThisComponent 'La hoja activa oHojaActiva = oDoc.getCurrentController.getByIndex(0) MsgBox oFormulario.getDrawPage() oFormularios = oPaginaDibujo.DataSourceName = "Directorio" .getName() End If End Sub Puedes cambiar el nombre del formulario: Sub Dim Dim Dim Dim Dim Formularios3() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oDoc = ThisComponent oHojaActiva = oDoc.setName("Nuevo Formulario") End Sub Puedes cambiar el origen de datos del formulario: Sub Dim Dim Dim Dim Dim Formularios4() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oDoc = ThisComponent oHojaActiva = oDoc.getActiveSheet() oPaginaDibujo = oHojaActiva.getCount() Then MsgBox oFormularios.getDrawPage() oFormularios = oPaginaDibujo.hasByName(sNombre) Then MsgBox oFormularios.getForms() iNum = 1 'Nos aseguramos de que existe el número de formulario If iNum < oFormularios.getName() End If sNombre = "Directorio" 'Nos aseguramos de que existe el nombre del formulario If oFormularios.getByIndex(iNum).getByIndex(0) MsgBox oFormulario.getByName(sNombre).getActiveSheet() 'La página de dibujo oPaginaDibujo = oHojaActiva.getActiveSheet() oPaginaDibujo = oHojaActiva.getCurrentController.DataSourceName 'Cambiamos la fuente de datos oFormulario.getForms() oFormulario = oFormularios.getDrawPage() 'Todos los formularios oFormularios = oPaginaDibujo.getName() 'Cambiamos el nombre del primer formulario oFormulario.

1 Formularios (Forms) Aquí debes de tener algunas consideraciones importantes.getCurrentController. por lo que no las repetiremos aquí. por lo que perderás cualquier vinculo a los datos.getCurrentController.getByIndex(0) 'Establecemos la base de datos fuente oFormulario.getForms() oFormulario = oFormularios. no solo el formulario puede estar vinculado con esta.getDrawPage() oFormularios = oPaginaDibujo. Además de la fuente de datos.getActiveSheet() oPaginaDibujo = oHojaActiva.DataSourceName = "Directorio" 'Como origen una consulta oFormulario. también pueden estar vinculados a ella.getByIndex(0) 'Establecemos la base de datos fuente oFormulario. pero claro. puedes establecer el tipo de contenido.Command = "tblCiudades" End Sub En el siguiente ejemplo establecemos una consulta como origen de datos Sub Dim Dim Dim Dim Dim Formularios6() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oDoc = ThisComponent oHojaActiva = oDoc. no obtendrás nada de datos.getActiveSheet() oPaginaDibujo = oHojaActiva.CommandType = 1 'El nombre de la consulta oFormulario. es enlazar una vez al inicio de la configuración de un formulario. Sub Dim Dim Dim Dim Dim Formularios5() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oDoc = ThisComponent oHojaActiva = oDoc. podemos establecer un comando SQL como origen de datos: . o para corregir desajustes realizados por los usuarios. y el contenido.DataSourceName = "Directorio" 'Como origen una tabla oFormulario. lo más común.430 End Sub 7. los controles del formulario.CommandType = 0 'El nombre de la tabla oFormulario. los nombres de las fuentes de datos. ten cuidado al cambiar la fuente de datos.getDrawPage() oFormularios = oPaginaDibujo. no te dará ningún error.Command = "qryCiudades" End Sub Por ultimo.getForms() oFormulario = oFormularios. son nombres de bases de datos registradas en OOo y ya vistas en el capitulo de Bases de datos. si la fuente de datos no existe.

insertByName("MiDirectorio".getForms() 'Creamos un nuevo formulario oNuevoFormulario = oDoc. Puedes agregar nuevos formularios a la colección.sun.component.getCurrentController.getDrawPage() oFormularios = oPaginaDibujo. pero no es lo común. .getByIndex(0) 'Establecemos la base de datos fuente oFormulario.CommandType = 2 'La instrucción SQL oFormulario. Sub Dim Dim Dim Dim Dim Formularios8() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oNuevoFormulario As Object oDoc = ThisComponent oHojaActiva = oDoc.Aprendiendo OOo Basic 431 Sub Dim Dim Dim Dim Dim Formularios7() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oDoc = ThisComponent oHojaActiva = oDoc.form.getCurrentController.Form" ) 'Lo agregamos a los formularios oFormularios.getActiveSheet() oPaginaDibujo = oHojaActiva. es mejor que verifiques que el nombre no exista como ya se vio y agregues nombres únicos a la colección de formularios para su fácil identificación.getActiveSheet() oPaginaDibujo = oHojaActiva.Command = "SELECT * FROM tblContactos" End Sub Todas las precauciones y particularidades vistas en las bases de datos.getForms() oFormulario = oFormularios.getDrawPage() oFormularios = oPaginaDibujo. por lo que te recomiendo las tengas siempre presentes. son aplicables a los formularios.createInstance( "com.DataSourceName = "Directorio" 'Como origen una instrucción SQL oFormulario. oNuevoFormulario) End Sub Puedes agregar formularios con el mismo nombre y no te dará ningún error.star.

createInstance("com.insertByIndex(0.getActiveSheet() oPaginaDibujo = oHojaActiva.createInstance("com.432 7. generalmente son controles estáticos.getForms() oFormulario = oFormularios.component. generalmente un titulo. pues su función es solo mostrar un texto al usuario sin que este pueda modificarlo. Y As Long ) Dim oPos As New com. 1500 ) Call CambiaPos( oNuevaEtiqueta.sun.form.1 Formularios (Forms) 7.Name = "lblId" 'El texto que verá el usuario oNuevaEtiquetaModelo.add( oNuevaEtiqueta ) End Sub 'Macro para cambiar la posición de un objeto Sub CambiaPos( Obj As Object. Sub Dim Dim Dim Dim Dim Dim Dim Etiquetas1() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oNuevaEtiqueta As Object oNuevaEtiquetaModelo As Object oDoc = ThisComponent oHojaActiva = oDoc.Control = oNuevaEtiquetaModelo 'Lo agregamos al formulario. 1000. 5000.getCurrentController. es el índice que tendrá el nuevo control agregado oFormulario. X As Long.FixedText") 'Establecemos su nombres oNuevaEtiquetaModelo.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oNuevaEtiqueta = oDoc. 1000 ) 'Creamos una nueva etiqueta oNuevaEtiquetaModelo = oDoc. el clic del ratón.sun. el primer argumento.getDrawPage() oFormularios = oPaginaDibujo. agrega una etiqueta al formulario llamado “MiDirectorio”.awt. El siguiente ejemplo. por ejemplo.setPosition( oPos ) End Sub 'Macro para cambiar el tamaño de un objeto .X = X oPos.sun.star.star.drawing. oNuevaEtiquetaModelo) 'Agregamos la forma a la página de dibujo para que sea visible oPaginaDibujo.star. pero no es usual que se haga.Point oPos.Y = Y Obj. Se les puede asociar un evento.Label = "Clave" 'Conectamos la forma con el nuevo control oNuevaEtiqueta. un mensaje o el encabezado de un campo.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oNuevaEtiqueta.2 Etiquetas (Label) Las etiquetas son los controles más simples. en este caso 0.

getActiveSheet() oPaginaDibujo = oHojaActiva.Width = Ancho oTam. usamos el siguiente código.star. etc). Sub Dim Dim Dim Dim Dim Dim Etiquetas2() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object olblClave As Object oDoc = ThisComponent oHojaActiva = oDoc.200) 'La fuente 'El tamaño de fuente 'El color de fondo . Ancho As Long.getByName("lblId") With olblClave . línea.sun. Alto As Long ) Dim oTam As New com. los controles soportan la mayoría de las propiedades vistas anteriormente (color. Al ser una forma (shape). fuente.getDrawPage() oFormularios = oPaginaDibujo.setSize( oTam ) End Sub Las subrutinas para cambiar de posición y tamaño. para acceder a la etiqueta creada en el ejemplo anterior.getByName( "MiDirectorio" ) 'Referencia al control llamado lblId olblClave = oFormulario. relleno.awt.getByName( "MiDirectorio" ) 'Referencia al control llamado lblId olblClave = oFormulario.FontHeight = 18 .Aprendiendo OOo Basic 433 Sub CambiaTam( Obj As Object.FontName = "Linux Biolinum" .getCurrentController. por ejemplo.200.Size oTam. son las mismas usadas en capítulos anteriores.getCurrentController.Height = Alto Obj.getActiveSheet() oPaginaDibujo = oHojaActiva.getForms() oFormulario = oFormularios.Label = "Nuevo texto" End Sub Otras propiedades que puedes manipular en las etiquetas son: Sub Dim Dim Dim Dim Dim Dim Etiquetas3() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object olblClave As Object oDoc = ThisComponent oHojaActiva = oDoc.BackgroundColor = RGB(200.getDrawPage() oFormularios = oPaginaDibujo.getForms() oFormulario = oFormularios. por lo que no las repetiremos aquí y nos centraremos en la forma de manipular las propiedades particulares de cada control desde su “modelo”.getByName("lblId") 'Cambiamos el texto que ve el usuario olblClave.

cuentan con una propiedad para activarlos o desactivarlos (Enabled).getForms() oFormulario = oFormularios.0) . para permitir su interacción con el usuario o no.BorderColor = RGB(255. como para permitirle modificarla. también puede ser.Enabled End Sub Esta propiedad es más útil en otro tipo de controles.getCurrentController.VerticalAlign = 1 End With End Sub 7.2 Etiquetas (Label) 'El tipo de borde (2 = plano ) 'El color del borde (solo efectivo si Border = 2) 'El color del texto 'Alineación horizontal 'Alineación vertical El borde (Border). Sub Dim Dim Dim Dim Dim Dim Etiquetas4() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object olblClave As Object oDoc = ThisComponent oHojaActiva = oDoc. la alienación horizontal puede ser a la izquierda (0). La mayoría de los controles. tanto para mostrar información. es decir. sin borde(0) o 3D (1). arriba (0).434 .getActiveSheet() oPaginaDibujo = oHojaActiva.getDrawPage() oFormularios = oPaginaDibujo.0.Border = 2 .200) . en medio (1) o abajo (2). que en las etiquetas. 7. agregamos un nuevo cuadro de texto a nuestro formulario. puede tomar los valores.getByName( "MiDirectorio" ) 'Referencia al control llamado lblId olblClave = oFormulario.Enabled = Not olblClave. al centro (1) o a la derecha (2).TextColor = RGB(0. en el siguiente ejemplo.3 Cuadros de texto (TextBox) Los cuadro de texto (TextBox) son controles que nos permiten interactuar con el usuario. se invierta el valor de esta propiedad de la misma etiqueta.0.Align = 1 . la vertical. en el siguiente ejemplo.getByName("lblId") 'Invertimos el valor de la propiedad olblClave. Sub Dim Dim Dim Dim Dim Dim Dim CuadroTexto1() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oCuadroTexto As Object oCuadroTextoModelo As Object oDoc = ThisComponent .

sun.230.getForms() oFormulario = oFormularios.createInstance("com.add( oCuadroTexto ) End Sub Los cuadros de texto. 800 ) Call CambiaPos( oCuadroTexto. 2000 ) 'Creamos un nuevo cuadro de texto oCuadroTextoModelo = oDoc.BackgroundColor = RGB(230.getForms() oFormulario = oFormularios.Border = 1 .form.Control = oCuadroTextoModelo 'Lo agregamos al formulario oFormulario.star.100.getCurrentController.getActiveSheet() oPaginaDibujo = oHojaActiva.200) .230) .component.FontName = "Linux Biolinum" .ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oCuadroTexto. oCuadroTextoModelo) 'Agregamos la forma a la página de dibujo para que sea visible oPaginaDibujo.Aprendiendo OOo Basic 435 oHojaActiva = oDoc.Name = "txtNombre" 'Conectamos la forma con el nuevo control oCuadroTexto.star.sun.Align = 0 End With End Sub 'La fuente 'El tamaño de fuente 'El color de fondo 'El tipo de borde (1 = 3D ) 'El color del texto 'Alineación horizontal (izquierda) El principal uso de estos controles es recuperar su contenido o establecerlo. 2000.getByName( "MiDirectorio" ) 'Referencia al control llamado txtNombre otxtNombre = oFormulario.TextField") 'Establecemos su nombre oCuadroTextoModelo.FontHeight = 14 .drawing. Sub Dim Dim Dim Dim Dim Dim CuadroTexto2() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object oDoc = ThisComponent oHojaActiva = oDoc.getByName("txtNombre") With otxtNombre .getDrawPage() oFormularios = oPaginaDibujo.insertByIndex(0.createInstance("com.getDrawPage() oFormularios = oPaginaDibujo.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oCuadroTexto = oDoc. comparten algunas propiedades con las etiquetas.getCurrentController.TextColor = RGB(0. 10000.getActiveSheet() oPaginaDibujo = oHojaActiva. Sub Dim Dim Dim CuadroTexto3() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object .

MultiLine = True .EchoChar = 42 .getCurrentController.getByName( "MiDirectorio" ) 'Referencia al control llamado txtNombre otxtNombre = oFormulario. Los cuadros de texto.getDrawPage() oFormularios = oPaginaDibujo.DataField = "Nombre" End With End Sub 'El carácter de contraseña 42 = * 'Longitud máxima aceptada 'Si es o no multilínea 'Si se muestra o no la barra de desplazamiento horizontal 'Si se muestra o no la barra de desplazamiento vertical 'Si es imprime o no el control 'Si es o no de solo lectura 'Establece el campo de la base de datos mostrada Algunas de estas propiedades se contraponen.getByName("txtNombre") With otxtNombre . El campo vinculado (DataField). el carácter de contraseña (EchoChar) no tiene efecto como tampoco las barras de desplazamiento (Hscroll y Vscroll).HScroll = False . el usuario no podrá escribir en el.Printable = True .getDrawPage() oFormularios = oPaginaDibujo.getForms() oFormulario = oFormularios.MaxTextLen = 20 . por ejemplo.436 Dim Dim Dim Dim oFormularios As Object oFormulario As Object otxtNombre As Object sInfo As String 7.getActiveSheet() oPaginaDibujo = oHojaActiva.getCurrentController.VScroll = True .getByName( "MiDirectorio" ) 'Referencia al control llamado txtNombre otxtNombre = oFormulario. Sub Dim Dim Dim Dim Dim Dim CuadroTexto4() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object oDoc = ThisComponent oHojaActiva = oDoc.3 Cuadros de texto (TextBox) oDoc = ThisComponent oHojaActiva = oDoc. solo será efectivo si previamente el formulario se relaciono con una base de datos y con una fuente de datos (tabla. .getActiveSheet() oPaginaDibujo = oHojaActiva. si estableces el control en solo lectura (ReadOnly).getForms() oFormulario = oFormularios.ReadOnly = False .getByName("txtNombre") 'Recuperamos el texto del control sInfo = otxtNombre. por supuesto.Text 'Lo mostramos MsgBox sInfo 'Solicitamos un nuevo contenido sInfo = InputBox("Escribe un nuevo contenido para el control") 'Y lo establecemos otxtNombre.Text = sInfo End Sub También puedes usar la propiedad String para recuperar o establecer el texto del control. cuentan con muchas más propiedades. si estableces el control en multilínea (MultiLine).

getCurrentController.getActiveSheet() oPaginaDibujo = oHojaActiva.getCellAddress 'Creamos la propiedad para vincular mOpc(0). además.getDrawPage() oFormularios = oPaginaDibujo. el nombre del campo “debe existir” en el origen de datos.getByName("txtNombre") 'Activamos y desactivamos el control otxtNombre.getByName("txtNombre") 'Obtenemos la dirección de la celda B5 oDirCeldaVinculada = oHojaActiva.NamedValue" oVinculo As Object oDoc = ThisComponent oHojaActiva = oDoc. mOpc()) 'Y la vinculamos al cuadro de texto otxtNombre.Enabled = Not otxtNombre.4).getByName( "MiDirectorio" ) 'Referencia al control llamado txtNombre otxtNombre = oFormulario.Value = oDirCeldaVinculada 'Creamos la instancia de la celda a vincular oVinculo= oDoc. solo puedes establecer el campo vinculado (DataField) o la celda vinculada (ValueBinding).star.getCellByPosition(1. Puedes vincular el control con una celda de cualquier hoja.createInstanceWithArguments("com.beans.star.getForms() oFormulario = oFormularios. toma en cuenta que activarlo es diferente de establecerlo en solo lectura (ReadOnly).getDrawPage() oFormularios = oPaginaDibujo.getByName( "MiDirectorio" ) 'Referencia al control llamado txtNombre otxtNombre = oFormulario.table.sun.Enabled End Sub . establece esta propiedad en vacía. Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim CuadroTexto5() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object oDirCeldaVinculada As Object mOpc(0) As New "com.Name = "BoundCell" mOpc(0).getCurrentController. esto te permite reflejar cualquier cambio que se haga en uno en el otro. Sub Dim Dim Dim Dim Dim Dim CuadroTexto6() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object oDoc = ThisComponent oHojaActiva = oDoc.sun.getForms() oFormulario = oFormularios.CellValueBinding".setValueBinding( oVinculo ) End Sub Puedes activar y desactivar (Enabled) el control. tendrá efecto el ultimo que establezcas como en nuestro ejemplo. Si quieres quitar la relación.Aprendiendo OOo Basic 437 consulta o instrucción SQL).getActiveSheet() oPaginaDibujo = oHojaActiva.

para ello.getDrawPage() oFormularios = oPaginaDibujo. es posible convertirlo en cuadro de texto enriquecido. es enviarles el foco.getByName("txtNombre") 'Accedemos a la vista del control otxtNombreVista = oDoc.getActiveSheet() oPaginaDibujo = oHojaActiva.RichText = True 'Creamos un cursor oCursor = otxtNombre. Sub Dim Dim Dim Dim Dim Dim Dim CuadroTexto7() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object oCursor As Object oDoc = ThisComponent oHojaActiva = oDoc.getCurrentController. 0. "Segunda línea". False) 'Insertamos otra línea de texto otxtNombre. tenemos que aprender un nuevo concepto.getByName( "MiDirectorio" ) otxtNombre = oFormulario. False) End Sub Una tarea muy común al trabajar con controles.getForms() oFormulario = oFormularios. solo es posible hacer a través de la “vista” del control.Multiline = True otxtNombre. False) 'Insertamos un salto de parrafo otxtNombre.3 Cuadros de texto (TextBox) Este control. mover el cursor a este.438 7.getDrawPage() oFormularios = oPaginaDibujo. capaz de mostrar texto con diferentes formatos.createTextCursor() 'Insertamos una línea de texto otxtNombre.getControl( otxtNombre ) 'Le enviamos el foco otxtNombreVista.getCurrentController. para entrar al modo “vista.getForms() oFormulario = oFormularios. pero para usar otras propiedades y métodos.getActiveSheet() oPaginaDibujo = oHojaActiva.getByName( "MiDirectorio" ) 'Referencia al control llamado txtNombre otxtNombre = oFormulario. a este modo de acceso se le llama “modelo”. es decir.getByName("txtNombre") 'Establecemos que sea multilínea y que soporte texto enriquecido otxtNombre.getCurrentController. "Primera línea".insertString( oCursor.insertControlCharacter( oCursor.setFocus() End Sub . nos ha bastado como medio el mismo formulario. hasta ahora para acceder a los controles de un formulario.insertString( oCursor. usamos el siguiente código. Sub Dim Dim Dim Dim Dim Dim Dim CuadroTexto8() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object otxtNombreVista As Object oDoc = ThisComponent oHojaActiva = oDoc.

Sub Dim Dim Dim Dim Dim Dim Dim CasillaVerificacion1() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object oCasilla As Object oCasillaModelo As Object oDoc = ThisComponent oHojaActiva = oDoc. generalmente se usan para indicar si se hace o no una actividad u opción. pero algunas otras propiedades solo están disponibles en este modo.4 Casilla de verificación (CheckBox) Las casillas de verificación (CheckBox).setVisible( Not otxtNombreVista.getCurrentController.getDrawPage() oFormularios = oPaginaDibujo. es decir. este método.drawing.getDrawPage() oFormularios = oPaginaDibujo. Casi todos los controles que veremos. tienen su modo “vista” y la posibilidad de enviar el foco y ocultarlos.getControl( otxtNombre ) 'Alternamos entre mostrar y ocultar el control otxtNombreVista.getByName("txtNombre") 'Accedemos a la vista del control otxtNombreVista = oDoc. son controles de verdadero o falso.getCurrentController. solo tiene efecto en tiempo de “ejecución”. Desde el modo “vista”. 7.isVisible ) End Sub Toma en cuenta que si el formulario esta en modo “diseño”.Aprendiendo OOo Basic 439 Observa como accedemos al modo “vista” del control. puedes acceder también al contenido del control con su propiedad Text. Sub Dim Dim Dim Dim Dim Dim Dim CuadroTexto9() oDoc As Object oHojaActiva As Object oPaginaDibujo As Object oFormularios As Object oFormulario As Object otxtNombre As Object otxtNombreVista As Object oDoc = ThisComponent oHojaActiva = oDoc.createInstance("com.getForms() oFormulario = oFormularios. el control de todos modos se mostrará. El siguiente ejemplo agrega una casilla de verificación a nuestro formulario.getActiveSheet() oPaginaDibujo = oHojaActiva.getByName( "MiDirectorio" ) otxtNombre = oFormulario.getActiveSheet() oPaginaDibujo = oHojaActiva.sun.star.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oCasilla = oDoc. a través del controlador (getCurrentController) del documento.ControlShape") .getForms() oFormulario = oFormularios.getCurrentController. como posibilidad de ocultar o mostrar el control.

Control = oCasillaModelo 'Lo agregamos al formulario oFormulario.createInstance("com.sun.Enabled = Not ochkMayus.Align = 0 .Label = "Guardar todo en MAYUSCULAS" 'Conectamos la forma con el nuevo control oCasilla.getActiveSheet. Sub CasillaVerificacion3() Dim oFormulario As Object Dim ochkMayus As Object oFormulario = ThisComponent.440 7.getDrawPage.Enabled End Sub .220. Sub CasillaVerificacion2() Dim oFormulario As Object Dim ochkMayus As Object oFormulario = ThisComponent.getCurrentController.getForms.BackgroundColor = RGB(200.getByName( "chkMayus" ) 'Alternamos la activación del control ochkMayus.CheckBox") 'Establecemos su nombre oCasillaModelo.getByName( "MiDirectorio" ) ochkMayus = oFormulario. 800 ) Call CambiaPos( oCasilla.240) .star.VisualEffect = 2 End With End Sub 'Alineación horizontal 'Color de fondo 'Color de la fuente 'Tamaño de la fuente 'Si se imprime el control 'Alineación vertical 'Establece el estado triple 'Formato plano (1 = 3D) Puedes activarlo y desactivarlo. 5000 ) 'Creamos una nueva casilla de verificación oCasillaModelo = oDoc.70.TriState = False .4 Casilla de verificación (CheckBox) 'Cambiamos su tamaño y posicion Call CambiaTam( oCasilla.getByName( "chkMayus" ) With ochkMayus .VerticalAlign = 1 .component. oCasillaModelo) 'Agregamos la forma a la página de dibujo para que sea visible oPaginaDibujo.insertByIndex(0. este se puede formatear completamente como en las etiquetas (label) y los cuadros de texto (textbox).getCurrentController.TextColor = RGB(50. 8000.Name = "chkMayus" 'Y el texto que verá el usuario oCasillaModelo.getForms.form.getActiveSheet.add( oCasilla ) End Sub Al contar con texto para mostrar al usuario.Printable = True . 3000.getDrawPage.90) .getByName( "MiDirectorio" ) ochkMayus = oFormulario.FontHeight = 16 .

1 o 2.drawing. esta puede tomar los valores 0.getDrawPage.State = 1 End Sub Las casillas de verificación.star. 7. son controles casi indenticos a los cuadros de texto (TextBox). activo.form. y se les puede establecer un valor máximo y un mínimo. 8000.sun.createInstance("com. en la ficha Números.getDrawPage. Sub Dim Dim Dim CampoFormateado1() oFormulario As Object oCuadroConFormato As Object oCuadroConFormatoModelo As Object oFormulario = ThisComponent.getForms.createInstance("com.getCurrentController.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oCuadroConFormato.getForms. que permite tener este control en.getByName( "MiDirectorio" ) ochkMayus = oFormulario.component.getCurrentController. 3000.. con el mismo código de los cuadros de texto. esta activa o no.getActiveSheet. también las puedes vincular con un campo de datos (DataField) o con una celda (ValueBinding).. y de la propiedad de triple estado (TriState).star. dependiendo si.Aprendiendo OOo Basic 441 Para obtener o establecer el estado del control.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oCuadroConFormato = ThisComponent.getActiveSheet. con la diferencia de que estos aceptan todos los formatos que tenemos disponibles en el menú Formato | Celdas.getByName( "chkMayus" ) 'Verificamos el estado de la casilla Select Case ochkMayus.Name = "txtFVentas" 'Conectamos la forma con el nuevo control . 5000 ) 'Creamos un nuevo campo formateado oCuadroConFormatoModelo = ThisComponent.sun. 800 ) Call CambiaPos( oCuadroConFormato. Sub CasillaVerificacion4() Dim oFormulario As Object Dim ochkMayus As Object oFormulario = ThisComponent.5 Campo formateado (FormattedField) Los campos formateados (FormattedField). se usa la propiedad State.FormattedField") 'Establecemos su nombre oCuadroConFormatoModelo.State Case 0 MsgBox "La casilla no esta seleccionada" Case 1 MsgBox "La casilla esta seleccionada" Case 2 MsgBox "La casilla no tiene selección" End Select 'La activamos ochkMayus. desactivado o sin selección.

getForms. Veamos como agregar uno a nuestro formulario. Listar formatos en un archivo de Calc. Sub CampoFormateado2() Dim oFormulario As Object Dim otxtfVentas As Object oFormulario = ThisComponent.getForms.star.Spin = True .add( oCuadroConFormato ) End Sub Puede usar las mismas propiedades que para los cuadros de texto (TextBox).getDrawPage.insertByIndex(0. Este control también lo puedes activar y desactivar (Enabled) y establecerle un campo de datos origen (DataField).EffectiveMin = 1 . 5000.getByName( "MiDirectorio" ) otxtfVentas = oFormulario.getActiveSheet.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oBotonComando = ThisComponent.##0. 10000 ) .getCurrentController.6 Botón de comando (CommandButton) Los botones de comando (CommandButton) son controles generalmente usados para iniciar una acción por que usualmente tienen asociada una macro al evento “clic del ratón”. 7.FormatKey = 4 End With End Sub 'El 'El 'Si 'El valor mínimo valor máximo se muestra o no el campo giratorio formato para el contenido ( 4 = "#.getCurrentController. la alienación del contenido siempre será a la izquierda.createInstance("com. oCuadroConFormatoModelo) 7.getActiveSheet. puedes obtener estos valores con la macro que te muestro en. 800 ) Call CambiaPos( oBotonComando. es el mismo para las celdas.getCurrentController.Control = oCuadroConFormatoModelo 'Lo agregamos al formulario oFormulario.getDrawPage. 3000.drawing.getDrawPage. así como vincularlo con una celda (ValueBinding).sun.5 Campo formateado (FormattedField) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent.442 oCuadroConFormato.00" ) Si estableces que se muestre el campo giratorio (Spin). El valor para el formato (FormatKey).ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oBotonComando.getActiveSheet. Sub Dim Dim Dim BotonComando1() oFormulario As Object oBotonComando As Object oBotonComandoModelo As Object oFormulario = ThisComponent.EffectiveMax = 100 .getByName ( "txtFVentas" ) With otxtfVentas . aunque soportan varios más. aquí vemos las propiedades particulares para este control.

TextColor = RGB(0. muy útil para deshabilitar momentáneamente su uso.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control ocmdGuardar = oFormulario.Control = oBotonComandoModelo 'Lo agregamos al formulario oFormulario.star. es decir el cursor.BackgroundColor = RGB(220.230. en los formularios.sun.getActiveSheet. Veamos las principales propiedades particulares de este control. este método abreviado tiene una función ligeramente diferente. oBotonComandoModelo) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent.DefaultButton = True .7 Botón de opción (OptionButton) Estos controles generalmente trabajan juntos dos o más. esta dentro de algún control del formulario.CommandButton") 'Establecemos su nombre oBotonComandoModelo.getDrawPage.component. pero solo eso.FontHeight = 18 . pues permiten seleccionar solo una opción de entre los que haya en el formulario.getCurrentController.getCurrentController. la combinación de teclas llevará el cursor a dicho control.240) .FontName = "Linux Biolinum" . Sub BotonComando2() Dim oFormulario As Object Dim ocmdGuardar As Object oFormulario = ThisComponent.insertByIndex(0.Label = "~Guardar" 'Conectamos la forma con el nuevo control oBotonComando. nos permite subrayar la letra inmediata siguiente para usarse como método abreviado de teclado.add( oBotonComando ) End Sub Observa el símbolo “~” antes del título del botón de comando. .Name = "cmdGuardar" oBotonComandoModelo. este.getByName ("cmdGuardar") With ocmdGuardar .Printable = True End With End Sub 'Alineación horizontal ( 1 = centro ) 'Alineación vertical ( 1 = medio ) 'Color de fondo 'Si es el botón predeterminado 'La fuente 'El tamaño de fuente 'El color del texto 'Si se imprime el control Este control también cuenta con la propiedad para activar o desactivar (Enabled).VerticalAlign = 1 .Aprendiendo OOo Basic 443 'Creamos un nuevo botón de comando oBotonComandoModelo = ThisComponent.getDrawPage.Align = 1 . solo le lleva el foco. ten cuidado.getActiveSheet.20.getForms.250) . generalmente se agregan dos o más como en el siguiente ejemplo. 7. esta tendrá preferencia. cuando tiene una macro asociada.form. cuando el “foco”. si estableces una combinación ya usada en la interfaz del usuario.createInstance("com. por ello.

getDrawPage.createInstance("com. .Control = oBotonOpcionModelo 'Lo agregamos al formulario oFormulario.createInstance("com. simplemente estableciendo el mismo nombre para cada grupo agregado.star.Name = "optEstilo" oBotonOpcionModelo.getCurrentController.sun. 3000.getActiveSheet. oBotonOpcionModelo) ThisComponent.sun.ControlShape") Call CambiaTam( oBotonOpcion.star.form.component.getActiveSheet.Control = oBotonOpcionModelo oFormulario.Label = "Escala de grises" oBotonOpcion. pero observa que hasta ahora.getDrawPage. Al tener texto visible por el usuario.insertByIndex(0. comparten la mayoría de las propiedades vistas hasta ahora (color de fuente y fondo. oBotonOpcionModelo) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent. hemos usado el nombre del control para hacer referencia a el.RadioButton") 'Establecemos su nombre oBotonOpcionModelo. 5000. 12000 ) oBotonOpcionModelo = ThisComponent. 800 ) Call CambiaPos( oBotonOpcion. 800 ) Call CambiaPos( oBotonOpcion.add( oBotonOpcion ) 'Agregamos un segundo control oBotonOpcion = ThisComponent.component.RadioButton") oBotonOpcionModelo.sun. de este modo. 800 ) Call CambiaPos( oBotonOpcion.444 Sub Dim Dim Dim BotonOpcion1() oFormulario As Object oBotonOpcion As Object oBotonOpcionModelo As Object 7. tamaño de fuente.insertByIndex(0.star.add( oBotonOpcion ) 'Y un tercero oBotonOpcion = ThisComponent. etc). como en el siguiente ejemplo.createInstance("com.getDrawPage. oBotonOpcionModelo) ThisComponent. para distinguirlos. 3000.getCurrentController.getCurrentController.component.Name = "optEstilo" oBotonOpcionModelo.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oBotonOpcion.ControlShape") Call CambiaTam( oBotonOpcion. 5000.sun.Label = "Blanco y negro" oBotonOpcion.Control = oBotonOpcionModelo oFormulario.sun.drawing.star.insertByIndex(0. si quieres que se comporten como un grupo.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oBotonOpcion = ThisComponent.RadioButton") oBotonOpcionModelo.star. ahora accederemos a ellos con su índice.star.drawing.getForms.getDrawPage.form. esto es importante.Name = "optEstilo" oBotonOpcionModelo. estilo de fuente.getCurrentController.getActiveSheet.createInstance("com.drawing.getActiveSheet. 11000 ) 'Creamos un nuevo botón de opción oBotonOpcionModelo = ThisComponent. en vez de con su nombre. puedes crear tantos grupos de controles de botón de opción (OptionButton) como quieras.createInstance("com.createInstance("com.7 Botón de opción (OptionButton) oFormulario = ThisComponent.add( oBotonOpcion ) End Sub Observa que a los tres les hemos establecido el mismo nombre. pero a estos controles les hemos dado el mismo nombre.Label = "Color" 'Conectamos la forma con el nuevo control oBotonOpcion.form. 5000. 13000 ) oBotonOpcionModelo = ThisComponent. 3000.sun.

visible desde el menú Ver | Barra de herramientas ->.Rnd*255) ooptEstilo = oFormulario.getCurrentController.BackgroundColor = RGB(Rnd*255.Rnd*255.Rnd*255) End Sub 'Color de fondo 'Color de la fuente 'Color de fondo 'Color de la fuente 'Color de fondo 'Color de la fuente Y con justa razón te preguntarás.TextColor = RGB(Rnd*255.BackgroundColor = RGB(Rnd*255.BackgroundColor = RGB(Rnd*255. en el navegador de formularios.Rnd*255.getByName( "MiDirectorio" ) ooptEstilo = oFormulario. para ver esta ventana.Rnd*255.getForms. puedes hacerlo de varias maneras.Rnd*255) ooptEstilo.getByIndex(1) ooptEstilo.Rnd*255. .Rnd*255) ooptEstilo = oFormulario.getByIndex(0) ooptEstilo.Rnd*255) ooptEstilo.Rnd*255.Rnd*255) ooptEstilo.getDrawPage. visualmente en la interfaz de Calc. después solo sigue la secuencia de la imagen siguiente. tienes que tener visible la barra de herramientas “Campos de control de formulario”.TextColor = RGB(Rnd*255. ¿como se que índice tiene cada control?.Aprendiendo OOo Basic Sub BotonOpcion2() Dim oFormulario As Object Dim ooptEstilo As Object 445 oFormulario = ThisComponent.getActiveSheet.Rnd*255.TextColor = RGB(Rnd*255.getByIndex(2) ooptEstilo.

7 Botón de opción (OptionButton) .446 7.

Aprendiendo OOo Basic 447 .

BackgroundColor = RGB(Rnd*255.getForms.getForms.getCurrentController.7 Botón de opción (OptionButton) Con código. oGrupoEstilo) For Each oBoton In oGrupoEstilo() 'Consultamos el estado del botón If oBoton. Sub Dim Dim Dim BotonOpcion4() oFormulario As Object oGrupoEstilo() As Object oBoton As Object oFormulario = ThisComponent.getByName( "MiDirectorio" ) 'Accedemos al grupo completo oFormulario. como en el ejemplo siguiente: Sub Dim Dim Dim BotonOpcion3() oFormulario As Object oGrupoEstilo() As Object oBoton As Object oFormulario = ThisComponent.getGroupByName("optEstilo".getActiveSheet.getDrawPage.getGroupByName("optEstilo".Rnd*255. puedes acceder a los controles por el nombre del grupo. que solo uno de ellos puede tener en verdadero (True).Rnd*255) Next End Sub Lo importante de los botones de opción (Optionbutton) es saber cual de ellos. oGrupoEstilo) 'Iteramos entre los elementos del grupo For Each oBoton In oGrupoEstilo() 'Cambiamos el color de fondo aleatoriamente oBoton. esta seleccionado.getCurrentController. para ello se consulta su propiedad State.getActiveSheet.getByName( "MiDirectorio" ) oFormulario.448 7. dentro del grupo.getDrawPage.State Then 'Mostramos el que este seleccionado .

insertByIndex(0.getCurrentController.getDrawPage.sun.getActiveSheet. 5000.8 Cuadro de lista (ListBox) Los cuadros de lista (ListBox).getCurrentController.Aprendiendo OOo Basic 449 MsgBox "Opción seleccionada: " & oBoton. es muy sencillo saber cual es el que esta seleccionado.component. sin recorrer uno a uno. en el siguiente ejemplo.getForms. 3000. agregamos un nuevo control de lista a nuestro formulario.ListBox") 'Establecemos su nombre oCuadroListaModelo.form.getActiveSheet.Name = "lstCiudades" 'Conectamos la forma con el nuevo control oCuadroLista. Sub CuadroLista2() Dim oFormulario As Object Dim olstCiudades As Object . 7.createInstance("com.star. 10000 ) 'Creamos un nuevo cuadro de lista oCuadroListaModelo = ThisComponent.createInstance("com. oCuadroListaModelo) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent.Control = oCuadroListaModelo 'Lo agregamos al formulario oFormulario.sun. 5000 ) Call CambiaPos( oCuadroLista.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oCuadroLista.getDrawPage. cuando se asocia una macro al evento clic de los botones de opción.star.Label Exit For End If Next End Sub Como veremos más adelante. Sub Dim Dim Dim CuadroLista1() oFormulario As Object oCuadroLista As Object oCuadroListaModelo As Object oFormulario = ThisComponent. Estos controles también cuenta con la propiedad de activarse o desactivarse (Enabled) y la capacidad para establecerle un campo de datos origen (DataField).getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oCuadroLista = ThisComponent. así como vincularlo con una celda (ValueBinding).drawing. son controles usados generalmente para mostrar un listado y poder seleccionar una o varias opciones dependiendo de sus propiedades.add( oCuadroLista ) End Sub Las propiedades principales de este control son.

450

7.8 Cuadro de lista (ListBox)

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) With olstCiudades .BackgroundColor = RGB(Rnd*255,Rnd*255,Rnd*255) .Border = 2 .BorderColor = RGB(Rnd*255,Rnd*255,Rnd*255) .Dropdown = False .MultiSelection = True End With End Sub 'Color de fondo 'Tipo de borde ( 1 = 3D ) 'Solo si Border = 2 'Si es desplegable 'Si se permite la multiselección

Si estableces que el control sea desplegable (Dropdown), te mostrará una flecha para desplegar el contenido, con lo que se comportará de forma similar al cuadro combinado (ComboBox), mi recomendación es establecer esta propiedad siempre en falso (False), si quieres un cuadro combinado, usa el control visto en el siguiente tema. Haya varias formas de agregar elementos a un cuadro de lista, la primera y más sencilla es agregar una matriz de datos.
Sub Dim Dim Dim CuadroLista3() oFormulario As Object olstCiudades As Object mDatos()

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) mDatos = Array("Mexico", "Madrid","Buenos Aires","Bogota","Lima") olstCiudades.StringItemList = mDatos() End Sub

Este control acepta también como origen de datos un campo de bases de datos (DataField). Otra forma es vincular el control con un origen de celdas, tanto para el valor seleccionado (ValueBinding), como para los valores mostrados (ListEntrySource).
Sub Dim Dim Dim Dim Dim Dim CuadroLista4() oFormulario As Object olstCiudades As Object oDirCeldaVinculada As Object oRangoOrigen As Object mOpc(0) As New "com.sun.star.beans.NamedValue" oVinculo As Object

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) 'Obtenemos la dirección de la celda B5 oDirCeldaVinculada = ThisComponent.getCurrentController.getActiveSheet.getCellByPosition(3,24).getCellAddress 'Creamos la propiedad para vincular mOpc(0).Name = "BoundCell" mOpc(0).Value = oDirCeldaVinculada 'Creamos la instancia de la celda a vincular createInstanceWithArguments oVinculo= ThisComponent.createInstanceWithArguments("com.sun.star.table.CellValueBinding", mOpc())

Aprendiendo OOo Basic
'Y la vinculamos al cuadro de lista olstCiudades.setValueBinding( oVinculo )

451

'Establecemos el rango de celdas origen oRangoOrigen = ThisComponent.getCurrentController.getActiveSheet.getCellRangeByName("D27:D40").getRangeAddress mOpc(0).Name = "CellRange" mOpc(0).Value = oRangoOrigen 'Creamos el vinculo oVinculo= ThisComponent.createInstanceWithArguments("com.sun.star.table.CellRangeListSource", mOpc()) 'Lo vinculamos al cuadro de lista olstCiudades.setListEntrySource( oVinculo ) End Sub

Otra forma es agregar (y quitar) los elementos de forma dinámica, para lograr esto, repasemos un concepto para el acceso a propiedades y métodos de los controles, hasta ahora, con hacer referencia al control a través del formulario nos era suficiente, a esta forma de referencia se le llama de acceso al “modelo”, pero algunas propiedades y métodos solo están disponibles en el modo de acceso “vista”, para acceder a este modo, usamos el siguiente código.
Sub Dim Dim Dim CuadroLista5() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) 'Accedemos a la vista del control a través del controlador del documento olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) 'Y podemos enviar el foco, es decir, el cursor a el olstCiudadesVista.setFocus() End Sub

En el acceso “vista”, tenemos una serie de métodos y propiedades para manipular completamente los elementos de un cuadro de lista (ListBox), veamos los más importantes. Para agregar elementos usamos el método addItem de la siguiente manera.
Sub Dim Dim Dim Dim CuadroLista6() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object sInfo As String

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) Do 'Solicitamos un elemento sInfo = Trim( InputBox("Escribe la ciudad a agregar")) 'Si esta vacio salimos If sInfo = "" Then Exit Do 'Lo agregamos como primer elemento olstCiudadesVista.addItem( sInfo, 0) Loop

452
End Sub

7.8 Cuadro de lista (ListBox)

El código anterior siempre agregará los nuevos elementos al inicio de la lista, si quieres agregarlos al final, tenemos que saber cuantos elementos ya existen en la lista, esto lo logramos con la propiedad ItemCount, que te devuelve el número total de elementos actuales en el cuadro de lista.
Sub Dim Dim Dim Dim CuadroLista7() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object sInfo As String

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) Do sInfo = Trim( InputBox("Escribe la ciudad a agregar")) If sInfo = "" Then Exit Do 'Lo agregamos como ultimo elemento olstCiudadesVista.addItem( sInfo, olstCiudadesVista.ItemCount) Loop End Sub

También podemos agregar una matriz completa.
Sub Dim Dim Dim Dim CuadroLista8() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object sInfo()

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) sInfo = Array("Barcelona","Montevideo","Arequipa") 'Agregamos una matriz completa olstCiudadesVista.addItems( sInfo, 0) End Sub

Observa que el método es addItems, en plural. Solo puedes agregar matrices de una sola dimensión. Ahora, vamos a eliminar elementos de la lista, para ellos existe un solo método, pero es más que suficiente.
Sub Dim Dim Dim Dim CuadroLista9() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object iRes As Integer

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" )

Aprendiendo OOo Basic

453

olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) iRes = MsgBox( "¿Estas seguro de borrar el siguiente elemento? = " & olstCiudadesVista.getItem( 0 ), 4) If iRes = 6 Then 'Quitamos el primer elemento de la lista olstCiudadesVista.removeItems( 0,1 ) End If iRes = MsgBox( "¿Estas seguro de borrar el siguiente elemento? = " & olstCiudadesVista.getItem( olstCiudadesVista.getItemCount-1 ), 4) If iRes = 6 Then 'Quitamos el ultimo elemento de la lista olstCiudadesVista.removeItems( olstCiudadesVista.getItemCount-1,1 ) End If End Sub

El método para eliminar elementos (removeItems), requiere de dos argumentos, el primero es la posición del primer elemento a borrar, las posiciones del cuadro de lista, como en las matrices, siempre empieza en cero, el segundo argumento es el número total de elementos a borrar. En los dos ejemplos anteriores, solo eliminamos un elemento, el primero (0) y el ultimo (getItemCount-1), es decir, contamos el total de elemento y le restamos uno para obtener el índice del ultimo elemento. Observa como le mostramos al usuario el elemento a borrar con el método getItem, simplemente pasándole el índice del elemento a mostrar, este método siempre te devuelve un texto (string) con el contenido del elemento indicado. Con estos argumentos en posible limpiar la lista completa, es decir, dejarla en blanco para empezar de nuevo.
Sub Dim Dim Dim Dim CuadroLista10() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object iRes As Integer

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) iRes = MsgBox( "¿Estas seguro de borrar TODOS los elementos de la lista?", 4 ) If iRes = 6 Then 'Quitamos todos los elementos de la lista olstCiudadesVista.removeItems( 0, olstCiudadesVista.getItemCount ) End If End Sub

Recuerda que es una buena practica de programación, cuando se realizan operaciones que no se puedan deshacer, sobre todo si son de borrado, preguntar al usuario si esta seguro de realizarla. Ya vimos como devolver un elemento de la lista (getItem), ahora, veremos como devolver todos los elementos de la lista (getItems).
Sub Dim Dim Dim Dim Dim CuadroLista11() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object mDatos() co1 As Integer

454

7.8 Cuadro de lista (ListBox)

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) 'Devolvemos todos los elementos a una matriz mDatos() = olstCiudadesVista.getItems() 'Mostramos los elementos en la matriz For co1 = LBound(mDatos) To Ubound(mDatos) MsgBox mDatos(co1) Next co1 End Sub

Un punto importante es saber que elemento o elementos selecciono el usuario, para ello tenemos varios métodos, veamos.
Sub Dim Dim Dim Dim Dim CuadroLista12() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object sSeleccionado As String iPos As Integer

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) 'Obtenemos el elemento seleccionado sSeleccionado = olstCiudadesVista.getSelectedItem() 'Obtenemos la posición del elemento seleccionado iPos = olstCiudadesVista.getSelectedItemPos() 'Mostramos la información MsgBox "Esta seleccionado: " & sSeleccionado & " en la posición " & iPos End Sub

Estos métodos siempre te devolverán un solo elemento, si el cuadro de lista (ListBox) no tiene “ningún” elemento seleccionado, el método getSelectedItemPos, te devolverá un valor negativo de -1, si el cuadro de lista (ListBox) tiene activada la propiedad para selecciones múltiples (MultiSelection), tienes que usar otros métodos.
Sub Dim Dim Dim Dim Dim Dim CuadroLista13() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object mSeleccionados() As String mPos() As Integer co1 As Integer

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) 'Obtenemos los elementos seleccionados mSeleccionados() = olstCiudadesVista.getSelectedItems() 'Obtenemos la posición del los elementos seleccionados mPos() = olstCiudadesVista.getSelectedItemsPos()

Aprendiendo OOo Basic

455

For co1 = LBound(mPos) To UBound(mPos) 'Mostramos la información MsgBox "Esta seleccionado: " & mSeleccionados(co1) & " en la posición " & mPos(co1) Next co1 End Sub

Observa que en los dos casos estamos obteniendo matrices de datos. Para finalizar de ver las propiedades y métodos más importantes de los cuadros de lista (ListBox), también es posible seleccionar elementos por código, veamos como.
Sub Dim Dim Dim CuadroLista14() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) 'Seleccionamos el primer elemento de la lista olstCiudadesVista.selectItemPos(0, True) 'Seleccionamos el ultimo elemento de la lista olstCiudadesVista.selectItemPos(olstCiudadesVista.getItemCount-1, True) End Sub

En el ejemplo, seleccionamos el primero y el ultimo elemento, dependiendo de la propiedad de multiselección (MultiSelection), el resultado será diferente, si esta en falso (False), la selección reemplazará a la anterior, si esta en verdadero (True), la selección se sumará a lo ya seleccionado. También puedes seleccionar varios elementos al mismo tiempo, claro, si la multiselección (MultiSelection) esta en verdadero (True).
Sub Dim Dim Dim Dim CuadroLista15() oFormulario As Object olstCiudades As Object olstCiudadesVista As Object mSeleccionar()

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) mSeleccionar() = Array(1,3,5) 'Seleccionamos los elementos de la matriz olstCiudadesVista.selectItemsPos(mSeleccionar(), True) End Sub

Por ultimo, puedes seleccionar un elemento por su contenido en vez de por su posición como en el siguiente ejemplo.
Sub CuadroLista16() Dim oFormulario As Object

456
Dim olstCiudades As Object Dim olstCiudadesVista As Object

7.8 Cuadro de lista (ListBox)

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) olstCiudades = oFormulario.getByName( "lstCiudades" ) olstCiudadesVista = ThisComponent.getCurrentController.getControl( olstCiudades ) 'Seleccionamos el elemento "Lima" olstCiudadesVista.selectItem("Lima", True) End Sub

Si el elemento no existe, no selecciona nada, por supuesto, con los métodos aprendidos en este tema, puedes asegurarte de que si exista, ¿verdad?. Este control también acepta la activación o desactivado por código (Enabled).

7.9

Cuadro combinado (ComboBox)

Los cuadro combinados (ComboBox), son una combinación de un cuadro de lista (ListBox) y un cuadro de texto (TextBox), cuentan con una flecha en el extremo derecho para desplegar el contenido de la lista, pues esta, permanece oculta y solo es visible el elemento actualmente seleccionado, para agregar este control a nuestro formulario, usamos.
Sub Dim Dim Dim CuadroCombinado1() oFormulario As Object oCuadroCombinado As Object oCuadroCombinadoModelo As Object

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oCuadroCombinado = ThisComponent.createInstance("com.sun.star.drawing.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oCuadroCombinado, 5000, 700 ) Call CambiaPos( oCuadroCombinado, 3000, 10000 ) 'Creamos un nuevo cuadro combinado oCuadroCombinadoModelo = ThisComponent.createInstance("com.sun.star.form.component.ComboBox") 'Establecemos su nombre oCuadroCombinadoModelo.Name = "cboPaises" oCuadroCombinadoModelo.DropDown = True 'Conectamos la forma con el nuevo control oCuadroCombinado.Control = oCuadroCombinadoModelo 'Lo agregamos al formulario oFormulario.insertByIndex(0, oCuadroCombinadoModelo) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent.getCurrentController.getActiveSheet.getDrawPage.add( oCuadroCombinado ) End Sub

Al ser una combinación de los controles mencionados (ListBox y TextBox), comparten con estos la mayoría de sus propiedades y métodos, sobre todo con el cuadro de lista

Aprendiendo OOo Basic

457

(ListBox). Como propiedades particulares de este, tenemos el número de líneas que muestra cuando se despliega el control.
Sub Dim Dim Dim CuadroCombinado2() oFormulario As Object ocboPaises As Object mDatos()

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) ocboPaises = oFormulario.getByName("cboPaises") 'Agregamos datos al cuadro combinado mDatos() = Array("México","Belice","El Salvador","Nicaragua") With ocboPaises .StringItemList = mDatos() .LineCount = 5 'El número de líneas a mostrar cuando se despliegue .MaxTextLen = 20 'El máximo de caracteres a aceptar End With End Sub

Para agrega y eliminar elementos de este control, se usan exactamente los mismo métodos que en el cuadro de lista (ListBox), sin olvidar que hay que hacerlo desde el modo “vista” del control, excepto los relacionados con la selección de elementos (selectItem, selectItemPos, selectItemsPos), puesto que este control trabaja de forma un poco diferente, cuando se selecciona un elemento de la lista (no es posible hacer multiselecciones), este valor se establece como valor de su propiedad Text, que puedes cambiar, esto es, el control puede tener un valor diferente a los de la lista de elementos.
Sub Dim Dim Dim CuadroCombinado3() oFormulario As Object ocboPaises As Object sDato As String

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) ocboPaises = oFormulario.getByName("cboPaises") 'Mostramos el elemento seleccionado MsgBox ocboPaises.Text 'Cambiamos el texto ocboPaises.Text = InputBox("Escribe un nuevo valor para el control") End Sub

La posibilidad de agregar elementos diferentes a los de la lista, puede tener dos vertientes, la primera (negativa) puede ser que se capture un dato no deseado, la segunda (positiva) es que el usuario puede agregar elementos nuevos directamente. Con los métodos vistos, tu determinaras si permites esto o no, dependiendo de tus necesidades, la perspectiva de una u otra, puede cambiar. Puedes usar la activación o desactivación para este control (Enabled)

458

7.10 Botón de selección (SpinButton)

7.10

Botón de selección (SpinButton)

Este control nos permite aumentar o disminuir el valor de otro control (o celda), por ello generalmente trabaja en conjunto con otro, para agregar uno al formulario, usamos.
Sub Dim Dim Dim BotonSeleccion1() oFormulario As Object oBotonSeleccion As Object oBotonSeleccionModelo As Object

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oBotonSeleccion = ThisComponent.createInstance("com.sun.star.drawing.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oBotonSeleccion, 4000, 700 ) Call CambiaPos( oBotonSeleccion, 3000, 15000 ) 'Creamos un nuevo botón de selección oBotonSeleccionModelo = ThisComponent.createInstance("com.sun.star.form.component.SpinButton") 'Establecemos su nombre oBotonSeleccionModelo.Name = "spnEdad" 'Conectamos la forma con el nuevo control oBotonSeleccion.Control = oBotonSeleccionModelo 'Lo agregamos al formulario oFormulario.insertByIndex(0, oBotonSeleccionModelo) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent.getCurrentController.getActiveSheet.getDrawPage.add( oBotonSeleccion ) End Sub

Las principales propiedades de este control son.
Sub BotonSeleccion2() Dim oFormulario As Object Dim ospnEdad As Object oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) ospnEdad = oFormulario.getByName("spnEdad") With ospnEdad .BackGroundColor = RGB(Rnd*255,Rnd*255,Rnd*255) .Border = 2 .BorderColor = RGB(Rnd*255,Rnd*255,Rnd*255) .Orientation = 1 .Printable = True .SymbolColor = RGB(Rnd*255,Rnd*255,Rnd*255) .SpinValueMin = 0 .SpinValueMax = 20 .SpinIncrement = 2 End With End Sub 'Color de fondo 'Tipo de borde ( 2 = Plano, 1 = 3D ) 'Color del borde, solo si Border = 2 'Orientación 1 = vertical, 0 = horizontal 'Si se imprime el control 'Color del símbolo (las flechas) 'Valor mínimo 'Valor máximo 'Incremento

De forma predeterminada, el control se agrega en forma horizontal, si cambias su orientación (Orientation) a vertical, tienes que cambiar su tamaño, de forma que quede más alto

Aprendiendo OOo Basic

459

que ancho, si no, veras un control totalmente desajustado. Para obtener el valor actual del control, usamos.
Sub BotonSeleccion3() Dim oFormulario As Object Dim ospnEdad As Object oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) ospnEdad = oFormulario.getByName("spnEdad") MsgBox "Valor actual del control = " & ospnEdad.spinValue End Sub

Este control acepta la vinculación con una celda (ValueBinding), así como la activación y desactivación (Enabled), también el envío del foco, así como ocultarlo, recordando que estas dos ultimas propiedades, están accesibles desde el modo “vista” del control.

7.11

Barra de desplazamiento (ScrollBar)

Este control es muy similar al botón de selección (SpinButton), pero se usa para desplazamientos más grandes, por que tiene una área para de trabajo más grande, para agregar una a nuestro formulario, usamos el siguiente código.
Sub Dim Dim Dim BarraDesplazamiento1() oFormulario As Object oBarraDesplazamiento As Object oBarraDesplazamientoModelo As Object

oFormulario = ThisComponent.getCurrentController.getActiveSheet.getDrawPage.getForms.getByName( "MiDirectorio" ) 'Creamos una nueva forma de control oBarraDesplazamiento = ThisComponent.createInstance("com.sun.star.drawing.ControlShape") 'Cambiamos su tamaño y posicion Call CambiaTam( oBarraDesplazamiento, 10000, 700 ) Call CambiaPos( oBarraDesplazamiento, 3000, 15000 ) 'Creamos una nueva barra de desplazamiento oBarraDesplazamientoModelo = ThisComponent.createInstance("com.sun.star.form.component.ScrollBar") 'Establecemos su nombre oBarraDesplazamientoModelo.Name = "sbKm" 'Conectamos la forma con el nuevo control oBarraDesplazamiento.Control = oBarraDesplazamientoModelo 'Lo agregamos al formulario oFormulario.insertByIndex(0, oBarraDesplazamientoModelo) 'Agregamos la forma a la página de dibujo para que sea visible ThisComponent.getCurrentController.getActiveSheet.getDrawPage.add( oBarraDesplazamiento ) End Sub

se tienen que establecer desde el modo “vista” del control. Sub BarraDesplazamiento2() Dim oFormulario As Object Dim osbKm As Object oFormulario = ThisComponent.getActiveSheet.11 Barra de desplazamiento (ScrollBar) Sus propiedades son muy similares al botón de selección (SpinButton).BlockIncrement = 25 .ScrollValueMin = 1 . .getForms.getByName( "MiDirectorio" ) osbKm = oFormulario.getForms. como se muestra en la siguiente imagen.getDrawPage. 7. el envío del foco.getCurrentController. son los controles estándar presentes en los formularios. usamos. pero existen otro conjunto de controles que podemos usar y a los cuales tenemos acceso desde la barra de herramientas “Campos de control de formulario”.getByName( "MiDirectorio" ) osbKm = oFormulario.getDrawPage. veamos las propiedades particulares de este control.460 7. Para conocer el valor actual de la barra de desplazamiento.12 Otros controles Hasta aquí.getByName("sbKm") With osbKm .ScrollValueMax = 1000 End With End Sub 'Cambio grande 'Cambio pequeño 'Valor mínimo 'Valor máximo El cambio grande (BlockIncrement) se da cuando presionamos un área libre de la barra de desplazamiento y el cambio pequeño (LineIncrement) cuando presionamos las flechas de los extremos. así como ocultarlo.LineIncrement = 5 .getByName("sbKm") MsgBox "Valor actual = " & osbKm.getActiveSheet.getCurrentController. así como la activación y desactivación (Enabled). Sub BarraDesplazamiento3() Dim oFormulario As Object Dim osbKm As Object oFormulario = ThisComponent.ScrollValue End Sub Este control acepta la vinculación con una celda (ValueBinding).

insertByIndex(0.jpg") 'La ruta de la imagen a mostrar .Name = "ibFoto" oNuevoControl.getActiveSheet.1 Botón gráfico (ImageButton) Este control nos permite tener una imagen como fondo de el.getCurrentController.createInstance("com. así como hacerlo invisible o enviarle el foco.component. 2000.getForms.form. podemos habilitar o deshabilitarlo. 7.drawing.getCurrentController.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.getCurrentController.getDrawPage. oNuevoControlModelo) ThisComponent. 5000 ) Call CambiaPos( oNuevoControl.getDrawPage. 5000.getDrawPage.sun.getByName( "MiDirectorio" ) oControl = oFormulario.ImageButton") oNuevoControlModelo.add( oNuevoControl ) End Sub Y sus principales propiedades. .getForms.getActiveSheet.createInstance("com.sun.ScaleMode = 2 'El modo de escalar ( 2 = Ajustar al control) End With End Sub En su modo “vista”. veamos las principales características de cada uno.star.Aprendiendo OOo Basic 461 Estos controles amplían las posibilidades para mostrar y controlar nuestros datos. Sub Dim Dim Dim BotonGrafico1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.getActiveSheet. 17000 ) 'Agregamos un nuevo botón gráfico oNuevoControlModelo = ThisComponent. Sub BotonGrafico2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.getByName("ibFoto") With oControl .star.ScaleImage = True 'Si se va a escalar la imagen .Control = oNuevoControlModelo oFormulario.12.ImageURL = ConvertToURL("/home/mau/foto.ControlShape") Call CambiaTam( oNuevoControl.

sun.getForms.getActiveSheet.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.star.462 7.sun. si el campo es una imagen.getActiveSheet.jpg") 'La ruta de la imagen a mostrar .getCurrentController.getDrawPage. 6000.star.getDrawPage.getActiveSheet. 7. 6000 ) Call CambiaPos( oNuevoControl.getByName("icProductos") With oControl .getDrawPage. deshabilitarlo y hacerlo invisible.3 Selección de archivo (FileSelection) Control que nos permite mostrar el cuadro de dialogo común para seleccionar un archivo. oNuevoControlModelo) ThisComponent.Name = "icProductos" oNuevoControl. Sub ControlImagen2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.component.getByName( "MiDirectorio" ) oControl = oFormulario.getCurrentController.createInstance("com. .insertByIndex(0. Sub Dim Dim Dim ControlImagen1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.12. 2000.12 Otros controles 7.Control = oNuevoControlModelo oFormulario.ImageURL = ConvertToURL("/home/mau/foto.add( oNuevoControl ) End Sub Puedes asignarle una imagen de forma dinámica.ControlShape") Call CambiaTam( oNuevoControl. no el archivo en si.ScaleMode = 2 'El modo de escalar ( 2 = Ajustar al control) End With End Sub En el modo “vista”. puedes enviarle el foco. usamos.getCurrentController.getForms.createInstance("com. es que a este control le puedes asignar el campo de una fuente de datos (DataField).ScaleImage = True 'Si se va a escalar la imagen . la mostrará en el control.drawing.2 Control de imagen (ImageControl) Este control es muy similar al botón gráfico (ImageButton). Para agregar uno al formulario.DatabaseImageControl") oNuevoControlModelo. la diferencia. para agregar un nuevo control.12. 18000 ) 'Agregamos un nuevo control de imagen oNuevoControlModelo = ThisComponent.form. usamos. solo te devuelve la ruta del archivo.

ControlShape") Call CambiaTam( oNuevoControl.DefaultText = "/home/mau" End Sub Para devolver el archivo seleccionado.getForms.getActiveSheet. puedes establecer una ruta por default.getCurrentController.Name = "fcArchivo" oNuevoControl.component.sun.createInstance("com.12.getActiveSheet.getByName("fcArchivo") MsgBox "Archivo seleccionado: " & oControl. color.getByName( "MiDirectorio" ) oControl = oFormulario.createInstance("com.star.getDrawPage.getActiveSheet.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.form.FileControl") oNuevoControlModelo. cuando se abra el dialogo. se abrirá en este directorio. Sub SeleccionArchivo3() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.Aprendiendo OOo Basic Sub Dim Dim Dim SeleccionArchivo1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object 463 oFormulario = ThisComponent. se usa su propiedad Text. 10000. 2000.getDrawPage.getCurrentController. puedes usar la mayor parte de las propiedades vistas para los controles que aceptan cadenas (fuente. tamaño. oNuevoControlModelo) ThisComponent.getByName("fcArchivo") oControl.insertByIndex(0.sun.getByName( "MiDirectorio" ) oControl = oFormulario. de este modo.4 Campo de fecha (DateField) Este control nos permite trabajar con fechas de una forma muy sencilla.getForms.star.getDrawPage. 18000 ) 'Agregamos un nuevo control de selección de archivo oNuevoControlModelo = ThisComponent.drawing.Control = oNuevoControlModelo oFormulario. 700 ) Call CambiaPos( oNuevoControl. 7.Text End Sub Puede recibir el foco y hacerse invisible a través del modo “vista”.getForms. incluso podemos mostrar un calendario para seleccionar fechas. .getCurrentController. etc). Se agrega de la siguiente manera. Sub SeleccionArchivo2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.getActiveSheet.getCurrentController.getDrawPage.add( oNuevoControl ) End Sub Al contar con un área de texto.

si no.createInstance("com.drawing. Veamos las propiedades particulares de este control. después el mes y por ultimo el día.getDrawPage. La propiedad para establecer el formato (DateFormat).getActiveSheet. permite al usuario mostrar un calendario para seleccionar la fecha.getDrawPage.getByName( "MiDirectorio" ) oControl = oFormulario.getActiveSheet.getByName("dfNacimiento") With oControl . si las vas a establecer de forma dinámica.12 Otros controles Sub Dim Dim Dim CampoFecha1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.getCurrentController.DateMin = 19000101 . pero primero va el año.add( oNuevoControl ) End Sub Al ser un campo con texto.insertByIndex(0.sun.getCurrentController.Name = "dfNacimiento" oNuevoControl.Control = oNuevoControlModelo oFormulario. 2000.form. te dará fechas erróneas.Dropdown = True .star.Spin = True End With End Sub 'Fecha mínima 'Fecha máxima 'Formato mostrado 'Si es desplegable 'Si muestra el campo giratorio Observa la forma “sui generis” de establecer los valores de las propiedades para el valor de la fecha mínima (DateMin) y máxima (DateMax) del control.DateFormat = 0 .DateMax = 20091231 .createInstance("com.component.DateMax = Format(Now.getForms. en formato de fecha pero no deja de ser texto. 5000.sun.DateField") oNuevoControlModelo.star. cuenta con toda las propiedades para manipularlo (color. 18000 ) 'Agregamos un nuevo campo de fecha oNuevoControlModelo = ThisComponent. oNuevoControlModelo) ThisComponent. Sub CampoFecha2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.getForms. es un número.getActiveSheet.464 7. puedes hacerlo a través de una cadena (string).getCurrentController.ControlShape") Call CambiaTam( oNuevoControl.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent. 700 ) Call CambiaPos( oNuevoControl. etc). tamaño. pero tienes que darle el formato exacto. fuente. .getDrawPage. ya vistas en otros controles. puedes tomar los siguientes valores enteros: ."YYYYMMDD") La propiedad para mostrar la flecha desplegable (Dropdown).

Aprendiendo OOo Basic 465 Nombre Estándar (corto) Valor 0 Ejemplo 20/09/09 .

getByName("dfNacimiento") 'Devuelve la fecha seleccionada como número MsgBox oControl.Date 'Devuelve el contenido del control como texto MsgBox oControl. pero más adelante aprenderemos a hacerlo directamente con código. pero no implementa la posibilidad de vincularlo a una celda. veamos como agregar uno nuevo en nuestro formulario.getByName( "MiDirectorio" ) oControl = oFormulario. Sub CampoFecha3() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.466 7. esto será en función de tus necesidades.5 Campo de hora (TimeField) Este control es muy similar al campo de fecha (DateField) pero para manejar valores de hora. 7.getForms. te será más conveniente usar una u otra forma.Text End Sub Dependiendo del formato que hayas establecido. En su modo de “vista”.getActiveSheet. Sub Dim Dim Dim CampoHora1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object .getDrawPage. puedes activarlo o desactivarlo (Enabled) y hacerlo invisible. Puedes vincularlo a un campo de datos origen (DataField).12.getCurrentController.12 Otros controles Nombre Estándar (corto YY) Estándar (corto YYYY) Estándar (largo) DD/MM/YY MM/DD/YY YY/MM/DD DD/MM/YYYY MM/DD/YYYY YYYY/MM/DD YY-MM-DD YYYY-MM-DD Valor 1 2 3 4 5 6 7 8 9 10 11 Ejemplo 20/09/09 20/09/2009 domingo 20 de septiembre de 2009 20/09/09 09/20/09 09/09/20 20/09/2009 09/20/2009 2009/09/20 09-09-20 2009-09-20 Para obtener la fecha actual del control puedes hacerlo de dos maneras.

pero no implementa la posibilidad de vincularlo a una celda.Aprendiendo OOo Basic 467 oFormulario = ThisComponent.getDrawPage. Para recuperar el valor actual del control. 20000 ) 'Agregamos un nuevo campo de hora oNuevoControlModelo = ThisComponent.getForms.Text End Sub En su modo de “vista”.getDrawPage.getByName("tfEntrada") 'Devuelve la fecha seleccionada como número MsgBox oControl.Name = "tfEntrada" oNuevoControl.ControlShape") Call CambiaTam( oNuevoControl.Time 'Devuelve el contenido del control como texto MsgBox oControl.createInstance("com. oNuevoControlModelo) ThisComponent. tiene que ser HoraMinutosSegundos. 5000.star.getCurrentController. Sub CampoHora2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.getByName( "MiDirectorio" ) oControl = oFormulario. Sub CampoHora3() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent. el formato solo acepta cuatro valores.component.getActiveSheet. tienes dos opciones.getCurrentController.sun. formato 24 horas con segundos (1).createInstance("com. Puedes vincularlo a un campo de datos origen (DataField).getDrawPage.getActiveSheet.star.getCurrentController.getCurrentController.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.getDrawPage.add( oNuevoControl ) End Sub Y sus propiedades particulares.form.Spin = True End With End Sub 'La hora mínima 8:30 'La hora máxima 15:00 '24 hr con segundos 'Muestra el control giratorio El formato para la hora mínima (TimeMin) y máxima (TimeMax).sun. formato 12 horas sin segundos (3) y formato 12 horas con segundos (4). y los segundos debe ser cuatro dígitos.drawing. puedes activarlo o desactivarlo (Enabled) y hacerlo invisible.getByName("tfEntrada") With oControl .getActiveSheet.TimeField") oNuevoControlModelo.getForms. .insertByIndex(0.getByName( "MiDirectorio" ) oControl = oFormulario.TimeMax = 15000000 .getActiveSheet.getForms.TimeFormat = 1 . 2000. formato 24 horas sin segundos (0). 700 ) Call CambiaPos( oNuevoControl.Control = oNuevoControlModelo oFormulario.TimeMin = 8300000 .

star.getDrawPage. en el siguiente ejemplo agregamos un nuevo control al formulario. oNuevoControlModelo) ThisComponent.ValueMin = 100 .ShowThousandsSeparator = True .drawing.Spin = True .Control = oNuevoControlModelo oFormulario.getDrawPage. Las propiedades particulares de este control son: Sub CampoNumerico2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.12.getForms.ControlShape") Call CambiaTam( oNuevoControl.getDrawPage. Sub CampoNumerico3() Dim oFormulario As Object Dim oControl As Object .insertByIndex(0.getCurrentController.getActiveSheet.component. Sub Dim Dim Dim CampoNumerico1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.getActiveSheet.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.getCurrentController. fuente.sun. comparten un mínimo de propiedades (color. 2000.createInstance("com.add( oNuevoControl ) End Sub Recuerda que todos los controles donde se muestre información al usuario.sun.NumericField") oNuevoControlModelo.468 7.form.ValueStep = 2 .DecimalAccuracy = 2 End With End Sub 'El 'El 'El 'Si 'Si 'El valor mínimo valor máximo salto entre valores muestra el control giratorio muestra el separador de miles número de decimales El separador de miles (ShowThousandsSeparator). 700 ) Call CambiaPos( oNuevoControl.getForms.getActiveSheet. será el mismo configurado en la interfaz del OOo.ValueMax = 500 . 20000 ) 'Agregamos un nuevo campo numérico oNuevoControlModelo = ThisComponent. 5000.createInstance("com.getByName( "MiDirectorio" ) oControl = oFormulario.Name = "nfPesos" oNuevoControl.getByName("nfPesos") With oControl . etc).12 Otros controles 7.getCurrentController.6 Campo numérico (NumericField) Este control permite manejar únicamente números.star.

ShowThousandsSeparator = True 'El símbolo de moneda 'Muestra el símbolo a la izquierda 'El valor mínimo 'El valor máximo 'El salto entre valores 'Si muestra el control giratorio 'Si muestra el separador de miles .getDrawPage. Para agregar un control de este tipo a nuestro formulario.getByName( "MiDirectorio" ) oControl = oFormulario.add( oNuevoControl ) End Sub Las propiedades particulares de este control son.getDrawPage. 20000 ) 'Agregamos un nuevo campo moneda oNuevoControlModelo = ThisComponent.7 Campo moneda (CurrencyField) Este control es casi idéntico al campo numérico (NumericField).getActiveSheet.insertByIndex(0. 7.ControlShape") Call CambiaTam( oNuevoControl. así como con un campo de datos.getCurrentController.getCurrentController.PrependCurrencySymbol = True .ValueStep = 5 . 2000.CurrencyField") oNuevoControlModelo.Aprendiendo OOo Basic 469 oFormulario = ThisComponent.getByName("cfIngresos") With oControl .getByName("nfPesos") 'Devolvemos el valor del control MsgBox "El valor actual del control es = " & oControl.Control = oNuevoControlModelo oFormulario.getActiveSheet.createInstance("com. Sub Dim Dim Dim CampoMoneda1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.createInstance("com.12.form.getCurrentController.ValueMin = 0 . 700 ) Call CambiaPos( oNuevoControl. Sub CampoMoneda2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent. con al diferencia de que puede mostrar un símbolo de moneda en su formato.getForms.Name = "cfIngresos" oNuevoControl.getDrawPage.star.sun.CurrencySymbol = "B$" .ValueMax = 1000 .Spin = True .getForms.sun.Value End Sub Este control si acepta la vinculación con una celda.getDrawPage.getForms. oNuevoControlModelo) ThisComponent.getCurrentController. 5000.getByName( "MiDirectorio" ) oControl = oFormulario.getActiveSheet.getActiveSheet.component. usamos el siguiente código.drawing.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.star.

getCurrentController. Sub CampoEnmascarado2() Dim oFormulario As Object .getByName("cfIngresos") 'Devolvemos el valor del control MsgBox "El valor actual del control es = " & oControl.ControlShape") Call CambiaTam( oNuevoControl.getActiveSheet.createInstance("com.8 Campo enmascarado (PatternField) Este control permite establecer una mascara de entrada para los datos del usuario.sun.getForms.getDrawPage.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.getActiveSheet.470 . Sub CampoMoneda3() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.Value End Sub Este control solo acepta el vinculo con un campo de datos.insertByIndex(0.12. 5000.getForms. oNuevoControlModelo) ThisComponent.getActiveSheet.sun. 20000 ) 'Agregamos un nuevo campo enmascarado oNuevoControlModelo = ThisComponent. 2000.Control = oNuevoControlModelo oFormulario.star. Sub Dim Dim Dim CampoEnmascarado1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent. pues permite limitar de forma muy estricta lo que este captura.drawing.star.component.DecimalAccuracy = 2 End With End Sub 'El número de decimales 7.12 Otros controles Para recuperar el valor actual del control usamos.createInstance("com. usamos. para agregar uno a nuestro formulario.PatternField") oNuevoControlModelo.getCurrentController.Name = "pfRFC" oNuevoControl. 700 ) Call CambiaPos( oNuevoControl.getCurrentController.getDrawPage.getByName( "MiDirectorio" ) oControl = oFormulario.form. 7. es muy útil en entornos con usuarios con poca experiencia.getDrawPage.add( oNuevoControl ) End Sub Este control tiene pocas propiedades particulares. pero son vitales para su correcto funcionamiento.

getByName("pfRFC") With oControl .getActiveSheet. Se permiten letras de la A a la Z. de acuerdo a la siguiente tabla. es esencial que trabajen todas juntas. se respetan mayúsculas y minúsculas.LiteralMask = "____-______-___" . 0 a 9. Se permiten todos los caracteres imprimibles. para que funcione el control de formato (StrictFormat) debe estar en verdadero esta propiedad. el cursor pasa al siguiente caracter editable. En la mascará de entrada (EditMask) determinamos que puede y que no puede capturar el usuario en esa exacta posición del caracter. Solo se permiten los números dígitos.EditMask = "AAAALNNNNNNLCCC" . la primera es autodescriptiva pero es muy importante que tenga la longitud exacta de la mascara de entrada (EditMask) y de la mascara de caracteres (LiteralMask).StrictFormat = True End With End Sub 'Longitud máxima del contenido 'Mascara de entrada 'Mascara de caracteres 'Control de formato Estas cuatro propiedades.getForms.Text .getByName( "MiDirectorio" ) oControl = oFormulario.MaxTextLen = 15 . y todos los dígitos. todas las letras pasan a mayúsculas.getForms. usamos.Aprendiendo OOo Basic Dim oControl As Object 471 oFormulario = ThisComponent. 0-9. Se permiten letras de la A a la Z.getCurrentController. 0-9. mientras no capture nada en las respectivas posiciones. Caracter L a A c C N X Restricción El caracter de esta posición. Se permiten letras de la A a la Z. al llegar a esta posición. todas se convierten a mayúsculas.getByName("pfRFC") MsgBox "Valor actual del control: " & oControl. se muestra tal cual. La mascara de caracteres. Posición Mascara de entrada Mascara de caracteres 123456789012345 AAAALNNNNNNLCCC ____-______-___ Para regresar el valor capturado.getDrawPage.getDrawPage. Se permiten letras de la A a la Z. es lo que ve el usuario. no puede editarse.getByName( "MiDirectorio" ) oControl = oFormulario. se respetan mayúsculas y minúsculas.getActiveSheet.getCurrentController. y todos los dígitos. Sub CampoEnmascarado3() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.

add( oNuevoControl ) End Sub Para establecer el titulo del control usamos.getByName( "MiDirectorio" ) oControl = oFormulario.12.GroupBox") oNuevoControlModelo.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.sun. 5000 ) Call CambiaPos( oNuevoControl.getDrawPage.ControlShape") Call CambiaTam( oNuevoControl.component.getForms.getCurrentController.getActiveSheet. 7. usamos.getActiveSheet. por ahora solo funciona en tiempo de diseño y el asistente de controles debe . 20000 ) 'Agregamos un nuevo campo enmascarado oNuevoControlModelo = ThisComponent.drawing.Name = "gbEstadoCivil" oNuevoControl.getDrawPage. oNuevoControlModelo) ThisComponent. generalmente se usa con grupos de botones de opción (OptionButton) aunque los puedes usar con cualquier otro grupo de controles.getActiveSheet.sun.Control = oNuevoControlModelo oFormulario. Para agregar uno al formulario.Label = "Estado civil" End Sub 7.12.472 7. 2000.getByName("gbEstadoCivil") 'Establecemos el titulo del control oControl.getForms. Sub CuadroGrupo2() Dim oFormulario As Object Dim oControl As Object oFormulario = ThisComponent.12 Otros controles End Sub Este control soporta la vinculación con un campo de datos (DataField).star.9 Cuadro de grupo (GroupBox) Este control solo es de apoyo visual para enmarcar otros grupos de controles. 5000.getCurrentController.createInstance("com. Sub Dim Dim Dim CuadroGrupo1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.star.getDrawPage.10 Control de tablas (TableControl) Este control nos permite mostrar una tabla.getCurrentController. consulta o instrucción SQL para enlazar bases de datos.form.insertByIndex(0.createInstance("com.

por ahora.add( oNuevoControl ) End Sub Las propiedades particulares de este control son. oNuevoControlModelo) ThisComponent. 25000 ) 'Agregamos un nuevo campo enmascarado oNuevoControlModelo = ThisComponent.createInstance("com.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent.add( oNuevoControl ) End Sub 7.ControlShape") Call CambiaTam( oNuevoControl.12.insertByIndex(0. 10000 ) Call CambiaPos( oNuevoControl. para agregar una al formulario. 3000.component. Sub Dim Dim Dim BarraNavegacion1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.createInstance("com.sun.getCurrentController.form.getDrawPage.star. 20000 ) 'Agregamos un nuevo campo enmascarado oNuevoControlModelo = ThisComponent. cuando el formulario esta enlazado a una base de datos. para agregarla al formulario usamos.getForms.NavigationToolBar") oNuevoControlModelo.getCurrentController. usamos el siguiente código.Control = oNuevoControlModelo oFormulario. pero.getCurrentController.getActiveSheet. Sub Dim Dim Dim TablaControl1() oFormulario As Object oNuevoControl As Object oNuevoControlModelo As Object oFormulario = ThisComponent.sun.getDrawPage. oNuevoControlModelo) ThisComponent.Name = "navBarra" oNuevoControl.11 Barra de navegación Este control permite.getActiveSheet. controlar la navegación entre los registros. 20000.Control = oNuevoControlModelo oFormulario.getActiveSheet.getForms.Name = "gcContactos" oNuevoControl.sun.star.ControlShape") Call CambiaTam( oNuevoControl. Sub BarraNavegacion2() Dim oFormulario As Object Dim oControl As Object .getDrawPage.drawing.getDrawPage.getByName( "MiDirectorio" ) oNuevoControl = ThisComponent. el formulario previamente debe estar enlazado con los datos origen.drawing.Aprendiendo OOo Basic 473 estar activado.getCurrentController.star.createInstance("com.sun. no podrás enlazarlo por código.createInstance("com.star. 3000.insertByIndex(0.component.getActiveSheet.form. 1000 ) Call CambiaPos( oNuevoControl. 10000.GridControl") oNuevoControlModelo.

te permite. tu decides que es lo que más te conviene.12 Otros controles oFormulario = ThisComponent.getDrawPage. esto te permite un mayor control de los datos.ShowPosition = True 'Muestra la información actual del cursor .getByName("navBarra") With oControl .Border = 2 'Borde plano .474 7.TextColor = RGB(Rnd*255.getCurrentController.getByName( "MiDirectorio" ) oControl = oFormulario.Rnd*255. el icono para manipular los registros (ShowRecordActions). y trabajo. pero requiere.ShowNavigation = True 'Muestra las flechas de navegación . nos será de mucha utilidad para el siguiente. casi todo el conocimiento adquirido en este capitulo. en ocasiones es útil deshabilitar estos y controlar estas acciones por código.ShowRecordActions = True 'Muestra los iconos para manipular registros . solo veras un marco sin ninguna utilidad. por supuesto. hemos visto la forma de agregarlos por código y manipular las principales propiedades de cada uno.Rnd*255) 'Color de fondo . Con esto terminamos con el manejo de formularios y sus controles.BackgroundColor = RGB(Rnd*255.IconSize = 0 'Pequeño = 0. editar y borrar registros. generalmente se muestran los cuatro.Rnd*255. . Grande = 1 .getForms. agregar. muchas más líneas de código.Rnd*255) 'Color de texto . también.ShowFilterSort = True 'Muestra los iconos para ordenar y filtrar End With End Sub Si estableces las ultimas cuatro propiedades en falso (False). en donde aprenderemos el manejo de cuadros de diálogo.getActiveSheet.

Aprendiendo OOo Basic 475 8 Trabajando con cuadros de dialogo .

tiene que responder a la pregunta ¿cuando?. . ¿cuando queremos que se ejecute una macro?.476 9 Trabajando con eventos 9 Trabajando con eventos Hemos llegado a un tema central en la programación de OOo. central por que una gran parte de la programación en OOo.

Aprendiendo OOo Basic 477 10 Apéndices 10. ve al menú Herramientas | Opciones. por ello. para los fines didácticos de estos apuntes.. . queda a tu criterio establecer el nivel adecuado para tu área y entorno de trabajo. El nivel de confianza es bastante explicito y creo que no requiere aclaraciones. es decir.. selecciona la rama Seguridad y dentro de las opciones mostradas.org. da un clic en el botón de comando Seguridad de macro. Para establecer el nivel de seguridad de las macros.. dentro de la sección OpenOffice. no tomes como un tema menor el de la seguridad. el nivel Medio es más que suficiente. el limite para lo que se puede hacer con macros es solo tu conocimiento y tu imaginación.. asegúrate de que las macros que estás activando y ejecutando sean de una fuente confiable.1 Seguridad en macros Como ya lo habrás notado.

puedes agregar su ubicación como un origen de confianza. puedes agregar tantas rutas como quieras. Cuidado con esto. en el mismo cuadro de dialogo anterior pero en la ficha Orígenes de Confianza.478 10.1 Seguridad en macros Si no quieres que te muestre el cuadro de dialogo de confirmación cada vez que abres tu archivo de trabajo. . asegurate de establecer solo rutas de verdadera confianza. desde las cuales. como dicen en mi pueblo -sobre advertencia no hay engaño-. se abrirán los archivos con las macros activadas de forma predeterminada sin pedirte confirmación.

10.2 Errores más comunes en tiempo de diseño Como ya explicamos en el tema 4. tampoco llamarla sin los argumentos correctos: . espero que los títulos sean lo suficientemente claro para tu consulta: ● No puede haber una macro sin nombre ● Toda macro debe cerrarse con End Sub ● No puede haber dos macro o funciones con el mismo nombre ● No puedes ejecutar directamente una macro que requiera argumentos ● Por supuesto. para estos ejemplos.Aprendiendo OOo Basic 479 10. este tipo de errores solo se producen mientras programamos y en ese momento hay que corregirlos. esta es una lista incompleta de los más comunes. solo te mostrare la imagen del código con el error.

480 10.2 Errores más comunes en tiempo de diseño .

si no lo haces no te dará un error y puedes quedar dentro de un bucle infinito ● . siempre debe cerrarse con Loop. recuerda que también termina en Then La estructura Do. aquí falta Then al If ● Por supuesto también debe llevar su correspondiente End If ● Si usas ElseIf. tienes que declara todas tus variables. sino ● ● Todas las estructuras deben ir completas.Aprendiendo OOo Basic 481 Si usas Option Explicit (como “debe” ser). te cuidado de establecer siempre la condición de terminación del bucle.

2 Errores más comunes en tiempo de diseño ● La estructura Select debe terminar en Case ● Y no te olvides de establecer la variable a evaluar ● Y cerrar con su respectivo End Select ● Los ciclos For. deben estar completa. con su correspondiente To ● Y su respectivo Next .482 10.

es decir. sobrepasar los limites que acepta un tipo de dato ● Debes de declarar las correspondientes etiquetas en On Error Goto y Goto ● La macro o función llamada debe existir . tienes que establecer correctamente el tipo de información que guardas en estas variables ● Este es muy común.Aprendiendo OOo Basic ● 483 Se requiere el uso de Dim para declarar variables ● Algunos datos no soportan la conversión de datos implícita.

For o Function y dentro de la estructura correspondiente correcta ● Otra muy común.2 Errores más comunes en tiempo de diseño ● No puedes hacer referencia al indice de una matriz fuera de sus rangos declarados ● No puedes.484 10. tienes que llamarlas con sus correctos argumentos ● . todas las instrucciones y funciones de OOo Basic. Do. con su correspondiente predicado Sub. dentro de la misma macro. definir dos vece la misma variable ● No puedes dividir por cero Debes de usar la instrucción Exit.

en nuestro caso usaremos la versión para Linux.1.html Tienes que seleccionar el archivo correcto para tu sistema operativo.org http://download.openoffice.Aprendiendo OOo Basic 485 10.3 Instalando SDK Lo primero que necesitamos es descargarlo desde la página de OpenOffice. .0/sdk.org/3.

Muévete hasta el directorio recién creado y veras una carpeta que se llama DEBS (o RPMS seǵun el que hayas descargado). de lo contrario te dirá que ya existe y no te descompactara el archivo. etc).1. así que dale una ruta sencilla o donde te sea cómodo encontrarlo. no necesitas derechos de administrador: Como notaras te pide un directorio.0-11_amd64.deb O desde una interfaz gráfica si tu distribución la implementa: . OpenSuse.1.0-11_amd64.0-11_amd64. etc).3 Instalando SDK Para instalar sigue leyendo: Desde una terminal ve hasta la ubicación donde descargaste el archivo anterior y ejecutalo. puedes instalar desde la línea de comandos: sudo dpkg -i ooobasis3. dentro de ella el archivo ooobasis3. tienes que darle un directorio nuevo. es un archivo para instalar.1-sdk_3. si tienes una distribución que soporte RMPs (Fedora. Debian.1.1-sdk_3. que sabes. esto es solo para descomprimir el archivo. lo instalas con: rpm -i ooobasis3.486 10.deb.1-sdk_3.rpm Si tienes una distribución que use DEBs (Ubuntu.

tendrás la referencia completa del API de OpenOffice.1/sdk/index.org .html Donde. entre otras herramientas y ejemplos.Aprendiendo OOo Basic 487 Ahora puedes abrir tu navegador favorito y abrir el archivo file:///opt/openoffice/basis3.

Len(sTmp)-1 ) oDoc.4 Mostrar información de un objeto en un archivo de Calc Sub Dim Dim Dim Dim Dim ObtenerDatos( Objeto As Object ) sRuta As String oDoc As Object mArg() a1() As String. Len(sTmp)-1 ) oDoc.DBG_Methods. sTmp As String sRuta = "private:factory/scalc" oDoc = StarDesktop." ) oDoc.DBG_SupportedInterfaces.setString( a1(0) ) For co1 = LBound( a2 ) To UBound( a2 ) sTmp = Trim(a2(co1)) If Left( sTmp.getCellByPosition( 0. co1+1 ).getByIndex(0).Sheets().Sheets(). ":" ) a2 = Split( Trim(a1(1)). 1) = Chr(10) Then sTmp = Right( sTmp. co1+1 ).Sheets().getByIndex(0).setString( a1(0) ) For co1 = LBound( a2 ) To UBound( a2 ) sTmp = Trim(a2(co1)) If Left( sTmp.mArg ) a1 = Split( Objeto.setString( sTmp ) Next co1 End Sub Asegurate de pasarle como parámetro una variable de objeto.getByIndex(0). Sub Pruebas Dim obj As Object obj = ThisComponent Call ObtenerDatos ( obj ) End Sub ." ) oDoc.Sheets().Sheets(). a2() As String co1 As Integer. Chr(10) ) oDoc. Len(sTmp)-1 ) oDoc.getCellByPosition( 0. 0 ). ".4 Mostrar información de un objeto en un archivo de Calc 10. ". 0 ).Sheets(). 0 ).488 10. ":" ) a2 = Split( Trim(a1(1)). 1) = Chr(10) Then sTmp = Right( sTmp.Sheets().setString( a1(0) ) For co1 = LBound( a2 ) To UBound( a2 ) sTmp = Trim(a2(co1)) If Left( sTmp. Len(sTmp)-1 ) oDoc. co1 ).getByIndex(0).getByIndex(0). si el objeto no implementa métodos. Len(sTmp)-1 ) oDoc.getCellByPosition( 2.setString( sTmp ) a1 = Split( Objeto. 1) = Chr(10) Then sTmp = Left( sTmp.getCellByPosition( 1.getCellByPosition( 0. co1 ).DBG_Properties.Sheets().0. ":" ) a2 = Split( Trim(a1(1)).getByIndex(0).setString( sTmp ) Next co1 If Right( sTmp. co1 ). 1) = Chr(10) Then sTmp = Right( sTmp.getCellByPosition( 1. 1) = Chr(10) Then sTmp = Left( sTmp.setString( sTmp ) a1 = Split( Objeto.getByIndex(0). pero te creará el archivo con al menos las propiedades que implementa.LoadComponentFromURL( sRuta.getByIndex(0). la macro te dará un error y se detendrá.setString( sTmp ) Next co1 If Right( sTmp.getCellByPosition( 1."_default".getCellByPosition( 2.

A.sun.addin.addin.sun.sun.addin.Analysis.DEC BIN.sheet.addin.addin.sheet.A.star.sheet.getBessely com.addin.5 Formulas de Calc español-ingles Nº 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 Español ABS ACOS ACOSH ACOT ACOTH ACTUAL AHORA ALEATORIO ALEATORIO.Analysis.getReceived CHAR CELL .addin.Analysis.RECIBIDA CARÁCTER CELDA Ingles ABS ACOS ACOSH ACOT ACOTH CURRENT NOW RAND com.sheet.PROGRE AMORTIZACION AÑO AÑOS ÁRABE ÁREAS ASC ASENO ASENOH ATAN ATAN2 ATANH B BAHTTEXT BASE BDCONTAR BDCONTARA BDDESVEST BDDESVESTP BDEXTRAER BDMAX BDMIN BDPRODUCTO BDPROMEDIO BDSUMA BDVAR BDVARP BESSELI BESSELJ BESSELK BESSELY BIN.sun.star.star.addin.getBesselj com.sheet.getBin2Oct CRITBINOM LOOKUP HLOOKUP VLOOKUP com.LIN AMORTIZ.addin.addin.Analysis.sun.Analysis.getAmordegrc PPMT YEAR com.CRIT BUSCAR BUSCARH BUSCARV CANTIDAD.getAmorlinc com.addin.sheet.sheet.getRandbetween com.A.sun.getBesseli com.getBesselk com.sun.HEX BIN.Analysis.Analysis.getBin2Dec com.star.sun.DateFunctions.sheet.star.star.ENTRE AMORTIZ.OCT BINOM.Analysis.sun.Analysis.sheet.sheet.star.addin.sun.sun.star.Aprendiendo OOo Basic 489 10.sun.getBin2Hex com.getDiffYears ARABIC AREAS ASC ASIN ASINH ATAN ATAN2 ATANH B BAHTTEXT BASE DCOUNT DCOUNTA DSTDEV DSTDEVP DGET DMAX DMIN DPRODUCT DAVERAGE DSUM DVAR DVARP com.star.star.Analysis.star.sheet.star.sheet.Analysis.

L2 CUPON.sheet.Analysis.CORREL COEFICIENTE.sheet.star.Analysis.addin.getQuotient CODE CORREL SKEW RSQ MATCH COLUMN COLUMNS COMBIN COMBINA TRIM com.getCouppcd com.sun.sheet.FECHA.getConvert EUROCONVERT COS COSH COT COTH COVAR GROWTH QUARTILE com.Analysis.ASIMETRIA COEFICIENTE.sheet.addin.A.Analysis.490 10.L1 CUPON.getDelta RIGHT OFFSET STDEV STDEVA STDEVP STDEVPA DEVSQ AVEDEV DAY com.FECHA.BLANCO CONTAR.sheet.sheet.sheet.NUM CURTOSIS DB DDB DDE DEC.addin.sun.Analysis.sun.R2 COINCIDIR COLUMNA COLUMNAS COMBINAR COMBINAR2 COMPACTAR COMPLEJO CONCATENAR CONTAR CONTAR.addin.star.addin.5 Formulas de Calc español-ingles Nº 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 Español CHISQDIST CHISQINV COCIENTE CÓDIGO COEF.sun.Analysis.DIAS CUPON.sun.getComplex CONCATENATE COUNT COUNTBLANK COUNTIF COUNTA CONVERT com.sun.addin.star.sun.sheet.sheet.star.L1 CUPON.addin.sun.SI CONTARA CONVERTIR CONVERTIR_ADD CONVERTIR.star.getCoupdays com.DIAS.sheet.L2 CUPON.star.getCoupdaybs com.A.addin.sheet.BIN DEC.Analysis.getCoupdaysnc com.sheet.sun.sun.getDec2Bin com.DIAS.sun.addin.addin.star.sun.sun.Analysis.sheet.addin.addin.EURO COS COSH COT COTH COVAR CRECIMIENTO CUARTIL CUPON.getDec2Hex com.Analysis.addin.Analysis.Analysis.getWorkday DAYS .star.star.sheet.Analysis.addin.Analysis.OCT DECIMAL DELTA DERECHA DESREF DESVEST DESVESTA DESVESTP DESVESTPA DESVIA2 DESVPROM DÍA DIA.Analysis.LAB DÍAS Ingles CHISQDIST CHISQINV com.A.DE.star.getCoupncd com.star.star.star.getDec2Oct DECIMAL com.sun.HEX DEC.getCoupnum KURT DB DDB DDE com.star.

INV DISTR.NORM.getDaysInYear com.sheet.NORM DISTR.addin.sun.addin.INV DISTR.DateFunctions.getIsLeapYear ISBLANK ISERR ISERROR ISFORMULA ISODD ISLOGICAL ISNA ISNONTEXT ISNUMBER ISEVEN com.INV DISTR.addin.addin.sheet.ESTAND DISTR.getNetworkdays DAYS360 WEEKDAY com.NORM DISTR.Analysis.addin.sheet.addin.sheet.star.getFactdouble FALSE .XY ES.BETA.Analysis.sheet.GAMMA.star.star.sheet.getDaysInMonth ADDRESS WEIBULL BETADIST BETAINV BINOMDIST EXPONDIST FDIST FINV GAMMADIST GAMMAINV HYPGEOMDIST CHIDIST LOGNORMDIST NORMDIST NORMSDIST NORMSINV NORMINV TDIST TINV EASTERSUNDAY com.getMduration VDB CHOOSE FIND INT STEYX com.IMPAR_ADD ESAÑOBISIESTO ESBLANCO ESERR ESERROR ESFÓRMULA ESIMPAR ESLOGICO ESNOD ESNOTEXTO ESNÚMERO ESPAR ESPAR_ADD ESREF ESTEXTO ESTILO ESTIMACIÓN.getDuration com.LINEAL ESTIMACIÓN.JI DISTR.DateFunctions.sun.sun.sheet.T.DateFunctions.LOGARÍTMICA EXP EXTRAE FACT FACT.star.MODIF DVS ELEGIR ENCONTRAR ENTERO ERROR.addin.addin.DOBLE FALSO Ingles com.sun.Analysis.sun.star.EXP DISTR.Aprendiendo OOo Basic 491 Nº 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 Español DIAS.getIseven ISREF ISTEXT STYLE LINEST LOGEST EXP MID FACT com.star.F DISTR.LAB DÍAS360 DÍASEM DÍASENAÑO DÍASENMES DIRECCIÓN DIST.T DISTR.sheet.BETA DISTR.star.INV DISTR.HIPERGEOM DISTR.GAMMA DISTR.sun.WEIBULL DISTR.TÍPICO.star.sun.ESTAND.F.sheet.addin.Analysis.NORM.Analysis.BINOM DISTR.INV DOMINGOPASCUA DURACION_ADD DURACION.LOG.INV DISTR.sun.star.getIsodd com.sun.Analysis.NORM.

sun.Analysis.Analysis.sun.sun.ABS IM.getAccrint com.addin.sun.getEffect ISPMT ZGZ .5 Formulas de Calc español-ingles Nº 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 Español FECHA FECHA.star.getImdiv com.Analysis.star.sheet.star.addin.Analysis.addin.sheet.sun.getImreal com.sheet.Analysis.sheet.Analysis.getImlog2 com.star.star.getImsub com.Analysis.492 10.sun.COS IM.star.sheet.addin.addin.sheet.sheet.star.sheet.addin.RAIZ2 IM.sheet.Analysis.V INT.ERROR FUN.sheet.DEC HEX.Analysis.sun.getErf com.addin.Analysis.getErfc GAMMA GAMMALN GAUSS GETPIVOTDATA DEGREES SEARCH com.ANGULO IM.sun.sun.ACUM.Analysis.sun.getHex2Bin com.getHex2Oct HYPERLINK SHEET SHEETS HOUR TIMEVALUE TODAY EXACT com.sun.SUSTR IMAGINARIO ÍNDICE INDIRECTO INFO INT.LN IM.sheet.sheet.LN GAUSS GETPIVOTDATA GRADOS HALLAR HEX.sheet.sun.getHex2Dec com.addin.addin.sun.getImln com.Analysis.Analysis.sun.sheet.addin.sheet.addin.OCT HIPERVÍNCULO HOJA HOJAS HORA HORANÚMERO HOY IGUAL IM.getAccrintm EFFECTIVE com.CONJUGADA IM.sun.addin.SUM IM.star.A.sheet.getImsum com.star.Analysis.sun.addin.sun.EFECTIVO INT.sheet.star.sheet.DIR INT.addin.addin.BIN HEX.REAL IM.getImexp com.getImconjugate com.getImsin com.Analysis.Analysis.AÑO FRECUENCIA FUN.addin.getImlog10 com.sheet.star.Analysis.sheet.Analysis.star.ERROR.Analysis.sun.sheet.star.addin.PRODUCT IM.getImsqrt com.addin.star.sheet.SENO IM.sheet.getEomonth FISHER FORMULA com.COMPL GAMMA GAMMA.sheet.star.POT IM.star.star.EFECTIVO_ADD INT.Analysis.PAGO.Analysis.sun.addin.addin.star.sun.Analysis.star.sun.MES FISHER FORMULA FRAC.getImargument com.EXP IM.Analysis.getImpower com.addin.getImaginary INDEX INDIRECT INFO com.sun.getImproduct com.addin.star.A.A.getImabs com.star.addin.star.RENDIMIENTO Ingles DATE com.LOG2 IM.ACUM INT.getImcos com.MES FECHANÚMERO FIJO FILA FILAS FIN.addin.addin.DIV IM.sheet.sun.Analysis.sheet.sun.sheet.Analysis.getEdate DATEVALUE FIXED ROW ROWS com.star.addin.star.star.sun.addin.getYearfrac FREQUENCY com.Analysis.star.addin.Analysis.sun.sun.star.Analysis.sheet.sun.star.LOG10 IM.

Analysis.RENDTO LIMPIAR LN LOG LOG10 M.D M.BONO LETRA.getWeeknum .DEC MONEDA.Analysis.O.addin.SEMANA_ADD Ingles INTERCEPT CONFIDENCE LOGINV LEFT RANK JIS LARGE SMALL LEN com.M_ADD MÁX MÁXA MAYOR.sun.addin.Analysis.DE.Analysis.Analysis.getDollarde com.addin.C.sun.PRECIO LETRA.star.sun.C.star.Analysis.MAYOR K.Analysis.sheet.star.Analysis.IGUAL MAYÚSC MDETERM MEDIA.D_ADD M.DE.sheet.star.ARMO MEDIA.getGcd LCM com.sheet.sun.sheet.addin.star.ACOTADA MEDIA.sun.getTbillyield CLEAN LN LOG(.ESIMO.addin.addin.addin.LOG IZQUIERDA JERARQUÍA JIS K.TES.sun.EQV.getLcm MAX MAXA com.getGestep UPPER MDETERM TRIMMEAN HARMEAN GEOMEAN MEDIAN MONTH com.TES.EJE INTERVALO.sheet.SUPERIOR MUNITARIA N NEGBINOMDIST NO NOD NOMPROPIO NORMALIZACIÓN NPER NSHORA NUM.getMultinomial FLOOR CEILING MUNIT N NEGBINOMDIST NOT NA PROPER STANDARDIZE NPER TIME com.getDiffMonths MIN MINA LOWER MINUTE MINVERSE MIRR MMULT MODE DOLLAR com.star.star.TES.sun.addin.FRAC MULTINOMIAL MÚLTIPLO.star.addin.star.DateFunctions.addin.sun.sheet.Analysis.getDollarfr com.star.C.sheet.sun.CONFIANZA INV.sun.sheet.DE.DE.MENOR LARGO LETRA.GEOM MEDIANA MES MESES MÍN MÍNA MINUSC MINUTO MINVERSA MIRR MMULT MODA MONEDA MONEDA.sheet.1 LOG10 GCD com.ESIMO.C.Analysis.M M.getTbilleq com.star.addin.sheet.INFERIOR MÚLTIPLO.Aprendiendo OOo Basic 493 Nº 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 Español INTERSECCIÓN.getTbillprice com.sun.sheet.A.

sheet.sheet.sun.star.addin.getYielddisc com.sun.DESC RENDTO.star.A.addin.Analysis.PRINC.star.VENCIMIENTO PROBABILIDAD PRODUCTO PROMEDIO PROMEDIOA PRONÓSTICO PRUEBA.sheet.sun.INV PRUEBA.star.Analysis.getOct2Bin com.star.sheet.INV PRUEBA.getPricedisc com.addin.PERCENTIL REDOND.sun.IRREGULAR.sheet.getCumprinc IPMT PEARSON SLOPE PERCENTILE PERMUT PERMUTATIONA PHI PI DURATION POISSON POWER com.Analysis.star.IMPAR REDONDEA.sun.getOddlyield com.2 PRECIO.Analysis.INT.sheet.sun.MULT REDONDEA.MAS REDONDEAR.sun.getPricemat PROB PRODUCT AVERAGE AVERAGEA FORECAST FTEST FISHERINV CHITEST CHIINV TTEST ZTEST RADIANS SQRT com.PER.ENTRE PAGO.addin.addin.sun.sheet.1 PRECIO.sheet.getYieldmat REPT MOD ROMAN .addin.star.star.MENOS REEMPLAZAR RENDTO RENDTO.Analysis.star.2 RENDTO.DESCUENTO PRECIO.A.addin.Analysis.star.FISHER.sun.INT.sun.sun.addin.addin.getOddfprice com.getPrice com.1 RENDTO.sheet.Z RADIANES RAÍZ RAIZ2PI RANGO.T PRUEBA.JI PRUEBA.sheet.sheet.star.Analysis.sun.DEC OCT.star.Analysis.Analysis.JI.star.getOct2Dec com.sheet.addin.sun.IRREGULAR.addin.Analysis.star.addin.addin.PRINC.HEX PAGO PAGO.IRREGULAR.BIN OCT.5 Formulas de Calc español-ingles Nº 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 Español O OCT.PER.Analysis.ENTRE_ADD PAGOINT PEARSON PENDIENTE PERCENTIL PERMUTACIONES PERMUTACIONESA PHI PI PLAZO POISSON POTENCIA PRECIO PRECIO.Analysis.star.Analysis.getMround ODD EVEN ROUND ROUNDUP ROUNDDOWN REPLACE com.Analysis.sun.getOddlprice com.Analysis.F PRUEBA.star.ENTRE_ADD PAGO.getOct2Hex PMT CUMIPMT com.addin.Analysis.getYield com.sheet.getOddfyield com.PAR REDONDEAR REDONDEAR.Analysis.sun.sheet.sun.PER.494 10.addin.sheet.sheet.VENCTO REPETIR RESIDUO ROMANO Ingles OR com.getSqrtpi PERCENTRANK com.star.addin.A.PER.sun.IRREGULAR.ENTRE PAGO.addin.getCumipmt CUMPRINC com.sheet.

DE.addin.Analysis.addin.getXnpv AND .star.DESC TASA.sun.Analysis.sun.sun.Aprendiendo OOo Basic 495 Nº 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 Español ROT13 SEGUNDO SEM.star.Analysis.star.PER Y Ingles com.addin.getNominal TREND TEXT TYPE ERRORTYPE IRR com.star.star.getIntrate NOMINAL com.INT TASA.PRODUCTO SUMA.DateFunctions.sun.Analysis.getFvschedule NPV com.SI SUMAX2MASY2 SUMAX2MENOSY2 SUMAXMENOSY2 SUSTITUIR SYD T TAN TANH TASA TASA.star.getWeeksInYear SIN SINH IF SIGN SLN SUBTOTAL SUM SUMSQ SUMPRODUCT com.sheet.sheet.addin.Analysis.sun.star.addin.sheet.sheet.getDiffWeeks com.NO.ERROR TIR TIR.star.addin.star.addin.NOMINAL_ADD TENDENCIA TEXTO TIPO TIPO.SERIES SUMAR.sheet.NOMINAL TASA.sheet.PER TRANSPONER TRUNCAR VA VALOR VAR VARA VARP VARPA VERDADERO VF VF.sheet.sun.DateFunctions.sheet.addin.DEL.sun.sheet.sun.getSeriessum SUMIF SUMX2PY2 SUMX2MY2 SUMXMY2 SUBSTITUTE SYD T TAN TANH RATE com.CUADRADOS SUMA.getRot13 SECOND WEEKNUM com.AÑO SEMANAS SEMANASENAÑO SENO SENOH SI SIGNO SLN SUBTOTALES SUMA SUMA.PLAN VNA VNA.sheet.getDisc com.DateFunctions.Analysis.sun.addin.NO.addin.sun.getXirr TRANSPOSE TRUNC PV VALUE VAR VARA VARP VARPA TRUE FV com.Analysis.star.

table.getByIndex(0) . mArg() ) With oNuevoDocumento. 'Original de Andrew Pitonyak 'Estas versiones Mauricio Baeza Sub ListarFuentes1() Dim oToolkit As Object Dim oDevice As Object Dim oFontDescriptors As Object Dim co1 As Long Dim mArg() Dim oNuevoDocumento As Object Dim Campos(0) As New com.sun.getColumns(). etc).0).star.PropertyValue oToolkit = CreateUnoService("com.Field = 0 Campos(0). Las dos son muy parecidas. con unos pequeños cambios las mostramos en un archivo nuevo de Calc.FontDescriptors() oNuevoDocumento = StarDesktop.6 Listar fuentes en un archivo de Calc La siguientes macros están basadas en la que muestra Andrew Pitonyak en su excelente libro de macros (ve la bibliografía). esta primera te muestra el nombre de la fuente junto con los estilos o variantes que soporta.setValue( co1+1 ) .TableSortField aSD(0) As New com.getCellByPosition(0.star.Name = "SortFields" aSD(0). Sub Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim ListarFuentes2() oToolkit As Object oDevice As Object oFontDescriptors As Object co1 As Long mArg() oNuevoDocumento As Object oFD As Object oCursor As Object Campos(0) As New com.PropertyValue .Toolkit") oDevice = oToolkit.OptimalWidth = True End With End Sub La segunda es similar.StyleName ) Next Campos(0).getCellByPosition(0. 0) oFontDescriptors = oDevice.sun.getCellByPosition(1.496 10.setString( "Nº" ) . cursiva. en el original se muestran los nombres de las fuentes en un cuadro de mensaje.star.beans.co1+1).awt.setString( "Fuente" ) For co1 = LBound(oFontDescriptors) To UBound(oFontDescriptors) .setString( oFontDescriptors(co1).createScreenCompatibleDevice(0.loadComponentFromURL( "private:factory/scalc".getSheets(). 0.TableSortField Dim aSD(0) As New com.star.Name & " " & oFontDescriptors(co1).5 Formulas de Calc español-ingles 10.star. esto es por que la mayoría de estas variantes las establecemos por código con otros métodos y propiedades (negrita.table.co1+1).getCellRangeByName( "B1:B" & CStr(co1+1) ).beans.0).sun.sun.IsAscending = True aSD(0). excepto que solo te muestra el nombre de la fuente. "_default". sin variantes.sort( aSD() ) .getCellRangeByName("A1:B1").sun.Value = Campos() .getCellByPosition(1.

co1+1).ContainsHeader = True oFD.Toolkit") oDevice = oToolkit.getCellRangeByName( "B1:B" & CStr(oCursor.1) 'Como filtramos.collapseToCurrentRegion() 'Ordenamos los nombres de las fuentes Campos(0).Aprendiendo OOo Basic 497 oToolkit = CreateUnoService("com.awt.getCellByPosition(0. "_default". siempre te devolverá los mismos formatos.0).getColumns. incluirá todos tus formato personalizados. si le pasas alguno de tus documento. averiguamos cuantas filas quedaron oCursor = .setString( "Nº" ) .removeByIndex(0. Esta macro puede tener dos pequeñas mejoras que te quedan de tarea. en la columna de ejemplos.0).1).getRows.0).getCellByPosition(2.SkipDuplicates = True oFD.getCellAddress() .star. 0) oFontDescriptors = oDevice.getColumns(). excepto los de la categoría Definidas por el usuario.getCellRangeByName( "A1:A" & CStr(co1+1) ). esto es normal.getCellByPosition(0.createFilterDescriptor( True ) oFD.setValue( 1 ) .0) ) oCursor.Name = "SortFields" aSD(0).filter( oFD ) 'Eliminamos los datos originales.OptimalWidth = True End With End Sub 10.getCellRangeByName("A1:B1").createScreenCompatibleDevice(0.getCellByPosition(0. mArg() ) With oNuevoDocumento. pero podrías implementar la copia de estos formatos para que se vea el resultado. podrás ver en la columna E un ejemplo de cada formato. puedes discriminar los documentos para que solo soporte los que tengan el método getNumberFormats y segundo.getByIndex(0) . 0.setString( "Fuente" ) For co1 = LBound(oFontDescriptors) To UBound(oFontDescriptors) . 1 ) 'Autoajustamos el ancho de las columnas .Value = Campos() .createCursorByRange( .Field = 0 Campos(0).getCellByPosition(0.getCellRangeByName( "A1:A" & CStr(co1+1) ).CopyOutputData = True oFD.loadComponentFromURL( "private:factory/scalc".sort( aSD ) 'Insertamos la numeracion de las fuentes .getRows.getCount) ). si le pasas un documento nuevo. primero.getCount) ). pues el nuevo documento no tiene estos formato. columna A .Name ) Next 'Con un filtro obtenemos registros unicos en la columna C oFD = .OutputPosition = .getCellRangeByName("A2:A" & CStr(oCursor.7 Listar formatos en un archivo de Calc Solo tienes que pasarle la referencia al documento del cual te interese ver sus propiedades.getSheets().IsAscending = True aSD(0).FontDescriptors() oNuevoDocumento = StarDesktop.getCellByPosition(1. 'Basada en el original de Andrew Pitonyak 'Esta versión Mauricio Baeza Sub Todos_Los_Formatos(Documento As Object) Dim oFormatos As Object .setString( oFontDescriptors(co1).sun.fillAuto( 0.

setValue( co1+1 ) 'Definimos la categoria del formato Select Case oFormato.setValue( co1+100+(Rnd*1000) ) 'Le establecemos el formato correspondiente .sun. "_default".getCellByPosition( 3.False ) For co1 = LBound( mClaves ) To UBound( mClaves ) 'Obtenemos cada formato oFormato = oFormatos.getCellByPosition( 2.co1 ).getCellByPosition( 4.NumberFormat = mClaves(co1) 'Ajustamos el ancho de las columnas .getCellByPosition( 0.setString( oFormato.setString( sTipo ) 'Escribimos la cadena del formato .getColumns.aLocal.getCellRangeByName( "A1:E1" ).star.setValue( mClaves(co1) ) 'Escribimos un numero aleatorio entre 100 y 1000 .getNumberFormats() 'Obtenemos todas las claves de los formatos mClaves = oFormatos.getByKey( mClaves(co1) ) 'Numero secuencial .OptimalWidth = True Next End With End Sub .getByIndex(0) 'Obtenemos los formatos del documento pasado oFormatos = Documento.co1 ).loadComponentFromURL( "private:factory/scalc". mArg() ) With oNuevoDocumento.co1 ).queryKeys( 0.Type Case 2 : sTipo = "Fecha" Case 4 : sTipo = "Tiempo" Case 6 : sTipo = "Fecha Tiempo" Case 8 : sTipo = "Moneda" Case 16 : sTipo = "Numero" Case 32 : sTipo = "Cientifico" Case 64 : sTipo = "Fraccion" Case 128 : sTipo = "Porcentaje" Case 256 : sTipo = "Texto" Case 1024 : sTipo = "Logica" Case 2048 : sTipo = "Indefinida" Case Else : sTipo = "Definido por el usuario" End Select .getCellByPosition( 1.FormatString ) 'y su clave correspondiente .7 Listar formatos en un archivo de Calc 'Para escribir los formatos en un nuevo documento de Calc oNuevoDocumento = StarDesktop.co1 ).Locale oNuevoDocumento As Object sTipo As String 10. mArg() oFormato As Object co1 As Integer aLocal As New com.getCellByPosition( 4. 0.co1 ).498 Dim Dim Dim Dim Dim Dim mClaves.lang.getSheets().co1 ).

eso si.php StarOffice 8 Programming Guide for BASIC http://docs.services.php?f=20 Un sitio con muchas macros de todos los niveles y sabores: www.openoffice. este libro le debe mucho a sus ejemplos: www. La Guía de programación de StarOffice 8 para BASIC.com/app/docs/doc/819-0439 .Aprendiendo OOo Basic 499 11 Bibliografía Una de las motivaciones de este libro.ooomacros. es solo un conjunto bastante grande de ejemplos.sun.org.org/en/forum/viewforum. es esencial para introducirte en la programación con OOo Basic: http://docs. son realmente escasos los sitios que tratan la programación con OOo Basic en nuestro idioma.ar/ooo NOTA: al día de hoy 02-Sep-09. cuidado.org/oo. es la falta de documentación es español.com.sun. no es un libro que pueda tomarse como guia para aprender desde cero. siempre dispuesto a ayudar en las listas de correo. se publica mucho código interesante y siempre hay gente dispuesta a ayudarte: http://user. www.pitonyak.com/app/docs/doc/819-1327?l=es En ingles: En los foros de ayuda de OpenOffice. esperemos pronto tenerlo de vuelta. pero serán incomprensibles si no tienes las bases elementales.org El libro de Andrew Pitonyak si bien no es para novatos ya es todo un clásico en la red. muy buenos. el sitio esta desactivado.arielconstenlahaile. en su página encontraras interesantes ejemplos de código en OOo Basic. En español: Ariel Constela es un excelente compañero.

..........................500 12 Índice Alfabético 12 Índice Alfabético B bibliotecas.9 M módulos..9 I IDE................................................................................................10 ...............................................12 S Standard....................................................................

Sign up to vote on this title
UsefulNot useful