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

miércoles, 26 de noviembre de 2025

Evaluación.


Automatización de la evaluación

Aplicación de la prueba




No se trata sólo de empezar por el principio, también pretendo sistematizar los distintos momentos y subprocesos que se pueden diferenciar en el proceso de implementación de una prueba, recurso o test de evaluación y, consecuentemente, identificar (y diferenciar) los diferentes subprocesos o fases en que se concreta la automatización de la evaluación.

Lo lógico, me parece a mi, es empezar por la presentación de los materiales para que el alumno resuelva la o las tareas que se le proponen, lo que no es otra cosa que la aplicación de la prueba, que también incluye las instrucciones y todo lo relativo a la explicación de cómo se espera que se desarrolle el proceso, tarea ésta que corresponde al examinador (el OE en nuestro caso).

Cierto es que existen diferentes tipos de pruebas, también por el modo en que se presentan qué tipo de inputs y se esperan del alumno qué tipo de respuestas. En función de todo esto tenderemos también diferentes niveles y modos de automatizar, e incluso de que esta automatización sea innecesaria.

La forma más compleja de automatización, pero también la más sencilla de implementar por estar bien acotada, es aquella de ítem de elección múltiple en la que el alumno debe seleccionar una imagen entre varias en respuesta a una demanda del examinador. Pero no es la única.

Verdad que no es la única, pero sí la que nos puede servir para ilustrar en qué consiste la automatización en este punto de su desarrollo; y hacerlo de forma muy concreta y precisa, hasta el punto que podemos decir que el resto de los procedimientos no son otra cosa que expresiones diferentes (y normalmente más simples) de este modelo. Veremos algunas de estas variantes, pero antes nos centraremos en cómo implementar ésta que hemos considerado prototípica.

La automatización de la aplicación de una prueba de evaluación tal y como la he concretado antes tiene un precedente ajeno a la automatización propiamente dicha, pero en línea con la digitalización de las pruebas de evaluación. Me refiero al uso de presentaciones tipo pptx que contienen las láminas para mostrar al niño  y que, al igual que con las de papel, seleccionar la que corresponda, 1 entre 4, normalmente.

El siguiente paso ya hace posible la automatización de la aplicación de la prueba y se basa en implementar macros o código (vg. VBA o OOo Basic), estableciendo alguna forma de interacción del niño con los comandos incorporados el soporte, incluyendo su uso sobre la imagen. Esto también tiene un precedente en el uso de las presentaciones y los mecanismos de interacción que incorporan, pero este precedente no permite interacciones como las que se requieren para automatizar la aplicación de la prueba, aunque aparenten ser similares.

Una alternativa al uso de las presentaciones es emplear hojas de cálculo, dado que admiten el uso interactivo de imágenes, la recogida de datos en sus celdas y la incorporación de script para la gestión del soporte. Un ejemplo de ello lo tenemos en las posibilidades que presentan los documentos Calc y la construcción de DocAp basados en ellas. 

Ciertamente no son la única solución, pero sí una de las más sencillas, generalizables y sostenibles. La sencillez viene dada por las tres características explicadas en el párrafo anterior. Las otras dos cualidades derivan de que ese uso está al alcance de cualquier profesional que muestre interés por crear este tipo de recursos.

martes, 15 de julio de 2025

Textos. OOo Basic

Copiar y pegar texto entre documentos


Normalmente esta tarea la resolvemos de forma manual y está bien que así sea, pero en algunas ocasiones es posible que necesitemos automatizar este procedimiento, así que vamos a exponer en esta entrada una alternativa basada en OOo Basic.



Bueno, en realidad el código OOo Basic es escaso, ya que lo que predomina es la utilización de código-macro, resultando el script la ya utilización de una macro desde la perspectiva de la formulación de un script. Nada novedoso, por cierto. Pasemos a mostrar el código:

Sub CopiarTexto

Dim sRuta As String
Dim mOpciones(0) As New "com.sun.star.beans.PropertyValue"
Dim oDoc As Object
Dim NombreDoc As String
 
NombreDoc = "AutoDocTxt"

