Difference between revisions of "ES/Manuales/GuiaAOO/TemasAvanzados/Macros/StarBasic/TrabajandoConOOo/CreandoNuestroPrimerServicio"
Line 1: | Line 1: | ||
{{DISPLAYTITLE:Creando nuestro primer “servicio” (objeto)}} | {{DISPLAYTITLE:Creando nuestro primer “servicio” (objeto)}} | ||
− | |||
{{ES/AyudaWiki/Borrador}} | {{ES/AyudaWiki/Borrador}} | ||
− | |||
Para crear, acceder y manipular un servicio, “necesitas” asignarlo a una variable de objeto, de la siguiente manera. | Para crear, acceder y manipular un servicio, “necesitas” asignarlo a una variable de objeto, de la siguiente manera. | ||
− | |||
− | |||
− | |||
+ | <source lang="oobas"> | ||
+ | Dim NombreVariable As Object | ||
</source> | </source> | ||
+ | |||
E inicializarla para poder usarla, para ello, usamos la función ''createUnoService''. | E inicializarla para poder usarla, para ello, usamos la función ''createUnoService''. | ||
+ | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub AccediendoAOpenOffice1() | ||
+ | Dim appOpenOffice As Object | ||
− | + | appOpenOffice = createUnoService( "com.sun.star.frame.Desktop" ) | |
− | + | End Sub | |
+ | </source> | ||
− | |||
− | + | El servicio <tt>com.sun.star.frame.Desktop</tt> es usado muy frecuentemente, pues nos permite acceder a “toda” la aplicación y sus componentes, por ello, existe una palabra clave que nos da acceso inmediato a este “servicio”; '''“'''<tt>StarDesktop</tt>'''”''' por lo que, la siguientes dos líneas son equivalentes. | |
− | |||
− | |||
− | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | appOpenOffice = createUnoService( "com.sun.star.frame.Desktop" ) | ||
− | + | appOpenOffice = StarDesktop | |
− | + | ||
− | appOpenOffice = StarDesktop | + | |
− | + | ||
</source> | </source> | ||
+ | |||
Ejecutando la macro anterior, por ahora, no veras ningún efecto, pero aquí empieza lo divertido e interesante, vamos a explorar por dentro del OpenOffice.org, modifica la macro para que quede de la siguiente manera. | Ejecutando la macro anterior, por ahora, no veras ningún efecto, pero aquí empieza lo divertido e interesante, vamos a explorar por dentro del OpenOffice.org, modifica la macro para que quede de la siguiente manera. | ||
+ | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Option Explicit | ||
− | + | Sub AccediendoAOpenOffice2() | |
+ | Dim appOpenOffice As Object | ||
+ | Dim oActivo As Object | ||
− | + | 'Inicializamos una variable con el servicio com.sun.star.frame.Desktop | |
+ | appOpenOffice = StarDesktop | ||
− | + | 'Obtenemos una referencia al componente activo | |
+ | oActivo = appOpenOffice.CurrentComponent | ||
− | + | 'Mostramos el tipo de componente | |
+ | MsgBox oActivo.Identifier | ||
− | + | End Sub | |
+ | </source> | ||
− | |||
− | + | Ahora si, al ejecutar te tiene que mostrar el siguiente mensaje. | |
− | |||
− | + | [[Image:ES_StarBasic_TrabajandoConOOo.23.png|center]] | |
− | |||
− | + | Pero, tal vez te muestre este otro. | |
− | |||
− | + | [[Image:ES_StarBasic_TrabajandoConOOo.22.png|center]] | |
− | |||
− | + | Incluso tal vez el siguiente. | |
− | |||
− | + | [[Image:ES_StarBasic_TrabajandoConOOo.21.png|center]] | |
− | |||
¿Por qué? Porque dependerá desde donde “llames” (ejecutes) la macro, verifícalo, tal vez la ejecutaste directamente desde el IDE, o tal vez la llamaste desde una hoja de calculo o desde un archivo de texto. En el tema anterior vimos como llamar a una macro desde donde queramos, aunque lo más practico para los siguientes ejemplos es que programes tus macros dentro del archivo “'''''Mis macros'''''”, queda a tu criterio. | ¿Por qué? Porque dependerá desde donde “llames” (ejecutes) la macro, verifícalo, tal vez la ejecutaste directamente desde el IDE, o tal vez la llamaste desde una hoja de calculo o desde un archivo de texto. En el tema anterior vimos como llamar a una macro desde donde queramos, aunque lo más practico para los siguientes ejemplos es que programes tus macros dentro del archivo “'''''Mis macros'''''”, queda a tu criterio. | ||
+ | |||
Abre seis archivos, uno por cada tipo de documento que podemos manejar en OpenOffice.org (hoja de calculo, documento de texto, presentación, dibujo, base de datos y formula) no necesariamente tienes que guardarlos, pero no estaría de más por que los vamos a usar en repetidas ocasiones. Ejecuta la macro anterior desde cada uno de estos documentos. Todos excepto la base de datos te tienen que mostrar el mensaje correctamente y en el caso de la base de datos, te tiene que mostrar el error siguiente. | Abre seis archivos, uno por cada tipo de documento que podemos manejar en OpenOffice.org (hoja de calculo, documento de texto, presentación, dibujo, base de datos y formula) no necesariamente tienes que guardarlos, pero no estaría de más por que los vamos a usar en repetidas ocasiones. Ejecuta la macro anterior desde cada uno de estos documentos. Todos excepto la base de datos te tienen que mostrar el mensaje correctamente y en el caso de la base de datos, te tiene que mostrar el error siguiente. | ||
+ | |||
[[Image:ES_StarBasic_TrabajandoConOOo.04.png|center]] | [[Image:ES_StarBasic_TrabajandoConOOo.04.png|center]] | ||
+ | |||
Apréndete muy bien estas dos nuevas palabras “'''propiedad'''” y “'''método'''”, las vas a usar de aquí en adelante y siempre que programes en OOo Basic. En este caso, es una '''“propiedad”''' lo que esta mal, es decir, la propiedad '''Identifier''', no la implementan las bases de datos. Sabiendo esto, podríamos empezar a proponer una macro genérica para saber que tipo de documento es el activo, probemos con la siguiente. | Apréndete muy bien estas dos nuevas palabras “'''propiedad'''” y “'''método'''”, las vas a usar de aquí en adelante y siempre que programes en OOo Basic. En este caso, es una '''“propiedad”''' lo que esta mal, es decir, la propiedad '''Identifier''', no la implementan las bases de datos. Sabiendo esto, podríamos empezar a proponer una macro genérica para saber que tipo de documento es el activo, probemos con la siguiente. | ||
+ | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub AccediendoAOpenOffice3() | ||
+ | Dim appOpenOffice As Object | ||
+ | Dim oActivo As Object | ||
− | + | 'Inicializamos una variable con el servicio com.sun.star.frame.Desktop | |
+ | appOpenOffice = StarDesktop | ||
− | + | 'Obtenemos una referencia al componente activo | |
+ | oActivo = appOpenOffice.CurrentComponent | ||
− | + | 'Mostramos el tipo de componente | |
+ | Select Case oActivo.Identifier | ||
+ | Case "com.sun.star.sheet.SpreadsheetDocument" | ||
+ | MsgBox "Soy una hoja de calculo" | ||
+ | Case "com.sun.star.presentation.PresentationDocument" | ||
+ | MsgBox "Soy una presentacion" | ||
+ | Case "com.sun.star.drawing.DrawingDocument" | ||
+ | MsgBox "Soy un dibujo" | ||
+ | Case "com.sun.star.formula.FormulaProperties" | ||
+ | MsgBox "Soy una formula" | ||
+ | Case "com.sun.star.text.TextDocument" | ||
+ | MsgBox "Soy un documento de texto" | ||
+ | End Select | ||
− | + | End Sub | |
+ | </source> | ||
− | |||
− | + | Ejecuta la macro anterior desde cada uno de los seis archivos, excepto desde la base de datos pues te dará un error, claro, puedes, si quieres, implementar un controlador de errores pero por ahora no lo haremos, busquemos otra alternativa, por ejemplo, probemos ahora la propiedad <tt>ImplementationName</tt> y veamos que pasa, | |
− | |||
− | + | <source lang="oobas"> | |
+ | Sub AccediendoAOpenOffice4() | ||
+ | Dim oActivo As Object | ||
− | + | 'Obtenemos una referencia al componente activo | |
+ | oActivo = StarDesktop.CurrentComponent | ||
− | + | 'Mostramos el tipo de componente | |
− | + | MsgBox oActivo.ImplementationName | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | MsgBox | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
+ | End Sub | ||
</source> | </source> | ||
− | |||
− | + | Esta vez si nos muestra un mensaje en todos los documentos, pero notaras que esta propiedad en algunos documentos no es muy clara, aquí el resumen de lo que tendrías que obtener en cada caso: | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{| class=wikitable | {| class=wikitable | ||
− | |||
!Aplicación | !Aplicación | ||
− | |||
! ''Tipo de documento | ! ''Tipo de documento | ||
− | + | ! ''Propiedad <tt>ImplementationName</tt>'' | |
− | ! ''Propiedad | + | |
|- | |- | ||
− | |||
| Writer | | Writer | ||
− | |||
| Documento de texto | | Documento de texto | ||
− | + | | <tt>SwXTextDocument</tt> | |
− | + | ||
|- | |- | ||
− | |||
| Calc | | Calc | ||
− | |||
| Hoja de calculo | | Hoja de calculo | ||
− | + | | <tt>ScModelObj</tt> | |
− | + | ||
|- | |- | ||
− | |||
| Impress | | Impress | ||
− | |||
| Presentaciones | | Presentaciones | ||
− | + | | <tt>SdXImpressDocument</tt> | |
− | + | ||
|- | |- | ||
− | |||
| Draw | | Draw | ||
− | |||
| Dibujo | | Dibujo | ||
− | + | | <tt>SdXImpressDocument</tt> | |
− | + | ||
|- | |- | ||
− | |||
| Base | | Base | ||
− | |||
| Base de datos | | Base de datos | ||
− | + | | <tt>com.sun.start.comp.dba.ODatabaseDocument</tt> | |
− | + | ||
|- | |- | ||
− | |||
| Math | | Math | ||
− | |||
| Formula | | Formula | ||
+ | | <tt>com.sun.start.comp.math.FormulaDocument</tt> | ||
+ | |} | ||
− | |||
− | + | ¿Te fijas que interesante?, nota el valor devuelto en las hojas de calculo y como las presentaciones y los dibujos devuelven el mismo resultado, por lo que esta propiedad, a pesar de estar implementada en todos los tipos de documentos, no resulta muy idónea para diferenciar a cada uno. ¿Y si en vez de devolver una cadena de texto, le preguntamos a cada componente si son lo que dicen ser?, es decir, por ejemplo, una hoja de calculo implementa propiedades y métodos (servicios) para manipular hojas de calculo, en este caso, este servicio se llama "<tt>com.sun.star.sheet.SpreadsheetDocument</tt>”, y cada documento soporta un tipo de servicio diferente. Todos los objetos admiten un método que nos permite preguntar si dicho objeto soporta un servicio en especial, este método se llama <tt>supportsService</tt> y hay que pasarle como argumento el nombre del servicio que queremos validar y nos devolverá verdadero (True) o falso (False) según soporte o no el servicio, por lo que la sintaxis competa de este método es: | |
− | |||
{{ES/Macros/Sintaxis|Variable As Boolean <nowiki>=</nowiki> Objeto.supportsService( Nombre_del_Servicio As String)}} | {{ES/Macros/Sintaxis|Variable As Boolean <nowiki>=</nowiki> Objeto.supportsService( Nombre_del_Servicio As String)}} | ||
+ | |||
Veámoslo trabajando en el siguiente ejemplo. | Veámoslo trabajando en el siguiente ejemplo. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub AccediendoAOpenOffice5() | ||
+ | Dim oActivo As Object | ||
+ | Dim bImplementaServicio As Boolean | ||
− | + | oActivo = StarDesktop.CurrentComponent | |
− | + | ||
− | + | ||
− | + | ||
− | oActivo = StarDesktop.CurrentComponent | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | bImplementaServicio = oActivo.supportsService("com.sun.star.sheet.SpreadsheetDocument") | |
− | End | + | If bImplementaServicio Then |
+ | MsgBox "Soy una hoja de calculo" | ||
+ | Else | ||
+ | MsgBox "NO soy una hoja de calculo" | ||
+ | End If | ||
+ | End Sub | ||
</source> | </source> | ||
− | |||
− | + | Y prueba desde todos nuestros documentos que funciona correctamente por lo que ya podemos implementar una macro mejor para saber que tipo de documento tenemos activo, simplemente consultando si soporta su respectivo “''servicio”.'' | |
− | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub AccediendoAOpenOffice6() | ||
+ | Dim oActivo As Object | ||
− | + | oActivo = StarDesktop.CurrentComponent | |
− | + | If oActivo.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | |
+ | MsgBox "Soy una hoja de calculo" | ||
+ | ElseIf oActivo.supportsService("com.sun.star.text.TextDocument") Then | ||
+ | MsgBox "Soy un documento de texto" | ||
+ | ElseIf oActivo.supportsService("com.sun.star.presentation.PresentationDocument") Then | ||
+ | MsgBox "Soy una presentacion" | ||
+ | ElseIf oActivo.supportsService("com.sun.star.drawing.DrawingDocument") Then | ||
+ | MsgBox "Soy un dibujo" | ||
+ | ElseIf oActivo.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") Then | ||
+ | MsgBox "Soy una base de datos" | ||
+ | ElseIf oActivo.supportsService("com.sun.star.formula.FormulaProperties") Then | ||
+ | MsgBox "Soy una formula" | ||
+ | ElseIf oActivo.supportsService("com.sun.star.script.BasicIDE") Then | ||
+ | MsgBox "Soy el editor de codigo IDE" | ||
+ | Else | ||
+ | MsgBox "NO se que tipo de documento soy" | ||
+ | End If | ||
− | + | End Sub | |
+ | </source> | ||
− | |||
− | + | Ahora si, ya podemos discriminar correctamente los documentos. Saber si un objeto implementa un determinado servicio, es muy importante para minimizar el riesgo de errores y para consultar directamente las propiedades y métodos que implementa dicho servicio sin tener que estar “adivinando” nada y precisamente para no estar adivinando, existe una propiedad que nos devuelve una matriz (array) con los servicios que soporta un objeto, esta propiedad se llama <tt>SupportedServiceNames</tt> y su sintaxis es. | |
− | |||
− | + | {{ES/Macros/Sintaxis|Variable As Array <nowiki>=</nowiki> Objeto.SupportedServiceNames}} | |
− | |||
− | + | Como siempre, no hay como los ejemplos. | |
− | |||
− | + | <source lang="oobas"> | |
+ | Sub AccediendoAOpenOffice7() | ||
+ | Dim oActivo As Object | ||
+ | Dim mServicios() As String | ||
+ | Dim co1 As Byte | ||
− | + | 'Obtenemos una referencia al componente activo | |
+ | oActivo = StarDesktop.CurrentComponent | ||
− | + | 'Obtenemos una matriz con los servicios que implementa | |
+ | mServicios() = oActivo.SupportedServiceNames | ||
+ | 'Y mostramos el nombre de cada servicio | ||
+ | For co1 = LBound( mServicios() ) To UBound( mServicios() ) | ||
+ | MsgBox mServicios( co1 ) | ||
+ | Next | ||
+ | End Sub | ||
</source> | </source> | ||
+ | |||
Y si ejecutas la macro anterior desde cada uno de nuestros seis documentos abiertos, tienes que obtener la siguiente lista de servicios en cada uno. | Y si ejecutas la macro anterior desde cada uno de nuestros seis documentos abiertos, tienes que obtener la siguiente lista de servicios en cada uno. | ||
− | |||
+ | {| class=wikitable | ||
! ''Aplicación'' | ! ''Aplicación'' | ||
− | |||
! ''Tipo de documento'' | ! ''Tipo de documento'' | ||
− | + | ! ''Propiedad <tt>SupportedServiceNames</tt>'' | |
− | ! ''Propiedad | + | |
|- | |- | ||
− | |||
| Writer | | Writer | ||
− | |||
| Documento de texto | | Documento de texto | ||
− | + | | <tt>com.sun.star.document.OfficeDocument com.sun.star.text.GenericTextDocument com.sun.star.text.TextDocument</tt> | |
− | + | ||
|- | |- | ||
− | |||
| Calc | | Calc | ||
− | |||
| Hoja de calculo | | Hoja de calculo | ||
+ | | <tt>com.sun.star.sheet.SpreadsheetDocument </tt> | ||
− | + | <tt>com.sun.star.sheet.SpreadsheetDocumentSettings</tt> | |
− | + | ||
− | + | ||
|- | |- | ||
− | |||
| Impress | | Impress | ||
− | |||
| Presentaciones | | Presentaciones | ||
+ | | <tt>com.sun.star.document.OfficeDocument </tt> | ||
− | + | <tt>com.sun.star.drawing.GenericDrawingDocument </tt> | |
− | + | <tt>com.sun.star.drawing.DrawingDocumentFactory </tt> | |
− | + | <tt>com.sun.star.presentation.PresentationDocument</tt> | |
− | + | ||
− | + | ||
|- | |- | ||
− | |||
| Draw | | Draw | ||
− | |||
| Dibujo | | Dibujo | ||
+ | | <tt>com.sun.star.document.OfficeDocument </tt> | ||
− | + | <tt>com.sun.star.drawing.GenericDrawingDocument </tt> | |
− | + | <tt>com.sun.star.drawing.DrawingDocumentFactory </tt> | |
− | + | <tt>com.sun.star.drawing.DrawingDocument</tt> | |
− | + | ||
− | + | ||
|- | |- | ||
− | |||
| Base | | Base | ||
− | |||
| Base de datos | | Base de datos | ||
+ | | <tt>com.sun.star.document.OfficeDocument</tt> | ||
− | + | <tt>com.sun.star.sdb.OfficeDatabaseDocument </tt> | |
− | + | ||
− | + | ||
|- | |- | ||
− | |||
| Math | | Math | ||
− | |||
| Formula | | Formula | ||
+ | | <tt>com.sun.star.document.OfficeDocument </tt> | ||
− | + | <tt>com.sun.star.formula.FormulaProperties</tt> | |
− | + | ||
− | + | ||
− | + | ||
|} | |} | ||
− | |||
− | < | + | Nota como Impress y Draw implementan casi los mismos servicios y observa como hay un servicio (<tt>com.sun.start.document.OfficeDocument</tt>), que, excepto en la hoja de calculo, es común a todos los documentos, pero no creas que la hoja de calculo no lo implementa, podemos demostrar que lo implementa con el siguiente ejemplo que tienes que ejecutar desde cualquier hoja de calculo, en todos los demás documentos también te funcionara, pero recuerda que solo queremos comprobar si la hoja de calculo implementa este servicio. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub AccediendoAOpenOffice8() | ||
+ | Dim oActivo As Object | ||
+ | Dim bImplementaServicio As Boolean | ||
− | + | oActivo = StarDesktop.CurrentComponent | |
− | + | bImplementaServicio = oActivo.supportsService("com.sun.star.document.OfficeDocument") | |
− | + | If bImplementaServicio Then | |
− | + | MsgBox "Verdad que si esta implementado el servicio" | |
− | + | Else | |
− | + | MsgBox "NO esta implementado el servicio" | |
− | + | End If | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | MsgBox | + | |
− | + | ||
− | + | ||
− | + | ||
− | End | + | |
+ | End Sub | ||
</source> | </source> | ||
− | |||
− | + | Este servicio común a todos los documentos, también es muy usado e importante como más adelante podrás comprobarlo. Por ahora, copia la siguiente macro y pruébala de nuevo con todos los documentos. | |
− | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub AccediendoAOpenOffice9() | ||
+ | Dim oActivo As Object | ||
+ | Dim mServicios() As String | ||
+ | Dim co1 As Byte | ||
− | + | oActivo = StarDesktop.CurrentComponent | |
+ | mServicios() = oActivo.'''getSupportedServiceNames'''() | ||
+ | For co1 = LBound( mServicios() ) To UBound( mServicios() ) | ||
+ | MsgBox mServicios( co1 ) | ||
+ | Next | ||
− | Sub | + | End Sub |
+ | </source> | ||
− | |||
− | + | Notaras que trabaja exactamente igual que la anterior, pero ve que no hemos usado la propiedad <tt>SupportedServiceNames</tt>, sino el método <tt>getSupportedServiceNames</tt>'''()''', diferenciados por el prefijo get y los paréntesis, los dos hacen lo mismo, pero en OOo Basic, casi todos los métodos tienen su correspondencia en una propiedad, si te es útil, recuerda tus clases elementales de español, los objetos son como los sustantivos, las propiedades son adjetivos y los métodos son verbos, así mismo y muy importante, las propiedades siempre son de un tipo de dato soportado por OOo Basic (<tt>string</tt>, <tt>integer</tt>, <tt>array</tt>, etc.), por lo que tienes que tener las mismas consideraciones (y precauciones) vistas en varios temas atrás, principalmente cuando vimos variables y funciones, así mismo los métodos, cuando se les pasan argumentos y cuando devuelven un valor se ven afectados por estas consideraciones, por lo que reitero, ten cuidado con los tipos de datos que usas en ellos. | |
− | |||
− | + | A lo largo de este capitulo, te mostrare, en la medida de lo posible, el uso como método y como propiedad, más adelante me limitare a usar métodos y tú usaras el que más de agrade. | |
− | |||
− | + | Hasta ahora, hemos accedido a un solo documento, pero podemos acceder a todos los documentos actualmente abiertos en OpenOffice.org, copia y prueba la siguiente macro. | |
− | |||
− | + | <source lang="oobas"> | |
+ | Option Explicit | ||
− | + | Sub Controlando_OpenOffice1() | |
+ | Dim oDocumentos As Object | ||
+ | Dim oDocumento As Object | ||
+ | Dim oEnumeraDocumentos As Object | ||
− | 'Nos desplazamos al siguiente elemento y lo asignamos | + | 'Accedemos a todos los documentos actualmente abiertos |
+ | oDocumentos = StarDesktop.getComponents() | ||
+ | 'Enumeramos cada uno | ||
+ | oEnumeraDocumentos = oDocumentos.createEnumeration() | ||
+ | 'hasMoreElements devuelve verdadero (True) mientras haya elementos | ||
+ | Do While oEnumeraDocumentos.hasMoreElements() | ||
+ | 'Nos desplazamos al siguiente elemento y lo asignamos | ||
+ | oDocumento = oEnumeraDocumentos.nextElement() | ||
+ | 'Mostramos el tipo de documento | ||
+ | MsgBox "Soy un documento de " & TipoDocumento( oDocumento ) | ||
+ | Loop | ||
− | + | End Sub | |
− | + | Function TipoDocumento(ByRef Documento As Object) As String | |
+ | Dim sAplicacion As String | ||
− | + | If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | |
+ | sAplicacion = "Calc" | ||
+ | ElseIf Documento.supportsService("com.sun.star.text.TextDocument") Then | ||
+ | sAplicacion = "Writer" | ||
+ | ElseIf Documento.supportsService("com.sun.star.presentation.PresentationDocument") Then | ||
+ | sAplicacion = "Impress" | ||
+ | ElseIf Documento.supportsService("com.sun.star.drawing.DrawingDocument") Then | ||
+ | sAplicacion = "Draw" | ||
+ | ElseIf Documento.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") Then | ||
+ | sAplicacion = "Base" | ||
+ | ElseIf Documento.supportsService("com.sun.star.formula.FormulaProperties") Then | ||
+ | sAplicacion = "Math" | ||
+ | ElseIf Documento.supportsService("com.sun.star.script.BasicIDE") Then | ||
+ | sAplicacion = "Basic" | ||
+ | Else | ||
+ | sAplicacion = "Desconocido" | ||
+ | End If | ||
− | + | TipoDocumento = sAplicacion | |
− | End | + | End Function |
+ | </source> | ||
− | |||
− | + | Toma nota de como hemos convertido una macro usada anteriormente en una función que nos devuelve el tipo de documento abierto. Muchos objetos en OpenOffice.org, solo son accesibles creando una “enumeración”, así que la estructura de la macro anterior la podrías usar con frecuencia. Una “enumeración”, es como un listado de objetos, se crean con el método <tt>createEnumeration()</tt>, el método <tt>.hasMoreElements()</tt> nos sirve para saber si todavía hay elementos y el método <tt>.nextElement()</tt>, permite movernos al siguiente elemento de la enumeración. | |
− | |||
− | + | Empecemos con código un poco más divertido, la siguiente variante de la macro anterior, te cerrara “todos” los archivos de Calc que no tengan cambios por guardar, '''CUIDADO''', si ejecutas la siguiente macro desde un archivo de Calc podrías cerrarte el archivo con resultados inesperados. | |
− | |||
− | + | <source lang="oobas"> | |
− | + | Sub Controlando_OpenOffice2() | |
− | + | Dim oDocumentos As Object | |
− | + | Dim oDocumento As Object | |
− | + | Dim oEnumeraDocumentos As Object | |
− | + | Dim co1 As Integer | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | End | + | oDocumentos = StarDesktop.getComponents() |
+ | oEnumeraDocumentos = oDocumentos.createEnumeration() | ||
+ | Do While oEnumeraDocumentos.hasMoreElements() | ||
+ | oDocumento = oEnumeraDocumentos.nextElement() | ||
+ | 'Verificamos que sea un archivo de Calc | ||
+ | If TipoDocumento( oDocumento ) = "Calc" Then | ||
+ | 'Si no ha sido modificado o los cambios ya están guardados | ||
+ | 'el método isModified devolverá falso (False) | ||
+ | If Not oDocumento.isModified() Then | ||
+ | 'el método dispose cierra el archivo | ||
+ | oDocumento.dispose() | ||
+ | co1 = co1 + 1 | ||
+ | End if | ||
+ | End If | ||
+ | Loop | ||
+ | MsgBox "Se cerraron un total de " & CStr(co1) & " archivos de Calc" | ||
+ | End Sub | ||
</source> | </source> | ||
− | |||
− | + | Ten mucho cuidado con el método <tt>dispose</tt>, te cerrará el archivo sin preguntarte nada, tenga o no tenga cambios guardados, úsalo con conocimiento de causa. Observa como usamos la propiedad <tt>isModified()</tt>, para saber si el documento ha sido modificado. | |
− | |||
− | + | La Interfaz de Programación de la Aplicación (API por sus siglas en ingles) proporciona, decenas incluso centenas de servicios con métodos y propiedades para controlar y manipular OpenOffice.org, la puedes consultar en linea en la página oficial de OpenOffice.org (por ahora solo en ingles) en: [http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html] | |
− | |||
− | + | También puedes descargarla y después consultarla fuera de línea para su acceso inmediata o si no tienes conexión permanente a Internet, en el [[ES/Manuales/GuiaAOO/TemasAvanzados/Macros/StarBasic/Apendices/InstalarSDK|Instalar el SDK]] te muestro como hacerlo. Para una consulta óptima de esta documentación, lo ideal es saber de forma anticipada que servicio, método o propiedad estamos buscando, para ello, todos los objetos cuentan con unas propiedades especiales que nos dan mucha información, veamos cuales son. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
=== Propiedades especiales de depuración === | === Propiedades especiales de depuración === | ||
+ | Ya vimos en el tema anterior como saber con el método “<tt>supportsService</tt>” si un objeto soporta un determinado servicio, pero tiene el inconveniente de que tenemos que saber anticipadamente el nombre de dicho servicio, lo cual a veces es un poco complicado. También vimos el uso del método <tt>getSupportedServiceNames()</tt> que nos devuelve una matriz con los nombres de los servicios que implementa el objeto. | ||
− | |||
Para obtener toda la información de un objeto, este cuenta con tres propiedades que nos informan de todas las propiedades, métodos e '''“interfaces”''' que implementa dicho objeto, estas propiedades son tres: | Para obtener toda la información de un objeto, este cuenta con tres propiedades que nos informan de todas las propiedades, métodos e '''“interfaces”''' que implementa dicho objeto, estas propiedades son tres: | ||
− | |||
− | * | + | * <tt>Dbg_SupportedInterfaces</tt> |
+ | * <tt>Dbg_Properties</tt> | ||
+ | * <tt>Dbg_Methods</tt> | ||
− | |||
− | Las tres son de tipo texto ( | + | Las tres son de tipo texto (<tt>string</tt>) y se usan de la siguiente manera. |
+ | |||
<source lang="oobas"> | <source lang="oobas"> | ||
+ | Sub ConsultandoObjetos1() | ||
+ | Dim sDatos As String | ||
− | + | MsgBox StarDesktop.Dbg_Properties | |
− | + | MsgBox StarDesktop.Dbg_Methods | |
− | + | MsgBox StarDesktop.Dbg_SupportedInterfaces | |
− | + | ||
− | MsgBox StarDesktop.Dbg_Properties | + | |
− | + | ||
− | MsgBox StarDesktop.Dbg_Methods | + | |
− | + | ||
− | MsgBox StarDesktop.Dbg_SupportedInterfaces | + | |
− | + | ||
− | + | ||
+ | End Sub | ||
</source> | </source> | ||
+ | |||
No te me confundas con esto de las '''“interfaces”''', para nuestros fines es perfectamente valido que los llamemos “servicios”, simplemente piensa en las interfaces como una forma de organizar servicios, pero en OOo Basic no tiene importancia por que accedemos directamente a las propiedades y métodos de los servicios. | No te me confundas con esto de las '''“interfaces”''', para nuestros fines es perfectamente valido que los llamemos “servicios”, simplemente piensa en las interfaces como una forma de organizar servicios, pero en OOo Basic no tiene importancia por que accedemos directamente a las propiedades y métodos de los servicios. | ||
+ | |||
La pequeña macro anterior, te tiene que mostrar un cuadro de mensaje con las propiedades del objeto. | La pequeña macro anterior, te tiene que mostrar un cuadro de mensaje con las propiedades del objeto. | ||
+ | |||
[[Image:ES_StarBasic_TrabajandoConOOo.20.png|center]] | [[Image:ES_StarBasic_TrabajandoConOOo.20.png|center]] | ||
+ | |||
Sus métodos: | Sus métodos: | ||
+ | |||
[[Image:ES_StarBasic_TrabajandoConOOo.07.png|center]] | [[Image:ES_StarBasic_TrabajandoConOOo.07.png|center]] | ||
+ | |||
Y sus interfaces (servicios): | Y sus interfaces (servicios): | ||
+ | |||
[[Image:ES_StarBasic_TrabajandoConOOo.19.png|center]] | [[Image:ES_StarBasic_TrabajandoConOOo.19.png|center]] | ||
− | |||
− | + | Observa el servicio señalado con una flecha, si vamos a su documentación, en línea ([http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html]) o local (<nowiki>file:///opt/openoffice/sdk/docs/common/ref/com/sun/star/frame/XComponentLoader.html</nowiki>), te darás cuenta que solo tiene un método <tt>loadComponentFromURL</tt>, pero un método muy importante, pues nos permite crear documentos nuevos o abrir archivos existentes, lo cual veremos al terminar este tema. | |
− | |||
− | + | Ahora probemos con los datos del documento activo. | |
− | |||
− | + | <source lang="oobas"> | |
+ | Sub ConsultandoObjetos2() | ||
+ | Dim sDatos As String | ||
− | MsgBox StarDesktop.getCurrentComponent.Dbg_Methods | + | MsgBox StarDesktop.getCurrentComponent.Dbg_Properties |
+ | MsgBox StarDesktop.getCurrentComponent.Dbg_Methods | ||
+ | MsgBox StarDesktop.getCurrentComponent.Dbg_SupportedInterfaces | ||
− | + | End Sub | |
+ | </source> | ||
− | |||
− | |||
− | |||
Esta vez nos muestra muchos más datos, ¿verdad?, observa de que forma tan simple podemos obtener mucha información, en las propiedades, nota que se nos muestra el tipo de valor que puedes obtener de las propiedades y que será el mismo tipo para establecerla si la propiedad es de escritura. Por ejemplo, si ejecutamos la macro anterior desde una hoja de calculo podremos ver entre sus propiedades las siguientes: | Esta vez nos muestra muchos más datos, ¿verdad?, observa de que forma tan simple podemos obtener mucha información, en las propiedades, nota que se nos muestra el tipo de valor que puedes obtener de las propiedades y que será el mismo tipo para establecerla si la propiedad es de escritura. Por ejemplo, si ejecutamos la macro anterior desde una hoja de calculo podremos ver entre sus propiedades las siguientes: | ||
− | |||
− | * | + | * <tt>SbxARRAY Printer</tt> |
+ | * <tt>SbxSTRING Location</tt> | ||
+ | * <tt>SbxOBJECT Sheets</tt> | ||
− | |||
− | Tenemos una propiedad que devuelve un | + | Tenemos una propiedad que devuelve un <tt>array</tt> (1), otra una cadena (2.- <tt>string</tt>) y por ultimo un objeto (3.- <tt>object</tt>). |
+ | |||
Ahora, en los métodos también nos muestra información valiosa, por ejemplo y siguiendo en la suposición de que nos informamos de una hoja de calculo, tenemos: | Ahora, en los métodos también nos muestra información valiosa, por ejemplo y siguiendo en la suposición de que nos informamos de una hoja de calculo, tenemos: | ||
− | |||
− | * | + | * <tt>SbxSTRING getURL ( void )</tt> |
+ | * <tt>SbxVOID storeAsURL ( SbxSTRING, SbxARRAY ) </tt> | ||
+ | * <tt>SbxINTEGER resetActionLocks ( void )</tt> | ||
− | |||
− | En este caso tenemos el método | + | En este caso tenemos el método <tt>getUrl</tt> que devuelve una cadena (<tt>string</tt>) y no necesita argumentos (1), el método <tt>storeAsURL</tt> requiere una cadena (<tt>string</tt>) y un array como argumentos (2), pero no devuelve ningún valor y por ultimo el método <tt>resetActionLocks</tt>, devuelve un entero (<tt>integer</tt>) y no necesita argumentos (3). Por ahora lo importante es saber reconocer la sintaxis de esta información para usarla en nuestras macros. |
+ | |||
Por ultimo, cualquiera de los servicios mostrados, muestra la información necesaria para ir a la documentación del API y saber que otros servicios soporta, que métodos y que propiedades. | Por ultimo, cualquiera de los servicios mostrados, muestra la información necesaria para ir a la documentación del API y saber que otros servicios soporta, que métodos y que propiedades. | ||
− | |||
− | * | + | * <tt>com.sun.star.datatransfer.XTransferable</tt> |
+ | * <tt>com.sun.star.view.XPrintable</tt> | ||
+ | * <tt>com.sun.star.sheet.XSpreadsheetDocument</tt> | ||
− | |||
Creo que con esto queda demostrado que no hay que estar adivinando nada, solo hay que hacer las preguntas y búsquedas correctas. | Creo que con esto queda demostrado que no hay que estar adivinando nada, solo hay que hacer las preguntas y búsquedas correctas. | ||
− | |||
− | < | + | Dentro de las macros incorporadas en OpenOffice.org, existen varias que nos ayudan a depurar nuestras macros, para el tema que estamos tratando, existe una en especial que te escribe la información de las tres propiedades vistas en un nuevo documento de Writer, la macro se llama <tt>WritedDgInfo</tt> y solo hay que pasarle el objeto del cual queremos obtener su información, veámoslo con un ejemplo: |
− | |||
− | + | <source lang="oobas"> | |
− | + | Sub ConsultandoObjetos3() | |
− | + | ||
− | + | BasicLibraries.LoadLibrary( "Tools" ) | |
+ | Call WritedbgInfo( StarDesktop.getCurrentComponent() ) | ||
+ | End Sub | ||
</source> | </source> | ||
+ | |||
Prueba la macro anterior, llamándola desde diferentes documentos, aunque la puedes ejecutar siempre y cuando la variable pasada apunte “efectivamente” a una variable de objeto. Con unas pequeñas variantes podemos hacer que en vez de un documento de Writer, nos escriba la información en una hoja de calculo, en el [[ES/Manuales/GuiaAOO/TemasAvanzados/Macros/StarBasic/Apendices/MostrarInfoObjetoCalc|Mostrar información de un objeto en un archivo de Calc]] te muestro como hacerlo. | Prueba la macro anterior, llamándola desde diferentes documentos, aunque la puedes ejecutar siempre y cuando la variable pasada apunte “efectivamente” a una variable de objeto. Con unas pequeñas variantes podemos hacer que en vez de un documento de Writer, nos escriba la información en una hoja de calculo, en el [[ES/Manuales/GuiaAOO/TemasAvanzados/Macros/StarBasic/Apendices/MostrarInfoObjetoCalc|Mostrar información de un objeto en un archivo de Calc]] te muestro como hacerlo. | ||
− | Para terminar este tema, veamos como nos puede ayudar la ventana del Observador también con los objetos, copia la siguiente macro, establece un punto de ruptura como te muestro en la imagen siguiente y agrega al observador la variable | + | |
+ | Para terminar este tema, veamos como nos puede ayudar la ventana del Observador también con los objetos, copia la siguiente macro, establece un punto de ruptura como te muestro en la imagen siguiente y agrega al observador la variable <tt>oActivo</tt>. | ||
+ | |||
[[Image:ES_StarBasic_TrabajandoConOOo.03.png|center]] | [[Image:ES_StarBasic_TrabajandoConOOo.03.png|center]] | ||
+ | |||
Ejecuta la macro, regresa al IDE y observa los datos de la variable que tenemos en observación: | Ejecuta la macro, regresa al IDE y observa los datos de la variable que tenemos en observación: | ||
+ | |||
[[Image:ES_StarBasic_TrabajandoConOOo.02.png|center]] | [[Image:ES_StarBasic_TrabajandoConOOo.02.png|center]] | ||
+ | |||
Por ahora, la mayor parte de esta información no te dirá mucho, pero observa que interesante nos muestra el título del documento (1) y los tipos de estilos (2) que aprenderemos a usar más adelante. Por ahora, solo familiarízate con la forma en que se muestra la información, el tipo de este y el valor mostrado, esto, es de mucha utilidad como podremos comprobarlo más adelante. | Por ahora, la mayor parte de esta información no te dirá mucho, pero observa que interesante nos muestra el título del documento (1) y los tipos de estilos (2) que aprenderemos a usar más adelante. Por ahora, solo familiarízate con la forma en que se muestra la información, el tipo de este y el valor mostrado, esto, es de mucha utilidad como podremos comprobarlo más adelante. |
Revision as of 02:16, 18 March 2013
Para crear, acceder y manipular un servicio, “necesitas” asignarlo a una variable de objeto, de la siguiente manera.
Dim NombreVariable As Object
E inicializarla para poder usarla, para ello, usamos la función createUnoService.
Sub AccediendoAOpenOffice1() Dim appOpenOffice As Object appOpenOffice = createUnoService( "com.sun.star.frame.Desktop" ) End Sub
El servicio com.sun.star.frame.Desktop es usado muy frecuentemente, pues nos permite acceder a “toda” la aplicación y sus componentes, por ello, existe una palabra clave que nos da acceso inmediato a este “servicio”; “StarDesktop” por lo que, la siguientes dos líneas son equivalentes.
appOpenOffice = createUnoService( "com.sun.star.frame.Desktop" ) appOpenOffice = StarDesktop
Ejecutando la macro anterior, por ahora, no veras ningún efecto, pero aquí empieza lo divertido e interesante, vamos a explorar por dentro del OpenOffice.org, modifica la macro para que quede de la siguiente manera.
Option Explicit Sub AccediendoAOpenOffice2() Dim appOpenOffice As Object Dim oActivo As Object 'Inicializamos una variable con el servicio com.sun.star.frame.Desktop appOpenOffice = StarDesktop 'Obtenemos una referencia al componente activo oActivo = appOpenOffice.CurrentComponent 'Mostramos el tipo de componente MsgBox oActivo.Identifier End Sub
Ahora si, al ejecutar te tiene que mostrar el siguiente mensaje.
Pero, tal vez te muestre este otro.
Incluso tal vez el siguiente.
¿Por qué? Porque dependerá desde donde “llames” (ejecutes) la macro, verifícalo, tal vez la ejecutaste directamente desde el IDE, o tal vez la llamaste desde una hoja de calculo o desde un archivo de texto. En el tema anterior vimos como llamar a una macro desde donde queramos, aunque lo más practico para los siguientes ejemplos es que programes tus macros dentro del archivo “Mis macros”, queda a tu criterio.
Abre seis archivos, uno por cada tipo de documento que podemos manejar en OpenOffice.org (hoja de calculo, documento de texto, presentación, dibujo, base de datos y formula) no necesariamente tienes que guardarlos, pero no estaría de más por que los vamos a usar en repetidas ocasiones. Ejecuta la macro anterior desde cada uno de estos documentos. Todos excepto la base de datos te tienen que mostrar el mensaje correctamente y en el caso de la base de datos, te tiene que mostrar el error siguiente.
Apréndete muy bien estas dos nuevas palabras “propiedad” y “método”, las vas a usar de aquí en adelante y siempre que programes en OOo Basic. En este caso, es una “propiedad” lo que esta mal, es decir, la propiedad Identifier, no la implementan las bases de datos. Sabiendo esto, podríamos empezar a proponer una macro genérica para saber que tipo de documento es el activo, probemos con la siguiente.
Sub AccediendoAOpenOffice3() Dim appOpenOffice As Object Dim oActivo As Object 'Inicializamos una variable con el servicio com.sun.star.frame.Desktop appOpenOffice = StarDesktop 'Obtenemos una referencia al componente activo oActivo = appOpenOffice.CurrentComponent 'Mostramos el tipo de componente Select Case oActivo.Identifier Case "com.sun.star.sheet.SpreadsheetDocument" MsgBox "Soy una hoja de calculo" Case "com.sun.star.presentation.PresentationDocument" MsgBox "Soy una presentacion" Case "com.sun.star.drawing.DrawingDocument" MsgBox "Soy un dibujo" Case "com.sun.star.formula.FormulaProperties" MsgBox "Soy una formula" Case "com.sun.star.text.TextDocument" MsgBox "Soy un documento de texto" End Select End Sub
Ejecuta la macro anterior desde cada uno de los seis archivos, excepto desde la base de datos pues te dará un error, claro, puedes, si quieres, implementar un controlador de errores pero por ahora no lo haremos, busquemos otra alternativa, por ejemplo, probemos ahora la propiedad ImplementationName y veamos que pasa,
Sub AccediendoAOpenOffice4() Dim oActivo As Object 'Obtenemos una referencia al componente activo oActivo = StarDesktop.CurrentComponent 'Mostramos el tipo de componente MsgBox oActivo.ImplementationName End Sub
Esta vez si nos muestra un mensaje en todos los documentos, pero notaras que esta propiedad en algunos documentos no es muy clara, aquí el resumen de lo que tendrías que obtener en cada caso:
Aplicación | Tipo de documento | Propiedad ImplementationName |
---|---|---|
Writer | Documento de texto | SwXTextDocument |
Calc | Hoja de calculo | ScModelObj |
Impress | Presentaciones | SdXImpressDocument |
Draw | Dibujo | SdXImpressDocument |
Base | Base de datos | com.sun.start.comp.dba.ODatabaseDocument |
Math | Formula | com.sun.start.comp.math.FormulaDocument |
¿Te fijas que interesante?, nota el valor devuelto en las hojas de calculo y como las presentaciones y los dibujos devuelven el mismo resultado, por lo que esta propiedad, a pesar de estar implementada en todos los tipos de documentos, no resulta muy idónea para diferenciar a cada uno. ¿Y si en vez de devolver una cadena de texto, le preguntamos a cada componente si son lo que dicen ser?, es decir, por ejemplo, una hoja de calculo implementa propiedades y métodos (servicios) para manipular hojas de calculo, en este caso, este servicio se llama "com.sun.star.sheet.SpreadsheetDocument”, y cada documento soporta un tipo de servicio diferente. Todos los objetos admiten un método que nos permite preguntar si dicho objeto soporta un servicio en especial, este método se llama supportsService y hay que pasarle como argumento el nombre del servicio que queremos validar y nos devolverá verdadero (True) o falso (False) según soporte o no el servicio, por lo que la sintaxis competa de este método es:
Veámoslo trabajando en el siguiente ejemplo.
Sub AccediendoAOpenOffice5() Dim oActivo As Object Dim bImplementaServicio As Boolean oActivo = StarDesktop.CurrentComponent bImplementaServicio = oActivo.supportsService("com.sun.star.sheet.SpreadsheetDocument") If bImplementaServicio Then MsgBox "Soy una hoja de calculo" Else MsgBox "NO soy una hoja de calculo" End If End Sub
Y prueba desde todos nuestros documentos que funciona correctamente por lo que ya podemos implementar una macro mejor para saber que tipo de documento tenemos activo, simplemente consultando si soporta su respectivo “servicio”.
Sub AccediendoAOpenOffice6() Dim oActivo As Object oActivo = StarDesktop.CurrentComponent If oActivo.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then MsgBox "Soy una hoja de calculo" ElseIf oActivo.supportsService("com.sun.star.text.TextDocument") Then MsgBox "Soy un documento de texto" ElseIf oActivo.supportsService("com.sun.star.presentation.PresentationDocument") Then MsgBox "Soy una presentacion" ElseIf oActivo.supportsService("com.sun.star.drawing.DrawingDocument") Then MsgBox "Soy un dibujo" ElseIf oActivo.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") Then MsgBox "Soy una base de datos" ElseIf oActivo.supportsService("com.sun.star.formula.FormulaProperties") Then MsgBox "Soy una formula" ElseIf oActivo.supportsService("com.sun.star.script.BasicIDE") Then MsgBox "Soy el editor de codigo IDE" Else MsgBox "NO se que tipo de documento soy" End If End Sub
Ahora si, ya podemos discriminar correctamente los documentos. Saber si un objeto implementa un determinado servicio, es muy importante para minimizar el riesgo de errores y para consultar directamente las propiedades y métodos que implementa dicho servicio sin tener que estar “adivinando” nada y precisamente para no estar adivinando, existe una propiedad que nos devuelve una matriz (array) con los servicios que soporta un objeto, esta propiedad se llama SupportedServiceNames y su sintaxis es.
Como siempre, no hay como los ejemplos.
Sub AccediendoAOpenOffice7() Dim oActivo As Object Dim mServicios() As String Dim co1 As Byte 'Obtenemos una referencia al componente activo oActivo = StarDesktop.CurrentComponent 'Obtenemos una matriz con los servicios que implementa mServicios() = oActivo.SupportedServiceNames 'Y mostramos el nombre de cada servicio For co1 = LBound( mServicios() ) To UBound( mServicios() ) MsgBox mServicios( co1 ) Next End Sub
Y si ejecutas la macro anterior desde cada uno de nuestros seis documentos abiertos, tienes que obtener la siguiente lista de servicios en cada uno.
Aplicación | Tipo de documento | Propiedad SupportedServiceNames |
---|---|---|
Writer | Documento de texto | com.sun.star.document.OfficeDocument com.sun.star.text.GenericTextDocument com.sun.star.text.TextDocument |
Calc | Hoja de calculo | com.sun.star.sheet.SpreadsheetDocument
com.sun.star.sheet.SpreadsheetDocumentSettings |
Impress | Presentaciones | com.sun.star.document.OfficeDocument
com.sun.star.drawing.GenericDrawingDocument com.sun.star.drawing.DrawingDocumentFactory com.sun.star.presentation.PresentationDocument |
Draw | Dibujo | com.sun.star.document.OfficeDocument
com.sun.star.drawing.GenericDrawingDocument com.sun.star.drawing.DrawingDocumentFactory com.sun.star.drawing.DrawingDocument |
Base | Base de datos | com.sun.star.document.OfficeDocument
com.sun.star.sdb.OfficeDatabaseDocument |
Math | Formula | com.sun.star.document.OfficeDocument
com.sun.star.formula.FormulaProperties |
Nota como Impress y Draw implementan casi los mismos servicios y observa como hay un servicio (com.sun.start.document.OfficeDocument), que, excepto en la hoja de calculo, es común a todos los documentos, pero no creas que la hoja de calculo no lo implementa, podemos demostrar que lo implementa con el siguiente ejemplo que tienes que ejecutar desde cualquier hoja de calculo, en todos los demás documentos también te funcionara, pero recuerda que solo queremos comprobar si la hoja de calculo implementa este servicio.
Sub AccediendoAOpenOffice8() Dim oActivo As Object Dim bImplementaServicio As Boolean oActivo = StarDesktop.CurrentComponent bImplementaServicio = oActivo.supportsService("com.sun.star.document.OfficeDocument") If bImplementaServicio Then MsgBox "Verdad que si esta implementado el servicio" Else MsgBox "NO esta implementado el servicio" End If End Sub
Este servicio común a todos los documentos, también es muy usado e importante como más adelante podrás comprobarlo. Por ahora, copia la siguiente macro y pruébala de nuevo con todos los documentos.
Sub AccediendoAOpenOffice9() Dim oActivo As Object Dim mServicios() As String Dim co1 As Byte oActivo = StarDesktop.CurrentComponent mServicios() = oActivo.'''getSupportedServiceNames'''() For co1 = LBound( mServicios() ) To UBound( mServicios() ) MsgBox mServicios( co1 ) Next End Sub
Notaras que trabaja exactamente igual que la anterior, pero ve que no hemos usado la propiedad SupportedServiceNames, sino el método getSupportedServiceNames(), diferenciados por el prefijo get y los paréntesis, los dos hacen lo mismo, pero en OOo Basic, casi todos los métodos tienen su correspondencia en una propiedad, si te es útil, recuerda tus clases elementales de español, los objetos son como los sustantivos, las propiedades son adjetivos y los métodos son verbos, así mismo y muy importante, las propiedades siempre son de un tipo de dato soportado por OOo Basic (string, integer, array, etc.), por lo que tienes que tener las mismas consideraciones (y precauciones) vistas en varios temas atrás, principalmente cuando vimos variables y funciones, así mismo los métodos, cuando se les pasan argumentos y cuando devuelven un valor se ven afectados por estas consideraciones, por lo que reitero, ten cuidado con los tipos de datos que usas en ellos.
A lo largo de este capitulo, te mostrare, en la medida de lo posible, el uso como método y como propiedad, más adelante me limitare a usar métodos y tú usaras el que más de agrade.
Hasta ahora, hemos accedido a un solo documento, pero podemos acceder a todos los documentos actualmente abiertos en OpenOffice.org, copia y prueba la siguiente macro.
Option Explicit Sub Controlando_OpenOffice1() Dim oDocumentos As Object Dim oDocumento As Object Dim oEnumeraDocumentos As Object 'Accedemos a todos los documentos actualmente abiertos oDocumentos = StarDesktop.getComponents() 'Enumeramos cada uno oEnumeraDocumentos = oDocumentos.createEnumeration() 'hasMoreElements devuelve verdadero (True) mientras haya elementos Do While oEnumeraDocumentos.hasMoreElements() 'Nos desplazamos al siguiente elemento y lo asignamos oDocumento = oEnumeraDocumentos.nextElement() 'Mostramos el tipo de documento MsgBox "Soy un documento de " & TipoDocumento( oDocumento ) Loop End Sub Function TipoDocumento(ByRef Documento As Object) As String Dim sAplicacion As String If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then sAplicacion = "Calc" ElseIf Documento.supportsService("com.sun.star.text.TextDocument") Then sAplicacion = "Writer" ElseIf Documento.supportsService("com.sun.star.presentation.PresentationDocument") Then sAplicacion = "Impress" ElseIf Documento.supportsService("com.sun.star.drawing.DrawingDocument") Then sAplicacion = "Draw" ElseIf Documento.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") Then sAplicacion = "Base" ElseIf Documento.supportsService("com.sun.star.formula.FormulaProperties") Then sAplicacion = "Math" ElseIf Documento.supportsService("com.sun.star.script.BasicIDE") Then sAplicacion = "Basic" Else sAplicacion = "Desconocido" End If TipoDocumento = sAplicacion End Function
Toma nota de como hemos convertido una macro usada anteriormente en una función que nos devuelve el tipo de documento abierto. Muchos objetos en OpenOffice.org, solo son accesibles creando una “enumeración”, así que la estructura de la macro anterior la podrías usar con frecuencia. Una “enumeración”, es como un listado de objetos, se crean con el método createEnumeration(), el método .hasMoreElements() nos sirve para saber si todavía hay elementos y el método .nextElement(), permite movernos al siguiente elemento de la enumeración.
Empecemos con código un poco más divertido, la siguiente variante de la macro anterior, te cerrara “todos” los archivos de Calc que no tengan cambios por guardar, CUIDADO, si ejecutas la siguiente macro desde un archivo de Calc podrías cerrarte el archivo con resultados inesperados.
Sub Controlando_OpenOffice2() Dim oDocumentos As Object Dim oDocumento As Object Dim oEnumeraDocumentos As Object Dim co1 As Integer oDocumentos = StarDesktop.getComponents() oEnumeraDocumentos = oDocumentos.createEnumeration() Do While oEnumeraDocumentos.hasMoreElements() oDocumento = oEnumeraDocumentos.nextElement() 'Verificamos que sea un archivo de Calc If TipoDocumento( oDocumento ) = "Calc" Then 'Si no ha sido modificado o los cambios ya están guardados 'el método isModified devolverá falso (False) If Not oDocumento.isModified() Then 'el método dispose cierra el archivo oDocumento.dispose() co1 = co1 + 1 End if End If Loop MsgBox "Se cerraron un total de " & CStr(co1) & " archivos de Calc" End Sub
Ten mucho cuidado con el método dispose, te cerrará el archivo sin preguntarte nada, tenga o no tenga cambios guardados, úsalo con conocimiento de causa. Observa como usamos la propiedad isModified(), para saber si el documento ha sido modificado.
La Interfaz de Programación de la Aplicación (API por sus siglas en ingles) proporciona, decenas incluso centenas de servicios con métodos y propiedades para controlar y manipular OpenOffice.org, la puedes consultar en linea en la página oficial de OpenOffice.org (por ahora solo en ingles) en: http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html
También puedes descargarla y después consultarla fuera de línea para su acceso inmediata o si no tienes conexión permanente a Internet, en el Instalar el SDK te muestro como hacerlo. Para una consulta óptima de esta documentación, lo ideal es saber de forma anticipada que servicio, método o propiedad estamos buscando, para ello, todos los objetos cuentan con unas propiedades especiales que nos dan mucha información, veamos cuales son.
Propiedades especiales de depuración
Ya vimos en el tema anterior como saber con el método “supportsService” si un objeto soporta un determinado servicio, pero tiene el inconveniente de que tenemos que saber anticipadamente el nombre de dicho servicio, lo cual a veces es un poco complicado. También vimos el uso del método getSupportedServiceNames() que nos devuelve una matriz con los nombres de los servicios que implementa el objeto.
Para obtener toda la información de un objeto, este cuenta con tres propiedades que nos informan de todas las propiedades, métodos e “interfaces” que implementa dicho objeto, estas propiedades son tres:
- Dbg_SupportedInterfaces
- Dbg_Properties
- Dbg_Methods
Las tres son de tipo texto (string) y se usan de la siguiente manera.
Sub ConsultandoObjetos1() Dim sDatos As String MsgBox StarDesktop.Dbg_Properties MsgBox StarDesktop.Dbg_Methods MsgBox StarDesktop.Dbg_SupportedInterfaces End Sub
No te me confundas con esto de las “interfaces”, para nuestros fines es perfectamente valido que los llamemos “servicios”, simplemente piensa en las interfaces como una forma de organizar servicios, pero en OOo Basic no tiene importancia por que accedemos directamente a las propiedades y métodos de los servicios.
La pequeña macro anterior, te tiene que mostrar un cuadro de mensaje con las propiedades del objeto.
Sus métodos:
Y sus interfaces (servicios):
Observa el servicio señalado con una flecha, si vamos a su documentación, en línea (http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html) o local (file:///opt/openoffice/sdk/docs/common/ref/com/sun/star/frame/XComponentLoader.html), te darás cuenta que solo tiene un método loadComponentFromURL, pero un método muy importante, pues nos permite crear documentos nuevos o abrir archivos existentes, lo cual veremos al terminar este tema.
Ahora probemos con los datos del documento activo.
Sub ConsultandoObjetos2() Dim sDatos As String MsgBox StarDesktop.getCurrentComponent.Dbg_Properties MsgBox StarDesktop.getCurrentComponent.Dbg_Methods MsgBox StarDesktop.getCurrentComponent.Dbg_SupportedInterfaces End Sub
Esta vez nos muestra muchos más datos, ¿verdad?, observa de que forma tan simple podemos obtener mucha información, en las propiedades, nota que se nos muestra el tipo de valor que puedes obtener de las propiedades y que será el mismo tipo para establecerla si la propiedad es de escritura. Por ejemplo, si ejecutamos la macro anterior desde una hoja de calculo podremos ver entre sus propiedades las siguientes:
- SbxARRAY Printer
- SbxSTRING Location
- SbxOBJECT Sheets
Tenemos una propiedad que devuelve un array (1), otra una cadena (2.- string) y por ultimo un objeto (3.- object).
Ahora, en los métodos también nos muestra información valiosa, por ejemplo y siguiendo en la suposición de que nos informamos de una hoja de calculo, tenemos:
- SbxSTRING getURL ( void )
- SbxVOID storeAsURL ( SbxSTRING, SbxARRAY )
- SbxINTEGER resetActionLocks ( void )
En este caso tenemos el método getUrl que devuelve una cadena (string) y no necesita argumentos (1), el método storeAsURL requiere una cadena (string) y un array como argumentos (2), pero no devuelve ningún valor y por ultimo el método resetActionLocks, devuelve un entero (integer) y no necesita argumentos (3). Por ahora lo importante es saber reconocer la sintaxis de esta información para usarla en nuestras macros.
Por ultimo, cualquiera de los servicios mostrados, muestra la información necesaria para ir a la documentación del API y saber que otros servicios soporta, que métodos y que propiedades.
- com.sun.star.datatransfer.XTransferable
- com.sun.star.view.XPrintable
- com.sun.star.sheet.XSpreadsheetDocument
Creo que con esto queda demostrado que no hay que estar adivinando nada, solo hay que hacer las preguntas y búsquedas correctas.
Dentro de las macros incorporadas en OpenOffice.org, existen varias que nos ayudan a depurar nuestras macros, para el tema que estamos tratando, existe una en especial que te escribe la información de las tres propiedades vistas en un nuevo documento de Writer, la macro se llama WritedDgInfo y solo hay que pasarle el objeto del cual queremos obtener su información, veámoslo con un ejemplo:
Sub ConsultandoObjetos3() BasicLibraries.LoadLibrary( "Tools" ) Call WritedbgInfo( StarDesktop.getCurrentComponent() ) End Sub
Prueba la macro anterior, llamándola desde diferentes documentos, aunque la puedes ejecutar siempre y cuando la variable pasada apunte “efectivamente” a una variable de objeto. Con unas pequeñas variantes podemos hacer que en vez de un documento de Writer, nos escriba la información en una hoja de calculo, en el Mostrar información de un objeto en un archivo de Calc te muestro como hacerlo.
Para terminar este tema, veamos como nos puede ayudar la ventana del Observador también con los objetos, copia la siguiente macro, establece un punto de ruptura como te muestro en la imagen siguiente y agrega al observador la variable oActivo.
Ejecuta la macro, regresa al IDE y observa los datos de la variable que tenemos en observación:
Por ahora, la mayor parte de esta información no te dirá mucho, pero observa que interesante nos muestra el título del documento (1) y los tipos de estilos (2) que aprenderemos a usar más adelante. Por ahora, solo familiarízate con la forma en que se muestra la información, el tipo de este y el valor mostrado, esto, es de mucha utilidad como podremos comprobarlo más adelante.
Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO, o quieres ampliar la información, no dudes en dirigirte al Foro Oficial en español de Apache OpenOffice para Macros y API UNO |