Posicionamiento y desplazamiento mediante OOo Basic. (1)
Cuando trabajamos con textos podemos automatizar su composición partiendo de un documento en blanco y escribirlo totalmente desde código. Posiblemente esta sea la solución sencilla, pero no siempre es posible (y a veces tampoco recomendable) aplicarla. Cuando el documento-modelo nos viene impuesto (por ejemplo, el modelo de informe o de dictamen), replicarlo íntegramente mediante código (forma u contenido) resulta muy complicado y poco funciona, lo que compromete la viabilidad de su automatización.
Los posicionamientos básicos son al inicio y al final del documento. Ya sabemos cómo hacerlo usando Grabar macro (2), como podemos ver en las instrucciones que siguen, concretamente lo indicado en negrita:
- Al inicio: dispatcher.executeDispatch(document, ".uno:GoToStartOfDoc", "", 0, Array())
- Al final: dispatcher.executeDispatch(document, ".uno:GoToEndOfDoc", "", 0, Array())
Las instrucciones alternativas en OOo Basic repiten la diferencia inicio-fin (3):
- Al inicio: oText.insertString(oText.getStart(),sTexto & Chr(13), False)
- Al final: oText.insertString(oText.getEnd(),sTexto & Chr(13), False)
Sub EscribirInicioFinal
Dim oText As Object
Dim sTexto As String
oText = ThisComponent.Text
sTexto = "Patata"
oText.insertString(oText.getStart(),sTexto & Chr(13), False)
sTexto = "Coliflor"
oText.insertString(oText.getEnd(),sTexto & Chr(13), False)
End Sub
Sub IntertarTextoEnPosicionMarcadorDim oMarca1 As ObjectoMarca1 = ThisComponent.getBookmarks().getByName("Marcador1")oMarca1.getAnchor.setString("Inserto texto")
End Sub
Del acceso al marcador se encarga la función getBookmarks() que precisa de una concreción del procedimiento mediante una segunda función, la cual, en nuestro ejemplo, se concreta como acceso por el nombre (getByName()). La primera función no precisa parámetro, pero sí la segunda (getByName("Marca1")). En resumen, mediante la primera instrucción asignamos a la variable objeto el acceso al marcador Marca1:
oMarca1 = ThisComponent.getBookmarks().getByName("Marca1")
Mediante la segunda instrucción posicionamos un string en el punto del documento en que se inserta Marcador1. También podemos posicionar el contenido de una variable simple o resultante de la concatenación de varias. Del procedimiento "escribir" se encarga la función setString() a la que se pasa como parámetro el texto o la/s variable/s cuyo contenido queremos sea escrito en la posición del marcador.
oMarca1.getAnchor.setString("Inserto texto")
Partiendo de este script modelo básico, podemos crear script complejos que nos permitirán (no sin trabajo) complementar documentos-modelo igualmente complejos, con total precisión posicional.
Repito: este procedimiento está especialmente recomendado cuando el documento-modelo es de obligado uso o tiene un nivel de complejidad de formato que no resulta viable componer el documento directamente desde código.
Como síntesis y ejemplo de lo explicado en este entrada vamos a trabajar con documento que suponemos prescriptivo (8). Partimos del supuesto de la existencia de un documento-modelo que consta de una parte prediseñada mediante tablas y un párrafo predefinido personalizable y dos párrafos cuyo contenido se concreta mediante código.
En la primera parte (tablas) utilizamos los marcadores como recurso para completar su contenido, en un caso (Tabla1) accediendo al inicio de las celdas. Esta tabla no muestra su estructura, pero está formada por dos filas y dos columnas (los marcadores se simulan, puesto que, en realidad, no son visibles):
En las otras dos tablas, que sí se visualizan en su marco exterior, la ubicación de los marcadores no se basa en el posicionamiento en celdas, puesto que en realidad se trata de tablas de celda única (sin subdivisiones en filas y columnas); en realidad se ubican los marcadores del mismo modo que se hace en el primer párrafo: a continuación del nombre del campo. Ejemplo de la Tabla2:
La segunda forma de utilizar marcadores se ejemplifica en el párrafo que sigue da Tabla3 (Parrafo1). En él se definen implícitamente 4 campos, posicionados mediante los marcadores Marca7 a Marca10 (en este caso he optado por señalar su posición mediante |.
Obsérvese que, en este caso, he considerado pertinente explicar el modo en que se prepara y trabaja con el texto, ya que es necesario para conocer cómo funciona el procedimiento, dada la relación entre éste y el algoritmo que se emplea para automatizar la cumplimentación del documento-modelo.
Explicaré a continuación ese algoritmo, aunque es necesario tener descargado el documento que lo soporta para acceder al código y comprender mejor esta explicación. Por ello, y antes de proceder, te sugiero que descargues el documento original. Te dejo también acceso a su versión como plantilla, que es la que recomiendo utilizar en las prácticas con el documento para evitar el borrado de los marcadores, lo que inutiliza el propio algoritmo.
Sub Escribir
Dim mConten (12) As String
Dim Conta As Integer
Dim sVar As String
mConten(0) = "EOE de Oviedo"
mConten(1) = "Fco Javier Alonso"
mConten(2) = "1123456"
mConten(3) = "Jaime López Pérez"
mConten(4) = "12/08/2017"
mConten(5) = "CP Barrio Nuevo"
mConten(6) = "2º de E. Primaria"
mConten(7) = "24/10/2020"
mConten(8) = "reunión con el equipo educativo"
mConten(9) = "el seguimiento del alumno en el área de matemáticas"
mConten(10) = "la tutora, el orientador y la profesora de PT"
mConten(11) = "La reunión transcurre conforme a lo planeado. Se abordan las dificultades de Jaime en el área de matemáticas, constatándose mejora en el cálculo (sumas y restas) y en la resolución de problemas simples (una operación)"
mConten(12) = "Refozar la práctica del cálculo (restas con llevadas) e introducir operaciones simples de multiplicación y división. Informar a la familia para mejorar la colaboración Centro-Familia. La tutora mantendrá reunión con los padres la semana próxima."
For Conta = 0 To 12:
sVar = mConten(Conta)
InterTextoEnPos(sVar,Conta)
Next
End Sub
Este script se divide en tres partes: declaración de variables, asignación de valores a la matriz y bucle de llamada a la subrutina (script auxiliar).
- La variable sVar nos sirve como mecanismo de paso de los valores de la matriz a la subrutina (parámetro 1); la matriz mConten(12) se define formada por 13 elementos (0-12) y sirve para contener los datos necesarios para cumplimentar el documento, y, por último la variable Conta es un contador que permite delimitar el bucle final y sirve, además, como parámetro 2 de la llamada a la subrutina.
- En la segunda para asigno directamente valores a los elementos de la matriz mConten(12). Es un procedimiento simplificado para simplificar el ejemplo, ya que en un desarrollo del script que se pretenda función debería suponer el uso de procedimientos interactivos, que ahora me ahorro. Por ejemplo: mConten = InputBox("Nombre del SEO", "DATOS DEL SEO").
- Lo interesante de usar una matriz en vez de un conjunto de variables es que, además de simplificar el procedimiento (no ahorramos escribir 13 variables), permite trabajar directamente con el bucle, según veremos. No obstante presenta una dificultad que hace recomendable elaborar previamente (fase de planificación del algoritmo) una tabla de relaciones entre los marcadores, el contenido del elemento y la propia identificación del elemento. Por ejemplo: Marca0 | Nombre SEO | mConten0
- El bucle con el que finaliza el script es fundamental para entender el procedimiento. Gracias a él (y al uso de la matriz mConten()) podemos resolver el problema de cumplimentar el texto de forma sencilla y breve. Observa que utilizamos un bucle For sobre la base de la variable Conta y recurriendo a la asignación de los contenidos de la matriz, y de forma sucesiva, a la variable sVar. Para ello utilizamos Conta ahora como identificador del valor de posición de la matriz mConten (sVar = mConten(Conta)) (11).
- Este bucle contiene la llamada a la subrutina (script auxiliar) a la que damos como valores paramétricos las dos variables asociadas al desarrollo del buche: InterTextoEnPos(sVar,Conta). La comprensión de este modo de proceder requiera comprender, a su vez, dicho script.
Dim oMarca As Object
oMarca = ThisComponent.getBookmarks().getByName("Marca"+CStr(i))
oMarca.getAnchor.setString(sTexto)
Esta subrutina InterTextoEnPos() recibe dos parámetros (sTexto As String, i As Integer) que se asocian a los parámetros especificados en el bucle final del script principal en la llamada a la propia subrutina (InterTextoEnPos(sVar,Conta)).
sTexto -> sVar
Conta -> i
Además requiere una variable objeto (oMarca) que es la que cumple la doble tarea de recibir como contenido cada uno de los marcadores del texto...
oMarca = ThisComponent.getBookmarks().getByName("Marca"+CStr(i))
... y pasar los datos a las posiciones establecidas mediante los marcadores
oMarca.getAnchor.setString(sTexto)
Si en esta segunda tareas la función setString() es clave, en la primera lo es la forma en que se expresa el parámetro de la función getByName("Marca"+CStr(i)) Es gracias a la expresión "Marca"+CStr(i) que podemos acceder no a un marcador concreto, sino al conjunto de los marcadores (12). El bucle For que empleamos en el script principal y la asociación establecida entre Conta -> i hacen posible este recorrido y su buen funcionamiento. De establecer el contenido concreto en cada posición (marcador) se encarga la asociación entre los dos primeros parámetros de la subrutina y su llamada desde el bucle, esto es: sTexto -> sVar (13)
Aunque esta entrada se ha alargado más de lo que podría parecer conveniente, creo que el resultado es satisfactorio, ya que me ha permitido explicar con detalle el funcionamiento del algoritmo. Dada la frecuencia con la que debemos trabajar con documentos-modelo de uso prescriptivo u obligado, lo aquí expuesto no permitirá automatizar la elaboración de este tipo de soportes documentales. Incluso el código generado se puede considerar a modo de plantilla para afrontar necesidades reales. Es necesario, eso sí, implementar un procedimiento funcional de interface, así como trabajar con más detalle cómo elaborar textos complejos como los asociados a los componentes 11 y 12 de la matriz. Pero ambas cuestiones ya han sido abordadas en las dos entradas que preceden a ésta en el esquema de contenidos que puedes encontrar en Usos. A ellas te remito.
NOTAS
(2) De forma análoga podemos hacerlo respecto a las páginas y las líneas, así como en otros desplazamientos. Te aconsejo que crees una colección de macros simples específicamente pensados para dar respuesta a este objetivo para usarlas desde los script cuando sean necesarias. Posiblemente no sea de forma frecuente, porque, salvo situaciones excepcionales, siempre que sea posible es preferible generar el texto directamente mediante código, como ya dije.
(3) Para la instrucción de escritura de texto en OOo Basic [ver aquí]
(12) Es la combinación del bucle For que empleamos en el script principal y la asociación establecida entre Conta -> i los que hacen posible este recorrido y su buen funcionamiento. De no ser de este modo, necesitaríamos generar en la subrutina tantas líneas de código como marcadores hubiéramos creado.
(13) Además de otras cosas, la sincronización entre la matriz mConten() y la colección de marcadores, incluyendo la forma simplificada en que se expresan es resultado de un proceso previo de planificación. Esta fase es fundamental y saltársela puede suponer errores en el funcionamiento, trabajo innecesario y pérdidas de tiempo.





No hay comentarios:
Publicar un comentario
Comenta esta entrada