lunes, 16 de diciembre de 2024

Textos. Procedimientos

Modelo básico de DocAp (b)


Hay una diferencia entre este segundo modelo y [el anterior] en la fase de preparación, además de la que deriva de la forma diferente de manejar el servicio Writer: dado que ahora trabajamos con un documento creado (frente al documento en blanco del modelo anterior), no sólo tenemos que acceder a dicho documento (y no sólo activar el servicio Writer), sino que también tenemos que tener preparado previamente ese documento. Todo esto supone que este segundo modelo de docap resulte sensiblemente más complejo que el anterior (1).


Para empezar crearé el soporte Calc y el documento Writer, que ubicaré en un subdirectorio de fácil acceso (2). En mi caso creo un subdirectorio en USB-unidad D, al que llamo Acta (3) e incluyo en ella dos documentos: GestorActa (Calc) y ActaModelo (Writer).

El segundo paso consiste en crear el formulario en GestorActa y asociar los controles a las celdas, igual que en el docap-modelo anterior. También creo los módulos Modulo1 Modulo2 en el IDE.

Aunque puedo seguir trabajando en el script Main con las instrucciones que darán acceso a las celdas que contienen los datos, opto por trabajar sobre el documento ActaModelo, formateándolo y generando las posiciones de los marcadores.


Sobre este documento, y a modo de ejemplo, posiciono tres marcadores (Insertar | Marcador) (4) que llamados respectivamente mcdAsisten, mcdTemas y mcdFecha en las posiciones que corresponde. Finalizo la preparación del documento guardándolo y creando una copia de seguridad (5).

Una vez que hemos creado el documento Writer  volvemos a trabajar sobre GestorActa para generar el código OOo Basic. En primer lugar creo el código de acceso al contenido aportado por el usuario mediante el formulario (6), lo que incluye la declaración de variables y matrices (algunas las explicaré más adelante):

'Variables
Dim oHoja As Object, oCelda As Object
Dim mDatos() As String, mCeldas() As String, mMarcadores() As String
Dim n As Integer, i As Integer
Dim sAsisten As String

'Acceso a datos

oHoja = ThisComponent.getSheets().getByName("Hoja1")

n = 5
ReDim mDatos(n)

mCeldas= Array("I1","I2","I3","I4","I5","I6")

mMarcadores() = Array("mcdAsisten","mcdTemas","mcdFecha")

For i = 0 To UBound(mDatos())
oCelda = oHoja.getCellRangeByName(mCeldas(i))
mDatos(i) = oCelda.getString()
Next

Primero accedo a la Hoja1 del documento Calc (oHoja = ThisComponent.getSheets().getByName("Hoja1")) y después de redimensionar la matriz mDatos() (ReDim mDatos(n)) en función del número de elementos de la lista (n = 5), cargo el contenido en dicha matriz mediante un ciclo For (For i = 0 To UBound(mDatos())).

oCelda = oHoja.getCellRangeByName(mCeldas(i))
mDatos(i) = oCelda.getString()

Previamente he dado contenido a la matriz mCeldas() (mCeldas= Array("I1","I2","I3","I4","I5","I6")) para facilitar el funcionamiento del bucle (oCelda = oHoja.getCellRangeByName(mCeldas(i))). De este modo los datos contenidos en las citadas celdas pasan a la matriz mDatos() y quedan disponibles para su manejo desde código (mDatos(i) = oCelda.getString()).

Además adelanto trabajo dando contenido a la matriz mMarcadores() (mMarcadores() = Array("mcdAsisten","mcdTemas","mcdFecha")) que necesitaré más adelante.

Dado que en este docap también inciden los mismos condicionantes que en el docap anterior, tampoco aquí me detendré en desarrollar la fase procesamiento más allá del mínimo que exige la diferenciación de los tres campos que identificados por asociación con los tres marcadores implementados en el documento. Este mínimo se concreta en el bucle que asigna a la variable sAsisten la concatenación de los cuatro primeros componentes de la matriz mDatos() (sAsisten = sAsisten & Chr(13) & mDatos(i)) que corresponden a los posibles asistentes a la reunión:

For i = 0 To 3
If mDatos(i) = "" Then
sAsisten = sAsisten
Else
sAsisten = sAsisten & Chr(13) & mDatos(i)
End If
Next