'Acceder al documento. Sustituir la ruta por la propia.
sRuta = ConvertToUrl(Ruta_absoluta_del_documento & NombreDoc & ".odt")
oDoc = StarDesktop.loadComponentFromURL( sRuta, "_blank", 0, mOpciones() )

'Copiar el contenido o texto del documento (en este ejemplo, AutoDocTxt.odt)
dim document   as object
dim dispatcher as object

document   = ODoc.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:GoToStartOfDoc", "", 0, Array())
dispatcher.executeDispatch(document, ".uno:EndOfDocumentSel", "", 0, Array())
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())

'Pegar el texto en Calc
dim documentCalc   as object
documentCalc   = ThisComponent.CurrentController.Frame
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$A$1"
dispatcher.executeDispatch(documentCalc, ".uno:GoToCell", "", 0, args1())
dispatcher.executeDispatch(documentCalc, ".uno:Paste", "", 0, Array())

'Cerrar el documento Writer que contiene el texto
oDoc.close(True)
 
End Sub

En este caso el proceso se concreta como copia desde Calc de un texto contenido en un documento Writer. No es la única opción, siendo posibles diferentes combinaciones, pero ésta nos sirve como ejemplo para el resto, siendo suficiente con realizar algunos cambios en la identificación de los archivos de origen y destino. Esto, claro está, te queda a ti como tarea.

Apreciamos que este script se desarrolla en cuatro fases, siendo la primera de ellas el acceso al documento Writer desde Calc. Para ello establecemos primero la variables que se precisan (inicio del script), para pasar a acceder al documento mediante la función de conversión de ruta (ConvertToUrl())  que tú debes concretar con tu propia ruta. Observa que esta fase incluye la identificación del documento mediante una variable específica (NombreDoc = "AutoDocTxt"), a fin de facilitar la personalización del procedimiento.

La segunda fase se desarrollar en base a lenguaje-macro y se centra en la copia del contenido del texto, proceso que se desarrolla como aplicación de la funcionalidad Grabar macro desde el documento Writer, pero trasladado al script creado sobre Calc. En síntesis, lo que hacemos con esta macro es posicionar el curso al inicio del documento, seleccionar el texto que contiene desde la posición inicial al final del documento (y del texto) y copiarlo en el portapapeles.

En la tercera fase accedemos al documento Calc y copiamos en la celda (A1) de la hoja activa el contenido del portapapeles. Esta fase también se basa en código-macro, tal y como se puede apreciar, identificando la hoja Calc como el componente de referencia (ThisComponent.CurrentController.Frame) Sobre él, y concretamente sobre la celda identificada como punto de referencia (args1(0).Value = "$A$1") se procede a copiar el contenido del portapapeles (dispatcher.executeDispatch(documentCalc, ".uno:Paste", "", 0, Array())).

Finalizamos este script (fase cuarta) cerrando el documento Writer abierto en la primera fase (oDoc.close(True)), como forma de acentuar el logro del objetivo (la automatización del procedimiento), aunque esta fase es fácilmente prescindible sin que se vea alterado el logro del objetivo propuesto.

martes, 3 de diciembre de 2024

Textos. Automatización.

Textos desde macros


También podemos crear textos y trabajar con ellos utilizando macros. En este caso el planteamiento inicial es crear el texto desde la página en blanco, aunque también es posible (aunque más laborioso) trabajar con un documento formalizado, incluso en formato tabla, como es el caso del dictamen de escolarización.


La utilidad Grabar macro está pensada como recurso para capturar las pulsaciones del teclado (y algunos clic del ratón). Debemos activarla desde Herramientas | Macros | Grabar macro y proceder como ya quedó dicho en las entradas en las que se ha tratado este tema, como [por ejemplo]. En realidad es una utilidad que se ajusta bien al objetivo para el que está pensada y hacer uso de ella es una forma interesante de iniciarse en la programación, especialmente si posteriormente trabajamos sobre el código generado desde el IDE, [como ya vimos].

En lo que al trabajo con textos se refiere, y cuando el objetivo es crear documentos-aplicaciones [incluso de cierta complejidad], el código que genera esta funcionalidad nos puede resultar útil, incluso en fases más avanzadas, en las que predomina la creación de script desde OOo Basic, ya que es posible combinar el código macro con el código creado directamente desde el IDE.

