Está en la página 1de 88

Introducción

A
OpenOffice.org Basic

por
Noelson Alves Duarte
Versión 1

Índice
1 Macros OpenOffice.org Basic...........................................................................................................5
1.1 Introducción...............................................................................................................................5
1.2 Creando la Primera Macro.........................................................................................................5
1.3 Ejecutando la Primera Macro.....................................................................................................7
1.4 Compartiendo una Macro..........................................................................................................9
2Diálogos Personalizados...................................................................................................................11
2.1 Introducción.............................................................................................................................11
2.2 Creando un Cuadro de Diálogo ...............................................................................................11
2.3 Manejando Eventos del Cuadro de Diálogo............................................................................14
3 Pilotos Automáticos.........................................................................................................................17
3.1 Introducción.............................................................................................................................17
3.2 Creando un Piloto Automático................................................................................................17
3.3 Manipulando Eventos del Piloto Automático..........................................................................19
4 Introducción al API de OpenOffice.org...........................................................................................21
4.1 Introducción.............................................................................................................................21
4.2 Creando un nuevo documento.................................................................................................23
5 Trabajando con Documentos...........................................................................................................25
5.1 Cargando Documentos.............................................................................................................25
5.2 Guardando Documentos...........................................................................................................27
5.3 Imprimiendo Documentos.......................................................................................................28
5.4 Cerrando Documentos.............................................................................................................30
5.5 Identificando los Documentos Abiertos...................................................................................31
6 Documentos de Writer.....................................................................................................................33
6.1 Introducción.............................................................................................................................33
6.2 Editando texto..........................................................................................................................33
6.3 Moviéndose por el texto..........................................................................................................34
6.4 Formateando texto...................................................................................................................38
6.5 Formateando con estilo ...........................................................................................................40
6.6 Obteniendo el objeto seleccionado..........................................................................................44
6.7 Localizando objetos.................................................................................................................46
6.8 Búsqueda y Reemplazo............................................................................................................47
6.9 Insertando objetos....................................................................................................................49
6.10 Tablas.....................................................................................................................................50
7 Documentos de Calc........................................................................................................................57
7.1 Introducción.............................................................................................................................57
7.2 Hojas de cálculo.......................................................................................................................57
7.3 Editando...................................................................................................................................59
7.4 Navegando por las Celdas........................................................................................................61
7.5 Obteniendo objetos seleccionados...........................................................................................63
7.6 Formateando............................................................................................................................64
7.7 Búsqueda y Reemplazo............................................................................................................70
7.8 Ordenando................................................................................................................................71
7.9 Filtrando dados........................................................................................................................73
7.10 Insertando Subtotales.............................................................................................................74
7.11 Gráficos..................................................................................................................................76
8 Más información..............................................................................................................................81

Introducción a OpenOffice.org Basic 1


Versión 1

8.1 En la red...................................................................................................................................81
8.2 Con el autor..............................................................................................................................82
9 Créditos, Agradecimientos, Licencia...............................................................................................83
9.1 Créditos....................................................................................................................................83
9.2 Agradecimientos ....................................................................................................................83
9.3 Licencia....................................................................................................................................83

2 Introducción a OpenOffice.org Basic


Versión 1

Presentación
Este documento es el resultado de mi esfuerzo por aprender OpenOffice.org Basic.
Está enfocado, principalmente, en las extensiones del lenguaje Basic para OpenOffice.org, es de-
cir, en la API de OpenOffice.org. Siendo así, no se abordan las características básicas del len-
guaje de programación Basic.
Si usted ha programado anteriormente o conoce alguno de los “sabores” Basic y desea escribir
macros para OpenOffice.org éste es un buen punto de partida. Si no, le recomiendo buscar algún
curso en la red y familiarizarse con el lenguaje Basic antes de aventurarse en OOo Basic. Es muy
importante dominar los fundamentos de un lenguaje de programación.
Todos los ejemplos del código fuente se comprobaron con OpenOffice.org, versión 1.0.1, excep-
to los pequeños bloques de código fuera de las subrutinas.1
Para utilizar adecuadamente este texto, OpenOffice.org debe estar instalado en su ordenador.
Tras el Capítulo 3, recomiendo que usted instale, también, el Manual de Referencia de la API de
OpenOffice.org (consulte el capítulo 8. Más Informaciones). El Manual de Referencia se actua-
liza periódicamente y su versión actualizada está disponible también para consultas “on-line”.
Espero disponer de tiempo para continuar aprendiendo y adquiriendo informaciones útiles para
los programadores que, como yo mismo, no dominan la lengua inglesa. Por lo tanto, periódica-
mente, busque nuevas versiones de este documento.
Como resultado de un proceso de aprendizaje, esta Introducción..., seguramente, contiene
algunos errores e inconsistencias; espero contar con su ayuda para corregirlos.

20 de junio de 2003

El Autor

1 N. del T.: Esta traducción española ha sido adaptada a la versión 1.1, por cuyo motivo las capturas de pantalla y al-
gunos menús, pueden diferir de los que se mostraban en la obra original, elaborada a partir de la versión 1.0.1.
Además, la inclusión en la más reciente versión de OpenOffice.org de una potente grabadora de macros (no tratada
en esta Introducción), abre perspectivas insospechadas para los usuarios, al permitirles crear sus macros sin
necesidad de ser expertos programadores.

Introducción a OpenOffice.org Basic 3


Versión 1

4 Introducción a OpenOffice.org Basic


Versión 1 Macros OpenOffice.org Basic

1 Macros OpenOffice.org Basic

1.1 Introducción
Una macro es un programa escrito en lenguaje OpenOffice.org Basic con el objetivo de auto-
matizar tareas de OpenOffice.org
El lenguaje OpenOffice.org Basic mantiene las principales características de las versiones ac-
tuales de BASIC en lo referente a sintaxis, tipos de datos, operadores, comandos, funciones
internas y organización general del programa. Además, OpenOffice.org Basic permite el ac-
ceso a una gran cantidad de objetos, con sus métodos y propiedades, específicos de
OpenOffice.
OpenOffice.org posee un IDE (Integrated Development Environment – Entorno de Desarrollo
Integrado) completo, que incluye: edición de código fuente, verificación de errores, creación
de cuadros de diálogo y administración de librerías.

1.2 Creando la Primera Macro


Nuestra macro será bien sencilla. El operador escribirá una frase en un cuadro de texto, y se-
guidamente esta frase se añadirá a la posición actual del cursor de texto del documento activo
de Writer.
Para comenzar:
a) Ejecute Writer, cree un nuevo documento y sálvelo como Primera_Macro.sxw.
b) En la barra de menú seleccione Herramientas => Macros => Macro. Aparecerá el cuadro
de diálogo Macro.
Observe la jerarquía Macro desde, en el área izquierda del cuadro de diálogo; en ella tene-
mos dos entradas principales: soffice y Primera_Macro.sxw, ambas son recipientes o conte-
nedores para bibliotecas. Un nivel por debajo de las dos entradas tenemos la biblioteca Stan-
dard. Dentro de soffice => Standard tenemos el módulo Module1.
El recipiente soffice, que siempre se cargará con OpenOffice.org, contiene bibliotecas globa-
les usadas en todos los documentos de OpenOffice.org. Observe que algunas bibliotecas de
soffice están desactivadas.
Cada documento abierto tiene su propio contenedor con una biblioteca Standard. En la figura
1 siguiente, el único documento abierto es Primera_Macro.sxw.
La lista Macros existentes en, en el centro del cuadro de diálogo, muestra los nombres de los
procedimientos (subrutinas y funciones) del módulo seleccionado. El cuadro de texto Nom-
bre de la macro muestra el nombre del procedimiento seleccionado. Al seleccionar el nom-
bre de un procedimiento, se activan los botones Ejecutar, Asignar y Editar.

Introducción a OpenOffice.org Basic 5


Macros OpenOffice.org Basic Versión 1

Figura 1: Diálogo Macro

Figura 2: IDE Basic

6 Introducción a OpenOffice.org Basic


Versión 1 Macros OpenOffice.org Basic

Seguimos con la creación de nuestra primera macro:


a) Seleccione la biblioteca Standard de Primera_Macro.sxw.
b) Pulse sobre el botón Nuevo para crear un nuevo módulo.
c) Aparece el cuadro de entrada Módulo Nuevo, sugiriendo el nombre Module1.
d) Pulse Aceptar para crear un nuevo módulo. El IDE de Basic ha sido cargado.
e) Observe, en el editor Basic, la definición de una subrutina Sub Main ... End Sub. Vea tam-
bién que la pestaña Module1 está activa.
f) Escriba (o copie y pegue) el código fuente mostrado abajo entre las lineas Sub Main y End
Sub.
Dim oDocumento as Object
Dim oTexto as Object
Dim oCursorVista as Object
Dim oCursor as Object
Dim sInsertar as String

' solicita el texto


sInsertar = InputBox("Introduzca el texto:", "Insertar Texto", "")
' comprueba que se escribió algo
if sInsertar = "" then
exit sub
endif
' obtiene el modelo de documento
oDocumento = ThisComponent
' obtiene el servicio Text del documento
oTexto = oDocumento.getText()
' obtiene la posición del cursor en el GUI y crea un cursor de texto
oCursorVista = oDocumento.getCurrentController().getViewCursor()
oCursor = oTexto.createTextCursorByRange(oCursorVista.getStart())
' inserta el texto en la posición actual del cursor
oTexto.insertString(oCursor, sInsertar, FALSE)

Ya terminamos nuestra primera macro. Recuerde que está incluida en el documento


Primera_Macro.sxw.

1.3 Ejecutando la Primera Macro


Antes de continuar, analizaremos la ventana del IDE Basic. Tenemos, en la parte inferior iz-
quierda de la ventana una área denominada Observador y otra, Llamadas, a la derecha. Las
utilizaremos para observar los valores de las variables y las llamadas a procedimientos, res-
pectivamente, durante la ejecución de la macro.
Veamos, también la finalidad de algunos iconos de la ventana del IDE Basic:
Ejecutar – ejecuta una macro hasta encontrar un Punto de ruptura.
Punto de ruptura – define un punto de interrupción.
Paso a paso – ejecuta una macro, línea a línea.

Introducción a OpenOffice.org Basic 7


Macros OpenOffice.org Basic Versión 1

Detener – termina la ejecución de una macro. Se activa al iniciarse la ejecución de la macro.


Macros – permite seleccionar una macro para su ejecución.
Guardar el texto fuente como... – salva el módulo actual como un archivo Basic.
Insertar el texto fuente - inserta el código fuente de un archivo Basic.
Ha llegado el momento de probar el funcionamiento de nuestra macro:
a) En el editor Basic, desplace el cursor de texto a la línea sInsertar = InputBox( ... ). Pulse en
el icono Punto de ruptura. Aparecerá una marca de color rojo a la izquierda de la línea.
b) En el campo Observador, escriba sInsertar y pulse Enter, para inspeccionar el valor de la
variable durante la ejecución de la macro. Observe que se activa el icono Borrar observa-
dor, a la derecha del campo.
c) Pulse sobre el icono Ejecutar. Se inicia la ejecución de la macro, deteniéndose en el Punto
de ruptura; observe la flecha amarilla a la izquierda de la instrucción.
d) Pulsando en el icono Paso a paso, siga la ejecución de la macro. Cuando se muestre la caja
de entrada, introduzca su nombre y pulse el botón Aceptar. Continúe la ejecución pulsando
Paso a paso hasta el final, en que se desactivará el icono Parar.
Cambie a la ventana de documento Primera_Macro.sxw y observe como se insertó su nombre
en la posición del cursor, tal como deseábamos.
Si ocurrió algún error, revise el código fuente.
En el caso de que utilicemos una macro frecuentemente, podemos configurar OpenOffice.org
para ejecutarla más fácilmente. En la opción del menú Herramientas => Configurar, dispo-
nemos de las pestañas Menú – Teclado – Barras de símbolos, donde es posible asociar ma-
cros a opciones de menús, a iconos de la barra de herramientas, a una combinación de teclas o
a un evento de OpenOffice.org.
Antes de finalizar esta sección, vuelva a la ventana del IDE Basic, para simular un error en
nuestro código fuente:
a) En la penúltima línea de código – oTexto.insertString(...) – altere el nombre de la variable
oCursor por oCurso.
b) Ejecute la macro. Aparece un cuadro con un mensaje de error y un botón Aceptar. Obser-
ve que la flecha de seguimiento de la ejecución se vuelve roja en la línea donde ha ocurrido el
error. Tras aceptar el mensaje, finaliza la ejecución de la macro y la línea con el error perma-
nece seleccionada.

Figura 3: Error de ejecución

8 Introducción a OpenOffice.org Basic


Versión 1 Macros OpenOffice.org Basic

c) Sustituya el nombre erróneo de la variable oCurso por el correcto oCursor. Cierre el IDE
Basic.
Guarde el documento Primera_Macro.sxw.
En el próximo paso, veremos como hacer disponible una macro para todos los documentos de
OpenOffice.org.

1.4 Compartiendo una Macro


Las macros de una biblioteca del contenedor soffice / Standard se cargan conjuntamente con
OpenOffice.org. Las que se incluyen en las bibliotecas de cualquier otro documento, se
cargan con el mismo. En consecuencia, estarán disponibles para ejecución solamente cuando
el documento esté abierto.
En esta sección, veremos como exportar una macro de un documento a la aplicación
OpenOffice.org para que su ejecución sea posible desde cualquier documento, no tan sólo
desde el documento original. Ahora mostraremos los pasos necesarios para efectuar la tarea.
Para que la macro de un documento esté disponible para cualquier otro documento de
OpenOffice.org, siga los pasos siguientes:
a) Desde el documento Primera_Macro.sxw, seleccione Herramientas => Macros => Ma-
cro.y pulse Administrar
b) En el cuadro de diálogo Administrar, pulse la pestaña Bibliotecas.

Figura 4. Administrar Bibliotecas

Introducción a OpenOffice.org Basic 9


Macros OpenOffice.org Basic Versión 1

c) Seleccione, en el cuadro de lista Aplicación / Documento, la entrada soffice y pulse el


botón Adjuntar.
d) Se mostrará un diálogo Abrir Archivo. Localice y seleccione cualquier documento que
contenga la biblioteca de macros que desea compartir y pulse en el botón Abrir.
e) Aparecerá el diálogo Insertar Bibliotecas. Observe que las bibliotecas existentes en el ar-
chivo están marcadas para compartir. Desmarque las que no desea compartir y pulse Acep-
tar.

Figura 5. Añadir bibliotecas

Tras esta operación la biblioteca se habrá añadido al recipiente soffice. Normalmente, solo las
macros de la biblioteca Standard se cargan con OpenOffice.org. Para cargar alguna otra
bilbioteca, escoja Herramientas => Macros => Macro, seleccione el recipiente y haga una
doble pulsación de ratón sobre el nombre de la biblioteca.
Para las bibliotecas Standard, el método de exportación no funciona adecuadamente, pues el
recipiente soffice posee su propia bibliotecas Standard. En este caso debemos usar los recur-
sos de edición del IDE Basic para compartir la macro.
Active el IDE Basic y cree un nuevo módulo en la biblioteca Standard del recipiente soffice.
Seguidamente, abra el documento con la macro y, en el IDE Basic, active el módulo que con-
tiene la macro a compartir, seleccione toda la macro y copie; cambie al nuevo módulo en sof-
fice / Standard y pegue la macro copiada; guarde todo y cierre OpenOffice. Ahora su macro
forma parte de la biblioteca Standard de soffice y está disponible para su ejecución en
OpenOffice.org.
Si es su intención desarrollar macros para uso compartido, cree bibliotecas propias para
ellas, sobretodo si usan diálogos. Para crear una nueva biblioteca, en el diálogo Administrar

10 Introducción a OpenOffice.org Basic


Versión 1 Macros OpenOffice.org Basic

(figura 4), pulse sobre el botón Nuevo, emerge el diálogo Nueva Biblioteca, en el cuadro de
texto introduzca un nombre para su biblioteca y pulse sobre el botón Aceptar.
El SDK (Software Delevopment Kit) de OpenOffice.org proporciona la herramienta pkgchk
para empaquetamiento de macros, y su uso está fuera del ámbito de esta Introducción. Con-
sulte la Developers Guide para obtener información más detallada.

Introducción a OpenOffice.org Basic 11


Diálogos Personalizados Versión 1

2 Diálogos Personalizados

2.1 Introducción
OpenOffice.org Basic permite la creación de Cuadros de Diálogo Personalizados, gracias a un
poderoso e intuitivo editor de Diálogos que incorpora.
Los Cuadros de Diálogo son una excelente solución para interactuar con el usuario, permitien-
do que el programador diseñe una interface gráfica consistente para obtener o mostrar infor-
maciones al operador.

2.2 Creando un Cuadro de Diálogo

Figura 6: Editor de Diálogos

12 Introducción a OpenOffice.org Basic


Versión 1 Diálogos Personalizados

El Cuadro de Diálogo que vamos a crear será bien simple. Realmente, tan sólo sustituiremos
el cuadro de entrada usado en nuestra primera macro por un cuadro de diálogo personalizado.
Antes de comenzar, precisamos recuperar nuestro archivo Primera_Macro.sxw:
a) Cargue OpenOffice.org.
b) Abra el archivo Primera_Macro.sxw.
c) Desde el menú, escoja Herramientas => Macros => Macro, seleccione el Module1 de
nuestra macro y puse sobre editar para activar el IDE Basic.
d) Pulse con el botón secundario del ratón sobre la pestaña Module1. En el menú contextual
seleccione Insertar => Diálogo. Aparece el editor de cuadros de diálogo Basic, con un diálo-
go vacío. Observe que se ha creado una página denominada Dialog1.

e) Pulse sobre el icono Campos de control . Aparecerá un cuadro con diversos iconos.
Arrastre este cuadro para que quede situado a la derecha del cuadro de diálogo.
Veamos la finalidad de algunos de los iconos existentes en el cuadro de Controles.
Etiqueta – usado para colocar etiquetas en el cuadro de diálogo.
Botón – usado para colocar botones en el cuadro de diálogo.
Campo de texto – permite insertar un cuadro de texto en un diálogo.
Propiedades – muestra la ventana de propiedades del control seleccionado. Se activará cada
vez que seleccionemos un control. Además de la edición de las propiedades, permite asociar
procedimientos (código) a los eventos ocurridos en el control.
Activar el modo de prueba– muestra el cuadro de diálogo como si estuviese en ejecución.
Insertar controles en un cuadro de diálogo es una operación en tres pasos:
1) activar el icono del control en el cuadro de controles;
2) definir un área del cuadro de diálogo donde ubicar el control. Para esto presione el botón
principal del ratón y arrastre formando un rectángulo; entonces, libere el botón del ratón;
3) definir las propiedades del control.
Cuando añadimos un control al cuadro de diálogo, OpenOffice.org Basic automáticamente
define un valor predefinido para cada propiedad. Para mostrar las propiedades de un control
seleccionado, pulse sobre el icono Propiedades o efectúe una doble pulsación sobre el mis-
mo. Observe que la ventana Propiedades, dispone de una barra de desplazamiento vertical.
Vamos a trabajar en nuestro cuadro de diálogo:
a) Seleccione el cuadro de diálogo vacío, pulsando en su borde exterior. Observe las marcas
que aparecen en su perímetro. Podemos usar estas marcas para redimensionar nuestro cuadro
de diálogo.
b) Pulse sobre el icono Propiedades para mostrar su ventana como en la figura 7. En el cam-
po Titulo – pestaña General – escriba Insertar Frase y pulse Intro. Aparte la ventana de forma
que le permita ver el cuadro de diálogo y observe su título.

Introducción a OpenOffice.org Basic 13


Diálogos Personalizados Versión 1

c) Añada un control Etiqueta al cuadro de diálogo. Para ello, pulse en el icono Etiqueta, y a
continuación defina un rectángulo en la parte superior del cuadro de diálogo. Defina su pro-
piedad Título con el texto Introduzca el texto.

Figura 7: Ventana Propiedades

d) Coloque un Campo de Texto en el cuadro, por debajo de la etiqueta. Observe su propie-


dad Nombre: TextField1. En el código fuente, nos referimos a un control por su propiedad
Nombre, de ahí su importancia. Observe, también que este control no tiene la propiedad Tí-
tulo.
e) Colocaremos dos botones, alineados horizontalmente, en la parte inferior del cuadro de diá-
logo, bajo el campo de texto. Defina sus títulos como Aceptar y Cancelar.

14 Introducción a OpenOffice.org Basic


Versión 1 Diálogos Personalizados

Figura 8: Cuadro de Diálogo Insertar Frase

