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

jueves, 16 de mayo de 2024

OOo Basic. Interface.

Formularios (b). Writer (1)

Analizo ahora el acceso a los controles de uso más frecuente en un formulario desde OOo Basic. Esta entrada complementa, pues, una [entrada anterior] en la que se analizó el esquema general de trabajo con formularios desde un script.




Los controles de uso más frecuente en un formulario son cuatro (2): Caja de texto, Cuadro de lista, Botón de opción y Casilla (de verificación). Los dos primeros para facilitar la entrada de datos y los dos últimos para facilitar la selección de opciones.

Como ya sabemos, todos los controles de formulario deben ser implementados en el documento-soporte (ver [aquí] en los primeros párrafos de la entrada sobre procedimientos de implementación de Formulario), pero además es posible (y generalmente necesario) conformar la apariencia y forma de funcionamiento de cada uno de ello de forma específica. Para ello deberemos acceder a Propiedades del control, opción disponible a partir de la ventana emergente que activamos mediante Selección del control -> Clic derecho sobre el control seleccionado. Una vez dentro de este menú de opciones, podremos configurar nuestro control del modo que deseemos.

El control Cuadro de texto posiblemente sea el control más sencillo ya que se comporta funcionalmente como un InputBox(). No obstante presenta características plenas como Control de formulario (por lo que debe ser tratado como tal) y posibilidades de uso diferentes (y mucho más ricas) que las que ofrece InputBox() (3). El modo de acceso a su contenido sigue el procedimiento descrito en la segunda parte de [esta entrada], a la que remito para no repetirme aquí. Me limito ahora a explicar cómo podemos acceder al contenido textual propio de Cuadro de texto.

Dim oTxtNombre As Object
Dim sNombre As String
Dim mDatos(6) As String

oTxtNombre = oForm.getByName("txtAlNombre")
sNombre = oTxtNombre.Text
mDatos(0) = oTxtNombre.Text
  • Definido y caracterizado el funcionamiento de Cuadro de texto desde Propiedades del control, queda identificado por su Nombre (una de las opciones disponibles en Propiedades del control); por ejemplo "txtAlNombre" . Este nombre nos facilita una de las formas de acceso al control (oTxtNombre = oForm.getByName("txtAlNombre"))
  • Previamente deberemos haber creado una variable tipo Object para capturar el objeto control deseado (Dim oTxtNombre As Object), ya que necesitamos esta variable para hacer posible el acceso al control y a su contenido.
  • Tras acceder al control según la sintaxis ya expuesta (oTxtNombre = oForm.getByName("txtAlNombre")), la segunda fase del procedimiento consiste en acceder al contenido, necesariamente de tipo texto, dada la naturaleza de Cuadro de texto. Esto nos obliga a declarar previamente una variable tipo String o una matriz del mismo tipo (Dim sNombre As StringDim mDatos(6) As String en nuestro caso) (4), a la que  asignar el contenido del control.
  • Esta asignación se realiza mediante la siguiente instrucción. En ella oTxtNombre contiene el objeto Cuadro de texto y a través del objeto accedemos a su atributo Text, que es el que contiene a su vez el texto que el usuario ha introducido en Cuadro de texto, cadena alfanumérica que pasa a ser referenciada en la variable sNombre
sNombre = oTxtNombre.Text

El control Cuadro de lista se diferencia del control anterior por sustituir la entrada de texto de escritura libre por una entrada de valores, que es el listado de opciones que se presentan a la elección de usuario. Este listado puede crearse directamente desde Propiedades del control -> General -> Entradas de la lista o desde Propiedades del control -> Datos -> Tipos de contenido de la lista opción Lista de valores. Esta segunda opción también permite asociar el control a una tabla, una consulta o a otras opciones.

El acceso al control Cuadro de lista es igual que el acceso a Cuadro de texto, pero no así el acceso al contenido (en  este caso) seleccionado (la entrada del Cuadro de lista por el que opta el usuario). Observa el siguiente segmento del script:

Dim oCurso As Object, oCursoVista As Object
Dim sCurso As String
Dim mDatos(6) As String

oCurso =  oForm.getByName("curso")
oCursoVista = ThisComponent.getCurrentController.getControl( oCurso )
sCurso = oCursoVista.getSelectedItem()
mDatos(2) = oCursoVista.getSelectedItem()
  •  Para acceder al Cuadro de lista necesitamos dos variables Object
    • La primera (oCurso) nos permite acceder al control como tal (oCurso =  oForm.getByName("curso"))
    • y la segunda (oCursoVista) a su listado de opciones (oCursoVista = ThisComponent.getCurrentController.getControl( oCurso ))
  • Posteriormente asignamos la opción seleccionada (método getSelectedItem()) a una variable String, previamente declarada (Dim sCurso As String) haciendo uso de ese método (sCurso = oCursoVista.getSelectedItem()) (5)

El control Botón de opción es en realidad un conjunto (al menos dos) de controles que se vinculan entre sí, ofreciendo al usuario la posibilidad de elegir entre uno de ellos (el resto se descartan), por lo que presenta un comportamiento similar al del Cuadro de lista (en el que el usuario debe optar por una de las opciones que se le presentan), aunque en su apariencia formal son muy diferentes.