Centrándonos en el trabajo con y sobre texto, la mayor utilidad de Grabar macro es que podemos automatizar la composición de documentos con tan sólo activar la macro creada previamente, la cual sirve a modo de plantilla, sin que sea necesario que el documento contenga una sola palabra. Cierto es que para ello deberemos componer el texto que nos servirá de base y cierto también que para sacar el máximo provecho a este procedimientos deberemos saber identificar en el código la posición de las variables y, mejor aun, trabajar con variables mediante OOo Basic. Una vez alcanzado este nivel, especialmente si sabemos manejar también colecciones de datos (matrices), incluso podemos idear procedimientos que funcionen de forma similar a como hacemos con Combinar correspondencia, con todo lo que esto implica de automatización de procedimientos sencillos de creación de documentos personalizados repetidas veces.

Estoy pensando, como se puede deducir, en el trabajo con documentos en blanco, pero, como también dije antes, también podemos hacerlo sobre documentos-modelo. En este tipo de documentos deberemos prestar especial atención al movimiento del cursor por el documento, acción que debe ajustarse con precisión a lo necesario para ubicarnos en la posición deseada, ya que Grabar macro va a hacer justamente lo que se espera que haga: grabar cada una de nuestras acciones. 

Un tercer ejemplo de uso de macros es la combinación del uso de un diálogo (1) como recurso input sobre un documento en blanco. Se trata de un procedimiento de cierta complejidad, desarrollado en un nivel ya avanzado de trabajo con OOo Basic, pero que utiliza fundamentalmente código macro modificado desde el IDE. Como ejemplo tenemos en nuestro listado el [Informe de solicitud de becas NEAE] del que te hablo en [esta entrada], que puedes encontrar más abajo en esta misma sección del blog.

Como puedes ver, el uso de macros nos permite ya automatizar procedimientos, pero (y eso es para mi lo más importante) nos permite dar el paso definitivo del recurso a utilidades a iniciarnos en la programación: sólo debemos perder miedo al IDE y acercarnos al código que crea automáticamente Grabar macro (2).

NOTAS

(1) Recordarás que se trata de una modalidad de formulario emergente que se crea directamente desde el IDE y a cuyos controles se accede mediante código.
(2) Realmente trabajar desde el IDE nos puede resultar extraño y un tanto desconcertante al principio, pero la mayor dificultad que nos podemos encontrar en este momento es comprender las líneas de código que encontramos escritas. Aunque con un poco de atención enseguida le cogeremos "el truco", para avanzar realmente en la línea deseada es conveniente que prestes atención a lo que se explica en la sección [OOo Basic] de este blog. El camino se te va a hacer más corto y más llano.


lunes, 15 de julio de 2024

Procedimientos. Macros.

Vincular macros o script a un objeto (2)


Además de un comando o a una hoja, también podemos asignar una macro/script a un objeto figura o imagen. Aunque aquí nos basemos en Calc, esa posibilidad activar un script no se limita a este servicio, ya que es posible insertar una forma o una imagen en cualquiera de los servicios LibreOffice.




Después de implementar una forma (Insertar | Forma) y/o una imagen (Insertar | Imagen) en la hoja, hacemos clic derecho sobre ella para seleccionara. Automáticamente se despliega un menú de opciones, dentro de las cuales tenemos la opción Asignar macro.


Haciendo en ella accedemos a un submenú donde se diferencia una ventana superior donde se identifica la única opción de evento disponible (Botón del ratón presionado). En la ventana inferior se encuentran los subdirectorios que contienen las distintas ubicaciones de macros posibles (Macro de). Deberemos hacer clic en aquella que contenga la macro que deseamos asociar a la forma/imagen y seleccionarla en Macros existentes.


Una vez seleccionada la macro/script deberemos hacer clic en el comando Asignar (lateral derecho de la ventana) y después en Aceptar (marco inferior). Estas dos acciones son necesarias para que se realice correctamente la asignación de la macro/script al objeto forma/imagen.