f) Ajuste el cuadro de diálogo y sus controles de modo que queden con la apariencia de la fi-
gura 8.
Finalmente, terminamos nuestro cuadro de diálogo. Verificaremos su apariencia en ejecución;
para ello pulse sobre el icono Activar el modo de prueba en el cuadro de controles y, tras
observar el resultado, ciérrelo para regresar al editor.
En la próxima sección, daremos funcionalidad a nuestro cuadro de diálogo.

2.3 Manejando Eventos del Cuadro de Diálogo


Veamos como el cuadro de diálogo que acabamos de proyectar interactuará con el operador:
tras la aparición del cuadro de diálogo, el operador debe introducir el texto y después pulsar el
botón Aceptar o puede, simplemente, presionar el botón Cancelar. Para cada una de estas dos
acciones (y muchas otras), el sistema emite mensajes de eventos.
Para dar funcionalidad al cuadro de diálogo, necesitamos interceptar los eventos que nos inte-
resan, es decir, la pulsación del botón Aceptar o Cancelar, para efectuar seguidamente el pro-
ceso necesario.
El IDE Basic permite la asociación de procedimientos a eventos de controles mediante la
ventana Propiedades y su pestaña Eventos. La palabra procedimientos ya nos indica que ne-
cesitaremos código fuente.
En el IDE Basic, seleccione el módulo Module1.
En el editor de código Basic, introduzca (o copie y pegue) el código fuente siguiente, antes de
Sub Main.
Private oDialogo as Variant

Sub dlgEjecutaDialogo
oDialogo = createUnoDialog(DialogLibraries.Standard.Dialog1)
oDialogo.execute()
End Sub

Sub dlgCancelaDialogo
oDialogo.endExecute()
End Sub

Sub dlgInsertarFrase
Dim oDocumento as Object
Dim oTexto as Object
Dim oCursorVista as Object
Dim oCursor as Object
Dim sFrase as String

oDialogo.endExecute()
' observe la referencia al control TextField1 del cuadro de diálogo
sFrase = oDialogo.Model.TextField1.Text

Introducción a OpenOffice.org Basic 15


Diálogos Personalizados Versión 1

if sFrase = "" then


exit sub
endif
' obtiene el modelo de documento
oDocumento = ThisComponent
' obtiene el servicio Text en el documento

oTexto = oDocumento.getText()
' obtiene la posición do cursor en la GUI y crea un cursor de texto
oCursorVista = oDocumento.getCurrentController().getViewCursor()
oCursor = oTexto.createTextCursorByRange(oCursorVista.getStart())
' inserta el texto en la posición actual del cursor
oTexto.insertString(oCursor, sFrase, FALSE)

End Sub

En el código anterior, declaramos una variable oDialogo (Private oDialogo as Variant) fuera
de los procedimientos, lo que la vuelve visible para todo el módulo Module1.
Antes de mostrar el cuadro de dialogo, creamos un objeto oDialogo con createUnoDialog() y,
para ejecutarlo, llamamos a su método execute. Para cerrar el cuadro de diálogo llamamos a
su método endExecute (es llamado en dos procedimientos). Los objetos UNO (creados con
createUno) se deben declarar como de tipo Variant y no Object.
A continuación, asociaremos los procedimientos a los eventos del cuadro de diálogo.
Seleccione la página Dialog1 para activar el editor de cuadros de diálogo.

Figura 9: Diálogo Asignar macro

En nuestro cuadro de dialogo, seleccione el botón Aceptar y pulse sobre el icono Propieda-
des. Surge la ventana Propiedades, pulse la pestaña Acontecimientos (Eventos), y seguida-

16 Introducción a OpenOffice.org Basic


Versión 1 Diálogos Personalizados

mente el botón a la derecha del campo de evento Al ejecutar. Aparecerá la ventana Asig-
nar macro con el evento Al ejecutar seleccionado. En el árbol Macros, expanda las entradas
Primera_Macro.sxw y Standard y pulse en Module1. Al aparecer la relación de proce-
dimientos del módulo, seleccione el procedimiento dlgInsertarFrase y pulse sobre el botón
Asignar. Para cerrar la ventana pulse el botón Aceptar.
Ahora, repita los pasos anteriores para asignar el procedimiento dlgCancelaDialogo al evento
Al ejecutar del botón Cancelar.
Para OpenOffice.org Basic, el primer procedimiento en el módulo es el punto de entrada de la
macro. Por tanto, el procedimiento Sub dlgEjecutaDialogo se ejecutará automáticamente to-
das las veces que llamemos a nuestra macro.
Pruebe la macro y el cuadro de diálogo personalizado, pulsando sobre el icono Ejecutar, en la
barra de herramientas del IDE Basic. Introduzca una frase cualquiera en el cuadro de texto del
diálogo y pulse Aceptar. Tras la ejecución de la macro, verifique que la frase fue añadida
correctamente al documento.
En el próximo capítulo, transformaremos nuestro sencillo cuadro de diálogo en un Piloto Au-
tomático.

Introducción a OpenOffice.org Basic 17


Diálogos Personalizados Versión 1

3 Pilotos Automáticos

3.1 Introducción
Un Piloto Automático es un Diálogo mostrado en varios pasos. Es una forma eficiente de
guiar al usuario en la ejecución de una tarea.
OpenOffice.org trae de serie varios Pilotos Automáticos. Compruebe el funcionamiento de
uno de ellos, seleccionando Archivo => Piloto Automático => Carta.

3.2 Creando un Piloto Automático


En esta sección, veremos como transformar el cuadro de diálogo personalizado del capítulo
anterior en un Piloto Automático.
La idea general es, en un primer paso, obtener la frase, y en un segundo paso, solicitar una po-
sición para insertar la frase introducida. Para dar este efecto paso a paso, OpenOffice.org per-
mite la creación de cuadros de diálogo con múltiples páginas. El diálogo con la propiedad
Página igual a 1 será mostrado primero, el de página 2 a continuación, y así sucesivamente.
Los controles de OpenOffice.org Basic tienen una propiedad Página (Step), que controla en
que página del cuadro de diálogo será mostrado. Así, los controles con la propiedad Página
igual a 1 serán visibles en el diálogo de la página 1, aquellos con Página igual a 2 se mostrarán
con el diálogo de la página 2, y así en adelante. Un control se mostrará en todos los pasos
cuando su propiedad Página sea igual a 0.
El último diálogo accedido en el editor de diálogos, independientemente del número de su pá-
gina será el primero en ser mostrado en la ejecución de la macro. Consecuentemente, después
de diseñar los diálogos del Piloto Automático, regrese al diálogo de la página 1. Si usted de-
fine la propiedad Página de un cuadro de diálogo con valor 0, se mostrarán todos los controles
de todas las páginas.
En la transformación del diálogo en Piloto Automático, necesitaremos algunos otros controles
y también alterar algunas propiedades de los controles existentes.
Cargue Writer, abra el documento Primera_Macro.sxw, seleccione Herramientas => Ma-
cros => Macro, navegue hasta el módulo Primera_Macro – Standard – Module1 y pulse
Editar para activar el IDE Basic.
Pulse sobre la pestaña Dialog1, activando el Editor de Diálogos y redimensione el dialogo,
haciéndolo más largo. Seleccione los botones Aceptar y Cancelar (pulse Aceptar, presione
la tecla Shift y pulse en Cancelar) y mueva estos dos botones hacia la derecha.

18 Introducción a OpenOffice.org Basic


Versión 1 Pilotos Automáticos

En la barra de herramientas del IDE Basic, pulse el icono Controles y ubique el cuadro de
controles al lado del dialogo.
Pulse en el icono Botón, en el cuadro de controles y añada dos nuevos botones en el dialogo, a
la misma altura del botón Aceptar, más a su izquierda.
Seleccione el botón CommandButton3, pulse en el icono Propiedades, defina la propiedad
Título como << Anterior, y cambie el valor de la propiedad Activado a No.
Seleccione el botón CommandButton4 y defina su propiedad Título como Próximo >>.
Seleccione el botón Aceptar y modifique su Título a Finalizar.
Seleccione el diálogo (pulsando en su borde) y defina su propiedad Página (Step) como 1
(uno).
Seleccione el control Etiqueta y defina su propiedad Página como 1 (uno).
Seleccione el control Cuadro de texto y defina su propiedad Página como 1 (uno).
Ahora, retoque la primera página del Piloto Automático, dejándola de forma parecida a la si-
guiente figura:

Figura 10: Primera Página del Diálogo del Piloto Automático

Bien, sigamos con nuestro proyecto, diseñando la Página 2 del Piloto Automático.
Seleccione el diálogo y altere la propiedad Página en 2 (dos). Observe que los controles Eti-
queta y Cuadro de Texto desaparecen, pues ellos pertenecen a la Página 1. Los botones, que
tienen la página igual a 0 (cero), continúan visibles.
Añada una Etiqueta en la parte superior izquierda del diálogo y defina su Titulo como Selec-
cione una posición. Observe que la propiedad página es igual a 2 (dos), el mismo valor del
diálogo.
Pulse sobre el icono Botón de Opción, en el cuadro de controles, y ponga tres botones de op-
ción en la parte superior derecha del diálogo, uno bajo el otro.
Defina el Título del primer botón de opción como En la posición del cursor y su propiedad
Estado en Seleccionado. Defina el Título del segundo botón de opción como Al principio
del documento. Defina el Título del tercer botón de opción como Al final del documento.
Ahora, ajuste los controles de la segunda página del Piloto Automático, para que adopte una
apariencia similar a la de la siguiente figura. Observe que el botón de opción En la posición

Introducción a OpenOffice.org Basic 19


Pilotos Automáticos Versión 1

del cursor aparece activada por omisión. La activación o desactivación de los botones Ante-
rior y Siguiente se efectuará en tiempo de ejecución, por el código fuente que más adelante
insertaremos.

Figura 11: Segunda Página del Diálogo del Piloto Automático.

Para finalizar el diseño del Piloto Automático, seleccione el diálogo y regrese a la Página 1
(uno), pues OpenOffice.org, por omisión, mostrará la última página accedida desde el Editor
de Diálogos.
En la próxima sección, añadiremos el código fuente necesario para dar funcionalidad al Piloto
Automático.

3.3 Manipulando Eventos del Piloto Automático


Nuestro Piloto Automático tiene dos nuevos botones (Anterior y Siguiente) y necesitamos có-
digo fuente para interceptar o procesar sus eventos.
Active el IDE Basic y su editor e introduzca (o copie y pegue) el código siguiente encima de
Sub Main.

Sub dlgSiguienteDialogo
oDialogo.Model.Step = 2
oDialogo.Model.CommandButton3.Enabled = true
oDialogo.Model.CommandButton4.Enabled = false
End Sub

Sub dlgAnteriorDialogo
oDialogo.Model.Step = 1
oDialogo.Model.CommandButton3.Enabled = false
oDialogo.Model.CommandButton4.Enabled = true
End Sub

Antes de insertar la frase, necesitamos verificar la posición, seleccionada en el segundo paso,


(botones de opción) y tratar esa selección adecuadamente.

20 Introducción a OpenOffice.org Basic


Versión 1 Pilotos Automáticos

Inserte el código siguiente en Sub dlgInsertarFrase, a continuación de la línea oCursor =


oTexto.CreateTextCursorByRange(...) y antes de la línea oTexto.insertString(...).

' la posición de la frase es en el inicio o en el final


if oDialogo.Model.OptionButton2.State = 1 then
oCursor.gotoStart(FALSE)
elseif oDialogo.Model.OptionButton3.State = 1 then
oCursor.gotoEnd(FALSE)
endif

Ahora, conectaremos los procedimientos con los eventos que nos interesan.
Cambie al editor de diálogos.
Seleccione el botón Anterior y pulse en el icono Propiedades. En la ventana Propiedades,
pulse la pestaña Acontecimientos (Eventos) y seguidamente pulse el botón a la derecha
del campo del evento Al Ejecutar. En la ventana Asignar macros, expanda la entrada Pri-
mera_Macro.sxw y Standard de la lista Macros y pulse en Module1. En la relación de su-
brutinas, seleccione el procedimiento dlgAnteriorDialogo y pulse el botón Asignar. Pulse
Aceptar para cerrar la ventana.
Siguiendo los mismos pasos detallados anteriormente, asigne el procedimiento dlgSiguiente-
Dialogo al evento Al Ejecutar del botón Siguiente.
Ejecute la macro y compruebe que todo ocurrió como se esperaba.
Ahora, ya puede usted aventurarse a escribir sus propias macros. Como punto de partida,
consulte el próximo capítulo en busca de información complementaria.

Introducción a OpenOffice.org Basic 21


Pilotos Automáticos Versión 1

4 Introducción al API de OpenOffice.org

4.1 Introducción
La clave para la creación de programas que usan la API de OpenOffice.org son los servicios.
Un servicio es una especificación de un objeto, que engloba un conjunto de interfaces y pro-
piedades. Una interfaz es una colección de métodos. Una propiedad es un valor que deter-
mina una característica de un servicio y está formada por un nombre y un valor.
Para crear un servicio, usamos la función Basic createUnoService(), que devuelve un objeto
que soporta el servicio, o Null si no fuese posible la creación. Por ejemplo, para obetener el
servicio Desktop usamos la llamada:
oDesktop = createUnoService( “com.sun.star.frame.Desktop” )

El argumento de la función es la especificación completa para el servicio. Todas las referen-


cias a servicios comienzan por com.sun.star, seguido por el nombre del módulo, en este caso
frame y, finalmente, por el nombre del servicio Desktop. Observe también que la especifica-
ción se pasa como una cadena de caracteres “com.sun.star.frame.Desktop”.
Tras la llamada podemos verificar si el servicio fue creado con:
If isNull( oDesktop ) Then
' Error en la creación del servicio
End If

Existen servicios que son dependientes de un contexto. Por ejemplo, usted no puede crear una
celda fuera de una hoja de cálculo. Otros servicios no necesitan un ambiente para operar.
Existen, además, servicios que no ofrecen ninguna interfaz, sirviendo únicamente para obtener
y definir propiedades.
Basic ofrece dos propiedades que facilitan el acceso a los servicios:
StarDesktop – es el equivalente al objeto devuelto por una llamada a la función createUno-
Service(“com.sun.star.frame.Desktop”). Introduzca el siguiente código en una nueva subruti-
na, ejecute y observe el resultado:
MsgBox StarDesktop.Dbg_SupportedInterfaces
'
' es lo mismo que:
'
Dim oDesktop
oDesktop = CreateUnoService( "com.sun.star.frame.Desktop" )
MsgBox oDesktop.Dbg_SupportedInterfaces

22 Introducción a OpenOffice.org Basic


Versión 1 Introducción al API de OpenOffice.org

ThisComponent – devuelve el objeto documento que contiene el código Basic; existe sola-
mente en documentos Writer, Calc, Impress o Draw. Algunas de sus interfaces dependen del
tipo de documento.
Dim oDocumento As Object
oDocumento = ThisComponent

OpenOffice.org Basic tiene tres propiedades muy útiles para la inspección de objetos:
Dbg_SupportedInterfaces
devuelve las interfaces soportadas por el objeto
Dbg_Properties
devuelve las propiedades del objeto
Dbg_Methods
devuelve los métodos soportados por el objeto
Para obtener estas propiedades, use la forma Objeto.Propiedad. Por ejemplo, compruebe las
interfaces soportadas por el modelo de documento ejecutando el siguiente código:
Sub Main
MsgBox ThisComponent.Dbg_SupportedInterfaces
End Sub

La interfaz com.sun.star.lang.XServiceInfo posee los siguientes métodos, útiles para inspec-


ción de servicios:
getImplementationName ( ) As String
devuelve el nombre de implementación del servicio
supportsService (sNombre As String ) As Boolean
devuelve True (Verdadero) si el servicio sNombre es soportado
supportedServiceNames ( ) As String ()
devuelve un conjunto de cadenas con los nombres de los servicios soportados, incluso los in-
directos.
Para obtener o especificar valores de propiedades, tenemos dos casos:
a) si el número de propiedades es fijo, entonces usamos simples asignaciones de Basic, como:
Dim nColorAntiguo As Long
nColorAntiguo = oRectangleShape.FillColor
oRectangleShape.FillColor = RGB(255,0,0)

b) si es una secuencia, debemos definir un array antes de manipular las propiedades:


Dim mPropArchivo(1) As New com.sun.star.beans.PropertyValue
mPropArchivo(0).Name = "FilterName"
mPropArchivo(0).Value = "swriter: StarWriter 5.0"
mPropArchivo(1).Name = "AsTemplate"

Introducción a OpenOffice.org Basic 23


Introducción al API de OpenOffice.org Versión 1

mPropArchivo(1).Value = True

La secuencia com.sun.star.beans.PropertyValue implementa el servicio MediaDescriptor,


que describe cómo y dónde un recurso debe ser cargado o salvado. Observe como las
propiedades se definen por un par Name y Value.
A continuación, analizaremos un ejemplo de código que usa algunos de estos conceptos.

4.2 Creando un nuevo documento


Desarrollaremos, ahora, una subrutina para crear un nuevo documento a partir de un plantilla
existente. El código fuente Basic, en filas generales, necesita tratar los dos detalles siguientes:
a) obtener el camino completo para la plantilla;
b) cargar el archivo, informando a OpenOffice.org que se trata de una plantilla;
La siguiente subrutina Sub creaNuevoDocumento, ejecuta estas tareas apropiadamente.
' -------------------------------------------------
' Crea un nuevo documento a partir de una plantilla
' -------------------------------------------------
Sub creaNuevoDocumento
Dim oDesktop As Variant
Dim oDocumento As Object
Dim mPropArchivo(0) As New com.sun.star.beans.PropertyValue
Dim sUrl As String

' crea el objeto oDesktop


oDesktop = createUnoService("com.sun.star.frame.Desktop")
' define la URL del Archivo modelo, MODIFÍQUELO según su sistema
sUrl = "file:///D:/nad/openoffice/documentation.stw"
' define la propiedad AsTemplate como True (Verdadero)
mPropArchivo(0).Name = "AsTemplate"
mPropArchivo(0).Value = True
' crea el objeto oDocumento
oDocumento = oDesktop.loadComponentFromURL(sUrl,"_blank",0,mPropArchivo())
' INSERTAR CÓDIGO PARA SALVAR AQUÍ
End Sub

Las filas iniciada por la orden Dim declaran todas las variables usadas por la subrutina.
Para cargar un archivo, usamos el método loadComponentFromURL( ), que es definido por
una interfaz del servicio Desktop. Luego, necesitamos un objeto UNO Desktop, declarado en
la línea Dim oDesktop As Variant. Aquí, el tipo Variant sigue una recomendación de la Guía
de Desarrolladores para la declaración de objetos UNO.
La variable sUrl (tipo String) recibe una especificación completa del camino para el archivo.
Se pasará como argumento del método loadComponentFromURL( ).
El método loadComponentFromURL( ) devuelve un objeto Document. La línea Dim
oDocumento As Object reserva memoria para este objeto.

24 Introducción a OpenOffice.org Basic


Versión 1 Introducción al API de OpenOffice.org

El método loadComponentFromURL( ) recibe una secuencia de propiedades como argumento.


La línea Dim mPropArchivo declara y define un array para esta secuencia. La definición del
objeto se hace con el operador New seguido del tipo de objeto (As New com.sun.star.beans.-
PropertyValue).
La línea oDesktop = createUnoService(...) se encarga de la creación del objeto Desktop.
La línea oDocumento = oDesktop.loadComponentFromURL(...) carga el documento de acuer-
do con los argumentos y devuelve un objeto de tipo Document. Observe que la secuencia
mPropArchivo se pasa como argumento seguida de ( ). El argumento “_blank” significa que
se creará una nueva ventana para el documento.
Ahora, introduzca la Sub creaNuevoDocumento, alterando la variable sUrl para que conten-
ga una vía de acceso completa a una plantilla de texto en su sistema, y ejecute la macro para
ver el resultado.
En el próximo capítulo aprenderemos más sobre programación con documentos de
OpenOffice.org.

Introducción a OpenOffice.org Basic 25


Trabajando con Documentos Versión 1

5 Trabajando con Documentos

5.1 Cargando Documentos


Para cargar o crear un documento de OpenOffice.org debemos:
a) Crear un objeto Desktop
Dim oDesktop As Variant
oDesktop = createUnoService(“com.sun.star.frame.Desktop”)

b) Definir una URL


Debe usted proveer una cadena de caracteres como especificación completa de la ruta de ac-
ceso al documento; en caso de estar abriendo un documento existente, en la forma:
file:///ruta_completa_del_archivo
Para nuevos documentos, creados a partir del modelo patrón, existen URL's predefinidas que
deben usarse según el tipo del documento:
URL Descrição
private:factory/swriter Crea un nuevo documento de Writer
private:factory/scalc Crea un nuevo documento de Calc
private:factory/sdraw Crea un nuevo documento de Draw
private:factory/simpress Crea un nuevo documento de Impress

