lunes, 30 de octubre de 2023

OOo Basic. Writer

 Script y subrutinas de escritura

  • Código básico:

oDoc = ThisComponent.CurrentSelection.getByIndex(0).End
oDoc.String = "Texto que se desea escribir"

Script OOo Basic para automatizar la escritura de texto sin usar Grabar macro.

Contiene subrutina y script principal. El script se ha creado para facilitar interface con el usuario mediante InputBox(), pero puede prescindirse de ello sin alterar el funcionamiento del script.

  • Subrutina de composición de varios párrafos (Código)

Contiene subrutina (basada en matriz) y script principal. Ambos emplean una matriz para compartir datos masivos, La subrutina escribe el contenido utilizando un bucle for para automatizar el proceso.

viernes, 27 de octubre de 2023

Funciones.

 Variables, parámetros y argumentos

En las funciones y subrutinas las variables presentan un comportamiento específico que es necesario conocer tanto para entender estas unidades de programación como para diferenciar la una de la otra.


Al igual que un script o una macro, las subrutinas y las funciones suelen contar con variables que permiten asignar los valores o datos necesarios para su correcto funcionamiento. Pero subrutinas y funciones cuentan, además, con al menos una variable con una función específica: facilitar su comunicación con el script. Se trata de la variable (o variables) que se declara dentro del paréntesis con el que se identifica la propia subrutina como tal (y también la función).


En OOo Basic al crear un script (o una macro) es suficiente con identificar el componente y nombrarlo mediante Sub NombreMacro. Además hay que cerrarlo mediante End Sub (1). Pero para crear una subrutina es obligatorio escribir un paréntesis tras el identificador o nombre e incluir dentro un identificador de variable y su tipificación: sub NombreSubrutina(NombreVar As TipoVar)

La subrutina puede contar (o no) con variables declaradas dentro de ella, pero mientras que éstas son denominadas variables sin más, la o las que se declaran dentro del paréntesis son denominadas específicamente parámetros, por lo que el contenido queda identificado como sigue (o cualquier otra formulación, incluyendo varios parámetros):

Sub NombreRutina(IdParametro As TipoVariable)

Dim NombreVar 1As TipoVar, NombreVar2 As TipoVar (Opcionales)

NombreVar2 = NombreVar1 operador IdParametro (Operaciones)

If  NombreVar2 Operador X Then (por ejemplo...)
ProcesoAejecutar1
Else
        ProcesoAejecutar2
End If 

End Sub

Esta denominación (parámetro) lo es desde el punto de vista de la función o subrutina, pero como ésta ha de ser activada (llamada, si se prefiere) desde un script principal, el valor que se pasa equivalente y/o como concreción del parámetro  recibe el nombre de argumento.

Sub ScriptPrincipal

...
NombreRutina(argumento) (llamada a subrutina)
...

End Sub 

También el modo en que se utilizan parámetros y argumentos es diferente en función de que estemos hablando de una subrutina (que ejecuta una acción) o una función (que devuelve un valor), aunque esta diferenciación de nombre es pertinente en Basic, no lo es necesariamente en otros lenguajes (2). Las denominaciones (parámetro(s), argumento(s)) se mantienen, pero las estructuras, su identificación (3) y el modo de usarlas cambian.

Lo que sí es necesario es respetar el orden en que se pasan los argumentos, que debe coincidir con el que se establece en la formulación de la subrutina o función. Este orden es el que permite la correcta asignación referencial. Esto hace que no sea recomendable crear funciones (o subrutinas) con muchos argumentos, ya que resulta fácil cometer errores debidos a alteraciones del orden en que se pasan los datos.

En ciertos casos puede ser conveniente utilizar parámetros opcionales; para ello se declaran como tal en la formulación de la subrutina o función. 

fMiFuncion (param1 As String, param2 As Integer, optional param3 As String)

No obstante este procedimiento obliga a que los parámetros que siguen al declarado opcional, también lo sean, no así los anteriores.

Esos parámetros opciones pueden pasarse desde el script o no, sin que se altere el funcionamiento de la subrutina o función (4). Para detectar si un parámetro opcional ha sido pasado o no se emplea la función IsMissing(), que devuelve True si el argumento no ha sido pasado o False si se ha hecho.

