lunes, 16 de diciembre de 2024

Documentos. Modelo básico

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 (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 una unidad 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 desde el IDE para contener los script que crearé más tarde.

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-modelo, formateándolo y generando las posiciones de los marcadores. Este podría ser el resultado:


Sobre este documento, y a modo de ejemplo, posiciono tres marcadores (Insertar | Marcador) (4) que llamados respectivamente mcdAsisten, mcdTemas y mcdFecha donde se infiere por su nombre. Finalizo la preparación del documento guardándolo y creando una copia de seguridad (5).

Una vez que hemos creado el documento-modelo,  volvemos a trabajar sobre GestorActa para generar el código OOo Basic. En primer lugar, desarrollo el procedimiento de acceso al contenido introducido por el usuario mediante el formulario (6). Incluyo 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())) según el procedimiento ya conocido.

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 el 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] en la que se trata este tema con más detalle. Como característica específica decir que 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 el manejo de dicho documento, como puede ser el borrado accidental de los marcadores o la sustitución de dicho documento por el que deriva del uso del docap, a consecuencia de 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())), paro 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 sus enlaces puedes descargar [GestorActa] y [ActaModelo]. Recuerda que debes 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. No por ello deja doporte para el objetivo de semi-automatizar la cumplimentación del acta.
(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