c) Definir las propiedades del descriptor de medios


El descriptor de medios es un servicio (com.sun.star.document.MediaDescriptor) que define
como un recurso debe ser cargado. Las propiedades del descriptor se definen en una secuen-
cia com.sun.star.beans.PropertyValue. Declare un array para la secuencia, según el número
de propiedades a modificar, tal como sigue:
' declara un array vacío, para poderlo pasar como argumento
Dim mPatron()

' define un array para 1 propiedad (índice 0)


Dim mPropiedades(0) As New com.sun.star.beans.PropertyValue
mPropiedades(0).Name = "AsTemplate"
mPropiedades(0).Value = True

' define un array para 2 propiedades (índices 0 y 1)


Dim mPropiedades(1) As New com.sun.star.beans.PropertyValue

Siguen las descripciones para algunas de las posibles propiedades (existen varias):

26 Introducción a OpenOffice.org Basic


Versión 1 Trabajando con Documentos

Propriedade Tipo Descrição


AsTemplate boolean Si es True (Verdadero) crea un nuevo documento, a
partir del documento cargado, aunque éste no sea una
plantilla. Si fuese una plantilla y AsTemplate como
False, el documento será cargado para su edición.
FilterName String Define un filtro para ser usado para abrir o salvar un
documento.
JumpMark String Tras su carga, salta a una determinada posición (celda,
marcador, etc.).
Overwrite boolean Sobreescribe un documento al salvar. Por omisión,
True (Verdadero).
ReadOnly boolean Define si el documento debe ser de sólo lectura o lectu-
ra / escritura.
Unpacked boolean Al escribir el documento, no será compactado (zip).
Password String Contraseña para escribir o abrir un documento.

d) Definir la ventana de destino


Es el “marco” donde el documento será cargado o creado; si ya existe una ventana con el
nombre especificado, ésta es la que se usará, sino se creará una nueva.
Los nombres predefinidos que siguen nunca se deben usar como nombre de ventana:
“_blank”; “_default”; “_self”; “_parent”; “_top” y “_beamer”. Use “_blank” para crear una
nueva ventana.
e) Definir el “flag” (bandera) de búsqueda
Es una constante que define el tipo de algoritmo usado para encontrar la ventana de destino.
Utilice el valor 0 para no tenerla en cuenta.
f) Llamar al método loadComponentFromURL()
Este método, del objeto Desktop, carga el componente definido por la URL, dentro de la ven-
tana de destino. Veamos los detalles:
loadComponentFromURL( URL As String,
MarcoDestino As String,
FlagBusca As Long,
Propiedades As <com.sun.star.beans.PropertyValue> )
El valor de retorno es un objeto XComponent o Null en caso de error.
Este es un ejemplo de llamada al método:
oDocumento = oDesktop.loadComponentFromURL(sUrl, "_blank", _
0, mPropArquivo())

Esto es todo, analice nuevamente el código de Sub creaNuevoDocumento, del capítulo ante-
rior.

Introducción a OpenOffice.org Basic 27


Trabajando con Documentos Versión 1

5.2 Guardando Documentos


Para salvar un documento, debemos:
(los puntos a), b) y c) siguientes ya se vieron en la sección 5.1 Cargando documentos)
a) Crear un objeto Document
Normalmente, mediante una llamada a loadComponentFromURL( ) o a ThisComponent.
b) Definir una URL
Se trata de la ruta completa del recurso.
c) Definir sus propiedades
Son las propiedades del descriptor de medios.
d) Llamar al método adecuado
Lo documentos de OpenOffice.org soportan los siguientes métodos para salvar componentes:
store ( )
storeAsURL ( sURL As String, Propriedades As <com.sun.star.beans.PropertyValue> )
storeToURL ( sURL As String, Propriedades As <com.sun.star.beans.PropertyValue> )

El método store ( ) simplemente sobreescrive un archivo y no se debe usar en un nuevo docu-


mento sin nombre.
El método storeAsURL ( ) recibe dos argumentos y funciona como el comando Guardar Co-
mo de OpenOffice.org.
El método storeToURL ( ) recibe dos argumentos, salva el contenido del documento en sURL
y no altera el archivo original. Útil para exportar archivos.
Ejemplos de llamadas:
' salva un documento que ya existe
ThisComponent.store ( )
' o suponiendo que oDocumento fue definido
oDocumento.store ( )

Los documentos abiertos con loadComponentURL ( ), deben usar los métodos storeAsURL o
storeToURL.
Como ejemplo, introduzca (o copie y pegue) el siguiente código fuente, tras la línea
' INSERTAR CÓDIGO PARA SALVAR AQUÍ
de Sub creaNuevoDocumento ( ), edite la variable sUrl de acuerdo con su sistema, ejecute la
macro y verifique que un nuevo archivo fue escrito en sURL.
' ------------------------
' Escribe el nuevo archivo
' ------------------------

28 Introducción a OpenOffice.org Basic


Versión 1 Trabajando con Documentos

' Define la URL del nuevo archivo (MODIFÍQUELO según su sistema)


sUrl = "file:///D:/nad/openoffice/nuevo_texto.sxw"
' define la propiedad Overwrite como False
mPropArchivo(0).Name = "Overwrite"
mPropArchivo(0).Value = FALSE
' escribe el nuevo documento
oDocumento.storeAsURL(sUrl, mPropArchivo())

Tenemos, también los métodos siguientes, relacionados con la tarea de salvar archivos:
isModified() As Boolean
Devuelve True (Verdadero) si el recurso fue modificado; si no, devuelve False.
hasLocation ( ) As Boolean
Devuelve True (Verdadero) si el archivo ya existe (fue grabado); de lo contrario devuelve
False.
GetLocation ( ) As String
Devuelve un String con la URL del recurso.
isReadonly ( ) As Boolean
Devuelve True (Verdadero) si el recurso está abierto para sólo lectura, en caso contrario de-
vuelve False.
A continuación, tenemos un fragmento de código más elaborado para salvar archivos:
If (oDocumento.isModified) Then
If (oDocumento.hasLocation And (Not oDocumento.isReadOnly)) Then
oDocumento.store()
Else
oDocumento.storeAsURL(sURL, mPropArquivo())
End If
End If

5.3 Imprimiendo Documentos


El servicio OfficeDocument contiene la interfaz XPrintable, que provee los siguientes méto-
dos para impresión y definición de impresora en OpenOffice.org:
getPrinter ( ) As Variant < com::sun::star::beans::PropertyValue >
setPrinter ( aImpressora As Variant < com::sun::star::beans::PropertyValue >)
print ( xOpcoes As Variant < com::sun::star::beans::PropertyValue >)

Analicemos las características y llamadas de cada uno de estos métodos.


getPrinter () As Variant < com::sun::star::beans::PropertyValue >
Este método devuelve una secuencia con el descriptor de la impresora corriente. El descriptor
(PrinterDescriptor) contiene el nombre de la impresora y las definiciones de la impresora
según la siguiente tabla:

Introducción a OpenOffice.org Basic 29


Trabajando con Documentos Versión 1

Propiedad Descripción
Name Una cadena (String) con el nombre de la impresora.
PaperOrientation Contiene la orientación del papel
PaperFormat Especifica un tamaño de papel predefinido o definido por
el usuario
PaperSize Especifica el tamaño de papel en 1/100 mm.
IsBusy True (Verdadero) si la impresora está ocupada; False en
caso contrario
CanSetPaperOrientation True (Verdadero) si la impresora permite cambiar la
orientacióndel papel
CanSetPaperFormat True (Verdadero) si la impresora permita cambiar el for-
mato de papel
CanSetPaperSize True (Verdadero) si la impresora permite cambiar el ta-
maño del papel
Las últimas cuatro propiedades son de sólo lectura..
Veamos un ejemplo que accede a las propiedades de la impresora actual:
Sub obtieneDescriptorImpresora
Dim oDoc As Object
Dim oDescImpr As Variant
Dim sMsg As String

oDoc = ThisComponent
' obtiene array de estructuras PrinterDescriptor
oDescImpr = oDoc.getPrinter()
' obtiene tamaño del array de estructuras
iNumEstructuras% = UBound(oDescImpr)
' extrae los nombres de las propiedades de la impresora
For n = 0 To iNumEstructuras%
sMsg=sMsg + oDescImpr(n).Name + " "
Next n
' muestra los nombres de las propiedades
MsgBox sMsg,0,"Propiedades Impresora"
' obtiene y muestra el valor de la propiedad PageFormat
' A3=0; A4=1; Letter/Carta=5; ...
MsgBox oDescImpr(2).Value
' comprueba si PageFormat se puede modificar
If oDescImpr(6).Value Then
MsgBox "Formato de Página, ¡puede ser modificado!"
' entonces lo modifica a A4
oDescImpr(2).Value = 1
Else
MsgBox "Formato de Página, ¡no puede ser modificado!"
End If
' muestra nuevamente el valor de PageFormat
MsgBox oDescImpr(2).Value
End Sub

El código anterior llama al método getPrinter ( ) para obtener las propiedades de la impresora
actual. Seguidamente, en el bucle For ... Next, extrae los nombres de cada propiedad. Y, a
continuación, obtiene y altera el formato de página, si es posible.

30 Introducción a OpenOffice.org Basic


Versión 1 Trabajando con Documentos

setPrinter ( aImpresora As Variant < com::sun::star::beans::PropertyValue >)


Asigna una nueva impresora al documento. Puede implicar un reformateado.
Las propiedades de la impresora son las mismas que las de la tabla anterior.

print ( xOpciones As Variant < com::sun::star::beans::PropertyValue >)


Imprime el documento según las opciones de impresión (PrintOptions) en xOpciones. Estas
opciones se describen en la siguiente tabla:
Opción Descripción
CopyCount ( Int ) Especifica el número de copias a imprimir
FileName Cadena con el nombre de un archivo para la impresión
Collate Si True (Verdadero) todo el documento se imprimirá an-
tes de la siguiente copia; de lo contrario, imprime todas
las copias página a página
Pages Una cadena con las páginas que deben imprimirse, por
ejemplo: “1;3;5-8;12”

Veamos algunos ejemplos de código fuente. Para imprimir un documento:


' imprimir el documento con las definiciones actuales
Dim aOpciones ()
oDocumento.print ( aOpciones() )

Para imprimir solamente las páginas 1; 3; 5-8 e 12.


Dim aOpciones(0)
aOpciones(0).Name = "Page"
aOpciones(0).Value = "1;3;5-8;12"
ThisComponent.print ( aOpciones() )

Para imprimir en una impresora diferente de la predefinida, usted necesita alterar la propiedad
“Name” de la impresora y llamar a setPrinter definiendo una nueva impresora, tal como sigue:
Dim mImpresora(0) As New com.sun.star.beans.PropertyValue
Dim aOpciones() ' solamente para pasar el argumento
'
mImpresora(0).Name="Name"
mImpresora(0).value="Segunda_Impresora"
' define una nueva Impresora para el objeto,
' puede ocurrir un reformateado del documento
oDocumento.setPrinter = mImpresora()
' imprime con las opciones predefinidas
oDocumento.print( aOpciones() )

Introducción a OpenOffice.org Basic 31


Trabajando con Documentos Versión 1

5.4 Cerrando Documentos


Para cerrar un documento, debemos considerar dos casos:
a) Abierto con loadComponentFromURL( )
Vimos que este método devuelve un objeto XComponent. La interfaz de este servicio provee
el método dispose( ), que se usa para cerrar un componente, su llamada es simple:
oDocumento.dispose()

Añada la línea anterior tras la última linea de Sub creaNuevoDocumento( ), ejecute la macro
y observe el resultado.
b) Abierto por la interfaz de usuario de OpenOffice.org
Si el documento se cargó con la orden Archivo => Abrir de OpenOffice.org y no hubiese una
definición de un objeto Document, use la propiedad ThisComponent, como sigue:
ThisComponent.dispose()

Atención: el método dispose( ) descarta todas las modificaciones efectuadas en el documento.


Por consiguiente, antes de llamarlo, asegúrese de guardarlas. O, mejor incluso, use
isModified( ) para alertar al usuario.
Existen maneras más seguras para controlar el cierre de componentes, pero están más allá del
ámbito de esta Introducción.

5.5 Identificando los Documentos Abiertos


Todos los documentos abiertos son administrados por el objeto Desktop. Cada documento es
considerado un componente de este objeto, sin embargo, no todo componente es un documen-
to. Por ejemplo, si tenemos una hoja de cálculo y un documento de texto abiertos, con el Na-
vegador de Fuentes de Datos activo, existen tres componentes en el Desktop, de los cuales
sólo dos son documentos.
La Sub muestraComponentes, a continación, obtiene una enumeración de los componentes
activos, verifica cuales son modelos de documentos y muestra información sobre su tipo.
Sub muestraComponentes
Dim oComponentes As Variant
Dim oComp As Variant
Dim sURL As String
Dim sTipo As String

oComponentes = StarDesktop.getComponents().createEnumeration()
n = 0
Do While (oComponentes.hasMoreElements())
oComp = oComponentes.nextElement()
' no todos los componentes son modelos con una URL

32 Introducción a OpenOffice.org Basic


Versión 1 Trabajando con Documentos

If HasUnoInterfaces(oComp, "com.sun.star.frame.XModel") Then


sURL = oComp.getURL()
If oComp.SupportsService("com.sun.star.sheet.SpreadsheetDocument") Then
sTipo = "Calc"
ElseIf oComp.SupportsService("com.sun.star.text.TextDocument") Then
sTipo = "Writer"
ElseIf oComp.SupportsService("com.sun.star.drawing.DrawingDocument") Then
sTipo = "Draw"

ElseIf oComp.SupportsService("com.sun.star.formula.FormulaProperties") Then


sTipo = "Math"
Else
sTipo = "Otro"
End If
MsgBox sTipo + Chr$(13) + sURL
End If
n = n + 1
Loop
MsgBox "Componentes: " + Str$(n)
End Sub

Analice atentamente el código anterior, que muestra importantes aspectos de la programación


del API de OpenOffice.org. Observe como se crea una enumeración y como recorremos sus
elementos.
Tras la identificación de un documento, usted puede, por ejemplo, ordenar su impresión o su
cierre, además de manipular su contenido, aplicando las técnicas que serán vistas en los próxi-
mos capítulos.

Introducción a OpenOffice.org Basic 33


Documentos de Writer Versión 1

6 Documentos de Writer

6.1 Introducción
En este capítulo, veremos como efectuar tareas simples de procesamiento de texto como: edi-
ción, formateo, búsqueda y reemplazo.
Abordaremos la cuestión mediante ejemplos prácticos, con una breve explicación de los as-
pectos más importantes.
Un documento de Writer contiene principalmente texto, organizado en párrafos y tablas.
Además de estos elementos básicos, soporta marcos, objetos incrustados, campos, imágenes,
marcadores, índices y muchos otros objetos. Estos datos conforman un modelo de docu-
mento.
Mediante el modelo, podemos manipular los datos independientemente de su representación
visual. Para manejar el aspecto visual del documento, el modelo dispone de un objeto con-
trolador.
Algunos elementos de un documento (gráficos, marcos, etc) son nombrados y están anclados
en un párrafo, carácter o página. Los párrafos no reciben ni nombre ni índice, de modo que su
acceso debe ser secuencial.

6.2 Editando texto


Antes de comenzar a editar el texto de un documento, debemos tener en mente lo siguiente:
a) Crear una instancia del componente a editar, es decir, un objeto que represente el documen-
to de Writer;
b) Obtener el contenido a editar, en este caso, un objeto con el texto del documento;
c) Hacer la edición del contenido, usando los métodos apropiados.
Cree un nuevo documento de Writer, vaya al IDE Basic, introduzca el siguiente código y eje-
cute Sub editaTexto para ver el resultado
Sub editaTexto
Dim oDoc As Object
Dim oTxt As Object
Dim oTxtRange As Object
Dim sStr As String

oDoc = ThisComponent
oTxt = oDoc.getText()
sStr = "Esta es una "
oTxt.setString( sStr )
oTxtRange = oTxt.getEnd()
sStr = "cadena de caracteres "

34 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

oTxtRange.setString( sStr )
End Sub

En este ejemplo, usamos la interfaz XTextRange para editar texto. Sus métodos son:
getText( ) As Text
devuelve un objeto Text
getString( ) As String
devuelve un String contenido en el objeto
setString( sStr As String )
define un String con el contenido del objeto
getStart( ) As Object <TextRange >
devuelve un objeto TextRange apuntando al inicio del objeto que le llama
getEnd( ) As Object <TextRange>
devuelve un objeto TextRange apuntando al final del objeto que le llama
Inicialmente, llamamos al método getText( ), que devuelve un objeto Text, paso correspon-
diente al punto b) anterior.
Seguidamente, en la línea oTxt.setString(sStr), definimos una cadena de caracteres para nues-
tro objeto Text, esto quiere decir que todo el contenido del documento – objeto oTxt – será
sustituido por la cadena sStr de setString. Antes de insertar más texto, precisamos obtener el
final del contenido de oTxt con la llamada al método getEnd( ) y usar este nuevo objeto –
TextRange – para insertar más texto. A través del método getStart( ), podríamos insertar texto
al principio del contenido.
Observe, además, que las variables de los servicios Text y TextRange se declaran como
Object.
Atención, oTxt también es un TextRange, así que podemos sustituir la variable oTxtRange
por el encadenamiento de métodos siguiente:
oTxt.getEnd ().setString ( sStr )

Este proceso de edición es muy limitado. Tan sólo podemos sustituir todo el contenido del
texto e insertar texto al inicio o final del documento. Veamos como mejorar esto en la próxi-
ma sección.

6.3 Moviéndose por el texto


Para aumentar la flexibilidad en la edición de texto, el modelo de documento nos ofrece dos
tipos de cursor: un cursor de texto y un cursor de vista. El primero opera sobre el contenido
del documento independientemente de la interfaz gráfica, y el segundo representa el cursor vi-
sible en la interfaz gráfica. Usted puede crear tantos cursores como desee.

Introducción a OpenOffice.org Basic 35


Documentos de Writer Versión 1

El alcance de un cursor tiene un inicio y un final, que puede abarcar un rango variable de texto
o coincidir en un mismo punto. El alcance del cursor puede ser expandido con el desplaza-
miento del mismo.
En Writer, además del cursor de texto, tenemos también: cursor de palabra, cursor de senten-
cia y cursor de párrafo, todos ellos derivados del cursor de texto.
Veamos, ahora, las interfaces y métodos usados para flexibilizar la edición de texto.
La interfaz XSimpleText, derivada de XTextRange, se usa en la creación del cursor de texto,
en la inserción de cadenas y de caracteres de control, y posee los siguientes métodos::
createTextCursor ( ) As Object <TextCursor>
Devuelve un objeto cursor de texto (al principio del contenido).
createTextCursorByRange (aPos As TextRange) As Object <TextCursor>
Crea un objeto cursor de texto en la posición especificada por el argumento.
insertString(aPos As TextRange, sStr As String, bFlag As Boolean)
Inserta la cadena en la posición. Si bFlag fuese True (Verdadero) el contenido de aPos será
sustituido por sStr; si no, sStr se añadirá al final de aPos.
insertControlCharacter( aPos As TextRange, iChar As Integer, bFlag As Boolean )
Insertar un carácter de control en la posición aPos.
El servicio TextCursor, a través de la interfaz XTextCursor, suministra métodos para el con-
trol del estado y movimiento del cursor.
a) Métodos para mover el cursor:
goLeft (iNumChar As Integer, bExpande As Boolean) As Boolean
mueve el cursor a la izquierda iNumChar caracteres
goRight (iNumChar As Integer, bExpande As Boolean) As Boolean
mueve el cursor a la derecha iNumChar caracteres
gotoStart (bExpande As Boolean)
mueve el cursor al principio del texto
gotoEnd (bExpande As Boolean)
mueve el cursor al final del texto
gotoRange (xRange As <TextRange>, bExpande As Boolean)
mueve o expande el cursor sobre el objeto TextRange
En todos los métodos anteriores, si bExpande es True (Verdadero) se expandirá el alcance del
cursor.
b) Métodos para controlar el estado del cursor:
collapseToStart ( )
mueve la posición de final del cursor hasta el inicio del mismo
collapseToEnd ( )
mueve la posición de inicio del cursor hasta el final del mismo
isCollapsed ( ) As Boolean
devuelve True (Verdadero) si coinciden las posiciones inicial y final del cursor.