Para finalizar, una aclaración de "estilo": aunque dispongamos de dos denominaciones (parámetro y argumento), cada una con su significado concreto, es frecuente encontrar en la literatura especializada que se usa uno de los dos nombres para denominar ambos. Esto debe entenderse como un ejercicio de simplificación de la expresión o del vocabulario, ya que no altera la comprensión del fenómeno que se está explicando (5).

NOTAS

(1) Algunos programadores utilizan por costumbre  y asociación a las subrutinas el paréntesis al final del nombre, pero lo mantienen vacío (sub NombreMacro())
(2) Por ejemplo en Python se denomina función a ambas, aunque la diferencia de funcionamiento es la misma que en OOo Basic: existen funciones que no devuelven nada (ejecutan una acción) y otras que sí (las que en OOo Basic son funciones propiamente dichas)
(3) Posiblemente ya saber que en OOo Basic las subrutinas no reciben una identificador específico, pero las funciones sí, tanto para iniciarlas como para finalizarlas: Function... End Function.
(4) Si no declaramos un parámetro como opcional y no lo pasamos como argumento se produce un error.
(5) Personalmente prefiero utilizar el término parámetro al de argumento, por lo que será el que emplee cuando no utilice ambos de forma diferenciada. En toco caso, no creo que exista ningún argumento para preferir uno sobre otro cuando no se opta por la precisión terminológica.

martes, 24 de octubre de 2023

OOo Basic. Script

 Subrutinas creadas a partir de macros

Después de la introducción general al tema realizada en una [entrada anterior], disponemos ya de argumentos para tratar con más detalle esta cuestión: cómo transformar una macro simple en una subrutina.




Por recordar brevemente lo dicho en su momento, una subrutina no devuelve un dato o valor (lo que la diferencia de una función), sino que desarrolla una acción. 


La subrutina realiza una acción, momento en el que el control de proceso pasa a ella. Esta imagen representa el proceso, incluyendo esa especie de corte en la ejecución del proceso principal, momento en que entra en acción la subrutina, la cual, una vez finalizado su cometido, devuelve el control a la macro o script principal.

Visto y recordado esto, nos centrarnos ahora en el tema que nos ocupa ahora: ¿ qué procedimiento o procedimientos podemos seguir para transformar una macro en una subrutina?.

Esta pregunta se responde en plural: existen varios procedimientos y diferentes variaciones de cada uno de ellos. Yo me voy a limitar a diferenciar y exponer tres de ellos, los que considero que se ajustan mejor a la macro originaria. Según este criterio serían tres las variaciones fundamentales entre las macros, lo que da origen a tres procedimientos básicos de conversión a subrutina: 
  • Las macros que contienen explicitación de parámetros (matriz nombre-valor argsX(y))
  • Las macros que son susceptibles de ser ejecutadas mediante estructuras cíclicas (for...Next), esto es: de repetir la acción que desarrollan.
  • Y las macros susceptibles a ser tratadas mediante la condicionalidad (If)
Veamos cada una de ellas, empezando por las macros más simples que incluyen parámetros y en las que tomo como ejemplo la macro de posicionamiento [listado numérico] (1): 
  • matriz desglosada clave+valor:
dim args1(0) as new com.sun.star.beans.PropertyValue
	args1(0).Name = "On"
	args1(0).Value = true
  • Orden o instrucción asociada a dispatcher:
dispatcher.executeDispatch(document, ".uno:DefaultNumbering", "", 0, args1())

Es el contenido o valor del componente .Value (en el ejemplo anterior true) el que podemos establecer como variable-parámetro en la creación de la subrutina basada en macros de este tipo, procediendo como sigue:

  • Denominamos la subrutina añadiendo un paréntesis al final de su enunciado
Sub msbIndiceNumerico()

  • Declaro la variable-argumento bOpcion, que es de tipo booleano, como corresponde en función del valor del elemento de la matriz args1(0).Value

Sub msbIndiceNumerico(bOpcion As Boolean)

  • Y sustituyo el valor true asignado en la macro simple original por dicha variable

args2(0).Value = bOpcion

El resultado...

Sub msbIndiceNumerico(bOpcion As Boolean)

dim args1(0) as new com.sun.star.beans.PropertyValue
	 args1(0).Name = "On"