También lo son en el modo en que se accede a la opción seleccionada, requiriendo Botón de opción un manejo similar al que hacemos del valor que devuelve la función MsgBox() (6).

El acceso al "contenido" en Botón de opción es en realidad la captura de su pulsación por el usuario (oBtn1 = oFormulario.getByName("btn1")), y se requieren tantas variables como botones de opción contenga nuestro conjunto de opciones. Por ejemplo, en este caso, sólo dos (Dim oBtn1 As Object, oBtn2 As Object): el primero para capturar la pulsación del botón btn1 (oBtn1 = oFormulario.getByName("btn1")) y el segundo para capturar la pulsación del botón btn2 (oBtn2 = oFormulario.getByName("btn2"))

 


el acceso a los controles casilla botón presenta un grado de dificultad intermedio entre los dos anteriores y más similitud entre sí de la que aparenta. Se diferencian, eso sí, en el modo en que se utilizan en un formulario incrustado en Calc en el que estos controles se asocian a celdas, pero no tanto en caso de acceso directo (cuestión esta aun no tratada).

De hecho en Writer a los datos de casillas y botones se accede del mismo modo mediante OOo Basic, esto es, mediante el valor que adopta la función state(), que permite identificar si el botón o la casilla han sido seleccionados (1) o no (0) (valores booleanos).

Pero el funcionamiento de ambos controles en el funcionamiento dentro del formulario es diferentes: mientras que los botones se presentan claramente asociados y vinculados, las casillas son y tienen un funcionamiento independiente (unas de otras).

Documento
Este documento no tiene más función que la de ejemplificar el funcionamiento de las casillas y botones y de mostrar el modo de acceder a su contenidos mediante script OOo Basic.

NOTAS 

(1) Al igual que la [entrada que la precede], ésta sustituye e incluye el contenido de otras dos publicadas el día 8/07/2023. En ambas se analizaba el funcionamiento de un formulario creado sobre Writer y usado desde un script OOo Basic y el modo de acceso al contenido de sus controles.

(2) LibreOffice cuenta con un listado de controles de formulario mucho más amplio, pero estos cuatro cubren la mayoría de las necesidades que buscamos satisfacer con un formulario, de ahí que sean los de uso más frecuente y, por tanto, los que más interés tienen para la creación de un docap basado en Formulario.