36 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

Las interfaces XWordCursor, XSentenceCursor e XparagraphCursor, todas ellas


derivadas de XTextCursor, también proporcionan métodos para control y movimiento del
cursor.
a) Métodos de XWordCursor:
gotoNextWord (bExpande As Boolean) As Boolean
gotoPreviousWord (bExpande As Boolean) As Boolean
gotoEndOfWord (bExpande As Boolean) As Boolean
gotoStartOfWord (bExpande As Boolean) As Boolean
isStartOfWord ( ) As Boolean
isEndOfWord ( ) As Boolean

b) Métodos de XSentenceCursor:
gotoNextSentence (Expande As Boolean) As Boolean
gotoPreviousSentence (bExpande As Boolean) As Boolean
gotoStartOfSentence (bExpande As Boolean) As Boolean
gotoEndOfSentence (bExpande As Boolean) As Boolean
isStartOfSentence ( ) As Boolean
isEndOfSentence ( ) As Boolean

c) Métodos de XParagraphCursor:
gotoStartOfParagraph (bExpande As Boolean) As Boolean
gotoEndOfParagraph (bExpande As Boolean) As Boolean
gotoNextParagraph (bExpande As Boolean) As Boolean
gotoPreviousParagraph (bExpande As Boolean) As Boolean
isStartOfParagraph ( ) As Boolean
isEndOfParagraph ( ) As Boolean

Antes de presentar un ejemplo, veamos los caracteres de control que pueden ser insertados en
un documento de Writer. En la interface gráfica, se les denomina caracteres no imprimibles y
tienen funciones especiales en la presentación final del documento.
Para facilitar su empleo, estos caracteres están definidos como constantes, en el grupo de
constantes com.sun.star.text.ControlCharacter. Pueden ser insertados en el texto con el méto-
do insertControlCharacter ( ) o como parte del contenido de una cadena, en este caso, usando
su código Unicode.
Esta es una relación de los caracteres de control con sus respectivos códigos:

Constante Descripción Cód.


Unicode
PARAGRAPH_BREAK Inserta un salto de párrafo 0x000D
LINE_BREAK Salto de línea dentro de un párrafo 0x000A
HARD_HYPHEN Guión protegido; no lo modifica la separación 0x2011
silábica.

Introducción a OpenOffice.org Basic 37


Documentos de Writer Versión 1

Constante Descripción Cód.


Unicode
SOFT_HYPHEN Marca una posición preferida para la 0x00AD
separación silábica.
HARD_SPACE Espacio protegido, con tamaño fijo. 0x00A0
APPEND_PARAGRAPH Añade un nuevo párrafo No tiene

Finalizaremos la sección con un ejemplo demostrando el uso de algunos de los conceptos y


métodos presentados.
Active el IDE Basic, introduzca el siguiente código y ejecute la subrutina Sub procesaTexto.
La macro inserta texto, caracteres de control y un salto de página en un nuevo documento sin
nombre. Después, selecciona y sustituye dos palabras por una cadena vacía.

Sub procesaTexto
Dim oDesktop As Variant
Dim oDoc As Object
Dim oCursor As Object
Dim oTexto As Object
Dim mPropArchivo()
Dim sStr As String

oDesktop = createUnoService("com.sun.star.frame.Desktop")
oDoc = oDesktop.loadComponentFromURL("private:factory/swriter",_
"_blank", 0, mPropArchivo())
oTexto = oDoc.getText()
oCursor = oTexto.createTextCursor()
sStr = "Éste es el texto del primer párrafo del documento"
With oTexto
' inserta el texto en la posición actual del cursor
.insertString(oCursor, sStr, False)
' insertar un salto de párrafo
.insertControlCharacter(oCursor,_
com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
.insertString(oCursor, "Éste es el segundo párrafo", False)
.insertControlCharacter(oCursor, _
com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
End With
' inserta una nueva página
oCursor.gotoStartOfParagraph(True)
oCursor.breakType = com.sun.star.style.BreakType.PAGE_BEFORE
oTexto.insertString(oCursor, "Estoy en una nueva página.", False)
' mueve el cursor sin expansión
oCursor.gotoStart(False)
oCursor.gotoNextWord(False)
oCursor.gotoNextWord(False)
oCursor.gotoNextWord(False)
' mueve el cursor expandiendo, selecciona “texto de”
oCursor.gotoNextWord(True)
oCursor.gotoNextWord(True)
' sustituye el texto entre el principio y el final del cursor
oTexto.insertString(oCursor, "", True)

End Sub

38 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

En el código anterior, estudie el empleo del argumento bExpande (True o False), pues es muy
importante.
Otro aspecto es la inserción de salto de página. No existe un carácter de control para salto de
página o columna. Esa es una propiedad del párrafo. Observe que usamos oCursor para defi-
nir una propiedad del párrrafo (oCursor.breakType). Esto es posible porque el objeto Text-
Cursor hereda las características de TextRange.
Los posibles valores para la propiedad breakType (salto de página y columna) se enumeran en
com.sun.star.style.BreakType, aquí usamos PAGE_BEFORE.
Finalmente, observe en el nuevo documento que el cursor de vista se encuentra al final del
mismo, a pesar de la última acción (selección y reemplazo) ha ocurrido en el primer párrafo,
lo que demuestra la independencia entre el cursor de texto y la interfaz gráfica.
Recuerde, además, que el acceso a la interfaz gráfica se da a través del controlador del modelo
de documento. El código fuente de la subrutina dlgInsertarFrase, del Capítulo 3 (Piloto Au-
tomático), muestra como acceder al controlador y crear un cursor de vista.

6.4 Formateando texto


Es ésta otra tarea común en procesamiento de textos. Tenemos dos maneras de abordar el for-
mateo del texto: la primera es aplicar las caracterísiticas deseadas directamente sobre el
objeto, sobreescribiendo las definiciones básicas; por ejemplo, seleccionar un párrafo y
cambiar su ajuste; la segunda consiste en aplicar un estilo predefinido de formateo, por
ejemplo, seleccionar un párrafo y cambiar su estilo de Predefinido a Título.
En principio, vamos a demostrar el primer enfoque. Existe una gran cantidad de propiedades
relacionadas con el formato, como propiedades de caracteres y de párrafos.
El servicio com.sun.star.style.CharacterProperties define las propiedades comunes de ca-
racteres. Veamos algunas de ellas:
Propiedad Descripción
CharFontName Especifica el nombre de estilo de la fuente
CharFontStyleName Contiene el nombre de estilo de la fuente
CharFontFamily La familia de la fuente (com.sun.star.awt.FontFamily)
CharHeight Valor de la altura de los caracteres en puntos
CharUnderline Valor del carácter subrayado (com.sun.star.awt.Underline)
CharWeight Valor del peso de la fuente (com.sun.star.awt.FontWeight)
CharPosture Valor de inclinación de fuente (com.sun.star.awt.FontSlant)
CharFlash Si True (Verdadero), el carácter parpadea. Es opcional
CharStrikeout Tipo de tachado del carácter
(com.sun.star.awt.FontStrikeout)
CharRotation Rotación del carácter en grados

Introducción a OpenOffice.org Basic 39


Documentos de Writer Versión 1

En la tabla anterior, las referencias al módulo com.sun.star.awt, contienen posibles valores


para las respectivas propiedades de los caracteres.
El servicio com.sun.star.style.ParagraphProperties define las propiedades de los párrafos.
La siguiente tabla, presenta algunas:
Propiedad Descripción
ParaAdjust Define el tipo de alineación horizontal
(com.sun.star.style.ParagraphAdjust)
ParaBackColor Contiene el color de fondo, es opcional
ParaLastLineAdjust Define la alineación horizontal de la última línea
ParaLeftMargin Especifica la sangría izquierda en 1/100 mm ( As Long )
ParaRightMargin Especifica la sangría derecha en 1/100 mm ( As Long )
ParaTopMargin Define el espacio anterior al párrafo en1/100 mm (As Long)
ParaBottomMargin Define el espacio posterior al párrafo en 1/100 mm (As Long)
ParaStyleName Contiene el nombre de estilo del párrafo actual; es opcional.
LeftBorder Define borde izquierdo; opcn. (com.sun.star.table.BorderLine )
RightBorder Define borde derecho; opcn. (com.sun.star.table.BorderLine )
TopBorder Define borde superior; opcn. (com.sun.star.table.BorderLine )
BottomBorder Define borde inferior; opcn. (com.sun.star.table.BorderLine )
BorderDistance Distancia del borde al objeto
ParaFirstLineIndent Sangría de primera línea, es opcional.
ParaVertAlignment Alineación vertical (com.sun.star.text.ParagraphVertAlign)

Nuevamente, las referencias com.sun.star contienen posibles valores para las respectivas pro-
piedades, generalmente un valor de 0 a n para constantes. Veamos algunas de ellas:
Constantes de com.sun.star.style.ParagraphAdjust: LEFT, RIGHT, BLOCK, CENTER e
STRETCH.
Constantes de com.sun.star.text.ParagraphVertAlign: AUTOMATIC, BASELINE, TOP,
CENTER e BOTTOM.
Existen muchas otras propiedades para caracteres y párrafos, una consulta a la Guía para De-
sarrolladores o al Manual de Referencia, ambos de Sun Microsystems Inc., es indispensable
para quienes deseen programar en OpenOffice.org
Volvamos a nuestro último ejemplo Sub procesaTexto. Deseamos cambiar la inclinación y
color de fuente de la palabra “segundo” y, también, el estilo de un párrafo de estilo Título.
Introduzca el siguiente código, tras la última línea de la subrutina, ejecútela y observe el re-
sultado.
' ----------------------
' código para formateado
' ----------------------
oCursor.gotoNextParagraph(FALSE)

40 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

oCursor.gotoNextWord(False)
oCursor.gotoNextWord(False)
oCursor.gotoNextWord(False)
oCursor.gotoNextWord(True)
oCursor.CharPosture = com.sun.star.awt.FontSlant.REVERSE_ITALIC
oCursor.CharColor = RGB(255,0,0)
' aplica estilo de párrafo
oCursor.gotoNextParagraph(FALSE)
oCursor.paraStyleName = "Heading"

Observe la asignación a la propiedad CharPosture de un valor enumerado REVERSE_ITALIC


y, además, la modificación del estilo de párrafo a “Heading”. Tratándose de programación,
los nombres permanecen en inglés, difiriendo de los nombres que nos muestra OpenOffice.org
en el Catálogo de Estilos.

6.5 Formateando con estilo


Veamos, ahora, el segundo enfoque para formateado, que es la aplicación de un estilo al obje-
to. Siempre que sea posible, formatee sus documentos usando este método. Esto facilita futu-
ras modificaciones, pues basta cambiar las características de un estilo para que se modifiquen
todos los objetos formateados con él.
El módulo com.sun.star.style provee diversas interfaces para formateo, definición y acceso a
los estilo usados por OpenOffice.org.
Writer dispone de diversos tipos de estilos. Tenemos estilos de párrafo, estilos de carácter,
estilos de numeración y estilos de marco. Todos ellos agrupados dentro de la Familia de Esti-
los:
Familia de Estilos
Estilos de Páginas ( estilo_1, estilo_2, ..., estilo_n )
Estilos de Párrafo ( estilo_1, estilo_2, ..., estilo_n )
Estilos de Carácter ( estilo_1, estilo_2, ..., estilo_n )
Estilos de Marco ( estilo_1, estilo_2, ..., estilo_n )
Estilos de Numeración ( estilo_1, estilo_2, ..., estilo_n )

El servicio com.sun.star.style.StyleFamilies contiene las familias de estilos de un documen-


to; para obtener esta colección haga:
Dim oFamiliasEstilos As Object
oFamiliasEstilos = ThisComponent.getStyleFamilies()

En un documento de texto, una llamada al método getElementNames () devuelve un array


con los nombres de las siguientes familias:
CharacterStyles - estilos de carácter
ParagraphStyles - estilos de párrafo
FrameStyles - estilos de marco
PageStyles - estilos de página
NumberingStyles - estilos de numeración

Introducción a OpenOffice.org Basic 41


Documentos de Writer Versión 1

El servicio com.sun.star.style.StyleFamily contiene los estilos de una misma familia; para


obtener esta colección, use el acceso por nombre con getByName(“NombreDeFamilia”):
oEstParrafo = ThisComponent.StyleFamilies.getByName(“ParagraphStyles”)

El servicio com.sun.star.style.Style define las características de un estilo; para obtener un es-


tilo, use el acceso por índice, por ejemplo, si se definió el objeto oEstParrafo anterior:
oEstilo = oEstParrafo (1)

devuelve el segundo estilo dentro de la colección de estilos de párrafo.


La API de OpenOffice.org provee interfaces para facilitar el acceso a los elementos de una
colección. Al trabajar con estilos necesitamos conocer los métodos:
con.sun.star.container.XNameAcess
getByName (sNombre As String ) As Variant
getElementNames ( ) As aStrings ( )
hasByName ( sNombre As String ) As Boolean

con.sun.star.container.XIndexAcess
getCount ( ) As Long
getByIndex ( nIndice As Long ) As Variant

con.sun.star.container.XNameContainer
insertByName ( sNombre As String, oElemento As Variant)
removeByName ( sNombre As String )

El servicio com.sun.star.style.PageStyle define las propiedades más comunes de la página; a


continuación tenemos algunas:
Propiedad Descripción
BackColor Valor Long del color de fondo de página
LeftMargin Valor Long del margen izquierdo en 1/100 mm
RightMargin Valor Long del margen derecho en 1/100 mm
TopMargin Valor Long del margen superior en 1/100 mm
BottomMargin Valor Long del margen inferior en 1/100 mm
IsLandscape Si la orientación es horizontal o apaisada, True (Verdadero)
PageStyleLayout Determina el diseño de página del estilo
(com.sun.star.style.PageStyleLayout)
Size Valores Long especificando el tamaño del papel (Size.Width e
Size.Height)
Width Valor Long especificando el ancho de la página en 1/100 mm

42 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

Propiedad Descripción
Height Valor Long especificando la altura de la página en 1/100 mm
HeaderLeftMargin Valor Long especificando el margen izquierdo del encabezado
en 1/100 mm
HeaderRightMargin Valor Long definiendo el margen derecho del encabezado en
1/100 mm
HeaderIsOn Determina si el encabezado está activo (True / False)
FooterLeftMargin Valor Long especificando el margen izquierdo del pie de página
en 1/100 mm
FooterRightMargin Valor Long especificando el margen derecho del pie de página
en 1/100 mm
FooterIsOn Determina si el pie de página está activo (True / False)

Vamos a un ejemplo. Queremos mostrar el número de estilos de página disponibles en un do-


cumento, sus nombres y propiedad Size del estilo de página Predefinido (Standard). Los pa-
sos básicos serán:
a) obtener las familias de estilos del documento;
b) obtener los estilos de página;
c) obtener un array con los nombres de estilos de página;
d) usar un índice para extraer cada uno de los nombres;
e) obtener la página predefinida, usando el acceso por nombre.
La siguiente subrutina Sub muestraEstilosPagina implementa nuestro ejemplo:
Sub muestraEstilosPagina
Dim oDoc As Object
Dim oFamiliaEstilos As Object
Dim oEstilosPagina As Object
Dim oPaginaPredefinida As Object
Dim mNombresEstilosPagina As Variant
Dim sEstilo As String
Dim sMsg As String

oDoc = ThisComponent
' obtiene la Familia de Estilos (observe el uso de oDoc)
oFamiliaEstilos = oDoc.StyleFamilies
' obtiene los Estilos de Página
oEstilosPagina = oFamiliaEstilos.getByName("PageStyles")
' muestra el número de Estilos de Página
MsgBox oEstilosPagina.Count
' obtiene y muestra los nombres de los Estilos de Página
mNombresEstilosPagina = oEstilosPagina.getElementNames()
For n = LBound(mNombresEstilosPagina) To UBound(mNombresEstilosPagina)
sMsg=sMsg + mNombresEstilosPagina(n) + " "
Next n
MsgBox sMsg,0,"Estilos de Páginas"
' obtiene el Estilo de Página Predefinido (Standard)
oPaginaPredefinida = oEstilosPagina.getByName("Standard")

Introducción a OpenOffice.org Basic 43


Documentos de Writer Versión 1

' comprobando el tamaño de página


lAnchoPag = oPaginaPredefinida.Size.Width
lAltoPag = oPaginaPredefinida.Size.Height
MsgBox Str$(lAnchoPag) + " " + Str$(lAltoPag)

End Sub

A destacar, el acceso mediante índice dentro del bucle For ... Next, el acceso nominal al estilo
de página “Standard” y el acceso a la propiedad Size.
Observe, también, la llamada al método getStylesFamilies():
oFamiliaEstilos = oDoc.StylesFamilies
en OpenOffice.org Basic usted puede omitir el get y el set al programar propiedades.
Este ejemplo puede usarse como modelo para diversas operaciones con estilos.
Durante el formateo de texto, es habitual la creación y aplicación de nuevos estilos. Esta es
una tarea fácil de ejecutar dentro de una macro. Para ello seguiremos los pasos:
a) Obtener las familias de estilos del documento;
b) Obtener la familia del grupo donde será creado el nuevo estilo;
c) Crear una instancia de objeto del nuevo estilo;
d) Añadir el nuevo estilo al grupo;
e) Especificar las propiedades del nuevo estilo;
f) Aplicar el nuevo estilo.
Volveremos a tomar la subrutina Sub procesaTexto y añadiremos un nuevo estilo de párrafo.
Introduzca (o copie y pegue) el siguiente código, tras la última línea de la Sub procesaTexto,
ejecute la macro y observe las definiciones de estilo del primer párrafo del documento.
' ------------------------
' código para nuevo estilo
' ------------------------
Dim oFamiliasEstilos As Object
Dim EstilosParrafo As Object
Dim oNuevoEstilo As Object
' obtiene las familias de Estilos
oFamiliasEstilos = oDoc.StyleFamilies
' obtiene los estilos de párrafo
EstilosParrafo = oFamiliasEstilos.getByName("ParagraphStyles")
' crea un nuevo estilo de párrafo
oNuevoEstilo = oDoc.createInstance("com.sun.star.style.ParagraphStyle")
' añade el nuevo estilo con el nombre "nuevo_estilo"
EstilosParrafo.insertByName("nuevo_estilo",oNuevoEstilo)
' especifica las propiedades del estilo
oNuevoEstilo.Name = "nuevo_estilo"
oNuevoEstilo.CharFontName = "Arial"
oNuevoEstilo.CharHeight = 16
oNuevoEstilo.ParaAdjust = com.sun.star.style.ParagraphAdjust.CENTER
oNuevoEstilo.CharWeight = com.sun.star.awt.FontWeight.BOLD
' entonces, aplica el nuevo estilo al primer párrafo
oCursor.gotoStart(FALSE)
oCursor.gotoEndOfParagraph(TRUE)
oCursor.paraStyleName = "nuevo_estilo"

44 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

Del código anterior, observe la creación de un nuevo objeto, en este caso una instancia de un
estilo de párrafo, mediante la llamada al método createInstance(...), así como la definición de
las propiedades del nuevo estilo.

6.6 Obteniendo el objeto seleccionado


La API de OpenOffice.org permite que una macro obtenga el contenido de una selección para
aplicar alguna acción sobre el mismo. La interfaz com.sun.star.frame.XModel provee el si-
guiente método, que devuelve uno o más objetos como la selección actual del controlador ac-
tual:
getCurrentSelection ( ) As Object
El objeto devuelto es del tipo com.sun.star.uno.XInterface y depende del contenido de la se-
lección.
Contenido de la selección Objeto devuelto
Texto Uno o más objetos apuntando a TextRange
Celdas de tabla Un objeto apuntando a un cursor de tabla
Cuadro de texto Un objeto apuntando a un cuadro de texto
Gráfico Un objeto apuntando a un gráfico
Diseño Uno o más objetos apuntando a ShapeCollection

Para selección de texto, el método getCurrentSelection ( ) opera de la siguiente manera:


a) si no hay nada seleccionado, devuelve un objeto TextRange con la posición actual del cur-
sor de vista;
b) en una selección simple, devuelve un objeto TextRange con la selección;
c) en una selección múltiple, devuelve objetos TextRange con el cursor de vista para cada una
de las selecciones.
En el siguiente ejemplo, obtenemos una o más cadenas seleccionadas, y las ponemos en color
rojo:
Sub procesaSeleccion
Dim oDoc As Object
Dim oSel As Object
Dim oCurTxt As Object

oDoc = ThisComponent
oSel = oDoc.getCurrentSelection()
For i = 0 To oSel.Count-1
oCurTxt = oSel(i)
oCurTxt.CharColor = RGB(255,0,0)
Next i
MsgBox oSel.Count
End Sub