args1(0).Value = bOpcion

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

End Sub

... es una subrutina que puede ser llamada (2) desde una macro o script principal como alternativa a la llamada opcional a dos macros simples: la de aplicación y la de retirada del índice numérico (3).

Una variación del modelo anterior es la que incluye el uso de un bucle en el script desde el que se llama a la subrutina, generando así una secuencia de desarrollo o aplicación de la subrutina. Por ejemplo, podemos avanzar letra por letra (incluyendo los espacios en blanco) seleccionando o no los elementos que se recorren. [Esta subrutina es un ejemplo de ello].

También podemos utilizar este bucle dentro de la subrutina, afectando únicamente a los instrucciones de ejecución (dispatcher), [como en este ejemplo].

sub msbAvanPag(iNumPag As Integer)

Dim i As Integer
For i=0 To iNumPag
dispatcher.executeDispatch(document, ".uno:PageDown", "", 0, Array())
Next

end sub

La tercera forma de crear una subrutina a partir de una macro simple ya vulnera el criterio de macro simple, al menos en alguna de sus formulaciones, pero también puede ser una solución cuando el uso de dos parejas de macros simples sea requerido con cierta frecuencia.

Considero "parejas de macros simples" cuando éstas son complementarias una de la otra, como en el caso que sigue:

sub mcrBajarLinea

dim args1(1) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Count"
args1(0).Value = 1
args1(1).Name = "Select"
args1(1).Value = false
dispatcher.executeDispatch(document, ".uno:GoDown", "", 0, args1())

End Sub

Sub mcrSubirLinea

dim args1(1) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Count"
args1(0).Value = 1
args1(1).Name = "Select"
args1(1).Value = false
dispatcher.executeDispatch(document, ".uno:GoUp", "", 0, args1())

End Sub

Las macros mcrBajarLinea y mcrSubirLinea presentan una doble complementariedad: ambas pueden tener valora interno de args1(1).value true o false (se selecciona o no la línea) y ambas son complementarias entre sí (o subimos o bajamos de línea): uno:GoUp vs. uno:GoDown.

Existen varias formas de crear una subrutina, pero me voy a limitar a dos, que son variaciones sobre el mismo tema. La primera se basa en el uso del condicional If e implica en realidad usar dos ejecutores dispatcher dentro de la misma surutina... 

sub msbLinea(bSelect As Boolean,sMov As String)

dim args1(1) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Count"
args1(0).Value = 1
args1(1).Name = "Select"
args1(1).Value = bSelect
If sMov = "B" Then
dispatcher.executeDispatch(document, ".uno:GoDown", "", 0, args1())
MsgBox "He bajado una linea"
ElseIf sMov = "S" Then
dispatcher.executeDispatch(document, ".uno:GoUp", "", 0, args1())
MsgBox "He subido una línea"
Else
MsgBox "El valor de la variable 'sLinea' no es correcto" 
End If

End Sub
 ... que es llamada desde el script (msbLineaBis(true,"B")) de forma simple (4)

La segunda forma simplifica la formulación de la subrutina...

sub msbLinea(bSelect As Boolean,sMov As String)

dim args1(1) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Count"
args1(0).Value = 1
args1(1).Name = "Select"
args1(1).Value = bSelect
dispatcher.executeDispatch(document, sMov, "", 0, args1())

End Sub