El documento Calc que ejemplifica este proceso consta de dos hojas: en la primera he implementado una figura y en la segunda una imagen. Los script (podemos decir, de ida y vuelta) permiten acceder uno a Hoja2 y otro a Hoja1. De este modo, al hacer clic en el cuadrado azul (Hoja1) nos desplazamos a Hoja2 (previamente se muestra esta hoja y después se oculta Hoja1). El proceso que desarrolla el script asociado a la imagen situada en Hoja2 realiza el proceso contrario.

Documento. En [este libro Calc] puedes encontrar ejemplificado el proceso descrito en la entrada, incluyendo los dos script que se activan desde los objetos gráficos insertados en sus dos hojas.





Procedimientos. Macros.

Vincular macros o script a un objeto (1)


Una vez que hemos creado una macro o un script, necesitamos hacer que funciones. La primera alternativa consiste en utilizar las opciones de la interface del servicio (Herramientas | Macros | Ejecutar macro), solución simple y funcional pero poco atractiva a día de hoy. La segunda consiste en asignar la macro/script a un comando de formulario (botón), que es la forma que más se asemeja al modo standard de trabajar con las interfaces visuales. Pero aun hay otras opciones.


Una
forma un tanto especial y específico de las hojas de cálculo, consiste en asociar el script a la propia hoja. Para ello nos posicionamos en el navegador inferior de Calc y hacemos clic derecho sobre el nombre de una de las pestañas, la que representa la hoja a la que queremos asignar el script. 


Se visualiza la ventana emergente con el menú que vemos en la imagen superior y seleccionamos la opción Eventos de hoja. Haciendo clic en ella, accedemos a una ventana de selección de opciones de vinculación (eventos) (1)


Seleccionamos uno de estos eventos y  hacemos clic en Macros. A continuación podremos seleccionar la macro/script que nos interesa vincular a la página, seleccionarla y hacemos clic en Aceptar.


 
Nos devuelve a la ventana anterior (ahora con la macro seleccionada identificada en la columna Acción asignada) y volvemos a hacer clic en Aceptar.

De este modo la macro/script queda vinculada a la página en función del evento que hayamos escogido.

En el ejemplo que desarrollo como concreción del proceso anterior, he elegido el evento Activar documento y la macro Main. Esto implica que cuando Hoja1 sea la hoja activa se pondrán en marcha las instrucciones que contiene este script.

Sub Main

Dim oHoja As Object

oHoja = ThisComponent.getSheets.getByIndex(1)
oHoja.isVisible = True
Wait 500
oHoja = ThisComponent.getSheets.getByIndex(0)
oHoja.isVisible = False
Wait 500
oHoja = ThisComponent.getSheets.getByIndex(2)
oHoja.isVisible = True
Wait 500
oHoja = ThisComponent.getSheets.getByIndex(1)
oHoja.isVisible = False
Wait 500
oHoja = ThisComponent.getSheets.getByIndex(3)
oHoja.isVisible = True
Wait 500
oHoja = ThisComponent.getSheets.getByIndex(2)
oHoja.isVisible = False

End Sub

En resumen, se visibiliza (mostrar) una hoja, se espera 500 msg y se oculta la hoja precedente (2), con lo que la hoja visible pasa a ser también la hoja activa (3).

Documento. Este [libro Calc] contiene el código anterior asociado a Hoja1. Al abrir este documento, nos encontramos posicionados en Hoja4. Si nos desplazamos "manualmente" a Hoja1 se desarrollará el proceso esperado (4). 

NOTAS

(1) Si comparas los eventos posibles con los que se despliegan cuando trabajamos con el control de formulario Botón (Comando), verás que los eventos de hoja son mucho más limitados.
(2) Esto es así por trabajar con el índice de las hojas, lo que facilita la secuencia Mostrar-Ocultar.
(3) Este script contiene la instrucción Wait cuyo uso merece más atención de la que se le presta aquí. Será necesario analizarla específicamente en una entrada específica.
(4) Dado que se ocultan todas las hojas (menos Hoja4), para volver al estado inicial deberemos mostrar todas las hojas (Hoja | Mostar la hoja, seleccionamos todas las que se nos muestran y clic en Aceptar), pero mantendremos Hoja4 como hoja activa. Si guardamos el documento posicionándonos en Hoja1, de modo que al volver a activarlo estemos posicionados en ella, no se activará el script.