Introducción a OpenOffice.org Basic 45


Documentos de Writer Versión 1

Observe el acceso a los objetos seleccionados a través de un índice y la creación de un cursor


de texto antes del cambio de color.
Para extraer la cadena seleccionada, llame al método getString(), como sigue:
sCadena = oSel(i).getString()

El método getString() devuelve una cadena vacía para el primer objeto en los casos a) y c)
anteriores. Inserte el código inferior en el bucle For ... Next de procesaSeleccion y observe la
salida:
MsgBox Str$(i) + ": " + oSel(i).getString()

Si quiere usted efectuar alguna acción en la palabra sobre el cursor de vista, haga:
If Len(oSel(0).getString())= 0 Then
oCurTxt = oSel(0).Text.createTextCursorByRange(oSel(0).getStart())
oCurTxt.gotoStartOfWord(False)
oCurTxt.gotoEndOfWord(True)
End If

Analice como se crea el cursor de texto. Seguidamente, como ejercicio, haga que la Sub pro-
cesaSeleccion aplique un color también en la palabra sobre el cursor de vista.
La API de OpenOffice.org tiene, también, la interfaz com.sun.star.view.XSelectionSupplier,
que implementa algunos métodos de selección para la interfaz gráfica, entre ellos:
select ( oObjeto As Object ) As Boolean
si es posible, selecciona el objeto oObjeto en la interfaz gráfica.
getSelection ( ) oObjeto As Variant
obtiene la selección en la interfaz gráfica, puede devolver un objeto o una colección de obje-
tos.
Estos métodos pueden ser llamados mediante el controlador actual del modelo (vea la sección
de código más adelante).
Existen, además, dos métodos que pueden ser útiles para la identificación del contenido selec-
cionado, son:
getImplementationName ( ) As String
devuelve el nombre de la implementación del objeto
getName ( ) As String
devuelve el nombre del objeto, si el mismo estuviese nombrado, caso de gráficos y tablas.
Dim oControlador As Object
oControlador = oDoc.getCurrentController()
oSel = oControlador.getSelection()
sNomeImpl = oSel.getImplementationName()
sNome = oSel.getName()

46 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

Ahora, modifique Sub procesaSeleccion, para avisar al usuario cuando él seleccione algo
diferente de texto (pista: use getImplementationName).

6.7 Localizando objetos


Un documento de Writer puede contener otros objetos además de texto, como gráficos, tablas,
campos, cajas de texto, etc. Para cada tipo existe una interfaz con métodos que devuelven una
colección con los objetos existentes en el documento. He aquí algunos:
getTextTables ( ) As <com.sun.star.container.XNameAccess >
getTextFrames ( ) As <com.sun.star.container.XNameAccess >
getGraphicObjects ( ) As <com.sun.star.container.XNameAccess >
getTextSections ( ) As <com.sun.star.container.XNameAccess >
getBookMarks ( ) As <com.sun.star.container.XNameAccess >
getTextFields ( ) As <com.sun.star.container.XEnumerationAccess >
getFootNotes ( ) As <com.sun.star.container.XIndexAccess >
getEndNotes ( ) As <com.sun.star.container.XIndexAccess >
getDocumentIndexes ( ) As <com.sun.star.container.XIndexAccess >

La interfaz XNameAccess implementa los siguientes métodos:


getByName (sNombreDelObjeto As String ) As Variant
devuelve el objeto nombrado
getElementNames ( ) As String ()
devuelve una secuencia de cadenas con los nombres de los objetos de la colección
hasByName ( sNombre As String ) As Boolean
devuelve True (Verdadero) si el objeto de nombre sNombre existe en la colección
La interfaz XIndexAccess define los métodos siguientes:
getByIndex ( iIndice As Long ) As Object
devuelve el objeto en la posición iIndice de la colección
getCount ( ) As Long
devuelve el número de objetos de la colección
La interfaz XEnumerationAccess define el métido:
createEnumeration ( ) As Object <com.sun.star.container.XEnumeration>
devuelve un objeto XEnumeration
La interfaz XEnumeration implementa os métodos siguientes:
hasMoreElements ( ) As Boolean
devuelve True (Verdadero) si aún existen elementos en la colección
nextElement ( ) As Variant
devuelve el siguiente elemento.

Introducción a OpenOffice.org Basic 47


Documentos de Writer Versión 1

La localización es sencilla, basta llamar al método apropiado y a continuación, usar el acceso


nominal o indexado para obtener el objeto.
La subrutina siguiente, Sub localizaGraficos, muestra los nombres de todas las imágenes del
documento:
Sub localizaGraficos
Dim oGraficos As Object
Dim oGrafico As Object
Dim n As Integer

oGraficos = ThisComponent.getGraphicObjects()
For n = 0 To oGraficos.Count -1
oGrafico = oGraficos (n)
MsgBox oGrafico.getName()
Next n
MsgBox "Gráficos en el documento: " + Str$(oGraficos.Count)
End Sub

Para eliminar una imagen de su documento, puede usted usar el siguiente bloque de código:
oGrafico = oGraficos.getByName (“Gráfico2”)
oGrafico.dispose ()

Como ejemplo de como trabajar con enumeraciones, mediante el siguiente código mostrare-
mos el comando de cada uno de los campos de un documento:
Sub localizaCampos

Dim oCampos As Object


Dim oCampo As Object
Dim n As Integer

oCampos = ThisComponent.getTextFields().createEnumeration()
n = 0
Do While (oCampos.hasMoreElements())
oCampo = oCampos.NextElement()
MsgBox oCampo.getPresentation(True)
n = n + 1
Loop
MsgBox "Campos en el documento: " + Str$(n)

End Sub

Observe como la creación y el acceso a los elementos de una enumeración es secuencial y no


indexada o nominal. El método getPresentation() devuelve el contenido de un campo si el ar-
gumento es False.
Generalmente, para recuperar el objeto que nos interesa dentro de la colección devuelta por
uno de los métodos anteriores, necesitamos conocer su nombre o su posición dentro de la co-
lección.

48 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

6.8 Búsqueda y Reemplazo


La API de OpenOffice.org tiene mecanismos avanzados para la búsqueda y sustitución de tex-
to en un documento.
Para localizar y sustituir texto debemos: crear un descriptor de búsqueda o reemplazo; es-
pecificar sus propiedades y llamar al método apropiado.
La interfaz com.sun.star.util.XSearchable proporciona los siguientes métodos de búsqueda:
createSearchDescriptor ( ) As Object <SearchDescriptor>
crea un descriptor de búsqueda para recibir las propiedades de la búsqueda.
FindAll ( oDescriptor As Object ) As Object <com.sun.star.container.XIndexAccess>
devuelve una colección de TextRange con todos los resultados de la búsqueda.
FindFirst ( oDescriptor As Object ) As Object <com.sun.star.uno.XInterface>
devuelve un TextRange con el primer resultado de la búsqueda
FindNext ( oInicio As Object, oDescriptor As Object ) As Object <Xinterface>
devuelve un TextRange con el siguiente resultado de la búsqueda. El argumento oInicio será
el punto de partida para la búsqueda, normalmente el resultado de la última llamada a Find-
First o FindNext.
El servicio SearchDescriptor tiene los siguientes métodos:
getSearchString ( ) As String
obtiene la cadena de búsqueda
setSearchString ( sCadena As String )
especifica la cadena de búsqueda
He aquí algunas de sus propiedades:
Propiedad Descripción
SearchBackwards Si True (Verdadero) busca hacia el principio del documento
SearchCaseSensitive Si True considera mayúsculas / minúsculas
SearchWords Si True busca palabras completas
SearchStyles Si True busca por un estilo

En el siguiente ejemplo vamos a localizar, en el documento, todas las ocurrencias de la cadena


“( )” y pondremos su color de fuente en Rojo. Introduzca el código siguiente y ejecute la su-
brutina.
Sub buscaTodas
Dim oDoc As Object
Dim oDescBusca As Object

oDoc = ThisComponent
oDescBusca = oDoc.createSearchDescriptor()
oDescBusca.SearchWords = True
oDescBusca.setSearchString ("( )")
oResultado = oDoc.findAll( oDescBusca )

Introducción a OpenOffice.org Basic 49


Documentos de Writer Versión 1

For n% = 0 To oResultado.Count - 1
oResultado(n%).CharColor = RGB(255,0,0)
Next
MsgBox "Ocurrencias de " + oDescBusca.getSearchString() + _
" " + Str$(oResultado.Count)
End Sub

La tarea anterior, también puede ser completada mediante el uso de los métodos findFirst y
findNext:
oResultado = oDoc.findFirst( oDescBusca )
Do Until IsNull(oResultado)
oResultado.CharColor = RGB(250,100,50)
oResultado = oDoc.findNext(oResultado, oDescBusca )
Loop

La sustitución de texto está implementada por la interfaz XReplaceable, que hereda las carac-
terísticas de XSearchable. Ella proporciona los métodos:
createReplaceDescriptor ( ) As Object <com.sun.star.util.XReplaceDescriptor>
devuelve un descriptor de reemplazo para las propiedades
replaceAll ( xDescriptor As Object <com.sun.star.util.XReplaceDescriptor>) As Long
busca y reemplaza todas las ocurrencias, devolviendo el total de sustituciones efectuadas.
El servicio ReplaceDescriptor tiene métodos para las propiedades de cadena:
getReplaceString ( ) As String
obtiene la cadena de reemplazo
setReplaceString ( sCadena As String )
especifica la cadena de reemplazo
Veamos un ejemplo sencillo de búsqueda y reemplazo:
Sub sustituyeTodas
Dim oDoc As Object
Dim oDescriptor As Object

oDoc = ThisComponent
oDescriptor = oDoc.createReplaceDescriptor()
oDescriptor.setSearchString( "( )" )
oDescriptor.setReplaceString( "()" )
n = oDoc.replaceAll(oDescriptor)
MsgBox n

End Sub

Observe que no disponemos de un método para el reemplazo interactivo. Sin embargo, a


través de búsqueda y edición es posible implementar facilmente este procedimiento.

50 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

6.9 Insertando objetos


Abordaremos rápidamente otra tarea común en procesamiento de textos. La inserción de ob-
jetos de origen externo como gráficos y documentos, en un documento de Writer.
Insertar un documento de texto es muy fácil, basta con crear un cursor de texto y llamar al
método:
insertDocumentFromURL ( sURL As String, mPropiedades ( ) As Object )
Los argumentos de este método son idénticos a los ya vistos en la sección 5.1 Cargando Do-
cumentos.
Dim oCursorTxt As Object
Dim mPropiedades ( )
Dim sURL As String
oCursorTxt = ThisComponent.createTextCursor ( )
' sURL = “ruta_de_acceso_completa_del_archivo”
oCursorTxt.insertDocumentFromURL ( sURL, mPropriedades() )

Para insertar en la posición del cursor de la interfaz gráfica, cree el cursor de texto a partir del
cursor de vista.
La inserción de imágenes es un poco más complicada, para ello usted debe:
a) crear un objeto gráfico;
b) definir sus propiedades;
c) insertar el objeto.
Observe la subrutina Sub insertarGrafico siguiente:
Sub insertarGrafico
Dim oTxt As Object
Dim oCursorTxt As Object
Dim oGrafico As Object
Dim sURL As String

oTxt = ThisComponent.getText()
oCursorTxt = oTxt.createTextCursor()
oGrafico = ThisComponent.createInstance("com.sun.star.text.GraphicObject")
sURL = "file:///D:/NAD/OPENOFFICE/HOWTO/FIGURAS/DIALOGO.JPG"
oGrafico.GraphicURL = sURL
oGrafico.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH
oTxt.insertTextContent(oCursorTxt.getStart(), oGrafico, False)
End Sub

La llamada al método createInstance ( ) crea el objeto gráfico, después definimos las propie-
dades GraphicURL e AnchorType y, finalmente, insertamos el gráfico llamando al método
insertTextContent ( ) con los argumentos adecuados.
La propiedad AnchorType puede asumir, además, los siguientes valores: AT_CHARACTER,
AT_PAGE e AS_CHARACTER.
El API de OpenOffice.org (versión 1.0.1) salva en el documento la URL del gráfico. En con-
secuencia si usted lo cambia de su ubicación original, Writer no sabrá como encontrarlo.

Introducción a OpenOffice.org Basic 51


Documentos de Writer Versión 1

6.10 Tablas
Una tabla es un conjunto de celdas organizadas en filas y columnas, donde cada celda tiene un
nombre, normalmente indicado por letras y números. Las letras se refieren a las columnas y
los números a las filas. No obstante, si existiesen celdas unidas o divididas, el concepto de
columna podrá desaparecer y el esquema de nominación se complica.
Una celda puede contener texto simple (cadenas y números), gráficos, fórmulas y campos con
varias características de formateo.
Una tabla recibe un nombre único en el documento, pudiendo servir como origen para gráfi-
cos, tener su contenido ordenado y formatearse automáticamente.
El API de OpenOffice.org tiene diversos servicios e interfaces para manejar tablas, veremos
las principales.
La interfaz com.sun.star.text.XTextTable se encarga de la administración de las tablas en un
documento y contiene los siguientes métodos:
initialize ( nFilas As Long, nColumnas As Long)
Inicializa una tabla , recibe el número de filas y columnas como argumentos.
getCellNames ( ) As Object < Strings >
obtiene los nombres de las celdas, devolviendo un conjunto de cadenas
getCellByName ( sNombreCelda As String ) As Object < com.sun.star.table.XCell >
obtiene la celda nombrada en el argumento, devolviendo un objeto XCell
getRows ( ) As Object < com.sun.star.table.XTableRows >
obtiene las filas de la tabla, devolviendo un objeto XTableRows.
getColumns ( ) As Object < com.sun.star.table.XTableColumns >
obtiene las columnas de la tabla, devolviendo un objeto XTableColumns.
createCursorByCellName ( sNombreCelda As String ) As Object < XTextTableCursor >
crea un cursor de tabla, ubicado en la celda nombrada en el argumento
El servicio TextTable posee diversas propiedades, he aquí algunas de ellas:
Propiedad Descripción
LeftMargin Contiene el margen izquierdo de la tabla, valor Long
RightMargin Contiene el margen derecho de la tabla, valor Long
Split Un valor False impide la división de la tabla en dos pági-
nas
TableBorder Contiene la descripción del borde de la tabla
TableColumnSeparators Contiene la descripción de los separadores de columnas
de la tabla
BackGraphicURL Contiene la URL del gráfico de fondo de la celda

52 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

Las interfaces XTableRows e XTableColumns, devueltas por los métodos getRows () y get-
Columns (), además, proveen de los siguientes métodos:
insertByIndex ( nIndice As Long, nTotal As Long )
removeByIndex ( nIndice As Long, nTotal As Long )
getElementType ( ) As Type
hasElements ( ) As Boolean
getByIndex ( ) As Variant
getCount ( ) As Long

La interfaz XTextTableCursor, devuelta por el método createCursorByCellName, además


posee los métodos:
getRangeName ( ) As String
Devuelve la extensión de celdas del cursor, es decir, los nombres de las celdas superior iz-
quierda e inferior derecha, por ejemplo A2:D25 (observe el separador : ).
goLeft ( nCuanto As Integer, bExpande As Boolean ) As Boolean
goRight ( nCuanto As Integer, bExpande As Boolean ) As Boolean
goUp ( nCuanto As Integer, bExpande As Boolean ) As Boolean
goDown ( nCuanto As Integer, bExpande As Boolean ) As Boolean
gotoStart ( bExpande As Boolean )
gotoEnd ( bExpande As Boolean )
Métodos para movimiento y selección, nCuanto es la cantidad de celdas y, si bExpande fuese
True (Verdadero), extiende la selección durante el desplazamiento del cursor.
gotoCellByName (sNombreCelda As String, bExpande As Boolean ) As Boolean
Desplaza el cursor hasta la célula nombrada en el argumento.
mergeRange ( ) As Boolean
splitRange ( nCuanto As Integer, bHoriz As Boolean ) As Boolean
Métodos para unir y dividir celdas
Mediante el servicio TextTableCursor podemos efectuar el formateado de las celdas, pues él
incluye también los servicios CharacterProperties y ParagraphProperties.
La interfaz com.sun.star.table.XCellRange define los siguientes métodos para manejar las
celdas:
getCellByPosition ( nColumna As Long, nLinea As Long ) As Object < XCell >
getCellRangeByPosition ( nIzq, nSup, nDer, nInf ) As Object < XCellRange >
getCellRangeByName ( sRango As String ) As Object < XCellRange >

El servicio com.sun.star.table.CellRange incluye com.sun.star.table.CellProperties, que de-


fine las propiedades de una o más celdas. Veamos algunas:
Propiedad Descripción
CellBackColor Valor Long con el color del fondo de la celda
HoriJustify Alineación horizontal del contenido de la celda (enum CellHori-
Justify)

Introducción a OpenOffice.org Basic 53


Documentos de Writer Versión 1

VertJustify Alineación vertical del contenido de la celda (enum CellVertJus-


tify)
IsTextWrapped Si True (Verdadero), el ajusta la fila automáticamente
Orientation Orientación del contenido de la celda (enum CellOrientation)
RotateAngle Define la rotación del contenido de la celda (en 1/100 de gra-
dos)
TableBorder Describe el borde del conjunto de celdas (struct TableBorde)
TopBorder Describe el borde superior de cada celda (struct BorderLine)
BottomBorder Describe el borde inferior de cada celda (struct BorderLine)
LeftBorder Describe el borde izquierdo de cada celda (struct BorderLine)
RightBorder Describe el borde derecho de cada celda (struct BorderLine)
NumberFormat Índice del formato numérico usado en las celdas (servicio Num-
berFormatter)
CellProtection Describe la protección de la celda (servicio CellProtection)

La interfaz com.sun.star.table.XCell ofrece los métodos siguientes para manipular el conte-


nido de una celda:
getFormula ( ) As String
setFormula ( sFormula As String )
métodos para obtener o definir la fórmula de una celda
getValue ( ) As Double
setValue ( nValor As Double )
métodos para obtener o definir el valor de una celda
getType ( ) As Long < com.sun.star.table.CellContentType >
devuelve el tipo de contenido de una celda, como enumeración de CellContentType
getError ( ) As Long
devuelve el error de una celda, útil para rastrear errores en fórmulas
El nombre de una tabla puede ser obtenido o definido con los métodos siguientes, de la inter-
faz com.sun.star.container.XNamed:
getName ( ) As String
setName ( sNombreTabla As String )

El contenido de una tabla puede ser ordenado con la interfaz com.sun.star.util.XSortable y


sus métodos:2
createSortDescriptor ( ) As Variant <com.sun.star.beans.PropertyValue>
devuelve un descriptor para las propiedades de ordenación

2 N. del T.: Todo lo que se describe acerca de las posibilidades de ordenación dentro de la tabla, está comprobado en
OpenOffice.org versión 1.0.3, pero en la versión 1.1.RC no funciona. Todavía no tenemos claro si responde a
alguna modificación en la API, o algún otro tipo de error. En posteriores versiones de este documento quedará
debidamente aclarada esta cuestión.

54 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

sort (xDescriptor As Variant <com.sun.star.beans.PropertyValue> )


ejecuta la ordenación, según el descriptor
Siguen algunas de las propiedades del descriptor de ordenación (SortDescriptor):
Propiedades Descripción
IsCaseSensitive Si True (Verdadero), considera mayúsculas / minúsculas
SortAscending Si True (Verdadero), ordenación ascendente
SortColumns Si True (Verdadero) ordena por columnas, sino, lo hace por
filas

El servicio com.sun.star.table.TableSortDescriptor incluye el servicio SortDescriptor y po-


see las propiedades siguientes:
Propiedades Descripción
SortFields Describe los campos de ordenación
<com.sun.star.util.SortField>
MaxFieldCount Define el número máximo de campos, propiedad de sólo lectura
Orientation Define la orientación de la ordenación
<com.sun.star.table.TableOrientation>
ContainsHeader Si True (Verdadero), trata la primera fila como títulos, sin
ordenarla.

Ha llegado el momento de presentar un ejemplo. Inicialmente, crearemos, inicializaremos e


insertaremos una tabla con cinco filas y tres columnas, al inicio del documento actual. Des-
pués definiremos los títulos de las columnas. Escriba el siguiente código, ejecútelo y observe
el resultado:
Sub creaTabla
Dim oTxt As Object
Dim oTab As Object
'
' crea, inicializa e inserta la tabla al principio del documento
oTxt = ThisComponent.getText()
oTab = ThisComponent.createInstance("com.sun.star.text.TextTable")
oTab.initialize(5,3)
oTxt.insertTextContent(oTxt.createTextCursor(), oTab, FALSE)
'
' rellena los títulos de las columnas (celdas A1, B1 e C1 )
Dim oCelda As Object
oCelda = oTab.getCellByName("A1")
oCelda.setString("Columna A")
oCelda = oTab.getCellByName("B1")
oCelda.setString("Columna B")
oCelda = oTab.getCellByName("C1")
oCelda.setString("Columna C")
End Sub