En él, el condicional anidado If (If mDatos(i) = "" Then) impide que se generen saltos de línea en caso de ausencia de alguno de los cuatro potenciales asistentes (Asisten = sAsisten). 

Además incluyo en Main el código necesario para acceder al documento-modelo...

Dim sRutaAcceso As String, sRutaGuardar As String
Dim mOpciones(1) As New "com.sun.star.beans.PropertyValue"
mOpciones(0).Name = "AsTemplate"
mOpciones(0).Value = True

Dim oDocModelo As Object
sRutaAcceso = ConvertToUrl("D:/ACTA/ActaModelo.odt")
oDocModelo = StarDesktop.loadComponentFromURL( sRutaAcceso, "_blank", 0, mOpciones())

... según el procedimiento ya explicado en [esta entrada]. Como peculiaridad, en este caso abrimos dicho documento en modo plantilla...

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

... lo que facilita mantener sin modificar el propio documento-modelo, evitando así posibles errores en su manejo, como puede ser el borrado accidental de los marcadores o la sustitución de dicho documento por el que deriva como resultado del docap debida a una grabación descuidada del documento resultante.

Finalizamos Main con la llamada a la subrutina de escritura del acta, tantas veces como marcadores están disponible.

Acta(oDocModelo,sAsisten,mMarcadores(0))
Acta(oDocModelo,mDatos(4),mMarcadores(1))
Acta(oDocModelo,mDatos(5),mMarcadores(2))

Esta subrutina se limita a ejecutar la escritura del contenido pasado mediante el parámetro Texto (por ejemplo, sAsisten), en la posición que indica el parámetro Marcador (por ejemplo mMarcadores(0)), habiendo previamente accedido al documento abierto (oDocModelo = StarDesktop.loadComponentFromURL( sRutaAcceso, "_blank", 0, mOpciones())), para lo cual debemos pasar también como parámetro (Modelo As Object) dicho modelo (oDocModelo) (7)

Sub Acta(Modelo As Object,Texto As String,Marcador As String)
Dim oMarcador As Object
oMarcador = Modelo.getBookmarks().getByName(Marcador)
oMarcador.getAnchor.setString(Texto)
End Sub

Documento. Desde estos enlaces puedes descargar [GestorActa] y [ActaModelo]. Recuerda guardarlos en una unidad externa (D) dentro de un subdirectorio (ACTA). Si optas por otra ubicación deberás modificar la instrucción sRutaAcceso = ConvertToUrl("D:/ACTA/ActaModelo.odt") para ajustarla a la nueva ubicación.

NOTAS

(1) De lo que se deriva una recomendación: si no es estrictamente necesario, siempre será preferible trabajar con el modelo de docap más simple.
(2) Aunque es opcional, yo te recomiendo trabajar en estos casos con un soporte de almacenamiento externo. Por motivo de seguridad y confidencialidad así lo hago yo en este ejemplo, dado que quedará publicado en la nube. De este modo también te será más sencillo replicar el funcionamiento de este docap: es suficiente con seguir los mismos pasos que te explico en el texto.
(3) Como puede comprender, en este caso no es posible crear un docap totalmente independiente de un objetivo concreto de trabajo, aunque éste puede ser el que tu necesites. Por ello deberemos trabajar sobre un supuesto. Este supuesto es, en este caso, la cumplimentación de determinados apartados de un acta, por ejemplo de la UO.
(4) En [esta entrada] se explica con más detalle cómo proceder. 
(5) Esta copia garantiza disponer del documento tal y como fue creado, pensando en que pueda surgir alguna dificultad en el proceso, dada la sensibilidad de los marcadores al borrado accidental. Después veremos que nos conviene trabajar con una plantilla del documento para que el original siempre esté disponible.
(6) El mismo código que creamos en el docap-modelo anterior, como podrás comprobar.
(7) Esta no es la única forma de desarrollar ambos subprocesos, pero tiene la ventaja de diferenciar la fase de acceso al documento-modelo de la escritura del contenido propiamente dicha. Otra opción podría haber sido diferenciar la fase de acceso y manejo de los datos (Main) de la de acceso al documento y escritura. Una tercera fórmula sería diferenciar esa subrutina en dos partes: la primera se encargaría de acceder al documento-modelo y la segunda de escribir en él.

No hay comentarios:

Publicar un comentario

Comenta esta entrada