sábado, 13 de julio de 2024

Procedimientos. Datos

Ocultar hojas mediante macro

Cuando nos interese por cualquier motivo que las hojas de un libro Calc no sean directamente accesibles podemos ocultarlas para después mostrarlas selectivamente. Para ello disponemos de las funcionalidades pertinentes desde el menú Datos (1).


También podemos ocultar una hoja mediante una macro que oculta la hoja activa (2). Es muy sencilla; te la muestro a continuación:

Sub OcultarHoja

dim document   as object
dim dispatcher as object

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

dispatcher.executeDispatch(document, ".uno:Hide", "", 0, Array())

End Sub

No explico las cuatro primeras líneas por ser sobradamente conocidas, así que la tarea se simplifica aun más: la función dispatcher.executeDispatch() lanza la orden ".uno:Hide" sobre el objeto asignado a la variable document. Dicha orden consiste en atribuir al objeto el atributo "Oculto" (Hide), lo que equivale al uso del submenú Hoja | Ocultar hoja. Proceso finalizado (3)

Documento. Este [libro Calc] contiene la macro explicada en la entrada.

NOTAS

(1) También podemos hacerlo desde el menú que se despliega cuando hacemos clic derecho sobre el nombre de la hoja en el navegador inferior de Calc.
(2) Y mediante Grabar macro es la única opción disponible, que yo sepa.
(3) Esta macro es tan simple que poco podemos hacer para instrumentalizarla. Podemos, eso sí, modificar la macro, convirtiendo en variables públicas las de objeto (document dispatcher), creando después un script de asignación de los objetos correspondientes a dichas variables (VarSis, en mi caso) y llamar a ese script desde el inicio de la macro OcultarHoja; pero no podemos convertir esta macro en una subrutina, aunque sí utilizarla como script auxiliar a emplear (llamar) desde otros que impliquen en su algoritmo la ocultación de la hoja activa.

Herramientas. Procedimientos.

Macro para desplazarse por las hojas

Cuando el número de hojas que contiene nuestro libro Calc es elevado, desplazarse por ellas mediante el navegador inferior puede resultar poco práctico. Como alternativa podemos crear una macro que nos facilite este desplazamiento. Además así podremos ir a la hoja que deseemos desde un comando.


Una vez [creada la macro] según lo que ya sabemos toca estudiarla para sacar de ella todo el rendimiento posible.

Sub macroIrHoja2

dim document   as object
dim dispatcher as object

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

dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Nr"
args1(0).Value = 2
dispatcher.executeDispatch(document, ".uno:JumpToTable", "", 0, args1())

End Sub

Una ver eliminados los comentarios sobradamente conocidos, y en su sustitución, paso a explicar el funcionamiento de esta macro. El objetivo que se persigue con ella es desplazar a la hoja llamada "Hoja2", por lo que se supone que nos encontramos en otra hoja diferentes (1)