Introducción a OpenOffice.org Basic 55


Documentos de Writer Versión 1

Primero creamos el objeto tabla con createInstance (), después definimos las filas y columnas
con initialize (), insertamos la tabla en el documento con una llamada al método insertText-
Content ( ) y, entonces, obtenemos cada una de las celdas del encabezado y especificamos su
contenido.
El siguiente bloque de código demuestra el empleo del cursor de tabla, navegación, formateo
y unión de celdas. Añádalo a Sub creaTabla.
'
' crea un cursor de tabla en la celda CellNames(0) = A1
Dim oCurTab As Object
oCurTab = oTab.createCursorByCellName(oTab.CellNames(0))
' selecciona las celdas A1, B1 e C1
oCurTab.gotoStart(FALSE)
oCurTab.goRight(2, True)
' Aplica el estilo de párrafo Título en la selección
oCurTab.paraStyleName = "Heading"
' muestra el nombre de la extensión seleccionada (rango)
' Observe la forma en que se representa (invertida)
MsgBox oCurTab.getRangeName()
'
' nombra las celdas a partir de la línea 2 y
' escribe el número de fila en la columna C
Dim sNombres() As Variant
Dim sNombreCelda As String
sNombres = Array("A","B","C")
For i% = 1 To 4
For j% = 1 To 3
sNombreCelda = sNombres(j%-1)+ Str$(i%+1)
oCelda = oTab.getCellByName(sNombreCelda)
If (j% - 1 = 2) Then
' define un valor numérico para la celda
oCelda.setValue(i% + 1)
Else
oCelda.setString(sNombreCelda)
End If
Next j%
Next i%
'
' define una fórmula (suma de C2 hasta C4) para la celda C5
oCelda = oTab.getCellByName("C5")
oCelda.setFormula("sum <C2:C4>")
'
' une las celdas A5 y B5 y cambia su contenido
oCurTab.gotoCellByName("A5", False)
oCurTab.goRight(1, True)
oCurTab.mergeRange()
oCelda = oTab.getCellByName("A5")
oCelda.setString("Total")

Observe la creación del cursor de tabla con createCursorByCellNames (...), el uso del cursor
para formateo, el uso de los métodos setValue () y setFormula () y la selección y unión de las
celdas A5 y B5.
En el siguiente bloque de código, veremos la ordenación de una extensión de celdas (A2:C4)
de nuestra tabla. Basta insertar el código en Sub creaTabla y ejecutarla nuevamente para ver
el resultado.3
3 N. del T.: Este código funciona perfectamente en la versión 1.0.3 de OpenOffice.org, pero en el momento de escribir

56 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Writer

'
' ordena de A2 hasta C4
Dim oCampoOrd(0) As New com.sun.star.util.SortField
Dim oDescrOrd As Variant
Dim oRango As Object
'
' especifica el rango a ordenar
oRango = oTab.getCellRangeByName("A2:C4")
' define el campo de ordenación y sus propiedades
oCampoOrd(0).Field = 0
oCampoOrd(0).SortAscending = False
oCampoOrd(0).FieldType = com.sun.star.util.SortFieldType.ALPHANUMERIC
' crea el descriptor de ordenación
oDescrOrd = oTab.createSortDescriptor()
' define las propiedades del descriptor
oDescrOrd(0).Name = "SortFields"
oDescrOrd(0).Value = oCampoOrd()
oDescrOrd(1).Name = "ContainsHeader"
oDescrOrd(1).Value = False
oDescrOrd(2).Name = "SortColumns"
oDescrOrd(2).Value = False
' ordena el rango
oRango.sort(oDescrOrd())

Observe que comenzamos por la declaración de las variables, creamos un rango de celdas con
una llamada al método getCellRangeByName (), definimos las propiedades del campo de or-
denación, creamos el descriptor y definimos sus propiedades (el campo de ordenación es una
propiedad del descriptor) y, finalmente, invocamos el método sort () para ejecutar su tarea.
Antes de terminar esta sección, veamos como se obtiene el acceso a las tablas existentes en un
documento de texto. El proceso es el mismo visto en la sección 6.7 Localizando Objetos.
El método getTextTables () de la interfaz XTextTablesSupplier devuelve una colección con-
teniendo las tablas del documento. Este procedimiento recorre el documento de inicio a fin.
getTextTables () As Object <com.sun.star.container.XNameAccess>

El ejemplo inferior muestra la localización de las tablas de un documento, después obtiene las
colecciones de filas y columnas de la tabla de nombre “Tabla3”
Sub localizaTablas
Dim oTablas As Object
Dim oTabla As Object
Dim oFilas As Object
Dim oColumnas As Object
Dim n As Integer

oTablas = ThisComponent.getTextTables()
For n = 0 To oTablas.Count -1
oTabla = oTablas.getByIndex(n)
MsgBox oTabla.getName()
Next n
MsgBox "Tablas en el documento: " + Str$(oTablas.Count)
'

la traducción, adaptándola a la versión 1.1.RC3 nos hemos encontrado con que no funciona. En posteriores
revisiones del presente documento quedará debidamente aclarada esta cuestión.

Introducción a OpenOffice.org Basic 57


Documentos de Writer Versión 1

If (oTablas.hasByName ("Tabla3")) Then


oTabla = oTablas.getByName("Tabla3")
oFilas = oTabla.getRows()
oColumnas = oTabla.getColumns()
MsgBox Str$(oFilas.Count)+" - "+Str$(oColumnas.Count)
End If
End Sub

Recuerde que, para acceder a una tabla, usted debe conocer su nombre o su índice dentro de la
colección, y, seguidamente, llamar al método getByName () o getByIndex ().
Tras obtener la tabla deseada, use las técnicas ya presentadas para editar su contenido.

58 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

7 Documentos de Calc

7.1 Introducción
Un documento de Calc contiene una o más hojas de cálculo. Cada hoja de cálculo está forma-
da por celdas organizadas en filas y columnas, de modo parecido a una tabla de Writer. Estas
celdas contienen, básicamente, texto, que puede representar una cadena de caracteres, un valor
numérico, un campo o una fórmula.
Cada uno de los elementos citados (documento, hoja de cálculo y celda), posee características
propias. Algunas pueden ser modificadas como, por ejemplo, el estilo de página, el formato
numérico, de párrafo y de fuente.
Además de tareas comunes de edición, podemos aplicar al contenido de una hoja de cálculo
operaciones como ordenación, filtro, totalización, generación de gráficos, etc.
En una hoja de cálculo también podemos insertar objetos como imágenes, diseños, datos de
una fuente externa y objetos OLE.
Como usted ya habrá observado, dada la riqueza y la potencia de las operaciones con docu-
mentos de Calc, su programación es un asunto extenso. En las próximas secciones, intentare-
mos presentar lo básico.

7.2 Hojas de cálculo


Las funciones básicas, ya abordadas en el capítulo 5. Trabajando con Documentos, pueden ser
usadas también con documentos de Calc. Así, está sección cubrirá algunas operaciones sobre
las hojas de cálculo de un documento de Calc.
El módulo com.sun.star.sheet, de la API de OpenOffice.org contiene los principales servi-
cios, interfaces y grupos de constantes relacionados con hojas de cálculo.
El servicio SpreadsheetDocument representa el modelo de un documento de Calc, conte-
niendo atributos y una o más hojas. La interfaz XSpreadsheetDocument provee del método
getSheets ( ), que devuelve una colección con las hojas del documento.
getSheets ( ) As Object <com.sum.star.sheet.XSpreadsheets>
Los objetos de esta colección pueden ser accedidos por sus nombres o índices. Podemos,
también, crear una enumeración y usar el acceso secuencial.
La interfaz XSpreadsheets, devuelta por getSheets ( ), especifica los métodos siguientes:
insertNewByName ( sNombre As String, iPosicion As Integer )
moveByName ( sNombre As String, iDestino As Integer )
copyByName ( sNombreOrigen As String, sNombreCopia As String, iPosicion As Integer )

Introducción a OpenOffice.org Basic 59


Documentos de Calc Versión 1

Para fijar los conceptos anteriores, en el siguiente ejemplo, crearemos un documento y efec-
tuaremos algunas operaciones con hojas.
Sub creaDocCalc
Dim oDesk As Variant
Dim oDoc As Object
Dim mProp() As Variant
Dim sURL As String

' crea documento de Calc


oDesk = createUnoService("com.sun.star.frame.Desktop")
sUrl = "private:factory/scalc"
oDoc = oDesk.LoadComponentFromURL(sUrl,"_blank",0,mProp())
' muestra la propiedad decimales predefinida en el documento
MsgBox oDoc.StandardDecimals
'
' navega por las hojas existentes en el documento
Dim oHojas As Object
Dim oHoja As Object
Dim sMsg As String
'
oHojas = oDoc.getSheets()
sMsg = ""
For n=0 To oHojas.Count - 1
oHoja = oHojas.getByIndex(n)
sMsg = sMsg + oHoja.getName() + Chr$(13)
Next n
MsgBox sMsg + Str$(oHojas.Count)

' acceso nominal


If oHojas.hasByName("Hoja2") Then
oHoja = oHojas.getByName("Hoja2")
MsgBox oHoja.PageStyle
End If
' inserta una hoja al principio
oHojas.insertNewByName("Hoja4",0)
MsgBox oHojas.Count
' mueve al final
oHojas.moveByName("Hoja4",4)
End Sub

Observe los argumentos para la creación del documento, el acceso a los objetos de la colec-
ción y el uso de los métodos para insertar y mover una hoja de cálculo.
El servicio SpreadsheetView suministra funcionalidades relacionadas con la vista actual de
un documento de Calc. Incluye el servicio SpreadsheetViewSettings, que especifica algunas
propiedades de cada una de las hojas del documento y, su interfaz XspreadsheetView, aporta
los métodos a seguir para la definición de la hoja activa en el documento:
getActiveSheet ( ) As Object < XSpreadsheet >
setActiveSheet ( oHoja As Object < XSpreadsheet >)

Recuerde que las operaciones relacionadas con la interfaz gráfica son administradas por el ob-
jeto controlador del documento.
Introduzca el código fuente siguiente al final de Sub creaDocCalc, ejecute y observe el resul-
tado

60 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

' activa la Hoja4 en la GUI


If oHojas.hasByName("Hoja4") Then
MsgBox oDoc.getCurrentController().getActiveSheet().getName()
oHoja = oHojas.getByName("Hoja4")
oDoc.getCurrentController().setActiveSheet(oHoja)
End If

Inicialmente mostramos el nombre de la hoja activa y, entonces, seleccionamos la hoja de


nombre Hoja4.
Como se mostró en el capítulo 5. Documentos de Writer, podemos modificar el contenido de
un documento independientemente de la interfaz gráfica.

7.3 Editando
Para editar el contenido de una o más celdas, debemos tener en mente lo siguiente:
a) obtener la hoja donde se encuentran las celdas a editar;
b) obtener un rango conteniendo las celdas a editar, este paso es opcional, pues una hoja es un
rango de celdas;
c) obtener la celda a editar;
d) especificar el contenido de la celda.
El ítem a) se debe solucionar con el uso del método getSheets (), asociado al acceso nominal,
indexado o enumerado, como se ha visto en la sección anterior.
Las herramientas para solucionar los ítems b), c) y d) también se presentaron en la sección
6.10 Tablas e involucra los métodos de las interfaces XCellRange e XCell.
Métodos de la interfaz com.sun.star.table.XCellRange:
getCellByPosition ( nColumna As Long, nFila As Long ) As Object < XCell >
getCellRangeByPosition ( nIzq, nSup, nDer, nInf ) As Object < XCellRange >
getCellRangeByName ( sRango As String ) As Object < XCellRange >

Debemos recordar que la posición de una celda, dentro de un rango, es relativa al inicio del
rango.
Métodos de la interfaz com.sun.star.table.XCell:
getFormula ( ) As String
setFormula ( sFormula As String )
getValue ( ) As Double
setValue ( nValor As Double )
getType ( ) As Long < com.sun.star.table.CellContentType >
getError ( ) As Long

Para recordarlo, veamos un ejemplo de edición del contenido de las celdas de una hoja. Intro-
duzca el código inferior, ejecútelo y observe el resultado.

Introducción a OpenOffice.org Basic 61


Documentos de Calc Versión 1

Sub editaHoja

Dim oDesk As Variant


Dim oDoc As Object
Dim mProp() As Variant
Dim sURL As String
'
' crea documento de Calc
oDesk = createUnoService("com.sun.star.frame.Desktop")
sUrl = "private:factory/scalc"
oDoc = oDesk.LoadComponentFromURL(sUrl, "_blank", 0, mProp())
'
' edita celdas de la hoja
Dim oHoja As Object
Dim oCelda As Object
Dim sTitCol() As String

' escribe los títulos de las columnas


sTitCol = Array ("CÓDIGO","MATERIAL","CANTIDAD","P. UNIT","P. TOTAL")
oHoja = oDoc.getSheets().getByIndex(0)
For i% = 0 To 4
oCelda = oHoja.getCellByPosition(i%, 0)
oCelda.setString(sTitCol(i%))
Next i%
'
' rellena las celdas con texto, valor y fórmula
For i% = 1 To 6
For j% = 0 To 4
oCelda = oHoja.getCellByPosition(j%, i%)
If (j% = 0) Then
If i% < 4 Then
oCelda.setString("A" + Str$(i%))
Else
oCelda.setString("A" + Str$(i%-3))
End If
ElseIf (j% = 1) Then
oCelda.setString("Material de construcción " + Str$(i%))
ElseIf (j% = 2) Then
oCelda.setValue(i% * j%)
ElseIf (j% = 3) Then
oCelda.setValue(100 * Rnd())
Else
sFila = Trim$(Str$(i%+1))
sFormula = "=C" + sFila + " * " + "D" + sFila
oCelda.setFormula(sFormula)
End If
Next j%
Next i%
' resumo
oCelda = oHoja.getCellByPosition(0, 7)
oCelda.setString("COSTE TOTAL")
'
sFormula = "=Sum(E1:E6)"
oCelda = oHoja.getCellByPosition(4, 7)
oCelda.setFormula(sFormula)
'
End Sub

Observe que, en la segunda llamada del método setFormula(), definimos la fórmula usando el
nombre de una función en inglés. Para utilizar los nombres de las funciones mostrados por la

62 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

interfaz gráfica, use la propiedad FormulaLocal, del servicio com.sun.star.sheet.SheetCell.,


por ejemplo:
oCelda = oHoja.getCellByPosition(4, 7)
sFormula = "=Suma(E1:E6)"
oCelda.FormulaLocal = sFormula

El servicio SheetCell define las siguientes propiedades:


Propiedad Descripción
Position Sólo lectura, posición de la celda en la hoja
Size Sólo lectura, tamaño de la celda en 1/100 mm
FormulaLocal Cadena con el nombre local de la fórmula
FormulaResultType Sólo lectura, tipo de resultado de una fórmula
ConditionalFormat Definiciones de formateo condicional de la celda
ConditionalFormatLocal Definiciones locales de formateo condicional de la celda
Validation Definiciones de validación de la celda
ValidationLocal Definiciones locales de validación de la celda

En la próxima sección, trataremos de la creación y empleo de un cursor, otra funcionalidad de


los documentos de Calc.

7.4 Navegando por las Celdas


Una celda o un rango de celdas se identifica por su dirección, que está formada por los índices
de la hoja, columna inicial, fila inicial, columna final y fila final. La interfaz XCellRangeAd-
dressable define el siguiente métodos para la recuperación de esta dirección:
getRangeAddress ( ) As Object < com.sun.star.table.CellRangeAddress >
devuelve una estructura CellRangeAddress con los elementos Sheet, StartColumn, StartRow,
EndColumn e EndRow.
En una hoja de cálculo también podemos crear un cursor. Este cursor es un rango de celdas
con funcionalidades para navegación, formateo y edición, entre otras.
El servicio Spreadsheet, por medio de la interfaz XSpreadsheet, define los siguientes méto-
dos para la creación de un cursor de celdas:
createCursor ( ) As Object < XSheetCellCursor >
devuelve un cursor de celda conteniendo toda la hoja de cálculo.
createCursorByRange (oRango As Object < XSheetCellCursor > )
devuelve un cursor de celda conteniendo el rango de celdas del argumento.

Introducción a OpenOffice.org Basic 63


Documentos de Calc Versión 1

El servicio SheetCellCursor provee de toda la funcionalidad para operar con un cursor de


celda. El posee las interfaces XSheetCellCursor y XUsedAreaCursor, además de soportar
los servicios table.CellCursor e SheetCellRange.
La interfaz XSheetCellCursor define los siguientes métodos para contraer o expandir el cur-
sor:
collapseToCurrentRegion ()
collapseToCurrentArray ()
collapseToMergedArea ()
expandToEntireColumns ()
expandToEntireRows ()
collapseToSize ( nColumnas As Long, nFilas As Long )

Los siguientes métodos, de la interfaz XUsedAreaCursor, son útiles cuando deseamos operar
sobre el área utilizada de una hoja de cálculo. Por ejemplo, identificar la última celda con los
datos de una hoja.
gotoStartOfUsedArea ( bExpande As Boolean )
gotoEndOfUsedArea ( bExpande As Boolean )

La interfaz XCellCursor, del servicio CellCursor, provee los siguientes métodos, ya explica-
dos en la sección 6.10 Tablas del capítulo 6. Documentos de Writer.
gotoStart ( )
gotoEnd ( )
gotoNext ( )
gotoPrevious ( )
gotoOffSet ( nDesplazColumna As Long, nDesplazFila As Long )

Para demostrar el uso de un cursor, introduzca el siguiente código y ejecútelo para observar el
resultado.
Sub creaCursorCeldas
Dim oDesk As Variant
Dim oDoc As Object
Dim mProp() As Variant
Dim sURL As String
'
' crea documento de Calc
oDesk = createUnoService("com.sun.star.frame.Desktop")
sUrl = "private:factory/scalc"
oDoc = oDesk.LoadComponentFromURL(sUrl, "_blank", 0, mProp())
'
' trabaja con un cursor
Dim oHojas As Object
Dim oCursor As Object

oHojas = oDoc.getSheets().getByIndex(0)
oCursor = oHojas.createCursorByRange(oHojas.getCellByPosition(0,0))
' soporta XSpreadSheet
MsgBox oCursor.getSpreadsheet().getName()
' edita algunas celdas
' observe que la posición de la celda es relativa

64 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

oCursor.getCellByPosition(0,0).setFormula("Celda A1")
oCursor.gotoNext()
oCursor.getCellByPosition(0,0).setFormula("Celda B1")
oCursor.gotoNext()
oCursor.getCellByPosition(0,0).setFormula("Celda C1")
' mueve el cursor 5 celdas hacia abajo
oCursor.gotoOffSet(0,5)
oCursor.getCellByPosition(0,0).setFormula("Abajo de C1")
oCursor.CharHeight = 16
' obtiene toda el área en uso
oCursor.gotoStartOfUsedArea(False)
oCursor.gotoEndOfUsedArea(True)

' obtiene y muestra la dirección del cursor (índices)


oEnd = oCursor.getRangeAddress()
MsgBox Str$(oEnd.Sheet)+Str$(oEnd.StartColumn)+Str$(oEnd.StartRow)
MsgBox Str$(oEnd.Sheet)+Str$(oEnd.EndColumn)+Str$(oEnd.EndRow)
End Sub

Aquí hemos usado el método createCursorByRange ( ), pero podríamos haber usado


createCursor ( ). Observe que, para definir el contenido de una celda, debemos obtenerla
llamando al método getCellByPosition ( ), con la posición relativa al inicio del rango de
celdas del cursor. Observe, además, como se da la selección e identificación del área usada
por la hoja de cálculo.

7.5 Obteniendo objetos seleccionados


Los principales métodos para obtener el contenido de una selección se definen en la interfaz
com.sun.star.frame.XModel, son los siguientes:
getCurrentSelection ( ) As < com.sun.star.uno.XInterface >
devuelve la selección en el controlador actual o Null si no existe un controlador.
getCurrentController ( ) As < com.sun.star.frame.XController >
devuelve el controlador del modelo o Null si ningún controlador está registrado.
Diversas situaciones de selección pueden ocurrir, por ejemplo: la selección de un rango de
celdas, la selección de un gráfico, etc. A continuación, presentamos las más comunes.
El código siguiente define un objeto celda con la primera celda del rango.
' para una celda: com.sun.star.sheet.SheetCell
oCel = ThisComponent.getCurrentSelection().getCellByPosition(0,0)

