Mostrando entradas con la etiqueta Script. Mostrar todas las entradas
Mostrando entradas con la etiqueta Script. Mostrar todas las entradas

viernes, 26 de abril de 2024

OOo Basic

Primer script

En esta entrada vamos crear nuestro primer script con OOo Basic, el típico script con el que comienza toda andadura por el aprendizaje de los lenguajes de programación. Pero para ello deberemos saber dónde.


Al crear una macro nos hemos acercado al IDE, pero no terminamos de entrar en él porque no era necesario. Ahora sí.

El IDE (Entorno de Desarrollo Integrado) es la utilidad que nos permite trabajar con un lenguaje de programación. El ser OOo Basic un lenguaje de script interno y delimitado por la suite LibreOffice, su IDE se ubica y es accesible desde el propio entorno LibreOffice; desde la interface general y/o desde las interfaces de cada uno de sus servicios.

Nosotros vamos a trabajar (de momento) desde Writer, así que empezaremos creando un nuevo documento. Le daremos nombre (loDocumento1) y lo guardaremos en una carpeta que previamente habremos creado en nuestro Escritorio (1). De este modo empezaremos desde cero, que es la mejor forma de empezar.

Y lo haremos accediendo a Herramientas | Macros | Organizar macros | BASIC (2). Este es nuestro primer paso porque, al partir de un nuevo documento, como ya sabes, aun no se definido en él un espacio específico para nuestras macros y script.

En la ventana emergente hacemos clic (de nuevo) en Organizador y en la nueva ventanita seleccionamos el icono de nuestro documento (loPrimero.odt), en la crucecita que precede al nombre, y después en a que precede a la carpeta (Biblioteca) Standard  y hacemos clic en Nuevo (3). Surge una nueva ventanita que contiene un campo de texto con la palabra Module1 y tres botones: hacemos clic en Aceptar y automáticamente se crea Module1 dentro de Standard. Clic en Cerrar.