Apreciamos, en primer lugar, la sintaxis común a todas la macros:

  • La declaración de las variables objeto document   y dispatcher, y la asignación de esos objetos a las variables:

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

  • Observamos que la matriz args1(0) cuenta con dos dimensiones (Name y Value) (2): el primero toma el valor "Nr" que identifica que trabajaremos con el número de la hoja y el segundo, Value (valor) al que se asigna el dato (integer) concreto (2) (3)
  • Finalmente, el ejecutor de la macro (dispatcher.executeDispatch) nos muestra la instrucción que ejecuta la orden de saltar a la hoja señalada en args1(0).Value (".uno:JumpToTable"(4)
Una vez comprendido el código de esta macro, por ejemplo, puedes añadir más hojas a tu libro y construir un navegador implementado comandos asociados a macros. Esta que te comento a continuación no es la mejor opción, pero sí muy práctica: es suficiente con que copies y pegues la macro original las veces que desees, des nombres diferentes a los script creados y cambies el parámetro de args1(0).Value = 2 , sustituyendo así el número de orden de la hoja.

Pero también puedes transformar esta macro en una subrutina y ahorrarte un montón de líneas de código; de este modo será suficiente con llamar a la subrutina script.

Observa cómo convertí la macro original en una subrutina ( MovHoja (iH As Integer)). El script (IrHoja2) es ahora mucho más sencillo y, eso sí, tienes que repetirlo (con los cambios que corresponden) las veces que sea necesario si quieres aplicarlo a más hojas:

Sub IrHoja2 'Script

MovHoja (2)

End Sub


Sub MovHoja (iH As Integer) 'Subrutina

dim document   as object
dim dispatcher as object

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

dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Nr"
args1(0).Value = iH
dispatcher.executeDispatch(document, ".uno:JumpToTable", "", 0, args1())

End sub

El funcionamiento del conjunto es así de sencillo: desde el script se llama a la subrutina, pasando como argumento el id numérico de la hoja (6). La subrutina ejecuta el procedimiento ya visto antes en la macro, sustituyendo el contenido de args1(0).Value empelado en la macro por el identificador del parámetro que se define en la declaración de la subrutina (= iH) (7)

Documento. En [este libro Calc] encontrarás el código explicado en la entrada.

NOTAS

(1) Perogrullada: de no ser así no apreciaríamos el efecto de la macro.
(2) Como puedes ver, hasta ahora nada de especial en cuanto a la sintaxis de una macro
(3) Esto ya nos da una pista de cómo podemos manipular esta macro mediante OOo Basic.
(4) En el lenguaje macro, las hojas se asimilan a tablas, de ahí la instrucción JumpToTable.
(5) Aunque no es la única opción; y menos aun si sólo vas a trabajar con una macro.
(6) Fíjate que en el caso de las macros, el índice de la hoja coincide con su orden numérico observable: la primera es 1, no 0. Esto no es así en un script o una subrutina creado directamente en OOo Basic, ya que en él la matriz de hojas del libro se inicia con el valor 0.
(7) Con lo que, como sabes, se está asignando el valor establecido en el script en la llamada a la subrutina.

viernes, 26 de abril de 2024

OOo Basic. Datos

Variables

Una orientadora, Mercedes, está colaborando con la Jefa de estudios del colegio elaborando informes escolares de una lista de alumnos y alumnas (el motivo ahora no es relevante). Mercedes piensa usar lo que estamos aprendiendo sobre LibreOffice y piensa crear un documento-base en Writer para elaborar los informes que recojan los datos de ese análisis. Veamos cómo lo podemos enfocar.


Después de investigar unos cuantos expedientes y una vez que se hace idea de cómo abordar el tema, Mercedes se plantea crear un documento-modelo para recoger toda la información. Hace un informe a modo de "ejemplo" y, después de revisarlo y reajustarlo, se plantea utilizarlo como base para construir los restantes. 

Aunque una Mercedes real posiblemente actuara de otro modo (1), nosotros vamos a suponer que quiere poner en práctica lo aprendido hasta ahora: crear macros y script.

Puesta a la tarea, Mercedes crea una primera macro a la vez que va escribiendo su documento. Supongamos que este texto es parte del inicio del documento:

Juan es actualmente alumno de 4º de E. Primaria en el C.P. Aurelia Sánchez (Santullano)

Activa Grabar macro, escribe el texto, finaliza la grabación, prueba su macro y observa que funciona según lo previsto. Pero ahora se le presenta un dilema: si quiere hacer ahora el informe de Luis se encuentra conque o utiliza su documento como documento-base y sustituye Juan por Luis o tiene que crear una macro para cada alumno. Evidentemente esta segunda opción no es razonable, ya que no le quita trabajo (2).

Supongamos que, a pesar de ello, crea una segunda macro, ahora con este otro texto:

Luis es actualmente alumno de 2º de E. Primaria en el C.P. Aurelia Sánchez (Santullano)

Comparemos ambos textos:

  • Observamos que varían dos datos: el nombre del alumno y el curso.
  • El resto permanece igual
Esos datos que varían (Juan - Luis y 4º - 2º) son las variables. Ambos pertenecen a dos conjuntos, el conjunto nombre y el conjunto curso, por lo que podemos entender que una variable, además de lo obvio (un dato que varía) también se puede entender como la denominación genérica de un conjunto de datos.

Pero desde la perspectiva de la programación, una variable es, en realidad, un identificador de un espacio de memoria RAM a cuyo contenido se accede utilizando ese identificador.

En todo caso, y con independencia de con qué conceptualización nos quedemos, usar variables nos va a permitir resolver de forma sencilla el problema de Mercedes: es suficiente con que sustituya el nombre concreto por un identificador como sNombre y el curso por sCurso para que no necesite cambiar en el texto ni el nombre ni el curso. Pero aun no sabemos cómo se hace eso.

Vamos a ver qué dice las macros que ha creado Mercedes. Para ello accedemos al IDE como sigue: 
  • Herramientas | Macros  | Editar macros.
  • Si no estamos ya en nuestro documento, Biblioteca Standard, Módule1 (por ejemplo), repetimos la selección que implica llegar hasta aquí...
  • Y nos encontramos con el código siguiente:

sub InfoEscolar1
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Text"
args1(0).Value = "Juan es actualmente alumno de 4º de E. Primaria del C.P. Aurelia Sánchez (Santullano)"

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

end sub

sub InfoEscolar2
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Text"
args1(0).Value = "Luis es actualmente alumno de 2º de E. Primaria del C.P. Aurelia Sánchez (Santullano)"

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

end sub

Tenemos dos macros (Sub InfoEscolar1 y Sub InfoEscolar2) que son exactamente iguales, a excepción de la diferencia de nombre y curso que ya identificamos antes. Poca opción nos da esto para ahorrar tiempo. ¿Cómo podemos usar variables en este caso?.

Con el tiempo aprenderemos que una macro en realidad  hace uso de variables, pero por ahora las que emplea no nos resuelven el problema. Y esta es la principal limitación de las macros, motivo por el que necesitamos aprender a trabajar con OOo Basic, incluso para mejorar (y simplificar) el uso de macros.

Como ya sabemos crear un script en OOo Basic, en esta entrada vamos a avanzar lo suficiente para resolver el problema a Mercedes:
  • A continuación de la expresión dim dispatcher as object vamos a crear una línea en blanco (Intro) (en realidad dos líneas).
  • Y escribimos Dim sNombre As String en la primera y Dim sCurso As String en la segunda (3). Ya tenemos creadas nuestras variables.
  • A continuación buscamos línea...

args1(0).Value = "Juan es actualmente alumno de 4º de E. Primaria del C.P. Aurelia Sánchez (Santullano)"

  • Y sustituimos  "Juan es actualmente alumno de 4º de E. Primaria del C.P. Aurelia Sánchez (Santullano)" por sNombre & " es actualmente alumno de " & sCurso & " de E. Primaria del C.P. Aurelia Sánchez (Santullano)" (es importante respetar el uso de las comillas y los espacios iniciales)
Con esto la segunda macro ya no es necesaria, así que la podemos borrar.

Mercedes dispone ya de variables en sustitución de los datos (nombre y curso), pero aun no puede sacar todo el partido posible de su descubrimiento: necesita un medio para introducir los datos concretos (Juan y Luis, por ejemplo). Para ello tiene que aprender a dar valor (asignar contenido o datos) a las variables, para ello...
 usar una función OOo Basic llamada InputBox(), asociándola a cada una de sus variables. Vemos cómo.
  • A continuación de Dim sCurso As String generamos un salto de línea (mejor dos para que el código sea más visible) y escribimos estas dos líneas:

sNombre = "Juan"
sCurso = "4º" 

Con ellas estamos diciendo a OOo Basic que almacene en el espacio de memoria RAM identificado como sNombre el dato "Juan", de modo que cuando aparezca la expresión sNombre acceda a ese espacio de memoria, recupere su contenido (el dato "Juan" en este caso) y haga con él lo que corresponda (en nuestra "macro" escribir Juan antes de la cadena " es actualmente..."). Y lo mismo con sCurso.

Usar este procedimiento no es la mejor opción posible, ya que obliga a Mercedes a acceder al IDE y realizar las asignaciones pertinentes para cada informe, así que mejor buscamos otra solución más funcional: usaremos la función OOo Basic llamada InputBox(), asociándola a cada una de las variables. Vemos cómo:

  • Sustituimos  sNombre = "Juan" por sNombre = InputBox("Nombre del alumno"
  • Y hacemos lo mismo con sCurso
Ahora Mercedes ya no tiene que acceder al IDE, es suficiente escribir el nombre (y el curso) del alumno en espacio disponible en la ventanita emergente que genera la función InputBox() y que tendrá a su disposición de forma automática una vez que llame a la macro (Herramientas | Macros | Ejecutar macro)

Aunque parezca poco, en esta entrada hemos avanzado mucho:
  • Hemos accedido a una macro e identificado en ella la información que nos interesa.
  • Hemos aprendido a crear (declarar) y usar (asignar valor y sustituir el dato concreto por la variable) variables.
  • Y hemos automatizado y generalizado la creación de un documento combinando una macro con unas variables, lo que equivale a decir que hemos aprendido (de momento empezado a aprender) cómo superar las limitaciones de las macros mediante su tratamiento con OOo Basic.
  • Además hemos utilizado una función que facilita la fase Input del proceso básico de un script (Input - Procesamiento - Output) (4)
Evidentemente lo aprendido hasta ahora sobre las variables no es más que el principio, pero en las entradas que siguen seguiremos aprendiendo mucho más sobre ella. Por el momento te dejo para que descargues el documento [loPrimero.ods] con la macro modificada (InfoEscolar) según los pasos seguidos en esta entrada para que puedas estudiarla y crear tú las réplicas que te parezca (5).

NOTAS

(1) Una Mercedes real posiblemente se quedara aquí y se limitara a marcar los espacios de los datos que varían, manteniendo el resto del contenido, a modo de texto mutilado. No es mala opción y a la altura del proceso de aprendizaje en que nos movemos es posible que incluso sea la mejor opción. Excepción hecha del uso de la funcionalidad Combinar correspondencia, siempre que el documento no sea muy complejo. De todos modos (posiblemente sin saberlo) Mercedes está trabajando "manualmente" con variables (y constantes). No obstante nosotros vamos a darle más recorrido el tema y hacerlo un poco más complejo. Complicar lo sencillo es, a veces, una buena forma de aprender. 

(2) En realidad, aun en esta caricaturización de la situación crear una macro sí supone un ahorro de tiempo. Si el documento tiene cierta extensión, se aprecia la ventaja (relativa, pero real) que tiene Grabar macro: crear una macro que le dé forma y contenido evita tener que escribirlo todo desde cero. También es más estable, seguro y manejable que trabajar con un documento-modelo. Es necesario, eso sí, utilizar (por ejemplo) Editar | Buscar y reemplazar para ir modificando los datos que varíen (quedémonos con esto: datos que varían)

(3) También podemos escribir Dim sNombre As String, sCurso As String, pero por ahora nos interesa diferenciar ambas expresiones. Además seguramente habrás pensado que "alumno" no es un término correcto cuando tengamos que hacer el informe de Rosa, con lo que también podría ser considerada una variable. Pero, por didáctica nos limitaremos a las dos variables dichas.

(4) Como sin duda Mercedes es inteligente, se habrá dado cuenta además que, limpia de texto irrelevante, la sintaxis de la macro le permite crear todos los textos que se imagine, siendo suficiente con sustituir el párrafo de nuestra macro por cualquier otro texto, el cual puede haber creado previamente (copiar y pegar) o crearlo directamente sobre en el IDE. Esto incluye el uso de todas las variables que le interese. Sólo necesita copiar la macro, cambiar su nombre (Sub NuevoNombre) para no perder la macro original y realizar en args1(0).Value = a sustitución que propuse antes. Y todo ello sin necesidad de usar de nuevo Grabar macro. Eso sí que es un ahorro de tiempo.

(5) Para mayor claridad del ejemplo he borrado de la macro original todos los comentarios, que ahora son innecesarios, aunque es buena praxis comentar el código. Ya aprenderemos cómo. Originalmente esta macro se llamaba InfoEscolar1, pero como ahora no necesitamos crear una macro por cada informe que queramos crear, pasa a llamarse InfoEscolar.