La siguiente parte de código obtiene un rango de celdas contínuas y muestra los índices de ho-
ja, columna inicial y final, fila inicial y final.
' para un rango: com.sun.star.sheet.CellRange
oRango = oDoc.getCurrentSelection()
oEnd = oRango.getRangeAddress()
MsgBox Str$(oEnd.Sheet)+Str$(oEnd.StartColumn)+Str$(oEnd.StartRow)

Introducción a OpenOffice.org Basic 65


Documentos de Calc Versión 1

MsgBox Str$(oEnd.EndColumn)+Str$(oEnd.EndRow)

Podemos, además, seleccionar rangos de celdas no contínuas, en una misma hoja o en hojas
diferentes, el bloque de código siguiente resuelve esta situación. En un documento de Calc,
seleccione rangos no contiguos, llame a la macro y ejecútela para ver la salida.
Sub seleccionRangos
Dim oDoc As Object
Dim oRangos As Object

oDoc = ThisComponent
' oRangos soporta com.sun.star.sheet.SheetCellRanges
oRangos = oDoc.getCurrentSelection()
MsgBox oRangos.getCount()

oEnd = oRangos.getRangeAddresses()
For n=0 To UBound(oEnd)
MsgBox Str$(oEnd(n).Sheet)+Str$(oEnd(n).StartColumn)+Str$(oEnd(n).StartRow)
Next n
MsgBox oRangos.getRangeAddressesAsString()
End Sub

El método getCurrentSelection( ) maneja otros objetos, como gráficos o diseños. Podemos


usar el método getImplementationName( ) o supportsService( ), para intentar una identifica-
ción inicial del objeto seleccionado.
Además, disponemos de la interfaz com.sun.star.view.XSelectionSupplier, que define méto-
dos de selección para la interfaz gráfica, entre ellos:
select ( oObjeto As Object ) As Boolean
si es posible, selecciona el objeto oObjeto en la interfaz gráfica.
getSelection ( ) oObjeto As Variant
obtiene la selección en la interfaz gráfica, devolviendo un objeto o una colección de objetos.
Estos métodos pueden ser llamados mediante el objeto controlador del modelo, como se ve a
continuación:
' selecciona un rango de celdas en la hoja de cálculo
'
oDoc = ThisComponent
oCtr = oDoc.getCurrentController()
oHoja = oDoc.Sheets(0)
oRango = oHoja.getCellRangeByPosition (0, 1, 4, 6)
If (oCtr.select(oRango)) Then
MsgBox "Seleccionado en la vista"
Else
MsgBox "No seleccionado"
End If

La API de OpenOffice ofrece otras funcionalidades como la selección de un rango durante la


ejecución de una macro, que serán abordadas en otras secciones de este documento.

66 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

7.6 Formateando
La presentación final de un trabajo es muy importante y Calc ofrece una vasta gama de posi-
bilidades para auxiliarnos en el formateo de nuestros documentos.

Formateando Párrafos y Caracteres

Inicialmente, podemos aplicar al contenido de una celda las técnicas de formateo de párrafos y
caracteres. Los principales servicios, ya presentados en la sección 6.4 Formateando Texto del
capítulo anterior, son :
com.sun.star.style.ParagraphProperties
com.sun.star.style.CharacterProperties

El servicio com.sun.star.table.TableRow define las siguientes propiedades para formateo de


filas:
Propiedad Descripción
Height Define la altura de la fila en 1/100 mm
OptimalHeight Si True (Verdadero), ajusta automáticamente la altura de la
fila
IsVisible Si False, oculta la fila
IsStartOfNewPage Si True (Verdadero), inserta un salto de página vertical en
esta fila

El servicio com.sun.star.table.TableColumn define las siguientes propiedades para formateo


de columnas:
Propiedad Descripción
Width Define el ancho de columna en 1/100 mm
OptimalWidth Si True (Verdadero), ajusta automáticamente el ancho de la
columna
IsVisible Si False, oculta la columna.
IsStartOfNewPage Si True (Verdadero), inserta un salto de página horizontal en
esta columna

Otras propiedades para el formateo de celdas están cubiertas por los servicios:
com.sun.star.table.CellProperties
com.sun.star.table.TableBorder
com.sun.star.table.BorderLine
El servicio CellProperties contiene diversas propiedades. Las más importantes se vieron en la
sección 6.10 Tablas del capítulo 6. Documentos de Writer.

Introducción a OpenOffice.org Basic 67


Documentos de Calc Versión 1

Aplicaremos algún formato al ejemplo creado por Sub editaHoja. Añada el siguiente código
fuente al final de la subrutina, ejecute la macro y observe la salida:
' Formateo
Dim oRango As Object
Dim oFila As Object
Dim oColumna As Object
'
' formatea párrafos y caracteres
oRango = oHoja.getCellRangeByPosition(0, 0, 5, 0)
oRango.CharHeight = 12
oRango.CharWeight = com.sun.star.awt.FontWeight.BOLD
oRango.ParaAdjust = com.sun.star.style.ParagraphAdjust.CENTER
' ajusta la altura de la fila 1
oFila = oHoja.getRows().getByIndex(0)
oFila.OptimalHeight = True
' ajusta el ancho de la columna B
oColumna = oHoja.getColumns().getByIndex(1)
oColumna.OptimalWidth = True

A destacar en este ejemplo el método de recuperación de filas y columnas, mediante acceso


indexado.

Uniendo Celdas

En una hoja de cálculo podemos unir celdas, la interfaz com.sun.star.util.XMergeable define


los siguientes métodos con esta finalidad:
merge ( bUnion As Boolean )
Si bUnion es True (Verdadero) une el área del objeto, sino divide
getIsMerged ( ) As Boolean
Devuelve True (Verdadero) cuando el área del objeto está unida, sino devuelve False

Insertando Bordes

Otro aspecto importante en la presentación de una hoja de cálculo es la colocación de los bor-
des en torno a las celdas. El servicio CellProperties contiene las siguientes propiedades que
definen el tipo de borde de una celda o rango de celdas:
Propiedad Descripción
TableBorder Define el borde de una celda o rango de celdas
TopBorder Define el borde superior de cada celda del rango
BottomBorder Define el borde inferior de cada celda del rango
RightBorder Define el borde derecho de cada celda del rango
LeftBorder Define el borde izquierdo de cada celda del rango

El principal elemento de cada una de estas propiedades es la estructura BorderLine, conte-


niendo, entre otros, los campos Color y OuterLineWidth para el color y el grueso del la lí-

68 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

nea. Para la propiedad TableBorder, podemos definir cuatro líneas: TopLine, BottomLine,
RightLine y LeftLine.
Siguiendo con nuestro ejemplo, uniremos algunas celdas, y después, definiremos los bordes
para nuestra hoja. Añada el siguiente código a la subrutina Sub editaHoja y observe el resul-
tado de la ejecución:
' une celdas
oRango = oHoja.getCellRangeByPosition(0, 7, 3, 7)
oRango.merge(True)
' Define Borde
Dim oBorde As New com.sun.star.table.TableBorder
Dim oLinBorde As New com.sun.star.table.BorderLine
'
oRango = oHoja.getCellRangeByPosition(0, 0, 4, 7)
' define el grosor y color de la línea de borde
oLinBorde.OuterLineWidth = 30
oLinBorde.Color = CLng( "&H000099" )
oRango.setPropertyValue("TopBorder", oLinBorde)
oRango.setPropertyValue("RightBorder", oLinBorde)
oRango.setPropertyValue("LeftBorder", oLinBorde)
oRango.setPropertyValue("BottomBorder", oLinBorde)
' defina y aplica la propiedad TableBorder
oLinBorde.OuterLineWidth = 100
oLinBorde.Color = CLng( "&HAABBCC" )
oBorde.TopLine = oLinBorde
oBorde.BottomLine = oLinBorde
oBorde.RightLine = oLinBorde
oBorde.LeftLine = oLinBorde
oBorde.IsTopLineValid = True
oBorde.IsBottomLineValid = True
oBorde.IsRightLineValid = True
oBorde.IsLeftLineValid = True
oRango.setPropertyValue("TableBorder", oBorde)

Inicialmente definimos los bordes de todas las celdas de oRango, después aplicamos un borde
al rango. Observe los campos Is...Valid definidos como True.

Formato Numérico

OpenOffice.org posee diversas categorías de formato numérico. Cada categoría posee diver-
sos formatos predefinidos. Mediante la interfaz XNumberFormatsSupplier podemos leer, mo-
dificar e añadir nuevos formatos a nuestros documentos.
La interfaz XNumberFormatsSupplier contiene los métodos siguientes:
getNumberFormats ( ) As Object < com.sun.star.util.XNumberFormats >
getNumberFormatsSettings ( ) As Object < com.sun.star.beans.XPropertySet >

Entre los métodos de la interfaz XNumberFormats, tenemos:


getByKey (nClave As Long) As Object < XPropertySet >
queryKeys (nCategoria As Long, nLocal As Long, bInsertar As Boolean) As aArray ( )
queryKey (sFormato As String, nLocal As Long, bBusca As Boolean) As Long
addNew ( sFormato As String, nLocal As Long ) As Long

Introducción a OpenOffice.org Basic 69


Documentos de Calc Versión 1

La interfaz com.sun.star.util.XNumberFormatTypes contiene métodos para obtener el índi-


ce de algunos formatos predefinidos. Aquí usaremos el método:
getStandardFormat (nTipo AS Long, nLocal As Long) As Long

El grupo de constantes com.sun.star.util.NumberFormat define valores para, entre otras, las


siguientes categorías: DATE, TIME, CURRENCY, NUMBER, DATETIME.
El servicio CellProperties contiene la propiedad NumberFormat, que define el tipo de for-
mato numérico de una celda o rango de celdas.
Veamos un ejemplo ilustrativo. En un documento de Calc, cree la macro siguiente, ejecútela
y observe el resultado.
Sub muestraFormatosNumericos
Dim oDoc As Object
Dim oFormatos As Object
Dim mClaves As Variant
Dim mProp As Variant
Dim oLocal As New com.sun.star.lang.Locale

oDoc = ThisComponent
oFormatos = oDoc.getNumberFormats()
oSettings = oDoc.getNumberFormatSettings()
oInfo = oSettings.getPropertySetInfo()
oProp = oInfo.getProperties()
MsgBox UBound(oProp)
For n = 0 To UBound(oProp)
MsgBox oProp(n).Name
Next n
mClaves = oFormatos.queryKeys(0, oLocal, FALSE)
MsgBox UBound(mClaves)
mProp = oFormatos.getByKey(11).getPropertyValues()
' obtiene los nombres de las propiedades
sMsg = ""
For n=0 To UBound(mProp)
sMsg = sMsg + mProp(n).Name + Chr$(13)
Next n
MsgBox sMsg
' muestra el valor de FormatString
MsgBox mProp(0).Value

End Sub

Ahora, regresemos a nuestra subrutina Sub editaHoja para aplicar formatos numéricos en al-
gunas celdas. Añada el siguiente código, ejecútelo y observe la salida:
' Formatos Numéricos
Dim oFormatos As Object
Dim aLocal() As New com.sun.star.lang.Locale
' obtiene los formatos numéricos del modelo
oFormatos = oDoc.getNumberFormats()
' obtiene el índice del formato predefinido para MONEDA
n% = oFormatos.getStandardFormat( _
com.sun.star.util.NumberFormat.CURRENCY, aLocal())
' obtiene un rango de celdas

70 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

oRango = oDoc.getSheets().getByIndex(0).getCellRangeByPosition(3,1,4,6)
' modifica el formato predefinido para MONEDA
oRango.NumberFormat = n%
' obtiene una celda y la formatea como MONEDA
oCelda = oHoja.getCellByPosition(4, 7)
oCelda.NumberFormat = n%

Observe la declaración de los objetos, el uso del método getStandardFormat ( ) y el uso de la


propiedad NumberFormat para modificar el formato de las celdas.

Formato Condicional

El servicio com.sun.star.sheet.SheetCellRange contiene las siguientes propiedades para el


formato condicional:
conditionalFormat - define condiciones para formato condicional
conditionalFormatLocal - define condiciones locales para formato condicional

La interfaz XSheetConditionalEntries provee los métodos siguientes para operaciones con


condiciones de formateado:
addNew ( mCond () As < com.sun.star.beans.PropertyValue > )
el argumento mCond es un array con las siguientes entradas:
- “Operator” con los posibles valores definidos en com.sun.star.sheet.ConditionOperator:
NONE, EQUAL, NOT_EQUAL, GREATER, GREATER_EQUAL,
LESS, LESS_EQUAL, BETWEEN, NOT_BETWEEN, FORMULA
- “Formula1” conteniendo una cadena con un valor o fórmula
- “Formula2” conteniendo un valor o fórmula, usada cuando el operador es BETWEEN
- “StyleName” conteniendo un nombre de estilo de formato de celda
removeByIndex ( nIndice As Long )
elimina la condición nIndice
clear ( )
limpia las condiciones actuales para el formato
Añada el código siguiente al final de Sub editaHoja, ejecútelo y observe la salida:
' FORMATO CONDICIONAL
'
Dim mCond(2) As New com.sun.star.beans.PropertyValue
Dim oEntradas As Variant
' obtiene un rango de celdas
oRango = oDoc.getSheets().getByIndex(0).getCellRangeByPosition(4,1,4,6)
' obtiene el formato condicional actual
oEntradas = oRango.getPropertyValue("ConditionalFormat")
' define las propiedades de una condición para formateo
mCond(0).Name = "Operator"
mCond(0).Value = com.sun.star.sheet.ConditionOperator.GREATER
mCond(1).Name = "Formula1"

Introducción a OpenOffice.org Basic 71


Documentos de Calc Versión 1

mCond(1).Value = "500"
mCond(2).Name = "StyleName"
mCond(2).Value = "Result"
' limpia las condiciones existentes
oEntradas.clear()
' añade una nueva condición
oEntradas.addNew(mCond())
' aplica el formato condicional
oRango.setPropertyValue("ConditionalFormat", oEntradas)

En este código, aplicamos el estilo “Resultado” si el valor de la celda es mayor de 500,00 €.


También podemos aplicar estilos de formato de celdas definidos por los usuarios.

7.7 Búsqueda y Reemplazo


La búsqueda y reemplazo, en un documento de Calc, funciona de modo semejante a lo visto
en la sección 6.8 Búsqueda y Reemplazo, del capítulo 6. Documentos de Writer.
Recordando, la interfaz com.sun.star.util.XSearchable proporciona los métodos de búsqueda
siguientes:
createSearchDescriptor ( ) As Object <SearchDescriptor>
FindAll ( oDescriptor As Object ) As Object <com.sun.star.container.XIndexAccess>
FindFirst ( oDescriptor As Object ) As Object <com.sun.star.uno.XInterface>
FindNext ( oInicio As Object, oDescriptor As Object ) As Object <Xinterface>

El servicio SearchDescriptor tiene los siguientes métodos:


getSearchString ( ) As String
setSearchString ( sCadena As String )

He aquí algunas de sus propiedades:


Propiedad Descripción
SearchBackwards Si True (Verdadero), busca hacia el principio del documento.
SearchCaseSensitive Si True (Verdadero), considera mayúsculas/minúsculas.
SearchWords Si True (Verdadero), localiza tan sólo las celdas con el texto
exacto sin más, si no, localiza también las celdas donde el
texto forma parte del contenido.
SearchStyles Si True (Verdadero), busca por un estilo de celda.

Veamos un ejemplo de búsqueda: cree un nuevo documento de Calc, rellene algunas celdas
con el texto “TOTAL” y “TOTAL GENERAL”, seguidamente cree la macro inferior y ejecu-
te.
Sub buscaTexto
Dim oDoc As Object

72 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

Dim oDescBusca As Object


Dim oHoja As Object

oDoc = ThisComponent
oHoja = oDoc.Sheets(0)
oDescBusca = oHoja.createSearchDescriptor()
oDescBusca.SearchWords = True
oDescBusca.setSearchString ("TOTAL")
oResultado = oHoja.findFirst( oDescBusca )
i = 0
Do Until IsNull(oResultado)
oResultado.CharColor = RGB(250,100,50)
oResultado = oHoja.findNext(oResultado, oDescBusca )
i = i + 1
Loop
MsgBox "Ocurrencias de "+oDescBusca.getSearchString() + " " + Str$(i)
End Sub

Ahora, cambie la propiedad SearchWords a False y ejecute nuevamente la macro observando


su resultado.
La sustitución de texto se implementa por la interfaz XReplaceable, que hereda las caracterís-
ticas de XSearchable. Ella proporciona los métodos:
createReplaceDescriptor ( ) As Object <com.sun.star.util.XReplaceDescriptor>
replaceAll ( xDescriptor As Object <com.sun.star.util.XReplaceDescriptor>) As Long

El servicio ReplaceDescriptor tiene métodos para obtener y asignar la cadena de reemplazo:


getReplaceString ( ) As String
setReplaceString ( sCadena As String )

He aquí una búsqueda y reemplazo sencillas, en el mismo documento del ejemplo anterior:
Sub reemplazaTexto
Dim oDoc As Object
Dim oDescriptor As Object
Dim oHoja As Object

oDoc = ThisComponent
oHoja = oDoc.Sheets(0)
oDescriptor = oHoja.createReplaceDescriptor()
oDescriptor.setSearchString( "TOTAL GENERAL" )
oDescriptor.setReplaceString( "Total" )
n = oHoja.replaceAll(oDescriptor)
sMsg = oDescriptor.getSearchString()+" por "+oDescriptor.getReplaceString()
MsgBox sMsg + " = " + Str$(n)
End Sub

Observe que debemos ejecutar la búsqueda y reemplazo en un rango de celdas. En los ejem-
plos utilizamos toda la hoja de cálculo.

Introducción a OpenOffice.org Basic 73


Documentos de Calc Versión 1

7.8 Ordenando4
Para la ordenación de un rango de celdas, debemos utilizar los mismos conceptos y servicios
ya presentados en la sección 6.10 Tablas, del capítulo 6. Documentos de Writer.
A continuación, detallamos los principales métodos y propiedades utilizados en esta tarea.
Métodos de la interfaz com.sun.star.util.XSortable:
createSortDescriptor ( ) As Variant <com.sun.star.beans.PropertyValue>
sort (xDescriptor As Variant <com.sun.star.beans.PropertyValue> )

Algunas de las propiedades del descriptor de ordenación (SortDescriptor):


Propiedad Descripción
IsCaseSensitive Si True (Verdadero), considera mayúsculas / minúsculas
SortAscending Si True (Verdadero), ordenación ascendente
SortColumns Si True (Verdadero) ordena por columnas, sino, lo hace por
filas

El servicio com.sun.star.table.TableSortDescriptor incluye el servicio SortDescriptor y po-


see las propiedades siguientes:
Propiedad Descripción
SortFields Describe los campos de ordenación <com.sun.star.util.Sort-
Field>
MaxFieldCount Define el número máximo de campos, propiedad de sólo lectura
Orientation Define la orientación de la ordenación <com.sun.star.table.Ta-
bleOrientation>
ContainsHeader Si True (Verdadero), trata la primera fila como títulos, sin orde-
narla.

En el siguiente bloque de código, veremos la ordenación de un rango de celdas (A2:E7), del


documento creado por la subrutina Sub editaHoja. Introduzca el siguiente código al final de
la macro, ejecute y observe la salida.
' ============================
' ORDENANDO UN RANGO DE CELDAS
' ============================
Dim oCampoOrd(0) As New com.sun.star.util.SortField
Dim oDescrOrd As Variant
'
' define el rango a ser ordenado (A2:E7)
oRango = oDoc.getSheets().getByIndex(0).getCellRangeByPosition(0,1,4,6)

4 N. del T. Para esta sección rige lo que ya comentamos hablando de la ordenación de tablas en Writer. Los métodos
descritos son válidos en las versiones 1.0.x de OpenOffice.org, pero no funcionan en la versión 1.1.RC. En
posteriores revisiones de la presente Introducción... dejaremos el tema suficientemente concretado.

74 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

' define el campo de ordenación y sus propiedades


oCampoOrd(0).Field = 0
oCampoOrd(0).SortAscending = True
oCampoOrd(0).FieldType = com.sun.star.util.SortFieldType.ALPHANUMERIC
' crea el descriptor de ordenación
oDescrOrd = oRango.createSortDescriptor()
' define as propiedades del descriptor
oDescrOrd(0).Name = "SortFields"
oDescrOrd(0).Value = oCampoOrd()
oDescrOrd(1).Name = "ContainsHeader"
oDescrOrd(1).Value = False
oDescrOrd(2).Name = "SortColumns"
oDescrOrd(2).Value = False
' ordena el rango
oRango.sort(oDescrOrd())