... y pasa la responsabilidad de definir concretamente la instrucción a  ejecutar a la llamada desde el script (msbLineaBis(true,".uno:GoUp")(5)

Te dejo aquí enlace a la [segunda opción], ya que la considero la que mejor se ajusta al principio básico de conversión de macro simple en subrutina.

NOTAS

(1) Existen muchas otras macros simples que presentan esta estructura y que pueden ser convertidas en subrutinas siguiendo este mismo procedimiento. Una de ellas, y en la que su conversión en subrutina es especialmente recomendable, es la macro de escritura (también podemos hacer lo mismo con el script OOo Basic alternativo a la macro). Si ahora propongo esta macro de posicionamiento es precisamente para evitar utilizar siempre el mismo ejemplo, aunque posiblemente sea éste un ejemplo no tan explícito como al que sustituye.

(2) Recuerdo los dos modos de usar la subrutina desde la macro principal:

  • El más simple: incluir el valor deseado en la llamada a la subrutina de la macro (msbIndiceNumerico(true)). Este modo de uso, además de ser la más simple, es el más apropiado cuando la macro o script es a su vez sencillo.
  • Y el modo complejo que recomiendo cuando el script es complejo e interesa controlar los valores que se pasan a las subrutinas y a las funciones, y que consiste en lo siguiente:
    • En esa macro/script declaramos una variable del mismo tipo que la variable-parámetro de la subrutina, por ejemplo, Dim bIndice as Boolean
    • Damos valor a esa variable según lo que deseemos hacer (en esta caso, aplicar o eliminar el índice numérico): bIndice = true
    • "Llamamos a la subrutina incluyendo entre paréntesis la variable bIndice: msbIndiceNumerico(bIndice)
(3) Dado que estamos trabajando con estructuras basadas en macros, es necesario utilizar las variables de objeto y los objetos asociados a ellas. He concretado esto como script VarSis. Este script puede ser llamado desde la subrutina o desde el script o macro que la utilice. [Ver como ejemplo].

(4) Si se desea esta llamada puede plantearse de modo interactivo, mediante InputBox() u otra GUI. Aquí omito estas opciones por ser secundarias para el objetivo de la entrada.

(5) En este caso es aun necesario, o cuanto menos conveniente, descomponer el proceso de asignación del segundo valor en dos fases: en la primera se asigna valor (puede hacerse de forma interactiva como en 4) y en la segunda, mediante condicional, dar a la segunda variable de la llamada la expresión técnica precisa. De este modo se evita la comisión de algún error en la asignación del dato (vg, .uno:GoUp)

miércoles, 18 de octubre de 2023

Procedimientos. Docap.

DOCAP. Impress + Writer 

Ya vimos una primera formulación de un docap complejo que combina Calc con Writer. Analizaré en esta entrada otra formulación diferente en cuanto a uno de los servicios: utilizo Impress en lugar de Calc. Este cambio se explica fácilmente: ahora necesito las funcionalidades de Impress como recurso de manejo de información visual.

Aunque el esquema de funcionamiento es similar al modelo Calc + Writer, también se aprecian diferencias también, motivo por el cual he creído conveniente crear esta entrada.

Similitudes: Ahora Impress hace de servicio principal, lo que implica que no tenemos, como en el caso anterior, un gestor + un soporte para la salida de la información. Ahora tenemos un servicio-soporte para la exposición de la información y la aplicación de la actividad (Impress) y otro para la misma función que ya cumplió antes. Y en el intermedio el procesamiento de los datos recogidos en la fase inicial de la ejecución. 

Podemos representar lo anterior de forma simplificada mediante este esquema...

    

... entendiendo el condicional como mera representación de la fase de procesamiento, ya que es mucho más complejo, como veremos a continuación.

En la fase input se diferencian dos procedimientos de trabajo:
  • La introducción de datos de identificación, que se realiza mediante un cuadro de diálogo asociado a la presentación
  • Y la ejecución de la tarea, que se resuelve mediante comandos asociados a las figuras de cada diapositiva
El proceso comprende las siguientes fases:
  • El paso de los datos de identificación y de puntuación del ítem a matrices de datos
  • El conteo de aciertos
  • La calificación y valoración del resultado
  • Y la composición del texto a grabar en el documento de salida
Finalmente, en la fase de output se diferencian dos fases:
  • El acceso al documento-base y su apertura en modo plantilla (aquí se presenta una diferencia importante respecto al modelo de docap anterior, en el que se creaba ese documento)
  • Y el traslado de datos a las posiciones de marcador previamente establecidas en dicho documento (esta es una posibilidad que permite trabajar con documentos definidos previamente).
El [video] que sigue muestra esta estructura de forma detallada y en [esta entrada] puedes encontrar información complementaria a la que te presento aquí.




En la fase input, el uso de cuadro de diálogo [ver en GUI] está determinado por las propias limitaciones de Impress en cuanto al acceso a los sistemas gráficos de interface. 

DialogLibraries.LoadLibrary("Standard")
oPresentaCB=CreateUNODialog(DialogLibraries.Standard.getByName("DlgIdAl"))
oPresentaCB.Execute()

La segunda parte del input aprovecha las posibilidades que ofrece LO de asociar los elementos gráficos a macros/script.

El procesamiento de datos se centra en dos procesos:
  • Pasar los datos de los controles del cuadro de diálogo a una matriz string (sDatos()) para facilitar su procesamiento y, con ello, identificar al sujeto que realiza la actividad.
oDato(0) = oPresentaCB.getControl("DtFechaInfo")
sDato(0)= oDato(0).Text
  • Contabilizar los resultados y analizarlos en términos cuantitativos mediante el uso de instrucciones y estructuras OOo Basic.
For i = 0 To 11
Suma = Suma + Puntos(i)
Next
  • Con ambos, y mediante la concatenación de textos y variables, se elabora el contenido que posteriormente será traslado al soporte writer.
If Porcentaje > 80 Then
Valoracion= "Dado que el porcentaje de acierto es superior al 80%, se considera que el/la alumn@ comprende adecuadamente los conceptos básicos trabajados"
Else
Valoracion= "Dado que el porcentaje de acierto es inferior al 81%, se considera que el/la alumn@ no comprende suficientemente los conceptos básicos trabajados"
End If

Finalmente, el output empieza por el acceso al documento-base...

sRutaAcceso = ConvertToUrl("D:InfoCB.odt")
oDocModelo = StarDesktop.loadComponentFromURL( sRutaAcceso, "_blank", 0, mOpciones() )

... y finaliza con el traslado del contenido a las posiciones (marcadores de texto) que se establecieron en el documento-base en el momento en que éste se creó. 

oMrcFechaInfo = oDocModelo.getBookmarks().getByName("MarcaFechaInfo")
oMrcFechaInfo.getAnchor.setString(sDato(0))

lunes, 16 de octubre de 2023

OOo Basic. Ruta

Creación y acceso a archivos

Acceso  a archivo

  • Conversión de ruta al formato url (script)
sRuta = ConvertToUrl( "C:/Users/NombreUsuatio/Desktop/NombreArchivo.ext" )

En este caso se usa una ruta de la unidad C. Para conocer la ruta de un documento ubicado en esta unidad hacer clic derecho -> Propiedades.

En el script se trabaja con un archivo ubicado en la unidad D. 

Creación de una archivo 

oDocNuevo = StarDesktop.loadComponentFromURL( sRuta, "_default", 0, mArg() )

oDocNuevo es una variable tipo objeto, sRuta una variable tipo string y mArg() una matriz vacía. Es suficiente con modificar el valor que identifica el servicio para generar un tipo de archivo u otro (a excepción de bases de datos). Ver script.

Apertura de archivo

  • Apertura de archivo de texto (script)

oDocumento = StarDesktop.loadComponentFromURL( sRuta, "_blank", 0, mArg() )

oDocumento es una variable tipo objeto y sRuta una variable tipo string que contiene la ruta del archivo. mArg() es una matriz vacía (ver script)

sábado, 7 de octubre de 2023

Procedimientos. Docap.

DOCAP. Calc + Writer

Por oposición a los docap simples, denomino docap complejo a aquel que se formula sobre un documento de un servicio pero también involucra al menos a otro documento del mismo servicio o de otro diferente. En esta entrada voy a explicar cómo crear un docap (complejo) que combina una hoja de cálculo Calc y un documento Writer.


La característica  que define a un docap complejo es, pues, el uso de al menos dos documentos, de lo que deriva tanto la complejidad (del código, en relación al que se necesita para crear un docap simple) y el carácter compuesto, dado que hace uso de al menos dos componentes documentales cuyo manejo es preciso comprender para evitar errores en su gestión.

En esta entrada he optado por una fórmula relativamente simple, ya que Calc soporta muy bien el uso de macros y script, así como el empleo de formularios (y sus controles) para la generación de una interface gráfica sin un incremento significativo del coste de elaboración ni de complejidad de programación. Por estos dos motivos considero que debe ser la forma privilegiada de trabajar con docap complejos, siendo preferible a otras posibles formulaciones.

La creación de un docap Calc+Writer requiere, en lo fundamental, seguir los mismo pasos que seguimos para crear un docap simple sobre Calc en lo que se refiere a la forma en que se expresa la fase input. En ésta, la facilidad con la que Calc trabaja con los controles de formulario facilitan mucho la cosa, por lo que resuelve (en parte) la creación de la interface gráfica.

El acceso a los datos se resuelve gracias al procedimiento de acceso a las celdas mediante OOo Basic, mientras que el procesamiento de los datos se realiza de modo independiente respecto al proceso anterior y tiene que ver con la sintaxis del lenguaje (OOo Basic), de la cual ya sabemos lo suficiente.

En realidad la novedad de un docap complejo radica en la fase output, la cual requiere la creación del segundo documento mediante código, y el paso de estar trabajando sobre el primero a trabajar sobre el segundo (en este caso, un documento Writer).

Una vez explicado el proceso general, toca analizarlo punto por punto, empezando por la interface gráfica basada en el uso de formulario sobre Calc respecto a la cual decía antes que es mi opción preferida, afirmación ésta que interesa aclarar retomando lo ya explicado en entradas anteriores, concretamente las [accesibles desde GUI] y más específicamente la serie dedicada al trabajo con formularios en Calc que se inicia con [esta entrada].

Si bien el uso de formularios en Writer presenta cierta complejidad, en Calc éstas se simplifican mucho al disponer los controles de un procedimiento específico de asociación a las celda de la hoja de cálculo, lo que nos ahorra trabajo de programación, ya que esta parte (la creación de la interface gráfica) cae de parte de la preparación previa del documento Calc o documento gestor por su función en este tipo de docap.

El paso siguiente es acceder al contenidos de las celdas del gestor para poder asignar los datos a las variables, algo que también hemos trabajado ya [en esta entrada].

Podríamos decir que aquí finaliza la fase input y empieza la de procesamiento, pero sabemos que esto es una simplificación por lo visto respecto al [uso complejo de la función InputBox()], pero sobre todo por explicado en [esta entrada] sobre variables. No obstante sí nos puede servir de referencia para el inicio de esa segunda fase o de procesamiento. En este caso, para ello remito a [esta entrada].

La fase output se inicia con la creación en un documento (en este caso Writer) desde OOo Basic, un procedimiento muy similar al que empleamos para [crear una nueva hoja de cálculo], como tenderemos ocasión de comprobar. Lo que viene a continuación es la escritura del resultado en forma de párrafos de texto, siendo crucial mantener el foco en el documento Writer para que todo funcione correctamente.

El resultado final es [este documento Calc] que debes descargar para acceder al IDE si quieres visualizar el código. También puedes consultar la serie de vídeos que se inicia [con este].


Documentos. Combinada.

Comunicación con familias

Sabemos que esta medida de escolarización combinada supone una carga de trabajo muy importante. La mayor no es la de tipo burocrático, aunque no es desdeñable y bueno será todo lo que la alivie, como este docap de comunicación de las decisiones de la Comisión de Seguimiento a las familias cuando se producen determinados cambios o se prevén determinadas actuaciones,

Tanto por derecho como por conveniencia, la comunicación de la Comisión de Seguimiento de la Escolarización Combinada con las familias es fundamental para el correcto funcionamiento de esta medida de respuesta educativa. Siendo como es una medida controvertida y sumamente compleja, cumplir escrupulosamente los procedimientos que se establezcan para hacer efectiva esta comunicación es de vital importancia.

Y contar con una ayuda que facilite el correcto desarrollo de este tipo de actuaciones siempre será de agradecer, especialmente si nos permite automatizar la generación de documentos, reduciendo la carga de trabajo que implica, sin pérdida de calidad y personalización de la intervención.

Este docap sirve para crear documentos de comunicación de medidas a las familias. Aunque la firma es la del/de la responsable del Equipo educativo del centro de escolarización, se pretende que sea empleado por la persona que presida la Comisión de Seguimiento de la Escolarización Combinada (supuestamente el orientador u orientadora del centro de escolarización), quien lo presentará a la firma al responsable de la Dirección del centro, dentro del proceso de traslado de información y tramitación de las medidas que se plantearon en el seno de dicha Comisión.

Aclaro que parto de que se cumple el principio de que el centro de escolarización (de matriculación, para entendernos), que define la modalidad de escolarización del alumno o alumna y la gestión de su expediente escolar, es el centro ordinario en E. Infantil y el específico en E. Primaria. Al menos, esto es lo que está establecido por norma administrativa en determinadas comunidades autónomas, y en este contexto planteo el funcionamiento del docap.

En él, por delimitar su contenido, se consideran tres tipos de posibles medidas genéricas: la evaluación psicopedagógica prescriptiva según prescripción normativa, la modificación de apoyos especializados y la modificación de los periodos de asistencia a cada uno de los centros. Cualquier otra circunstancia o decisión de la Comisión no está considerada, lo que obliga, en su caso, a modificar tanto el control específico del formulario de entrada de datos como el código de tratamiento de los mismos.

Formalmente este docap se configura como docap complejo; se basa en LO-Calc y genera un documento LO-Writer como salida. La gestión de este documento queda a decisión del usuario, tanto a nivel de configuración y formateo, como de cambio de formato; por ejemplo es posible convertirlo a .pdf después de darle el formato deseado.

Se elegido esta formulación del docap por la simplicidad de gestión de los datos Calc desde OOo Basic y la fácil solución que proporciona ese servicio en el empleo de formularios, pero también por la versatilidad que supone trabajar con documentos de texto: que son editables y permiten realizar las modificaciones que se consideren pertinentes, haciendo que el docap resuelva la composición del documento-base, pero sin condicionar su formulación definitiva.

Aunque la explicación del docap la traslado al [vídeo enlazado con esta entrada], parece pertinente analizar aquí la estructura de su código.


En él podemos observar los diferentes componentes del docap y sus interacciones: partiendo del formulario y la asignación de sus controles a determinadas celdas, se accede mediante código a ellas y, posteriormente se complementa la información necesaria mediante el tratamiento condicional de los datos recogidos. Con estos datos se componen los textos (párrafos) que se escribirán en un documento Writer que se ha creado previamente mediante el procedimiento OOo Basic correspondiente.

El uso del docap es, como siempre, muy simple:

  • Se cumplimenta el cuestionario en la hoja de cálculo (gestor)
  • Se hace clic en el botón de comando "crear documento", que da acceso al desarrollo del proceso.
  • En función de los datos que se aporten se deberán cumplimentar InputBox() complementarios. Se debe tener cuidado con la pulsación sobre el botón "Aceptar" de estos interfaces para evitar saltos indebidos que alteran el resultado final del docap.
  • Se genera un documento Writer con los datos que ha creado el script. Este documento puedes ser guardado directamente o dejarlo abierto y disponible para las manipulaciones que se desee, incluyendo formateo para presentación y exportación bien como archivo de texto editable (.odt o .doc/.docx) o como .pdf.
  • Una vez creado el documento (y si preferimos antes de ponernos a trabajar con él) borraremos el contenido de los campos del formulario Calc haciendo clic en el botón-comando correspondiente.
Las posibilidades de mejora son varias, empezando por sustituir el uso de InputBox() por cuadros de diálogo para complementar el interface gráfico de entrada de datos y siguiendo por simplificar el código y mejorarlo ahí donde es posible (y hay unas cuantas mejoras potenciales). Como en otras ocasiones, dejo al usuario y su pericia la realización de estas mejoras y me reservo los mismos derechos.

No obstante, te expongo ahora otra línea de mejora que no normalmente no se plantea, pero que es coherente y posible (y yo diría deseable) desde este enfoque que se defiende en este blog: ser capaz de crear herramientas personalizadas:
  • Dado que estamos hablando de logar un nivel competencial que nos permita crear herramientas personalizadas (por ahora desde las propias opciones que presentan las suites ofimáticas), ¿por qué no practica este mismo enfoque adaptando instrumentos como el presenta a las necesidades y realidades concretas de un centro?
  • Desde esta perspectiva te planteo que, al margen de que afrontes o no mejoras como las que insinúo antes, adaptes el docap a tus necesidades mediante la asignación de valores a determinadas variables para que no sea necesario solicitarlos mediante interface.
  • Si lo haces, debes tener en cuenta lo que esto implica para el funcionamiento conjunto del script, por lo que te lo planteo desde la seguridad de que tu actual nivel de conocimiento y capacidad así lo permite.
    


martes, 3 de octubre de 2023

Procedimientos. Docap.

DOCAP. Texto con huecos.

El texto con huecos, texto mutilado o texto cloze, se emplea, [no sin crítica], como recurso de evaluación de la comprensión lectora, así que podemos emplearla para elaborar recursos didácticos. Pero también nos puede servir para crear docap de automatización de textos, como "alternativa" al propuesto en la [entrada anterior].



De hecho, cuando desde el nivel de usuario creamos un soporte textual con idea de que nos sirva de base o plantilla para componer textos similares personalizados, es frecuente recurrir a la sustitución de los datos a personalizar por un guion bajo con o sin algún tipo de indicación sobre su contenido. Algo similar a lo que se muestra en la imagen inferior, pero aplicado a un documento de gestión, como una convocatoria de reunión o similar.


En
 este caso, el proceso a seguir puede ser el siguiente:

  1. Sobre el documento que vamos a emplear como modelo (preferiblemente un documento realmente utilizado para la función), identificamos los datos susceptibles de ser personalizados. Podemos destacarlos de diferentes modos (negrita, otro color...)
  2. Conservando de momento una copia del texto inicial, eliminamos los datos a personalizar, manteniendo el resto del texto tal y como debería quedar al finalizar el proceso. 
  3. Los datos eliminados nos sirven para crear el listado de variables que después emplearemos en la construcción del docap.
  4. Hay que tener cuidado con las formas gramaticales derivadas de género y número ya que, o bien son sustituidas por formas únicas, compatibles con las diferentes formulaciones de la frase (y se expresan de este modo en el texto visible), o bien son también susceptibles de personalización, con lo que también se suprimen. En este segundo caso el tratamiento será mediante variables condicionadas [ver entrada], lo que implica su correspondiente tratamiento en la fase de procesamiento.
  5. Propongo que utilicemos [marcadores] como medio para ubicar de los datos en las posiciones que corresponda y a la función InputBox() como interface, preferiblemente en su formulación compleja [ver entrada].
  6. Dado que trabajamos desde Writer y en formato docap simple, la alternativa podría ser el cuadro de diálogo [ver entradao su combinación con InputBox()
Dejo la explicación en detalle a un vídeo basado en un ejemplo. cuyo soporte documental te proporciono. En [el vídeo] se explican las dos fases del proceso: la preparación previa del documento y el desarrollo del programa OOo Basic. En este caso creo un ejemplo más cercano a la intervención y la evaluación que a la automatización de un documento, por lo que, además del script principal (que es el que interesa, al ser común a ambos fines) se utiliza una macro (Grabar macro) que manipula la presentación de los datos. 


Por lo que se refiere al documento, te proporciono uno en [formato .odt] y otro en formato [plantilla]. En ambos casos debes descargarlos y abrirlos desde LO-Writer.

domingo, 1 de octubre de 2023

Procedimientos. Docap.

DOCAP. Nuevo documento

Este modo de crear un documento-aplicación (docap) ha sido yo desarrollado en la [entrada anterior], pero me interesa volver sobre él para diferenciar entre un docap creado mediante macros y otro creado utilizando OOo Basic.


La peculiaridad de este modo de trabajo es que, aparentemente, se parte un documento en blanco, aunque en realidad está "escrito" en desde el código.

Frente a aquel, en éste utilizo código OOo Basic en sustitución del que genera Grabar macro. Un ejemplos de ello es lo que podemos observar en [este docap] en el que, además de emplear expresiones OOo Basic alternativas al código macro para la escritura de texto...

Sub Escritura (sTxt As String)

Dim oText As Object
oText = ThisComponent.Text
oText.insertString(oText.getEnd(),sTxt & Chr(13) & Chr(13),False)

End Sub

... se utilizan formas complejas de la función InputBox()los ciclos (For...Next) y el condicional (If).

For i = 0 To 6

If i<4 Then
JustificarTexto
ElseIf i>=4 Then
CentrarTexto
End If

Escritura(Parrafo(i))

If i=4 Then
SaltoLinea (2)
End If

Next

Esta forma de crear docap tiene la ventaja de que es independiente del documento concreto, con lo que es posible aplicarlo sobre cualquier documento, siempre y cuando sea del mismo tipo (esto es, del mismo servicio; por ejemplo, Writer). Además necesitamos que el código esté guardado necesariamente en "Mis macros y diálogos", no el propio documento si es que queremos utilizarlo con independencia de éste.