Si hacemos clic en Nuevo (ahora referido a macro/script, accederemos al contenido de las tres carpetas disponibles en el IDE: Mis macros y diálogos, Macros y diálogos de la aplicación y loPrimero.odt: ésta es la que nos interesa ahora. Seguimos el proceso ya conocido de selección y despliegue de componentes y terminamos accediendo a una pantalla  casi vacía: 

REM  *****  BASIC  *****

Sub Main

End Sub

Este será el "espacio" (documento) en el que crearemos nuestros script. Por el momento nuestro primer script, justo entre las instrucciones Sub Main y End Sub. Cuando finalicemos esto será lo que veamos:

Sub Main

    print "OOo Basic para orientadores"

End Sub

No es el típico saludo "Hola Mundo" pero cumple su misma función: anunciar(nos) que estamos empezando a aprender OOo Basic.

Ahora sitúa el cursos dentro del Sub y haz clic en la flechita verde situada encima de la palabra REM, o en Ejecutar | Ejecutar: obtendrás una ventana emergente que contiene la frase que hemos escrito. Este es nuestro primer script. Por ahora suficiente (4)



NOTA

(1) Es una sugerencia; tú puedes crearlo con el nombre que te parezca y guardarlo en donde creas oportuno. A tu cargo también la organización interna de esta carpeta y recordar dónde guardas tus archivos.

(2) Verás otras opciones de lenguajes, pero ahora no nos interesan, así que nos centramos en BASIC, que no es otra cosa que OOo Basic. Podemos nombrar nuestro módulo como deseemos, pero por ahora no nos vamos a detener en estos detalle, así que aceptaremos el nombre que se nos propone (Module1)

(3) Como vamos a crear un módulo, y es la opción por defecto, no me voy a referir ahora a las otras opciones (Diálogos y Bibliotecas)

(4) Cuando queras finalizar y acceder de nuevo al documento, sigue esta secuencia: Archivo | Guardar o Archivo | Cerrar. La segunda cierra el IDE sin guardar lo que hemos creado, así que te recomiendo que utilices la primera opción para no perder el trabajo realizado. Para finalizar del todo cerraremos nuestro documento loPrimero.odt de igual modo que cerramos cualquier otro documento Writer, guardando los cambios.

sábado, 16 de marzo de 2024

Usos. Textos

Automatizar la escritura de textos mediante OOo Basic.

Parece lógico empezar por explicar estos procedimientos con las herramientas disponibles desde el propio procesador de textos (en nuestro caso Writer), ya que es la herramienta a la que estamos acostumbrados y porque el paso de Grabar macro a la escritura de script desde el IDE del propio servicio nos permite avanzar mucho en este aprendizaje sin necesidad de hacer uso de otros lenguajes. De hecho podríamos limitarnos a usar OOo Basic como única herramienta para automatizar la composición de texto, sin más complicación, pero hacerlo nos limita para el desarrollo de otros aspectos de la competencia digital, así que no es nuestra opción. 




Así que, como hay que ir por partes y, a ser posible, que el avance tenga su lógica, inicio esta sección exponiendo diferentes formas de "trabajar" con textos y en la automatización de su composición con las herramientas más básicas y accesibles: macros y script OOo Basic.

Veremos en primer lugar y como prolongación de lo visto en la sección anterior y primera del capítulo Usos, cómo combinar el uso de macros y OOo Basic para desarrollar este proceso de automatización. Hay más que escritura en este proceso, así que también trataremos sobre el establecimiento de formatos y el desplazamiento por el documento. Precisamente en ambos, la combinación de macros y script resulta muy beneficiosa en términos de facilidad de creación de código y  simplicidad de uso.

Pasaremos después a trabajar exclusivamente con OOo Basic en cuanto cuenta con alternativas diferenciadas en la funcionalidad Grabar macro para el manejo y la escritura de textos.

Finalmente nos enfrentaremos a tareas específicas, que derivan de las "imposiciones" formales y de formato de algunos textos con los que tenemos que trabajar como documento-base (un ejemplo de ello, los modelos de informe o de dictamen, pero hay más) y abordaremos el modo de cumplimentar "campos" de contenido en ellos.

Además de escribir textos, es frecuente que los documentos contengan también tablas, por lo que resulta de interés saber cómo crearlas y cumplimentarlas, así cómo realizar desplazamientos por ellas de forma automatizada.

viernes, 15 de marzo de 2024

Usos. Macros.

Uso de macros desde script (2)

La esencia de este procedimiento es la misma que la vista en la entrada anterior, pero la diferencia es que ahora los script son más genuinamente tales, esto es: en ellos se hace uso de los elementos del lenguaje (OOo Basic, en nuestro caso), lo que permite un mejor aprovechamiento de las propias macros y, sobre todo, un funcionamiento más funcional a la vez que complejo del algoritmo.


Este modo de trabajo supone, incluso, recurrir a OOo Basic para realizar ciertas modificaciones en las propias macros. Aunque esto no obligatorio (podemos seguir trabajando con las macros tal y como "salen del horno" de Grabar macro), hacerlo mejora sustancialmente la propia funcionalidad de la macro, por lo que es muy recomendable.

Lo que pretendemos ahora es dar más flexibilidad al conjunto (también a las macros), apoyándonos en los elementos del lenguaje OOo Basic y en lo conocemos de su sintaxis. Todo ello lo encontraremos en el contenido de esta página, como sabes.

Por comodidad y coherencia, partiré del conjunto de macros creados con motivo de la entrada anterior (1), incluyendo una macro simple de escritura para dar más funcionalidad a los script. Podríamos partir de un conjunto de macros simples diferentes, pero para nuestro objetivo, más que suficiente, es conveniente utilizar las anteriores macros.

Lo primero que vamos a hacer (2), es simplificar el código de las macros, aprovechando lo que sabemos sobre el uso de variables públicas y privadas. Como ves, al inicio de cada macro, Grabar macro genera un código básico que se repite en todas las macros, y en la misma posición. Estas líneas de código son las que llaman a dos objetos básicos para el funcionamiento de la macro: el documento activo y la funcionalidad lanzador de macro ("com.sun.star.frame.DispatchHelper") que Grabar macro almacena en dos variables que llamaré de sistema: document y dispatcher.

Este código repetido en cada macro es el siguiente:

dim document   as object
dim dispatcher as object

rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Y  como se repite siempre que creamos una macro, podemos considerar estas dos variables como públicas, por lo que las declararemos al inicio del módulo, fuera de las macros, para que sean accesibles a todas ellas y crearemos un script (sub VarSis) específico (3) con la asignación de los objetos a las variables. Esto se concreta en el código siguiente:

'Declaración de variables de sistema para macros

dim document   as object
dim dispatcher as object

'Subrutina de asignación de objetos a las variables de sistema para macros

Sub VarSis
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
End Sub

Ahora ya podemos simplificar y reducir la extensión del código, eliminando esos elementos de cada macro y sustituyéndolos por una llamada a VarSis (4) como, por ejemplo (5):

sub Inicio
VarSis
dispatcher.executeDispatch(document, ".uno:GoToStartOfDoc", "", 0, Array())
end sub

Aunque al ser la creación de macros un proceso automático, por lo que no tenemos que escribir nosotros ni una sola línea de código y, por ello, simplificar las macros (lo que acabamos de hacer) no nos ahorra tiempo; al contrario, supone un trabajo, sencillo, pero trabajo, sobre todo si las macros son muchas; recomiendo hacerlo por las ventajas que supone en términos de legibilidad y funcionalidad del código en su conjunto. De todas formas, si no lo hacemos no se va alterar el funcionamiento de las macros ni de los script que las empleen; se ahorra algo de tiempo de ejecución y de memoria RAM, pero resulta imperceptible, dada la velocidad de procesamiento y capacidad RAM de los ordenadores actuales.

Lo que ya no es opcional si queremos aprovechar los conocimientos que tenemos sobre el uso de OOo Basic es trabajar de forma que, integrando varias macros, podamos generar resultados que sin este uso de OOo Basic no lograríamos con macros o resultaría mucho más costoso. Además, en cuanto a lógica de programación es mucho más interesante crear este tipo de script que limitarse a llamar a macros.

Vamos a ver una de las formas de hacer uso de OOo Basic para crear un script que, basándose en macros y haciendo uso de variables y un ciclo, nos permita adaptar nuestro código de forma que resulte más útil e interesante.
  • Primero. Modificamos la estructura de determinadas macros (en este caso las que vamos a usar) (6) transformándolas de hecho en subrutinas (tienen la misma estructura que una subrutina (7). Veamos un ejemplo:
sub LetraTipo (sLetraT As string)

Varsis

dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = sLetraT
args1(0).Value = true
dispatcher.executeDispatch(document, ".uno:"+sLetraT, "", 0, args1())

end sub

  1. Tras  el nombre (LetraTipo) abro y cierro paréntesis y en su interior declaro la variable sLetraT como string: sub LetraTipo (sLetraT As string)
  2. En args1(0) sustituyo el dato original ("Bold") por la variable sLetraT: args1(0).Name = sLetraT. De este modo, en lugar de un valor fijo, puedo trabajar con los valores que asigne a la variable sLetraT.
  3. Procedo del mismo modo en el ejecutor o lanzador de la macro, sustituyendo el segundo argumento por una cadena de texto resultante de concatenar un texto fijo con la variable anterior. El resto de los argumentos no sufre variación: dispatcher.executeDispatch(document, ".uno:"+sLetraT, "", 0, args1()) (8)

  • Segundo. Creo un script en OOo Basic cuyo funcionamiento esperado es el siguiente:
      • Se sitúa el curso al inicio del documento 
      • Se escribe una frase en negrita.
      • Se produce un determinado número de saltos de línea
      • Y se escribe una segunda frase también en negrita

    Este script que contiene variables a las que se asignan valores; estas variables se pasan como argumentos a la hora de llamar a las macros-subrutinas, las cuales asumen la función de los argumentos que se declaran en dichas macros-subrutinas (ver Primero)

    Para generar los saltos de línea se hace uso de un bucle For que se inicia en 0 y se repite  tantas veces como el valor numérico que se asigne a iNumLineas (4 en nuestro caso). Tras este salto de línea se ejecuta de nuevo llamada a la macro-subrutina EscribirPalabra(), asignando previamente un string diferente a la variable sTexto (argumento de la macro-subrutina EscribirPalabra().

    Podemos pensar en otras formas de utilizar macros como elementos de script; esta es una de ellas, pero no la única. Por ejemplo, siguiendo la misma línea de trabajo que hemos desarrollado en este script, podemos hacerlo interactivo, solicitando al usuario valores de entrada para crear otros texto. Para ello usaríamos la función InputBox(), por ejemplo. Pero lo hecho es suficiente para mostrar las posibilidades que tiene esta forma de hacer uso de la combinación de macros, macros convertidas en subrutinas y script.

    Te dejo a continuación acceso al documento que contiene las macros y el script explicados en esta entrada.


    NOTAS.

    (1) Lo recomendable es ir creando macros simples, eso sí, adaptadas según se explicará en esta entrada, y guardarlas en el IDE en Mis macros y diálogos, para que sean accesibles desde cualquier script.  Los script, por el contrario, posiblemente sea preferible almacenarlos en el propio documento, aunque no siempre, ya que depende del uso que se pueda hacer de ellos: si van a ser de uso frecuente en diferentes documentos, es preferible guardarlos también en Mis macros... Esta ubicación es muy recomendable (en esos casos) para el usuario que crea el código, pero imposibilita compartir con otras personas. En ese caso, se proporcionará el código por separado y será el usuario final quien decida donde lo copia y almacena.

    (2) En realidad es lo segundo, ya que la primera acción debe ser (ahora ya muy recomendable) limpiar el código de las macros de código basura, tal y como se explicó en la entrada anterior.

    (3) Este script de asignación puede tener cualquier otro nombre que deseemos darle, no necesariamente VarSis. Eso queda a elección del programador, pero, obviamente, la llamada que después debemos realizar a ese script debe ser coherente con el nombre que le demos.

    (4) Observa que no necesario utilizar la expresión Call para llamar al script. es suficiente con escribir el nombre del script para que sea llamado. No obstante, el uso de Call facilita la lectura del código ya que denota que se está llamando a una subrutina externa.

    (5) En realidad no es necesario llamar a VarSis desde cada macro, es suficiente con llamar a este script desde el script con que queramos manejar las macros. Sí es conveniente hacer incluir en las macros la llamada al script VarSis si queremos mantener la autonomía de cada macro, por si ocasionalmente necesitamos activarlas de forma directa (e individual), desde la funcionalidad  Macros/Ejecutar macro del menú Herramientas.

    (6) Los cambios de nombre que realizo respecto al original son para dar más coherencia al significado de las macros respecto a lo que hacen.

    (7) Recuerda que en OOo Basic se diferencia entre subrutinas y funciones, pero en otros lenguajes (Python, por ejemplo) se llama función a ambas, diferenciándolas por su comportamiento: una subrutina realiza una acción y una función devuelve un dato. Esta denominación puede dar lugar a confusión, ya que, salvo que se especifique lo contrario, todos los script escritos en OOo Basic se inician por la expresión Sub, que deriva de Subroutine, que no necesita traducción.

    (8) Esto último no es necesario hacerlo en todas las macros (ver, por ejemplo, la transformación de la macro EscribirPalabra en subrutina), pero sí en este caso, ya que el contenido de ese segundo argumento contenía originalmente el valor .Bold ( ".uno:Bold"), lo que genera ahora conflicto con el diseño subrutina de la macro. Esto no implica necesariamente que genere error, pero sí puede alterar el funcionamiento del script.

    jueves, 14 de marzo de 2024

    Usos. Macros.

    De macro a script

    Aunque cuando expliqué las macros en OOo Basic ya hable de estos temas, me interesa volver sobre ello para hacerlo desde una perspectiva general y también más utilitaria, esto es: desde la perspectiva del uso que podemos hacer de la combinación de macros (entendidas como código resultante de Grabar macro) y script (entendidos como secuencias de código desarrollados desde el IDE) y los procedimientos de conversión de una macro en un script.

    Ahora, como dije, vamos a identificar macro como resultado de usar Grabar macro, ya que otra diferenciación conlleva problemas de concepto que no nos interesan. Grabar macro genera una sub(rutina), lo mismo que la podemos crear nosotros directamente desde el IDE, ambos comparten nombre, pero no filosofía e incluso, tampoco funcionalidad.

    En la entrada en que expliqué (brevemente) la diferencia entre la programación imperativa y la estructurada, dije que retomaríamos el tema cuando se tratara sobre las macros y su conversión en script, así que vamos a ello, ya que cuando hable de las macros desde OOo Basic poco se dijo al respecto, puesto que el objetivo era otro. De todos modos esa entrada puede serte ahora de interés, así que, si quieres, accede a ella desde este enlace.

    Si te fijas, una macro (Grabar macro) es, en realidad, un ejemplo de programación lineal o jerárquica: Grabar macro sólo es capaz de generar una secuencia lineal en la que una instrucción sigue a otra. Es lógico que esto sea así, ya que lo que hace esta funcionalidad de LO-Writer es grabar y convertir en sentencias OOo Basic la sucesión de acciones que realizamos en el documento desde el teclado. Es el uso que nosotros hacemos de las macros creadas el que da al funcionamiento de conjunto la "apariencia" de ejecución asimilable a lo que define a la programación estructurada: el uso sucesivo de subrutinas, pero una subrutina-macro únicamente es una sucesión de instrucciones. Más aun, no es posible que Grabar macro genere código ni con condicionales, ni con bucles, ni siquiera con sentencias GoTo; en resumen, Grabar macro no equivale a programar.

    Esto supone una grave limitación que sólo es posible superar trasformando una macro en un script, utilizando OOo Basic y desde el IDE. Afortunadamente esto es perfectamente posible, aunque con un coste: tenemos que entender la lógica de programación de la macro y conocer el lenguaje OOo Basic, algo que, a estas alturas tú ya sabes.

    Empezamos usando Grabar macro como puerta de entrada a la programación (en OOo Basic, y por tanto, desde la perspectiva de la competencia ofimática y desde el interior de los documentos), y necesitamos ahora, para mejorar nuestra capacidad de uso de lo aprendido respecto a ese lenguaje, detenernos en los modos o procedimientos de trabajar con el código de una macro para convertirlos en script; esto equivale a pasar de un modelo estrictamente lineal a otro estructurado, e incluso modular.

    ¿Por qué necesitamos trabajar desde el modelo estructurado, incluso aun mejor desde el modular?. O dicho de un modo más práctico: ¿por qué necesitamos programar en lugar de limitarnos a generar secuencias de macros?.

    Desde un punto de vista práctico y de utilidad inmediata, algunos problemas, algunos objetivos, si prefieres, podemos abordarlos exclusivamente con macros, pero la gestión de procedimientos de cierta (no mucho) complejidad requiere algo más, especialmente si nuestro objetivo es la automatización de documentos. Con macros podemos automatizar secuencias fijas de manejo del documento, bien de forma estrictamente lineal (una única macro resuelve todo el conjunto de acciones), bien de forma estructurada pero manual: activamos una secuencia de macros, una tras otra, conforme deseemos que se desarrolle el procedimiento.

    Pero en el mismo momento en que nos interesa generar una secuencia de macros de forma automática, ya necesitamos realizar la primera conversión de macros en script: necesitamos crear un script que llame sucesivamente a las macros en vez de hacerlo nosotros.

    Esta es la forma más simple de trabajar con macros desde script, y tiene sus ventajas respecto a crear una macro que las incluya a todas: podemos simplificar nuestro trabajo de generar macros (que no deja de ser tedioso) aplicando una forma elemental del modelo estructurado: generar piezas reutilizables de código mediante Grabar macro, que podemos llamar desde diferentes script, cuando las necesitemos, las veces que deseemos y en el orden que nos interese. Este procedimiento es siempre más económico en tiempos de programación que crear una y otra macro que se ajuste a la secuencia de acciones necesarias. 

    El siguiente paso puede ser condicionar la llamada a una macro a un resultado u a otro (condicionalidad), o llamar de forma repetida a una macro para que una secuencia de acciones se repita un número determinado de veces (iteración). Sin escritura de script desde el IDE no podemos hacer nada de eso.

    El tercero y último (para no extenderme más), es incluir dentro de la misma macro esas estructuras cíclicas o condicionales de las que hablamos antes.

    Para todo ello necesitamos trabajar desde el IDE y con OOo Basic, y especialmente para la tercera, saber descifrar el código que genera Grabar macro, lo que equivale a leer y entender código OOo Basic.

    A explicar estos procedimientos que ahora sólo he enunciado dedicaré las siguientes entradas.

    lunes, 30 de octubre de 2023

    OOo Basic. Writer

     Script y subrutinas de escritura

    • Código básico:

    oDoc = ThisComponent.CurrentSelection.getByIndex(0).End
    oDoc.String = "Texto que se desea escribir"

    Script OOo Basic para automatizar la escritura de texto sin usar Grabar macro.

    Contiene subrutina y script principal. El script se ha creado para facilitar interface con el usuario mediante InputBox(), pero puede prescindirse de ello sin alterar el funcionamiento del script.

    • Subrutina de composición de varios párrafos (Código)

    Contiene subrutina (basada en matriz) y script principal. Ambos emplean una matriz para compartir datos masivos, La subrutina escribe el contenido utilizando un bucle for para automatizar el proceso.

    martes, 24 de octubre de 2023

    OOo Basic. Script

     Subrutinas creadas a partir de macros

    Después de la introducción general al tema realizada en una [entrada anterior], disponemos ya de argumentos para tratar con más detalle esta cuestión: cómo transformar una macro simple en una subrutina.




    Por recordar brevemente lo dicho en su momento, una subrutina no devuelve un dato o valor (lo que la diferencia de una función), sino que desarrolla una acción. 


    La subrutina realiza una acción, momento en el que el control de proceso pasa a ella. Esta imagen representa el proceso, incluyendo esa especie de corte en la ejecución del proceso principal, momento en que entra en acción la subrutina, la cual, una vez finalizado su cometido, devuelve el control a la macro o script principal.

    Visto y recordado esto, nos centrarnos ahora en el tema que nos ocupa ahora: ¿ qué procedimiento o procedimientos podemos seguir para transformar una macro en una subrutina?.

    Esta pregunta se responde en plural: existen varios procedimientos y diferentes variaciones de cada uno de ellos. Yo me voy a limitar a diferenciar y exponer tres de ellos, los que considero que se ajustan mejor a la macro originaria. Según este criterio serían tres las variaciones fundamentales entre las macros, lo que da origen a tres procedimientos básicos de conversión a subrutina: 
    • Las macros que contienen explicitación de parámetros (matriz nombre-valor argsX(y))
    • Las macros que son susceptibles de ser ejecutadas mediante estructuras cíclicas (for...Next), esto es: de repetir la acción que desarrollan.
    • Y las macros susceptibles a ser tratadas mediante la condicionalidad (If)
    Veamos cada una de ellas, empezando por las macros más simples que incluyen parámetros y en las que tomo como ejemplo la macro de posicionamiento [listado numérico] (1): 
    • matriz desglosada clave+valor:
    dim args1(0) as new com.sun.star.beans.PropertyValue
    	args1(0).Name = "On"
    	args1(0).Value = true
    • Orden o instrucción asociada a dispatcher:
    dispatcher.executeDispatch(document, ".uno:DefaultNumbering", "", 0, args1())

    Es el contenido o valor del componente .Value (en el ejemplo anterior true) el que podemos establecer como variable-parámetro en la creación de la subrutina basada en macros de este tipo, procediendo como sigue:

    • Denominamos la subrutina añadiendo un paréntesis al final de su enunciado
    Sub msbIndiceNumerico()

    • Declaro la variable-argumento bOpcion, que es de tipo booleano, como corresponde en función del valor del elemento de la matriz args1(0).Value

    Sub msbIndiceNumerico(bOpcion As Boolean)

    • Y sustituyo el valor true asignado en la macro simple original por dicha variable

    args2(0).Value = bOpcion

    El resultado...

    Sub msbIndiceNumerico(bOpcion As Boolean)

    dim args1(0) as new com.sun.star.beans.PropertyValue
    	 args1(0).Name = "On"
    args1(0).Value = bOpcion

    dispatcher.executeDispatch(document, ".uno:DefaultNumbering", "", 0, args1()) 

    End Sub

    ... es una subrutina que puede ser llamada (2) desde una macro o script principal como alternativa a la llamada opcional a dos macros simples: la de aplicación y la de retirada del índice numérico (3).

    Una variación del modelo anterior es la que incluye el uso de un bucle en el script desde el que se llama a la subrutina, generando así una secuencia de desarrollo o aplicación de la subrutina. Por ejemplo, podemos avanzar letra por letra (incluyendo los espacios en blanco) seleccionando o no los elementos que se recorren. [Esta subrutina es un ejemplo de ello].

    También podemos utilizar este bucle dentro de la subrutina, afectando únicamente a los instrucciones de ejecución (dispatcher), [como en este ejemplo].

    sub msbAvanPag(iNumPag As Integer)

    Dim i As Integer
    For i=0 To iNumPag
    dispatcher.executeDispatch(document, ".uno:PageDown", "", 0, Array())
    Next

    end sub

    La tercera forma de crear una subrutina a partir de una macro simple ya vulnera el criterio de macro simple, al menos en alguna de sus formulaciones, pero también puede ser una solución cuando el uso de dos parejas de macros simples sea requerido con cierta frecuencia.

    Considero "parejas de macros simples" cuando éstas son complementarias una de la otra, como en el caso que sigue:

    sub mcrBajarLinea

    dim args1(1) as new com.sun.star.beans.PropertyValue
    args1(0).Name = "Count"
    args1(0).Value = 1
    args1(1).Name = "Select"
    args1(1).Value = false
    dispatcher.executeDispatch(document, ".uno:GoDown", "", 0, args1())

    End Sub

    Sub mcrSubirLinea

    dim args1(1) as new com.sun.star.beans.PropertyValue
    args1(0).Name = "Count"
    args1(0).Value = 1
    args1(1).Name = "Select"
    args1(1).Value = false
    dispatcher.executeDispatch(document, ".uno:GoUp", "", 0, args1())

    End Sub

    Las macros mcrBajarLinea y mcrSubirLinea presentan una doble complementariedad: ambas pueden tener valora interno de args1(1).value true o false (se selecciona o no la línea) y ambas son complementarias entre sí (o subimos o bajamos de línea): uno:GoUp vs. uno:GoDown.

    Existen varias formas de crear una subrutina, pero me voy a limitar a dos, que son variaciones sobre el mismo tema. La primera se basa en el uso del condicional If e implica en realidad usar dos ejecutores dispatcher dentro de la misma surutina... 

    sub msbLinea(bSelect As Boolean,sMov As String)

    dim args1(1) as new com.sun.star.beans.PropertyValue
    args1(0).Name = "Count"
    args1(0).Value = 1
    args1(1).Name = "Select"
    args1(1).Value = bSelect
    If sMov = "B" Then
    dispatcher.executeDispatch(document, ".uno:GoDown", "", 0, args1())
    MsgBox "He bajado una linea"
    ElseIf sMov = "S" Then
    dispatcher.executeDispatch(document, ".uno:GoUp", "", 0, args1())
    MsgBox "He subido una línea"
    Else
    MsgBox "El valor de la variable 'sLinea' no es correcto" 
    End If

    End Sub
     ... que es llamada desde el script (msbLineaBis(true,"B")) de forma simple (4)

    La segunda forma simplifica la formulación de la subrutina...

    sub msbLinea(bSelect As Boolean,sMov As String)

    dim args1(1) as new com.sun.star.beans.PropertyValue
    args1(0).Name = "Count"
    args1(0).Value = 1
    args1(1).Name = "Select"
    args1(1).Value = bSelect
    dispatcher.executeDispatch(document, sMov, "", 0, args1())

    End Sub

    ... y pasa la responsabilidad de definir concretamente la instrucción a  ejecutar a la llamada desde el script (msbLineaBis(true,".uno:GoUp")(5)

    Te dejo aquí enlace a la [segunda opción], ya que la considero la que mejor se ajusta al principio básico de conversión de macro simple en subrutina.

    NOTAS

    (1) Existen muchas otras macros simples que presentan esta estructura y que pueden ser convertidas en subrutinas siguiendo este mismo procedimiento. Una de ellas, y en la que su conversión en subrutina es especialmente recomendable, es la macro de escritura (también podemos hacer lo mismo con el script OOo Basic alternativo a la macro). Si ahora propongo esta macro de posicionamiento es precisamente para evitar utilizar siempre el mismo ejemplo, aunque posiblemente sea éste un ejemplo no tan explícito como al que sustituye.

    (2) Recuerdo los dos modos de usar la subrutina desde la macro principal:

    • El más simple: incluir el valor deseado en la llamada a la subrutina de la macro (msbIndiceNumerico(true)). Este modo de uso, además de ser la más simple, es el más apropiado cuando la macro o script es a su vez sencillo.
    • Y el modo complejo que recomiendo cuando el script es complejo e interesa controlar los valores que se pasan a las subrutinas y a las funciones, y que consiste en lo siguiente:
      • En esa macro/script declaramos una variable del mismo tipo que la variable-parámetro de la subrutina, por ejemplo, Dim bIndice as Boolean
      • Damos valor a esa variable según lo que deseemos hacer (en esta caso, aplicar o eliminar el índice numérico): bIndice = true
      • "Llamamos a la subrutina incluyendo entre paréntesis la variable bIndice: msbIndiceNumerico(bIndice)
    (3) Dado que estamos trabajando con estructuras basadas en macros, es necesario utilizar las variables de objeto y los objetos asociados a ellas. He concretado esto como script VarSis. Este script puede ser llamado desde la subrutina o desde el script o macro que la utilice. [Ver como ejemplo].

    (4) Si se desea esta llamada puede plantearse de modo interactivo, mediante InputBox() u otra GUI. Aquí omito estas opciones por ser secundarias para el objetivo de la entrada.

    (5) En este caso es aun necesario, o cuanto menos conveniente, descomponer el proceso de asignación del segundo valor en dos fases: en la primera se asigna valor (puede hacerse de forma interactiva como en 4) y en la segunda, mediante condicional, dar a la segunda variable de la llamada la expresión técnica precisa. De este modo se evita la comisión de algún error en la asignación del dato (vg, .uno:GoUp)

    lunes, 18 de septiembre de 2023

    OOo Basic. Script

    Crear macros desde el IDE

    Aunque Grabar macro siempre será una funcionalidad útil, lo cierto es que su uso intensivo como recurso para automatizar un documento presenta  limitaciones, especialmente si el documento es de cierta extensión y no presenta mayor complicación en términos de formato.



    En cierto modo de este tema ya se ha hablado en este blog, pero no de forma tan explícita como pretendo ahora, siendo la causa de "retomar" este tema y plantear esta perspectiva, la colección de vídeos que estoy publicando en mi [canal You Tube] dentro de la lista [Competencia Digital Para Orientadores] (aunque sería apropiado que se titulara Ofimática Para Orientadores), en la que estoy presentando el proceso de creación de un docap (documento-aplicación) que automatiza la creación de un instrumento para la comunicación con familias.

    Inicialmente genero un docap basado en macros simples empleadas desde un planteamiento modular, obviando la opción simple de crear una macro completa desde Grabar macro, pero haciendo un uso instrumental de esta funcionalidad.

    Pretendo en esta entrada enlazar la fase previa, en la que se hace uso exclusivo de Grabar macro, y la estrategia de utilizar esta funcionalidad como ayuda en la creación de docap, aunque la creación de las macros individuales se realizar de forma directa desde el IDE.

    Precisamente es esta una buena explicación de la diferencia entre ambas estrategias: 

    En la primera, el usuario simplemente debe activar Grabar macro y proceder a "escribir" y formatear el documento tal y como desea que se reproduzca automáticamente.
      • Este enfoque no requiere acceder al IDE y mucho menos entender el código generado por Grabar macro.
      • Incluso nuestro usuario se puede permitir  cometer errores, aunque cuantos menos mejor.
      • Y también favorece el buen desarrollo de la macro tener estudiada la sucesión de acciones a desarrollar.
    La segunda requiere el análisis de la secuencia de acciones a desarrollar para identificar qué cuantas son y en qué orden se producen, pero también requiere acceder al IDE para trabajar desde él y conocer el código que genera Grabar macro en cada una de las acciones posibles.

      • Al contrario del primer enfoque, en este la escritura de textos y la extensión de los mismos no constituye problema alguno, ya que combina el conocimiento del procedimiento (la sintaxis de la macro de escritura) con el copia-pega del texto, lógicamente donde corresponda.
      • Tampoco supone un problema la repetición de las mismas acciones, por frecuentes que sea ésta, ya que sólo necesita grabar una vez cada acción para reutilizarla tantas como sea necesario, haciendo uso del enfoque modular.   

    Es precisamente este enfoque modular, junto con la familiaridad en el uso del IDE y el conocimiento del código, lo que caracteriza esta estrategia que diferencia al usuario familiarizado con la creación de macros en un usuario capaz de dominar la creación de docap aun simples, pero funcionales, basados en el "lenguaje de macros" en sentido estricto.

    Cierto que aun no dispone de herramientas para personalizar las macros que crea, pero la implementación de variables es un paso relativamente fácil de dar, si bien para ello se debe acercar a lo que implica Combinar correspondencia para intuir este concepto, con los riesgos que esto entraña; por ello siempre será mucho más útil y funcional acceder a este nivel de conocimiento mediante algún tipo de instrucción.

    Las necesidades de estudio y aprendizaje se acentúan conforme se adentra uno en la creación de soluciones adaptadas al quehacer profesional. 

    Para finalizar esta entrada, te dejo enlace a los dos documentos, [el primero] basado en el uso lineal de Grabar macro y [el segundo] creado utilizando el enfoque modular. Recuerda que tienes que descargarlos y abrirlos desde Libre Office. Para una explicación detallada de las diferencias entre ambos puedes acceder a [este vídeo].



    sábado, 15 de julio de 2023

    OOo Basic. Script

    Macros. Programación modular

    Además de utilizar las macros como resultado de la ejecución de Grabar macro también podemos utilizarlas como elementos discretos a modo de subrutinas. Este enfoque se encuentra a medio camino entre la creación de macros y la escritura de script o programación. Ambos procedimientos pueden ser, además, complementarios. En todo caso remite a [lo que expuse] sobre la programación lineal o imperativa y la programación modular.



    Es importante remarcar esa idea de complementariedad, ya que en informática (también) las cuestiones pueden se resolver de diferentes maneras (aunque unas pueden ser mejores que otras), así que lo que no sepamos resolver mediante un script, podemos abordarlo mediante una macro.

    Pues bien, si en la [entrada anterior] aprendimos a identificar el contenido de una macro secuencial y a diferenciar diferentes funciones, en esta entrada vamos a profundizar en el modo de trabajo que podemos llamar programación modular que podemos caracterizar por el uso de secuencias de acciones (macros unitarias o de función única) combinadas. 

    Este modo de trabajo admite la combinación entre macros unitarias y script, combinación que permite desarrollar programas de cierta complejidad. Algunos ejemplos de ello podemos verlos en [aquí]

    Para el correcto desarrollo de un docap basado en este tipo de macros es necesario posicionar correctamente las variables básicas de toda macro, así como crear una macro específica en la que dichas variables se asocien a sus contenidos. Esta macro deberá ser llamada desde las macros individuales, permitiendo así su reutilización, con el consiguiente ahorro de tiempo.

    A parte de esto, es importante crear colecciones de macros individuales, necesariamente asociadas al servicio-soporte, las cuales pueden ser aplicadas modularmente cuando sea necesario.

    Aunque puede considerarse que es este un modo un tanto rudimentario de "programar", podemos decir que es similar al enfoque funcional y que algunos programas de cierta complejidad (FileMaker, por ejemplo) disponen de recursos de "programación" que, en síntesis, no son otra cosa que una colección amplia de funcionalidades, algo similar en filosofía a lo que aquí se plantea.


    lunes, 10 de julio de 2023

    OOo Basic. Script

     Trabajar con macros

    Ya hemos aprendido a crear una macro sencilla y es posible que te preguntes si el resultado merece el esfuerzo. En principio te diría que en macros como la creada en la entrada anterior, la respuesta dependerá de la frecuencia con la que la usemos: a menor frecuencia, menos "rentabilidad". Pero es que con una macro podemos hacer muchas más cosas... siempre que estemos dispuestos a seguir aprendiendo.




    Si recordamos, la secuencia de acciones que desarrollamos para crear la macro anterior fue la siguiente:

      • Nos situamos al inicio del documento
      • Seleccionamos tipo de letra
      • Seleccionamos tamaño de letra
      • Seleccionamos negrita
      • Seleccionamos color
      • Seleccionamos centrado
      • Escribimos una frase
      • Bajamos el cursor
      • Escribimos una segunda frase
      • Bajamos el cursor
      • Nos posicionamos al inicio de la línea
    Además recordarás que cometí algunos errores y que los corregí sobre la marcha, de modo que en el resultado final no se aprecian, pero ahí están.

    En efecto, todas y cada una de estas acciones han quedado grabada en nuestra macro, incluyendo los errores y su corrección, y ahora están a nuestra disposición para que las reutilicemos. 

    Para ello debemos plateamos el uso de las macros desde una perspectiva que no es ni se limita a la que empleamos en la construcción de nuestra primera macro y que se acerca más a la programación.

    Desarrollar esta segunda perspectiva pasa por enfrentarnos al código generado por la macro, identificar y eliminar los errores cometidos y diferenciar cada paso de la secuencia que desarrollamos para hacer de cada uno de ellos una herramienta reutilizable.

    En [este enlace puedes acceder al documentoen el que se creó la macro.

    OOo Basic. Script

     ¿Qué es una macro?

    Las macros son tan antiguas como los procesadores de texto, pero han ido evolucionando en funcionalidad al igual que éstos, aunque arrastrando la mala fama que genera ser susceptibles a usos perniciosos.




    Originariamente  una macro (macroinstrucción es su nombre completo) no era otra cosa que atajo de teclado para facilitar el trabajo, permitiendo la ejecución de un conjunto de acciones mediante la pulsación de una combinación de teclas. Hoy en día macro y script tiende a confundirse, aunque opino que son dos cosas radicalmente diferentes, tan diferentes como es su proceso de creación: la macro mediante la activación de una funcionalidad llamada Grabar macro y el script mediante la generación de código escrito en un lenguaje de programación desde un programa especial denominado IDE.

    A pesar de esta diferencias y todo lo que derivan de ellas, es común en los soportes que admiten macros (servicios de suites ofimáticas) se emplee el concepto macro abarcando ambas realidades.

    En principio, y en lo que a esta entrada se refiere, vamos a denominar macro al código que deriva de la aplicación de la grabadora de macros. El hecho de que estemos tratando este tema desde Writer no implica que no sea posible crear macros (según la definición anterior) en otros soportes (por ejemplo Calc), aunque es en los procesadores de texto donde, posiblemente, más utilidad tenga trabajar con macros  por la variedad de posibilidades que éstas tienen en el trabajo con documentos de texto.

    Para trabajar con macros es necesario que conozcas unas cuantas cosas que mejor que yo te puede explicar la [documentación oficial de LibreOffice], así que lo dejo en sus manos. Es un documento muy recomendable, aunque encontrarás en él la (para mi) confusión que antes te apunté entre macro y script.

    Además puede que te encuentres con que LibreOffice se resiste a dejarte acceder a las macros. Esto es debido al sistema de control de seguridad que tiene activado y a la consideración de las macros como elementos potencialmente peligrosos. Pero como aquí estamos hablando de macros de confianza, [este documento] te permitirá actuar en consecuencia (y en conciencia). El resto queda en tus manos.

    Una vez que ya hayas superado las dos fases anteriores, lo mejor que podemos hacer en poner en práctica eso de que la mejor forma de aprender es haciendo, planteamiento que, en términos generales, es más que dudoso, pero que en este caso se acerca bastante a la verdad: aprendamos a trabajar con macros creando una. El [vídeo] que sigue te muestra cómo crear una macro simple.