Observe que comenzamos por la declaración de variables, creamos un rango de celdas con
una llamada al método getCellRangeByPosition (), definimos sus propiedades (el campo de
ordenación es una propiedad del descriptor) y, finalmente, invocamos el método sort () para
ejecutar su tarea.

7.9 Filtrando dados


En esta sección, veremos los principales servicios e interfaces relacionados con la aplicación
de filtros a un rango de celdas.
La interfaz com.sun.star.sheet.XSheetFilterable especifica los métodos siguientes:
createFilterDescriptor ( bVacio As Boolean ) As Object < XSheetFilterDescriptor >
crea un descriptor vacío si bVacio es True, si no, preserva las informaciones
filter ( oDescriptor As Object < XSheetFilterDescriptor > )
aplica el filtro al rango de celdas
El servicio SheetFilterDescriptor controla las condiciones de la operación de filtro. He aquí
algunas de sus propiedades:
Propiedad Descripción
IsCaseSensitive Si True (Verdadero), distingue mayúsculas y minúsculas
SkipDuplicates Si True (Verdadero), se omitirán las entradas duplicadas
Orientation Filtra por Filas o Columnas ( TableOrientation )
ContainsHeader La primera fila o columna es un encabezado
CopyOutputData Si True (Verdadero), el resultado se copiará en otro lugar
OutputPosition Lugar para la copia ( estructura CellAddress )

La interfaz XSheetFilterDescriptor contiene los siguientes métodos para obtener y definir los
campos con los criterios del filtro:
getFilterFields ( ) aCampos () As Object < TableFilterField >

Introducción a OpenOffice.org Basic 75


Documentos de Calc Versión 1

devuelve los campos con los criterios de filtrado


setFilterFields ( aCampos () As Object < TableFilterField > )
define los campos con los criterios de filtrado
A estructura com.sun.star.table.TableFilterField contiene los siguientes elementos:
Connection - como será la conexión con la condición anterior ( Or / And )
Field - la columna usada en la condición
Operator - operador condicional ( FilterOperator )
IsNumeric - si True (Verdadero), el valor del campo (Field) es numérico
NumericValue - valor del campo, a usar si IsNumeric es True (Verdadero)
StringValue - cadena de caracteres, a usar si IsNumeric es False

Los pasos necesarios para filtrar datos en una hoja de cálculo son:
a) obtener el rango de celdas a filtrar;
b) definir la estructura de los campos con los criterios de filtro;
c) crear y definir los datos del descriptor del filtro;
d) aplicar el filtro.
Veamos una sección de código que aplica un filtro sencillo en un rango de celdas.
Sub aplicaFiltro
Dim oDoc As Object
Dim oHoja As Object
Dim oRango As Object
Dim oDescFiltro As Variant
Dim oCamposFiltro(0) As New com.sun.star.sheet.TableFilterField

oDoc = ThisComponent
oHoja = oDoc.getSheets().getByIndex(0)
oRango = oHoja.getCellRangeByPosition(0,1,4,6)
' define la estructura TableFilterField
oCamposFiltro(0).Field = 4
oCamposFiltro(0).IsNumeric = True
oCamposFiltro(0).Operator = _
com.sun.star.sheet.FilterOperator.GREATER_EQUAL
oCamposFiltro(0).NumericValue = 300
' crea el descriptor de filtro vacío (True)
oDescFiltro = oRango.createFilterDescriptor (True)
' define el campo de filtro
oDescFiltro.setFilterFields (oCamposFiltro())
' aplica el filtro
oRango.filter (oDescFiltro)
'
MsgBox "OK para filtrar Caracteres"
' redefine la estructura TableFilterField
oCamposFiltro(0).Field = 0
oCamposFiltro(0).IsNumeric = False
oCamposFiltro(0).Operator = com.sun.star.sheet.FilterOperator.GREATER
oCamposFiltro(0).StringValue = "A 1"
' crea un descriptor de filtro vacío (True)
oDescFiltro = oRango.createFilterDescriptor (True)
' define o campo de filtro
oDescFiltro.setFilterFields (oCamposFiltro())
' aplica o filtro

76 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

oRango.filter (oDescFiltro)
End Sub

Si quiere usted probar este código, inserte esta macro en el documento generado por la
subrutina Sub editaHoja y ejecútela, observando la salida. Observe que la estructura
TableFilterField puede tener más de un campo con criterios de filtro.
Intente añadir código para copiar el resultado del filtro en la Hoja2 del documento.

7.10 Insertando Subtotales


Las operaciones de totalización sobre un rango de celdas, son tremendamente prácticas. La
API de OpenOffice.org ofrece diversos servicios e interfaces para la programación de subtota-
les.
La interfaz XSubTotalCalculatable define los siguientes métodos:
createSubTotalDescriptor ( bVacio As Boolean ) As Object < XSubTotalDescriptor >
crea un descriptor de subtotal vacío si bVacio es True, sino, preserva los datos anteriores
applySubTotals ( oDesc As Object < XSubTotalDescriptor >, bReemplaza As Boolean )
aplica el subtotal, si bReemplaza es True, el resultado anterior será sustituido
removeSubTotals ( )
elimina los subtotales del objeto
El servicio SubTotalDescriptor es una representación de como se crearán los subtotales. A
continuación, algunas de sus propiedades:
Propiedad Descripción
InsertPageBreaks Inserta un salto de página después de cada subtotal
IsCaseSensitive Considera letras mayúsculas y minúsculas
EnableUserSortLis Si True (Verdadero) permite la definición de una lista para la
t ordenación
UserSortListIndex La lista a ordenar, si EnableUserSortList es True (Verdadero)
EnableSort Define si el contenido de los campos estará ordenado
SortAscending Si True (Verdadero), la ordenación será creciente (depende de
EnableSort )

Además de las propiedades anteriores, el descriptor debe contener los campos de subtotales.
La interfaz XSubTotalDescriptor proporciona métodos para añadir o eliminar campos:
addNew ( aColumnas() As < SubTotalColumn >, nColGrupo As Long)
añade los campos al descriptor, nColGrupo especifica la columna base para la agrupación
clear ( )
elimina todos los campos de subtotales del objeto
La estructura com.sun.star.sheet.SubTotalColumn contiene los elementos:

Introducción a OpenOffice.org Basic 77


Documentos de Calc Versión 1

Column - índice de la columna a subtotalizar


Function - el tipo de subtotal, definido en com.sun.star.sheet.GeneralFunction

Los pasos necesarios para añadir filas con subtotales en un rango son:
a) obtener el rango de celdas a totalizar;
b) definir la estructura de los campos de subtotal;
c) crear y definir los datos del descriptor de subtotal;
d) aplicar la operación de subtotal.
Veamos un segmento de código que aplica un subtotal en un rango de celdas.
Sub aplicaSubTotal
Dim oDoc As Object
Dim oHoja As Object
Dim oRango As Object
Dim oDescSubTotal As Variant
Dim oCamposSubTotal(0) As New com.sun.star.sheet.SubTotalColumn

oDoc = ThisComponent
oHoja = oDoc.getSheets().getByIndex(0)
oRango = oHoja.getCellRangeByPosition(0,0,4,6)
' define a estructura SubTotalColumn
oCamposSubTotal(0).Column = 4
oCamposSubTotal(0).Function = com.sun.star.sheet.GeneralFunction.SUM
' crea un descriptor de subtotal
oDescSubTotal = oRango.createSubTotalDescriptor (True)
' añade el campo subtotal y la columna base
oDescSubTotal.addNew (oCamposSubTotal(), 0)
' aplica el subtotal
oRango.applySubTotals(oDescSubTotal, True)
End Sub

Para comprobar este código, cree una macro en el documento generado por Sub editaHoja,
ejecútelo y analice el resultado.

7.11 Gráficos
Un gráfico es un documento incrustado en otro documento de OpenOffice.org. La API de
OpenOffice.org contiene diversos servicios e interfaces para la generación de gráficos, a partir
de los datos contenidos en una hoja de cálculo.
El servicio com.sun.star.table.TableCharts soporta los métodos de las interfaces XTable-
Charts, XIndexAccess y XEnumerationAccess.
Métodos de la interfaz com.sun.star.table.XTableCharts:
addNewByName ( sNombre As String,
oArea As Object < com.sun.star.awt.Rectangle >,
oRango ( ) As Object < com.sun.star.table.CellRangeAddress >,
bTitCol As Boolean, bTitLin As Boolean )
Añade el gráfico a la colección de gráficos de la hoja. Sus argumentos son:

78 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

sNombre - el nombre del gráfico


oArea - el área (rectángulo) donde se dibujará el gráfico
oRango - el rango de celdas con los datos
bTitCol - si True (Verdadero), los datos de la fila superior constituirán la leyenda
bTitLin - si True (Verdadero), la primera columna formará los títulos del eje

removeByName ( sNombre As String )


elimina el gráfico con el nombre sNombre de la colección.
El servicio com.sun.star.table.TableChart soporta la interfaz XTableChart con los métodos:
getHasColumnHeaders ( ) As Boolean
setHasColumnHeaders ( bTituloColumna As Boolean )
getHasRowHeaders ( ) As Boolean
setHasRowHeaders ( bTituloColumna As Boolean )
getRanges ( ) As sRangos ( ) < CellRangeAddress >
setRanges ( sRangos ( ) As Object < CellRangeAddress > )

Un documento gráfico contiene una referencia para un origen de datos, un diagrama y algunas
propiedades como título, subtítulo y leyenda. El servicio ChartDocument es el modelo de
documento gráfico y soporta las interfaces XChartDocument, XPropertySet y XMultiServi-
ceFactory. El mismo posee las siguientes propiedades:
HasMainTitle - Si True (Verdadero), muestra el título principal
HasSubTitle - Si True (Verdadero), muestra el subtítulo
HasLegend - Si True (Verdadero), muestra la leyenda

La interfaz com.sun.star.chart.XChartDocument proporciona los métodos:


getTitle ( ) As < com.sun.star.drawing.XShape >
getSubTitle ( ) As < com.sun.star.drawing.XShape >
getLegend ( ) As < com.sun.star.drawing.XShape >
getArea ( ) As < com.sun.star.beans.XPropertySet >
getDiagram ( ) As < com.sun.star.chart.XDiagram >
setDiagram ( oDiagrama As < com.sun.star.chart.XDiagram >)
getData ( ) As < com.sun.star.chart.XChartData >
attachData ( oDatosExternos As < com.sun.star.chart.XChartData >)

El diagrama es el objeto que contiene la forma del gráfico, basada en el servicio Diagram y
sus interfaces XDiagram y XPropertySet. Diferentes tipos de diagramas pueden ser creados
con el método createInstance (), de la interfaz XMultiServiceFactory. He aquí algunos ser-
vicios para tipos de diagramas:
com.sun.star.chart.BarDiagram
com.sun.star.chart.LineDiagram
com.sun.star.chart.PieDiagram
com.sun.star.chart.AreaDiagram
com.sun.star.chart.XYDiagram

Introducción a OpenOffice.org Basic 79


Documentos de Calc Versión 1

Podemos modificar la propiedad Diagram de un gráfico con el siguiente código:


oDiagrama = oGraf.createInstance("com.sun.star.chart.PieDiagram")
oGrafico.setDiagram ( oDiagrama )

El servicio com.sun.star.chart.Diagram tiene las siguientes propiedades:


DataRowSource - define si las series de datos están orientadas en filas o columnas
DataCaption - define como se mostrará la leyenda de los datos

Para crear un gráfico debemos seguir los siguientes pasos:


a) definir los datos a mostrar por el gráfico;
b) definir el área rectangular donde se diseñará el gráfico;
c) añadir el gráfico a la colección;
d) recuperar el objeto gráfico incrustado;
e) definir las propiedades del gráfico.
Veamos un ejemplo sencillo. Introduzca la macro siguiente y, tras ejecutarla, observe la sali-
da:
Sub creaGrafico
Dim oDesk As Variant
Dim oDoc As Object
Dim mProp() As Variant
Dim sURL As String
' crea documento de Calc
oDesk = createUnoService("com.sun.star.frame.Desktop")
sUrl = "private:factory/scalc"
oDoc = oDesk.LoadComponentFromURL(sUrl, "_blank", 0, mProp())
' edita celdas de la hoja de cálculo
Dim oHoja As Object
Dim oCelda As Object
Dim sTitCol() As String
' escribe los títulos de las columnas
sTitCol = Array ("Período","Ordenador","Periférico","Servicio","Total")
oHoja = oDoc.getSheets().getByIndex(0)
For i% = 0 To 4
oCelda = oHoja.getCellByPosition(i%, 0)
oCelda.setString(sTitCol(i%))
Next i%
' rellene las celdas con texto, valor y fórmula
For i% = 1 To 4
For j% = 0 To 4
oCelda = oHoja.getCellByPosition(j%, i%)
If (j% = 0) Then
oCelda.setString(Str$(i%) + "º Trim")
ElseIf (j% > 0 And j < 4) Then
oCelda.setValue(1000 * Rnd())
Else
sRango = "B" + Trim$(Str$(i%+1)) + ":" + "D" + Trim$(Str$(i%+1))
sFormula = "=Suma(" + sRango + ")"
oCelda.FormulaLocal = sFormula
End If
Next j%

80 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

Next i%
'
' inserta un gráfico de columnas
Dim oRect As New com.sun.star.awt.Rectangle
Dim oFinRango(0) As New com.sun.star.table.CellRangeAddress
Dim oGraficos As Object
' define el nombre del gráfico
sNombre = "Trimestral"
' define la dirección del rango de celdas con los datos
oFinRango(0).Sheet = 0
oFinRango(0).StartColumn = 0
oFinRango(0).StartRow = 0
oFinRango(0).EndColumn = 3
oFinRango(0).EndRow = 4
' define el área del gráfico
oRect.X = 1000
oRect.Y = 3000
oRect.Width = 12000
oRect.Height = 12000
' obtiene la colección de gráficos de la Hoja1
oGraficos = oHoja.Charts
' añade un gráfico a la colección
oGraficos.addNewByName(sNombre, oRect, oFinRango(), True, True)
' define las propiedades(Titulo)
oGraf = oGraficos.getByName(sNombre).getEmbeddedObject()
oGraf.Title.String = "Facturación Trimestral"
oGraf.HasSubTitle = True
oGraf.SubTitle.String = "Año 2003"
End Sub

Comenzamos rellenando las celdas con los datos, después definimos el nombre del gráfico, el
rango de las celdas con los datos y el área donde se dibujará el gráfico. Tras estos pasos preli-
minares, obtenemos la colección de gráficos de la hoja y añadimos nuestro gráfico a la colec-
ción, con una llamada al método addNewByName ( ). Finalmente, obtenemos el objeto grá-
fico incrustado, con una llamada el método getByName ( ) asociada al método getEmbedde-
dObject ( ) y, entonces, modificamos algunas propiedades del gráfico.
Aprovechando el ejemplo anterior, mostraremos como modificar la propiedad Diagram de un
gráfico. Añada el siguiente código al final de Sub creaGrafico y ejecútelo para crear un grá-
fico de pastel (circular), representando los datos de la fila 2 de la hoja de cálculo.
' Creando un gráfico do tipo circular
Dim oRangoCirc(1) As New com.sun.star.table.CellRangeAddress
'
MsgBox "Aceptar para un gráfico Circular"
' elimina el gráfico de barras
oGraficos.removeByName(sNombre)
sNombre = "GrafCirc"
' define la dirección del rango de las celdas con leyendas
oRangoCirc(0).Sheet = 0
oRangoCirc(0).StartColumn = 0
oRangoCirc(0).StartRow = 0
oRangoCirc(0).EndColumn = 3
oRangoCirc(0).EndRow = 0
' define la dirección del rango con datos
oRangoCirc(1).Sheet = 0
oRangoCirc(1).StartColumn = 0
oRangoCirc(1).StartRow = 1

Introducción a OpenOffice.org Basic 81


Documentos de Calc Versión 1

oRangoCirc(1).EndColumn = 3
oRangoCirc(1).EndRow = 1
' añade un gráfico a la colección
oGraficos.addNewByName(sNombre, oRect, oRangoCirc(), True, True)
' define las propiedades
oGraf = oGraficos.getByName(sNombre).getEmbeddedObject()
oGraf.Diagram = oGraf.createInstance("com.sun.star.chart.PieDiagram")
oGraf.Diagram.DataRowSource = com.sun.star.chart.ChartDataRowSource.ROWS
oGraf.Title.String = "1º Trimestre – 2003"

Observe que tenemos un array de estructuras CellRangeAddress, donde el primer elemento


contiene los datos de la leyenda del gráfico y el segundo los datos a ser representados. Obser-
ve también el cambio de la propiedad Diagram con una llamada al método createInstance ( )
y la modificación de la propiedad DataRowSource del diagrama.
Compruebe, además, que el hecho de poder definir un array CellRangeAddress, indica que
podemos tener rangos de celdas, contiguas o no, conteniendo los datos a representar gráfica-
mente.

82 Introducción a OpenOffice.org Basic


Versión 1 Documentos de Calc

Introducción a OpenOffice.org Basic 83


Más información Versión 1

8 Más información

8.1 En la red
OpenOffice.org :
http://www.openoffice.org
http://www.openoffice.org.br (en portugués - Brasil)
http://es.openoffice.org (en español)

Proyecto de Documentación de OpenOffice.org:


http://documentation.openoffice.org

API de OpenOffice.org http://api.openoffice.org


Este es el sitio indicado para los interesados en el desarrollo con OpenOffice.org. Además del
SDK, usted encontrará:
– OpenOffice.org 1.0.2 – Developers Guide (~ 12 Mb )
– Manual de Referencia de la API OpenOffice.org (~ 8 Mb )
– StarOffice Programmers Tutorial (~ 1 Mb )
– Ejemplos de la Developers Guide (~ 1 Mb )

Sun Microsystems http://docs.sun.com/db/doc/817-1826-10


El enlace apunta a StarOffice 6.0 Software Basic Programmer's Guide, un manual
introductorio bastante interesante.

OOoDocs.Org http://www.ooodocs.org
Documentación y notícias sobre o OpenOffice.org.

OOoMacros http://ooomacros.sourceforge.net
Repositorio de modelos, macros y asistentes para OpenOffice.org. Descargue todas las macros
y estudie su código para aprender más.

84 Introducción a OpenOffice.org Basic


Versión 1 Más información

OOExtras http://ooextras.sourceforge.net
Abundantes modelos, plantillas, macros e imágenes para añadir a la galería. Vale la pena
curiosear por aquí.

Pitonyak.org www.pitonyak.org/
Andrew Pitonyak y sus colaboradores merecen nuestra gratitud. Esta página contiene un
excelente documento sobre macros y lenguaje Basic. Consúltela periódicamente.

8.2 Con el autor


Acepto solicitudes de correcciones, inclusión de nuevos tópicos, contribuciones o aclaraciones
sobre OpenOffice.org Basic. Envíe un mensaje a:
noelsonduarte@globo.com

Introducción a OpenOffice.org Basic 85


Créditos, Agradecimientos, Licencia Versión 1

9 Créditos, Agradecimientos, Licencia

9.1 Créditos
Autor del diseño gráfico del modelo: Mirto Silvio Busico <m.busico@ieee.org>
Autor del texto explicativo del modelo: Gianluca Turconi <luctur@openoffice.org>
La traducción al español y adaptación de pantallazos a OOo 1.1 ha sido perpetrada por Ismael
Fanlo <ifanlo@tiscali.es>

9.2 Agradecimientos
A Sun Microsystems, Inc por el apoyo para la creación y desarrollo de OpenOffice.org.
A Sun Microsystems, Inc, una vez más, por hacer disponible la documentación sobre la API
de OpenOffice.org, sin la cual este trabajo no sería posible.
A todos los voluntarios que, con su trabajo, contribuyen al crecimiento de OpenOffice.org.

9.3 Licencia
Se permite la copia, distribución y / o modificación de este documento, bajo los términos de la
GNU Free Documentation License, Versión 1.1 o una versión posterior publicada por la Free
Software Foundation. Una copia de la licencia a compaña a este documento, consulte el ar-
chivo FDL.TXT. Si usted no recibió una copia de este archivo, por favor informe al autor o al
webmaster del sitio donde obtuvo este documento.
Copyright © 2003 Noelson Alves Duarte.

86 Introducción a OpenOffice.org Basic

También podría gustarte