(3El manejo de Cuadro de texto requiere el mismo procedimiento de acceso que cualquier otro control de formulario, por lo que no es factible trabajar con él como con InputBox(). En términos de funcionalidad, Cuadro de texto permite opciones de configuración que no están disponibles en InputBox() (que en esto es muy limitado); destaco por su utilidad la posibilidad de configurarlo multirrenglón, además de los formatos de texto (incluido tamaño de letra). Estas opciones de configuración permiten un uso muchos más amigable y funcional como interface, si bien requiere un trabajo previo de configuración desde Propiedades del control.

(4) La doble asignación a variable + matriz es innecesaria, aunque aquí la empleamos por motivos didácticos. En la explicación que sigue a esta nota en el cuerpo de la entrada sólo se recoge una de las dos alternativas de asignación, pero en el script se emplean ambas. El uso de la doble asignación podría estar justificada en algunos casos, pero entonces sería más adecuado que la propia variable se asignara al elemento x de la matriz (sNombre = oTxtNombre.Text -> mDatos(0) sNombre).

(5) Recuerda lo dicho en (4) respecto al tratamiento de la matriz mDatos(). Omito ahora comentar esta parte del script. Al contrario que en Cuadro de texto, en el que el acceso al control requería el uso de la propiedad Text del control (sNombre = oTxtNombre.Text), ahora el acceso a la opción seleccionada por el usuario se hace invocando los métodos .getCurrentController.getControl( oCurso) del objeto Cuadro de lista. Esto supone un procedimiento mucho más complejo que en caso del control Cuadro de texto o el control Campo de fecha, que sigue el mismo procedimiento: 

oFecha = oForm.getByName("fecha")
sFecha = oFecha.Text

(6) También en este caso deberemos tratar el valor devuelto mediante una estructura decisional (condicional If)

OOo Basic. Interface.

Formularios (a). Writer. (1)

Además de las formas simples de interface (MsgBox e InputBox), LibreOffice cuenta con otros dos recursos de interface: los formularios y los cuadros de diálogo. Los formularios son medios para facilitar la interacción usuario-programa, empleados fundamentalmente en la fase Input. A diferencia del cuadro de diálogo (en adelante, Diálogo, por brevedad), el formulario se puede emplear tanto como funcionalidad (2como asociado a a un script.


En esta entrada trataré sobre el uso del formulario sobre un documento Writer, aunque es extensible a su uso en otros servicios (Imperss, por ejemplo); posteriormente se analizará el uso del formulario sobre una hoja de cálculo (Hc) Calc. Los formularios de base de datos (Base) quedan fuera de nuestros objetivos.

La forma más básica de usar un formulario en Writer (3) es como medio para facilitar la entrada de información a un documento. Es una forma más elaborada de presentar documentos que contienen tablas como recursos para al entrada (input) de datos: un ejemplo, las carátulas de los documentos prescriptivos de evaluación (4).

Cierto que a nosotros nos interesa ir más allá del uso de Formulario como funcionalidad (esto es: nos interesa utilizarlo como recurso input en un script), pero no podemos olvidar que el primer paso va a ser necesariamente crear el formulario en y sobre el documento-base; de ahí la importancia que tiene dominar este prerrequisito; algo que no podemos dar por sentado, ya que como funcionalidad no está directamente disponible y en la práctica, en los documentos de trabajo (tanto los prescriptivos como en los que nosotros mismos creamos) predomina el uso de tablas sobre los formularios como medio de recogida y presentación de la información.

Además los medios para crear un formulario no tienen por qué estar disponibles por defecto, así que pueden quedar ocultos al usuario medio, siendo esta una de las causas de su escaso uso. Por ello, lo primero que tenemos que saber es cómo activar las opciones Formulario: Ver|Barra de herramientas|Diseño de formularios (muestra los controles del diseño de formularios) y Ver|Barra de herramientas|Controles de formularios (muestra la barra de herramientas que nos permite acceder a los diferentes campos de que puede constar un formulario). A partir de aquí lo único que debemos hacer es seleccionar el icono Modo diseño... (5)


... para entrar en la capa dibujo del documento y habilitar el acceso a los controles de formulario, seleccionar el icono del control que deseemos utilizar y posicionarlo en el documento.

Una vez creado el formulario, para crear un script que facilite su uso como recurso Input en un script, necesitamos acceder al IDE y, desde éste, trabajar en el script mediante el lenguaje OOo Basic. En esto centraremos el contenido de esta entrada.

Un script que nos permita acceder a un formulario creado en un documento y a sus controles se divide en tres fases sucesivas: 

  • En la primera accederemos al formulario creado en el documento.

Dim oDocumento As Object, oCapaDib As Object, oForms As Object, oForm As Object

oDocumento = ThisComponent
oCapaDib = oDocumento.getDrawPage()
oForms = oCapaDib.getForms()
oForm = oForms.getByName("frmActua")

Observa que todas estas variables son de tipo Object, lo que significa que, en esta fase del procedimiento estamos accediendo a los objetos que están o pueden estar en la base del soporte (del documento Writer) según la lógica de su código como programa.

Observa también que, siguiendo esa lógica, el formulario se ubica (es accesible) desde la capa gráfica del documento (DrawPage()), de la cual es uno de sus posibles componentes. Esta capa gráfica no es accesible desde la capa en la que nos situamos con el cursor cuando escribimos. (6)

  • En la segunda fase nos centramos en acceder a los controles del formulario y a su contenido.

Dim oTxtNombre As Object

Dim mDatos(6) As String
Dim i As Integer
 
oTxtNombre = oForm.getByName("txtAlNombre")
mDatos(0) = oTxtNombre.Text

 Observa que este subproceso se desarrolla en dos fases:

    • En la primera fase accedo a los controles, que son también objetos, de ahí que las variables que facilitan este acceso se declaran de tipo Object (v.g. Dim oTxtNombre As Object). El acceso se concreta mediante esta expresión: oTxtNombre = oForm.getByName("txtAlNombre")
    • En la segunda fase accedo al contenido de los controles, que como son de tipo texto, asocio a una matriz String (Dim mDatos(6) As String). La sintaxis de esta instrucción para acceder a un control simple de texto es la siguiente: mDatos(0) = oTxtNombre.Text. (7)
  •  Y finalmente, en la tercera, trabajaremos con ese contenido mediante los medios y procedimientos que mejor se ajusten al objetivo del script. Por ejemplo, y para simplificar, mostrar el contenido de los controles en pantalla mediante MsgBox, haciendo uso de un bucle para recorrer la matriz (8)

For i = 0 To 5
MsgBox mDatos(i)
Next

Documento. Te doy acceso al documento que contiene el formulario y el código desde el enlace siguiente:

Recuerda que debes descargarlo y abrirlo con LibreOffice y acceder al script desde el IDE (Herramientas/Macros/Editar macros)

NOTAS

(1) Esta entrada sustituye e incluye el contenido de otras dos publicadas el día 8/07/2023. En ambas se analizaba el funcionamiento de un formulario creado sobre Writer, empleado como interface Input dentro de un script OOo Basic.

(2) Por funcionalidad entiendo cualquier recurso que puede ser desarrollado desde la interface general del servicio (Writer, por ejemplo), sin necesidad de acceder al IDE. En Writer los formularios se crean en la capa "Dibujo" del documento directamente desde éste. Para crear un Diálogo es necesario acceder al IDE y crearlo específicamente de forma directa. Desde esta perspectiva el formulario es un objeto más accesible y simple que un diálogo.

(3) Y en el resto de los servicios, a excepción de Base, que tiene su propia lógica,  al ser dependiente necesariamente de los campos de la base de datos.

(4) Recuerda que puedes convertir un documento Writer en un pdf, incluso manteniendo la funcionalidad del formulario y sus controles. Esto permite crear formularios en pdf para que el usuario los cumplimente sin necesidad de tener instalado LibreOffice. Esto da mucha más versatilidad al documento de recogida de datos.

(5Este procedimiento implica activar el icono de la barra Controles de formulario. Este mismo icono está también disponible en la barra del Diseño de formulario. Activarlo también supone acceder a la definición del formulario y a otras utilidades, incluyendo la introducción de campos (comando Añadir campo), que también activa la barra Controles de formulario.

(6) El comportamiento del formulario en un soporte Calc es mucho más simple, ya que permite que (algunos) de sus controles se asocien directamente con las celdas de la hoja. Esto facilita el trabajo con formularios (mejor dicho, con los controles de formulario) en Calc.

(7) En realidad esta es una simplificación del sistema de acceso a los datos de los controles, tomando como referencia uno de ellos (Cuadro de texto), que es uno de los más simples (similar a un InputBox(), aunque más complejo. Queda para otra entrada la explicación de cómo emplear y acceder al contenido de diferentes controles del formulario.

(8) Esta es una de las opciones posible, no tanto de trabajo como de ejemplificación y constatación del funcionamiento del script. En un uso práctico deberíamos crear un procedimiento de trabajo que incluye el procesamiento de los datos y su uso para resolver un problema, como, por ejemplo, la creación de un texto en el que se analicen los resultados obtenidos en función de la fase de procesamiento. Pero lo que ahora nos interesa es constatar que hemos accedido a los datos del formulario, base para el desarrollo posterior del script.

miércoles, 8 de mayo de 2024

Recursos. Dictamen.

Dictamen 2024. Una propuesta de automatización.

Comenté en [esta entrada] el documento-modelo de informe de la Consejería de Educación asturiana de 2024 y [en esta otra] hice algunas propuestas (1) para su adaptación y uso por parte de los SEO. Además en [Usos] he estado desarrollando la explicación de diferentes estrategias para complementar los datos solicitados en las tablas tanto del informe como del dictamen (2), pero aun no he expuesto una propuesta de docap para automatizar la cumplimentación del modelo de dictamen, así que ahora toca.


Creo haber comentado ya algunas de las novedades del presente documento, que son menos que las que presenta el modelo de informe, aunque algunas hay y no necesariamente favorables para los SEO, pero en general se trata de un documento conservador, que se mantiene en la misma línea que los que le han precedido y que, al igual que aquellos, carece de herramientas para facilitar el trabajo de los SEO.

Mi idea es presentar aquí un docap que facilite el trabajo con el documento, empleando diferentes procedimientos de automatización de su cumplimentación. El resultado queda disponible como enlace al final de esta entrada.

El dictamen de escolarización es, en lo formal, es un formulario basado en tablas, claramente diseñado para ser cumplimentado desde el procesador de texto. dado que es un documento de uso obligado, no da lugar a propuestas de mejora, así que poco hay que decir al respecto, salvo constatar las múltiples posibilidades que presenta en lo que a mejoras se refiere. Y estoy pensando únicamente en las de carácter formal y de uso del documento. Del resto (el contenido y la carga conceptual que conlleva) mejor me mantengo en silencio, por lo que me centraré en explicar el funcionamiento del docap.

El enfoque que desarrollo en este docap es diferente a propuestas anteriores sobre otros modelos documentales similares (ver [aquí] una propuesta anterior), y puede que incluso menos ambiciosa, ya que aquella era una propuesta que implicaba el uso de un docap complejo, que involucraba y relacionaba varios documentos, y esta se limita a un docap simple, basado en un único documento (Writer). No obstante lo que aquí presento supone una mejora significativa en lo que al desarrollo del código se refiere, por lo que no creo que se trate de una simplificación de procedimientos que redunde negativamente en la funcionalidad de uso, más bien al contrario.

Este modelo de docap no permite unificar el proceso de creación de los diferentes documento prescriptivos (como sí sucede en el docap que se cita antes), pero gana en simplicidad de uso y supone una mejora importante del código.

Empezando por la forma de uso, es suficiente con hacer clic en el botón de comando (Crear DE) para que automáticamente se desarrolle la secuencia de pasos que se definen en el código, obteniéndose al final y como resultado, el documento cumplimentado y listo para ser archivado para su posterior manejo según las prescripciones de la Consejería, incluyendo su conversión el formato pdf (proceso que hay que realizar "manualmente" usando las funcionalidades de Writer). Lo que toca hacer al OE responsable de su elaboración es ir introduciendo los datos que se le solicitan mediante funciones InputBox() y MsgBox() (3)

No se contempla cumplimentar el anexo 1 ya que que su elaboración compete al ER (4y no al EOE del sector, por lo que, en la práctica, dicho anexo es tratado como un documento independiente del dictamen, aunque se incluya en él.

Se centra en el proceso de Nuevas Escolarizaciones (5), por lo que determinados campos son obviados, ya que no corresponden precisamente por su especificidad o cuyo contenido está ya predefinido por este mismo proceso. La consecuencia es que el contenido de determinados campos se asigna directamente en el script o no se tiene en cuenta.  

Como cabe esperar, por motivos de confidencialidad, cuando en el código se incluyen datos personales (alumnado, familias, OE), éstos son inventados.

Comento a continuación la estructura de script del docap y su funcionamiento básico.

Consta de 15 script que se distribuyen en 3 módulos:
  • Principal, que contiene el script principal (Carátula)
  • Auxiliares, que contiene las subrutinas y funciones que permiten el desarrollo de los procedimientos requeridos por el script principal
  • Matrices, que contiene las funciones que permiten la elección de los contenidos de los campos de selección (6)
El funcionamiento interno del algoritmo se basa en la llamada a las subrutinas y funciones desde el script principal,  facilitando así el funcionamiento modular del conjunto. En la base de este funcionamiento está el principio de linealidad o sucesión, de modo que el proceso se va desarrollando según el desarrollo del propio documento, tal y como éste se visualiza.

El uso de una matriz general de asignación de contenido (mDatos ()) permite la cumplimentación de los campos mediante un bucle (For) que, a su vez llama a la subrutina de escritura (Posicionamiento). Estos campos se identifican en el documento mediante marcadores, por lo que script y documento quedan relacionados mediante esos marcadores que han sido ubicados en el documento previamente (7)

For i = 0 To 33:
sVar = mDatos(i)
Posicionamiento(sVar,"d",i)
Next
La correspondencia de los numerales de los marcadores y de la matriz facilitan la correspondencia entre ambos y la variable contador (i), garantizando la correcta ubicación del contenido de la matriz en las posiciones que indican los marcadores.

Mediante [este enlace] puedes acceder al docap. Se debe descargar, guardar donde se desee y abrir con LO-Writer activando macros. Se recomienda crear antes manipular el documento y sus script te recomiendo crear una copia del mismo que sirva de copia de seguridad. Así se evita que cualquier alteración del original obligue a realizar una nueva descarga del documento. Es preferible que esa copia de seguridad se haga en formato plantilla y que se trabaje abriendo el documento en esta versión.

NOTAS

(1) En realidad se trata de una serie de tres entradas que se complementan. Aquí la [segunda] y la [tercera].

(2) Se trata de las siguientes indicadas en el apartado Documentos prescriptivos de la sección [Usos]: [campos simples], [campos condicionados], [campos calculados] y [campos de selección]. En la primera de esta serie se habla del docap que se presenta en la actual, dando cumplimiento así a la promesa pendiente.

(3) Me he ahorrado conscientemente (también de las consecuencias negativas de esta decisión) el trabajo de implementar recursos de interface más "vistosos", ya que se trata de una propuesta pensada para que sea  accesible a un orientador interesado en ajustarla a sus propias necesidades. Carece de ambición comercial y no hace concesiones a este enfoque, así que se sacrifica lo "vistoso" (incluso lo amigable) a lo funcional, también en términos de acceso al código y a su posible modificación por el usuario. 

(4) Equipo Regional para la Atención del Alumnado con NEAE. Consejería de Educación del Principado de Asturias.

(5) Proceso cuyo responsable por norma es el equipo de sector y en el que colabora, si así se considera, el ER. El objetivo de este proceso y a la vez programa (para estos SEO) es facilitar la escolarización de los niños y niñas con NEAE (fundamentalmente NEE) en 1º de E. Infantil para el curso siguiente, atendiendo a sus necesidades educativas. La resolución del mismo corresponde a una Comisión de Escolarización. 

(6) Puedes encontrar la explicación de su estructura y funcionamiento en esta entrada ([campos de selección]

(7) Previo a la creación del código se estudia el documento y se determinan las posiciones (campos) que es necesario identificar. Sobre esta base se crea una tabla de tres columnas en las que se enumeran y relacionas los marcadores, los elementos de la matriz (mDatos()) y el contenido. Posteriormente se ubican los marcadores en las posiciones correspondientes, los cuales se enumerar de forma sucesiva mediante un código alfanumérico simple (vg. d0,d1,d2...). Esto permite la posterior correspondencia entre marcadores y elementos de la matriz, de modo sea posible realizar la automatización de la escritura mediante un bucle For, tal y como se explica en el texto.

jueves, 2 de mayo de 2024

Usos. Documentos prescriptivos.

 Tablas. Campos condicionados

Otro tipo de campo frecuente en las tablas del dictamen y del informe es el que denomino aquí campo condicionado. Estos campos se caracterizan por ser dependientes de otro campo con el que se encuentra conceptualmente relacionado.


Veamos primero un ejemplo de este tipo de campos en el dictamen:


Los campos del apartado 5 del dictamen (también los del 6. Recursos de apoyo especializado) son de tipo condicionado, ya que el campo de la columna Sí/No condiciona su correspondiente de la columna Breve descripción: si contestamos en el primero deberemos incluir información en el segundo; en caso contrario el campo asociado quedará vacío (1)

También se presenta este tipo de campos en el modelo de informe, como comprobamos en la captura que sigue:


En este caso se trata de una tabla en la que se registra la presencia vs. ausencia de Medidas de Atención a la Diversidad (MAD). Su funcionamiento es igual al de la tabla anterior (dictamen): si la respuesta al ítem es , se deberá aportar información en el campo asociado de la columna 4. En caso contrario (No) su campo asociado quedará vacío.

Paso ahora a explicar el código necesario. Como ejemplo trabajaré con la tabla 5 del dictamen desarrollando una de las dos opciones, la menos eficiente, por lo que recomiendo una lectura atenta de todo lo que sigue.

Sub DictamenMod2

Dim oMarcador As Object
Dim sAjustesOrganizativosA As String, sAjustesOrganizativosB As String

sAjustesOrganizativosA = InputBox("¿Son necesarios ajustes organizativos y metodológicos?","DICTAMEN. 5. Adapciones que precisa","Sí-No")

 If sAjustesOrganizativosA= "Sí" Then

sAjustesOrganizativosB = InputBox("Describe las medidas organizativas, metodolóogicas y curriculares de acceso que consideras necesario.","DICTAMEN. 5. Adaptaciones que precisa")

ElseIf  sAjustesOrganizativosA= "Sí" Then

 sAjustesOrganizativosB = ""

Else

MsgBox("No has dado respuesta a lo demandado en el campo Ajustes organizativos del aparado 5 del DICTAMEN o la respuesta no se acepta como válida") 

   End If 

oMarcador = ThisComponent.getBookmarks().getByName("mcr0")
oMarcador.getAnchor.setString(sAjustesOrganizativosA)
oMarcador = ThisComponent.getBookmarks().getByName("mcr1")
oMarcador.getAnchor.setString(sAjustesOrganizativosB)

End Sub

  • Necesitamos crear la misma estructura que usamos en el caso de campos simples, incluyendo la creación de marcadores en el documento. 
  • Además de la variable object (oMarcador) que nos permite acceder a los objetos marcador del documento (mcr0 mcr1) Declaramos dos variables de contenido por aspecto: una para el campo condicionante (sAjustesOrganizativosA ) y otra para el condicionado (sAjustesOrganizativosB):
Dim oMarcador As Object
Dim sAjustesOrganizativosA As String, sAjustesOrganizativosB As String
  • Dar contenido a la variable condicionante se ajusta al modelo de campo básico, por lo que se le puede tratar mediante la misma fórmula...
sAjustesOrganizativosA = InputBox("¿Son necesarios ajustes organizativos y metodológicos?","DICTAMEN. 5. Adapciones que precisa","Sí-No")

... pero esto genera un posible error por omisión (respuesta vacía) o por separarse (en forma o en contenido) de las dos únicas opciones válidas (Sí/No). Para controlar estos posibles errores se pueden usar diferentes opciones y aunque estos errores sean excepcionales, su solución no es simple (2).

Otra posible formulación pasa por emplear la función MsgBox(), lo que nos obliga, a su vez una nueva variable Integer (Dim iR as Integer) a asociar a la función MsgBox(). Esta opción evita posibles errores por parte del usuario, aunque obliga también a modificar la estructura condicional, condicionando un script alternativo:

 Dim oMarcador As Object

Dim sAjustesOrganizativosA As String, sAjustesOrganizativosB As String

Dim iR As Integer

iR = MsgBox ("¿Son necesarios ajustes organizativos y metodológicos?",4,"DICTAMEN. 5. Adaptaciones que precisa")

 If iR = 6 Then

sAjustesOrganizativosA = "Sí"
sAjustesOrganizativosB = InputBox("Describe las medidas organizativas, metodolóogicas y curriculares de acceso que consideras necesario.","DICTAMEN. 5. Adapciones que precisa")

Else

 sAjustesOrganizativosA = "No"
 sAjustesOrganizativosB = ""

 End If 

Como podemos comprobar, esta segunda opción simplifica el script y lo hace más resisten a errores de uso (en realidad los reduce a cero), por lo que es preferible al primer script (3).

  • Finalmente, la escritura en el texto se mantiene en la formulación ya explicada en la entrada anterior sobre campos simples, aunque ahora son necesarias dos fases de escritura, que aquí se resuelven meramente por repetición del mismo procedimiento (4):

oMarcador = ThisComponent.getBookmarks().getByName("mcr0")
oMarcador.getAnchor.setString(sAjustesOrganizativosA)
oMarcador = ThisComponent.getBookmarks().getByName("mcr1")
oMarcador.getAnchor.setString(sAjustesOrganizativosB)

NOTAS

(1) Este segundo campo también sería condicionado si el contenido a introducir fuera uno u otro según la respuesta dada al campo condicionante. El ejemplo que presento aquí es la formulación más simple de este tipo de campos, pero también el único que se presenta en el informe y en el dictamen.

(2) En este caso se incluye en InputBox() las dos opciones de respuesta como tercer parámetro de la función; también se incluye la opción Else en el condicional If con un mensaje de advertencia. En el modelo propuesto podría añadirse a continuación de Else volver a interrogar sobre la variable sAjustesOrganizativosA y repetir el análisis que realiza el condicional, dando así una segunda opción. Como se puede ver, la solución no es sencilla, aunque en realidad es posible que estas circunstancias adversas se produzcan excepcionalmente.

(3) En principio, cuando nos encontremos con un campo de dos opciones siempre es preferible utilizar la función MsgBox() en lugar de InputBox(); no ahorraremos posibles errores y obtendremos un código más limpio y funcional. MsgBox() funciona en realidad como Boolean, pero su configuración de respuesta en OOo Basic nos obliga a asociarla a una variable numérica, ya que sus comandos (aquí el parámetro 4, que muestra las opciones - No) devuelven respectivamente los valores 6 y 7.

(4) Cuando el número de variables y marcadores a usar se multiplique será necesario trabajar con una matriz para agrupar las variables y un bucle para el proceso de escritura. Para los objetivos de esta entrada ambos resultan innecesarios. 

miércoles, 1 de mayo de 2024

Usos. Documentos prescriptivos.

Tablas. Campos simples.

Por aclarar: en estas entradas entiendo por documentos prescriptivos aquellos que elabora la Consejería de Educación para uso obligatorio de los SEO. El documento que impone como tal la Consejería cumple la función de documento-modelo (tanto en forma como en formato) y es de uso obligado. No obstante es posible realizar un doble proceso de conversión (Word->Writer->Word) desde LO-Writer, lo que, entremedias, nos permite automatizar (semi-automatizar cuanto menos) su cumplimentación. Aquí es donde entre OOo Basic.



Tanto el dictamen de escolarización como el informe psicopedagógico son dos de esos documentos prescriptivos,  yo diría que los principales, tanto por su uso (muy frecuente) como por su función (fundamental en la intervención de los SEO). 

Además añaden a la complejidad que conlleva la evaluación psicopedagógica el tener que ajustarse en lo formal al propio documento y al formato que impone. Sería de agradecer que que la Consejería de Educación aportara recursos que facilitaran la cumplimentación de estos documentos, pero no parece que esté en su agenda de prioridades; así que o nos ponemos nosotros manos a la obra o podemos esperar sentados. La IA no tiene mucho que aportar al respecto, al menos de momento (después a lo peor hasta nos arrepentimos de que sí, quien sabe...)

Quejas y suspiros a parte, y salvando que la principal dificultad es la complejidad que supone la evaluación psicopedagógica, sí podemos hacer mucho por simplificar y (semi)automatizar el trabajo, o parte significativa de él. Este es el propósito de esta serie de entradas que inicio con esta, y de otra que publico en [Recursos] (1).

Aquí, en [Usos]me ha parecido conveniente empezar por el trabajo con las tablas, ya que son componentes fundamentales de los documentos. El propio hecho de formar parte de estos documentos "impuestos" por la Consejería nos obliga, a su vez, a desarrollar formas específicas que trabajo, lo que tiene su parte positiva: obligatoriamente también agudiza el ingenio.

Partiré de los modelos de informe y dictamen de 2024 (los últimos publicados, en estos momentos) e iré analizando cada elemento (ítem) que se puede identificar en ellos, en función de la forma en que se deben (y pueden) cumplimentar.

Inicio por el modelo de dictamen por ser el de mayor complejidad en cuanto al uso y tipología de tablas y sólo realizaré propuestas concretas para el documento Informe en caso necesario, esto es: cuando lo visto en el dictamen no sea adecuado.

Lo primero que tienes que tener es el [dictamen-modelo] de la Consejería.

Y para que esta entrada no sea de mera presentación, voy a proponer una forma de trabajar con aquellos campos (ítem) que son más frecuentes y a la vez más sencillos: los llamaremos Item0 y están presentes (y predominan) en un número importante de las tablas que componen el dictamen (y el informe) (2).


A modo de ejemplo, en éstas que son las dos primeras tablas del dictamen (Tabla1 y Tabla2, diríamos) Item1 puede ser identificado en 6 de los 7 campos que contienen, aunque es cierto que algunos de ellos se pueden plantear de forma más compleja (3)

Cierto es, además, que si trabajáramos "manualmente" ambas tablas presentan una diferencia importante: mientras que en la primer es posible realizar los desplazamientos de celda mediante el tabulador, en la segunda nos vemos obligados a posicionarnos "manualmente" al final del identificador del contenido del campo (v.g. NIE). Pero como vamos a trabajar con OOo Basic, si elegimos el  procedimiento adecuado esa diferencia deja de existir.

Se trata de campos que se pueden cumplimentar partiendo del uso de marcadores en el documento (de ello ya hablé en [esta entrada]), estrategia de trabajo de la que hablaré a continuación. Además, los marcadores permiten una forma de trabajo lineal que facilita la combinación de matrices y bucles para el desarrollo del docap (sobre ello hablo en [esta entrada]). Describo a continuación el proceso a seguir:
  • En el documento-modelo (dictamen convertido a formato Writer) me posiciono en el punto en el que deseo introducir el dato, por ejemplo, Tabla2, tras Nombre y apellidos (4)
  • Sitúo el marcador (Insertar | Marcador) que denomino, por ejemplo, mcr4.
  • Dando por creado Module1 desde el IDE con lo que esto supone, creo el script (5)
    • Declaro las dos variables necesarias para el funcionamiento del script y los procedimientos de asignación de datos. En el caso de la variable sAlumno utilizando la función InputBox()
El script resultante es el siguiente. Observa que no hacemos referencia en ningún momento a la tabla con la que vamos a trabajar. Usando otros procedimientos (basados en macros, por ejemplo) sí sería necesario, pero el uso de marcadores simplifica mucho la ubicación de texto en cualquier posición del documento susceptible de ser marcado (o lo que es lo mismo, identificado con un marcador):

Sub DictamenMod1

Dim oMarcador As Object
Dim sAlumno As String

sAlumno = InputBox("Nombre y apellidos del alumno/a","DICTAMEN")

oMarcador = ThisComponent.getBookmarks().getByName("mcr4")
oMarcador.getAnchor.setString(sAlumno)

End Sub

  • Mientras que la primera variable (oMarcador) es de tipo objeto, la segunda (sAlumno) es de tipo string. Podría ser de cualquier otro tipo (Integer, por ejemplo), pero el trabajo sobre un texto hace que sea tratada como cadena de texto en lo que al proceso de escritura se refiere.
  • La instrucción sAlumno = InputBox("Nombre y apellidos del alumno/a","DICTAMEN") es de sobra conocida, por lo que no necesita más explicación: como sabemos, permite dotar de contenido a la variable de forma interactiva.
  • Mediante la instrucción de asignación...
oMarcador = ThisComponent.getBookmarks().getByName("mcr4")

 ... estamos accediendo mediante OOo Basic al objeto documento activo (ThisComponent), a la colección de objetos marcador (.getBookmarks()) y al marcador identificado por su nombre (.getByName("mcr4")). Para ello, como ya vimos, es necesario que tal objeto haya sido creado previamente en el documento.

  • Finalmente, la instrucción  oMarcador.getAnchor.setString(sAlumno) asigna el texto referenciado en la variable sAlumno (el que previamente haya introducido el usuario mediante InputBox()) en el objeto referenciado por la variable oMarcador, haciendo uso del método .getAnchor y del sub-método o función .setString() asociado al anterior (6)

La repetición de este mismo procedimiento, y su racionalización y simplificación mediante el uso de matrices y bucles, es la base del procedimiento de creación de docap de automatización del dictamen. 

Tendremos ocasión de describir este procedimiento, como ya prometí antes, pero por ahora me limito a proponerte que amplíes este procedimiento a los campos de las tablas del dictamen que consideres susceptibles de ser tratadas de este modo. Unos cuantos campos serán suficientes, ya que la mayoría se podrían resolver de este modo (no todos, como también veremos), pero en algunos de ellos existen alternativas más complejas pero también más funcionales. 

NOTAS

(1) Posiblemente también en Procedimientos y, de ser posible, en Recursos, aunque dependerá de cómo de desarrolle el proceso que ahora inicio.

(2) A Item1 se ajustan la mayoría (en algunas la totalidad) de los campos de 7 de las 19 tablas de que consta el documento. En concreto (y por orden de presentación) las siguientes: tabla 1, tabla 2, tabla 3, tabla 4 y tabla 5, tabla 12 y tabla 18. En este cómputo he incluido las cinco tablas del anexo 1 que corresponde cumplimentar al Equipo Regional (ER).

(3) Más compleja (veremos en qué consiste en otra entrada) y también más simple en algunos casos: Servicios de Orientación y Orientador/a de la Tabla1 bien pueden considerarse como constantes a nivel individual (de cada orientador/a) y figurar como datos del modelo personal de dictamen (y de informe).

(4) Tal vez no sea el campo-tipo ideal, ya que podemos trabajar con otro procedimiento (como veremos en un próxima entrada), pero lo cierto es que también con éste, que es el más simple. Tanto que, incluso incluyendo el uso de marcadores, se acerca mucho en funcionalidad a la que tiene elaborar el documento directamente desde Writer. En realidad esto no es del todo cierto, ya que incluso empleando este procedimiento, crear un docap para automatizar la elaboración del dictamen supone un ahorro de tiempo considerable, mayor cuantos más dictámenes tengamos que hacer.

(5) Estos pasos que aquí se muestran simplificados requieren de sus propios procedimientos. No explicaré cómo trabajar con el IDE para crear las condiciones que requiere la creación de un script por ser un procedimiento sobradamente conocido, ni el requerido para implementar marcadores en un texto puesto que ya traté ese tema en [esta entrada] cuya lectura recomiendo para mayor detalle. El desarrollo del script sí requiere explicación.

(6) Estamos utilizando terminología propia del paradigma de Programación Orientada a Objetos, que es la que se utiliza en Libre Office. Aunque el lenguaje OOo Basic no nos permite crear clases ni objetos, sí trabaja con ellos y con sus métodos y atributos. De ahí que cuente con ese tipo especial de variable de tipo objeto, uno de cuyos ejemplos es nuestra variable oMarcador. De hecho, el trabajo con objetos es fundamental para el desarrollo de script en OOo Basic. Sin ello no podríamos acceder a los documentos ni a los "objetos" que contienen. Tampoco podríamos crear macros.