Mostrando entradas con la etiqueta Acreditación. Mostrar todas las entradas
Mostrando entradas con la etiqueta Acreditación. Mostrar todas las entradas

lunes, 9 de febrero de 2026

Expedientes

Acceso a archivos

Este se puede considera el proceso inverso a lo que en su momento constituyó la generación automatizada de un documento de acreditación; también se puede entender como fase inicial del análisis de datos. Sea lo uno o lo otro, lo que nos importa es la consecuencia: se trata de generar un procedimiento que nos permita acceder al contenido de determinados documentos.

Pero como de algún modo hay que plantearlo para darle contexto, aprovecho la ocasión y el trabajo ya desarrollado para invertir su lógica y cerrar el círculo: si entonces se trataba de generar masivamente documentos partiendo de una tabla de datos, ahora se pretender procesar automáticamente y en cascada ciertos documentos para acceder a determinados datos y crear una fuente de datos.

Aunque el objetivo no es lo relevante, no está de más decir que se enmarca dentro del seguimiento o análisis de la intervención, que es una forma de análisis de datos adaptado a la acción de los SEO.

Dado que los datos son inventados (escandalosamente inventados), publicar el contenido de los documentos carece de importancia (cualquier parecido es mera coincidencia), incluyendo su uso (a fines comparativos) en Gemini o NotebookLM.

No puedo asegurar que sea así en todos los casos ya que mi experiencia es muy limitada, pero utilizar estas herramientas IA (y también ChatGPT) en el proceso descrito en la entrada antes citada ("Combinar correspondencia"), aunque es posible, sólo relativamente, con limitaciones cuantitativas y nunca exento de posibilidades de error. Esto es cierto al menos en determinadas condiciones, como son en las que yo me encuentro: Gemini y ChatGPT en sus cuentas gratuitas.

Pero si simulo el acceso al contenido de una colección de documentos para obtener determinados datos en NotebookLM los resultados son claramente positivos: es sencillo hacer la consulta y se obtienen resultados fiables y precisos. Cierto que si necesitamos procesar muchos documentos (y muchos no son tantos) deberás hacerlo en varios cuadernos porque no se puede sobrepasar un límite muy moderado (50 archivos en versión usuario, 300 en versión Google Workspace (empresa o educación).

Esta limitación de por sí es un hándicap nada despreciable, pero se puede asumir; lo que no se puede asumir (sí aquí por las características de la "base de datos" que uso) es la vulneración de la confidencialidad de datos que supone subir este tipo de archivos a la red, especialmente a un sistema IA. Esta limitación es radical y nos obliga a desarrollar otro tipo de alternativas si queremos combinar el análisis de nuestros datos con su automatización, lo que con frecuencia equivale a decir simplemente si realmente queremos realizar análisis de datos basados en la documentación disponible en el SEO.

La solución (una de ellas, porque ya sabemos que tampoco en informática hay una única solución) pasa, por ejemplo, por desarrollar un script Python que nos de respuesta al objetivo que nos podamos plantear. El problema: ni es sencillo ni es posible garantizar que lo que sirve para una cuestión sirva para otra, aunque parezca similar.

Es por ello que la propuesta que presento en esta entrada sirve para lo que se propone (y para otros casos) pero no está garantizado que se pueda generalizar. Deberemos plantear otras situaciones y otros objetivos para ir generando un almacén de herramientas de acceso y análisis de documentos. Ahora sólo estamos en los meros inicios.

Rebobino y concreto: tomo los archivos generados automáticamente mediante el script presentado en esta entrada y los convierto en documentación objeto de análisis. En realidad, más que de un análisis se trata de obtener de ellos datos funcionales para, por ejemplo, generar una "agenda de teléfonos" para establecer comunicación con los progenitores. Se requiere, por tanto, acceso al nombre del progenitor y al teléfono de contacto. Ambos son campos disponibles en nuestra base de datos de referencia, pero vamos a situarnos en ausencia de ese documento.

Primero buscaremos el nombre de los familiares. Para ello podemos aplicar este script...



import os
import re
from docx import Document

folder_path = 'Creados'
def extraer_familiar_regex(file_path):
	doc = Document(file_path)
    texto_total = []
    for tabla in doc.tables:
    	for fila in tabla.rows:
        	for celda in fila.cells:
            	t = celda.text.strip()
                if t and (not texto_total or t != texto_total[-1]):
                	texto_total.append(t)
	etiqueta_objetivo = "Nombre y apellidos:"
    contador = 0
	for i, texto in enumerate(texto_total):
    	if re.search(rf"^{etiqueta_objetivo}", texto, re.IGNORECASE):
        	contador += 1
            if contador == 2:
            	if i + 1 < len(texto_total):
                	return texto_total[i + 1]
               	
	return None

# --- Ejecución y muestra por consola ---

print(f"👤 Buscando nombres de familiares en '{folder_path}'...\n")

for filename in os.listdir(folder_path):
	if filename.endswith('.docx') and not filename.startswith('~$'):
    	ruta = os.path.join(folder_path, filename)
        try:
        	nombre_familiar = extraer_familiar_regex(ruta)
            if nombre_familiar:
            	print(f"✅ {filename}: {nombre_familiar}")
            else:
            	print(f"⚠️ {filename}: No se encontró el nombre del familiar.")
		except Exception as e:
        	print(f"❌ Error en {filename}: {e}")
print("\nBúsqueda finalizada. 🎯")


... que nos devuelve el listado de familiares por consola (te animo a que lo pruebes ubicándolo en la raíz del directorio que contiene la carpeta (subdirectorio) Creados, que contiene los documentos que sirve de base para este proyecto y que te dejo para descarga en Documentos.

De modo similar y con resultados parecidos, podemos obtener el dato Teléfonos:



import os
import re
from docx import Document

folder_path = 'Creados'

def extraer_telefonos_flexibles(file_path):
    doc = Document(file_path)
    telefonos_limpios = []
    
    # EXPLICACIÓN DEL PATRÓN (Marca):
    # \b[679]        -> Empieza por 6, 7 o 9 (límite de palabra)
    # (?:[\s.-]?\d)  -> Un número precedido opcionalmente por un espacio, punto o guion
    # {8}            -> Esto se repite 8 veces para completar los 9 dígitos
    # \b             -> Límite de palabra al final
    patron_flexible = r'\b[679](?:[\s.-]?\d){8}\b'
    
    for tabla in doc.tables:
        for fila in tabla.rows:
            for celda in fila.cells:
                texto = celda.text.strip()
                coincidencias = re.findall(patron_flexible, texto)
                
                for tel in coincidencias:
                    # Limpiamos el teléfono para que en el Excel/Consola quede uniforme (sin espacios)
                    # Ejemplo: "600 12 34 56" -> "600123456"
                    tel_limpio = re.sub(r'[\s.-]', '', tel)
                    
                    if tel_limpio not in telefonos_limpios:
                        telefonos_limpios.append(tel_limpio)
                        
    return telefonos_limpios

# --- Ejecución ---
print(f"🧐 Buscando teléfonos con formatos variables en '{folder_path}'...\n")

for filename in os.listdir(folder_path):
    if filename.endswith('.docx') and not filename.startswith('~$'):
        try:
            tels = extraer_telefonos_flexibles(os.path.join(folder_path, filename))
            if tels:
                print(f"✅ {filename}: {tels}")
            else:
                print(f"⚠️ {filename}: No se encontraron teléfonos.")
        except Exception as e:
            print(f"❌ Error en {filename}: {e}")


Aunque el código de ambos es muy interesante (lo que lo trabajaremos en entradas posteriores), no deja de ser una solución poco funcional, ya que lo deseable es que ambas búsquedas se den en el mismo script y que queden recogidas en un soporte fácil de consultar, como puede ser un archivo xlsx, por ejemplo.

Para responder a estas demandas vamos a presentar un script que unifique ambos procedimientos y devuelva ese archivo Excel.



import os
import re
import pandas as pd
from docx import Document

# Configuración
folder_path = 'Creados'
output_file = 'lista_datos2.xlsx'

def procesar_documentos():
    datos_finales = []
    
    # Patrones Regex
    patron_tel = r'\b[679](?:[\s.-]?\d){8}\b'
    etiqueta_nombre = "Nombre y apellidos:"

    print(f"🚀 Iniciando procesamiento de archivos en '{folder_path}'...")

    for filename in os.listdir(folder_path):
        if filename.endswith('.docx') and not filename.startswith('~$'):
            ruta = os.path.join(folder_path, filename)
            try:
                doc = Document(ruta)
                texto_total = []
                
                # 1. Aplanamiento lineal
                for tabla in doc.tables:
                    for fila in tabla.rows:
                        for celda in fila.cells:
                            t = celda.text.strip()
                            if t and (not texto_total or t != texto_total[-1]):
                                texto_total.append(t)
                
                # 2. Extracción de Familiar (2ª ocurrencia)
                nombre_familiar = "No encontrado"
                contador_nombres = 0
                for i, texto in enumerate(texto_total):
                    if re.search(rf"^{etiqueta_nombre}", texto, re.IGNORECASE):
                        contador_nombres += 1
                        if contador_nombres == 2:
                            if i + 1 < len(texto_total):
                                nombre_familiar = texto_total[i+1]
                            break

                # 3. Extracción de Teléfono (el primero que encuentre con Regex)
                # Unimos todo el texto para que Regex busque en todo el documento
                todo_el_texto = " ".join(texto_total)
                coincidencias_tel = re.findall(patron_tel, todo_el_texto)
                
                # Limpiamos el teléfono si existe
                tel_final = "No encontrado"
                if coincidencias_tel:
                    # Tomamos el primero y le quitamos espacios/puntos
                    tel_final = re.sub(r'[\s.-]', '', coincidencias_tel[0])

                # 4. Guardamos en la lista para Pandas
                datos_finales.append({
                    "Archivo": filename,
                    "Familiar": nombre_familiar,
                    "Teléfono": tel_final
                })
                
                print(f"✅ Procesado: {nombre_familiar} -> {tel_final}")

            except Exception as e:
                print(f"❌ Error en {filename}: {e}")

    # 5. Creación del DataFrame y Excel con Pandas
    if datos_finales:
        df = pd.DataFrame(datos_finales)
        df.to_excel(output_file, index=False)
        print(f"\n✨ Proceso completado. Se ha generado '{output_file}' con {len(df)} registros.")
    else:
        print("\n⚠️ No se encontraron datos para guardar.")

if __name__ == "__main__":
    procesar_documentos()
Mostrando lista_fam_tlf.py.


Este script, además de presentar por pantalla el listado de familiares y teléfonos, genera un archivo Excel (.xlsx) que contiene una tabla con esos mismos datos.

Aunque sólo sea por curiosidad, si quieres saber cómo lee Python los archivos docx, este script te muestra el resultado de aplicar las técnicas de simplificación que permiten a Python acceder a contenidos concretos. No se trata de la única opción existente, sólo una de las más sencillas pero potentes, como puedes ver por los resultados.



from docx import Document

file_path = 'Creados/Acredita_1.docx' 

def ver_lista_lineal(ruta):
    try:
        doc = Document(ruta)
        texto_total = []
        
        # 1. Proceso de "aplanamiento" (igual que en tu script original)
        for tabla in doc.tables:
            for fila in tabla.rows:
                for celda in fila.cells:
                    t = celda.text.strip()
                    # Filtro para evitar duplicados por celdas combinadas
                    if t and (not texto_total or t != texto_total[-1]):
                        texto_total.append(t)
        
        # 2. Mostrar el resultado como una lista pura
        print(f"--- LISTA LINEAL DE: {ruta} ---")
        for i, elemento in enumerate(texto_total):
            # Imprimimos el índice para que veas la "posición" de cada dato
            print(f"Posición {i}: {elemento}")
            
    except Exception as e:
        print(f"❌ Error: {e}")

ver_lista_lineal(file_path)


Puedes compara la sucesión de "etiquetas" y "campos" y la diferencia con la apariencia visual del documento .docx. Y es que uno de los problemas con los que nos encontramos a la hora de trabajar en este tipo de proyectos es la complejidad de los documentos objeto de análisis. Esta complejidad se incrementa cuanto tratamos con documentos prescriptivos, formados por una complicada estructura de tablas las cuales han sido modificadas a lo largo del tiempo generando problemas de acceso importantes que explicar las dificultades con las que nos podemos encontrar al tratar de automatizar procedimientos. Algo de esto ya sabemos.

Documentos.

Para finalizar te dejo acceso a los script Python y al listado de documentos sobre los que trabajan. En esta ocasión no aporto un cuaderno Colab porque no me detengo a analizar el código de los script. Son muchos y suficientemente complejos como para hacerlo ahora. Tiempo habrá y en ello colaborará Gemini, auxiliar también en la creación de estas soluciones.

RECUERDA Debes descargar estos documentos en una misma carpeta.

domingo, 8 de febrero de 2026

Acreditación

Modelo listado (base de datos) II


No es nada nuevo decir que (también) en programación las cosas se pueden hacer de muchas maneras. En una [entrada anterior] vimos una de las formas de automatizar la creación del documento Acreditación y en esta veremos otra diferente.


Las diferencias se deben a varias causas; la primera de ellas es que en esta ocasión no trabajaremos con un lenguaje "de macros" sino con Python. Además el script que creemos trabajará desde fuera del documento, y lo hará con documentos MS Office (.xlsx y .docx), no tanto por no existir opción de trabajo en Python con LibreOffice, pero sí porque las bibliotecas de trabajo de Python con MS Office son más robustas y sencillas.

La segunda diferencia es que en este caso crearemos un script que actúa a modo de "Combinar correspondencia en piloto automático", esto es, que crea tantos documentos de acreditación como registros tengamos en nuestra base de datos.

Pero aun hay más diferencias, estas de procedimientos: el script resultará del uso de un chatbot (Gemini) a modo de auxiliar de programación y se expresará como cuaderno de Google Colab. Esto nos permitirá incidir un poco más en la incorporación de la IA a la programación (y en sus límites) y en el uso de recursos On-line y sus (también) limitaciones.

Empezaré por decir que para la obtención del listado de campos de la acreditación utilicé una herramienta basada en Gemini llamada NotebookLM, disponible desde una cuenta G-mail. No es este el momento para hablar de ella, ni siquiera de lo que se puede conseguir con su uso, pero sí diré que es de utilidad (a veces mucho más que el propio Gemini), pero que el resultado que obtuve fue satisfactorio en términos de expectativas, aunque fue necesario trabajar con el texto para ajustarlo al objetivo: disponer de un listado de campos que recogiera todos los que presenta el documento para usarlo en la creación de la base de datos (encabezado).

En cualquier caso, siendo ésta como es una forma de incorporar la IA en los procedimientos de trabajo, decir que NotebooKLM presenta una importante limitación que es necesario destacar: no es adecuado usar esta aplicación cuando la información que se debe aportar contiene datos confidenciales. No siendo el caso (que no lo es), su utilidad (en este caso el análisis de la composición estructural de un documento) es indudable, aunque limitada, por lo que dije.

También es de utilidad, ahora Gemini, para "inventar" contenido (registros) para la base de datos creada (manualmente, aunque con ayuda), pero lo cierto es que no hacía falta mucho: los datos inventados eran necesarios para probar el funcionamiento del script, pero no me interesaba que fueran creíbles; es más, necesitaba que no lo fueran precisamente porque también Gemini adolece de la misma limitación respecto al tratamiento de datos confidenciales, y los que teóricamente debe contener una base de datos de estas características lo son, y mucho.

También respecto a Gemini hay que decir, pues, lo mismo, aunque desde una perspectiva diferente: es muy útil para facilitar la automatización de determinadas formas de trabajo, aunque ajustar las respuestas a las necesidades puede llegar a ser un proceso trabajoso (no lo fue en este caso, dada la simplicidad de la tarea), incluyendo el necesario tratamiento del soporte en que ofrece sus resultados (en este caso, hoja de cálculo de Google).

Centrándonos en el núcleo de este proceso (la creación del script en Python), también Gemini se presenta como una herramienta útil, y por partida doble: como chatbot genérico (que fue el caso), y como asistente de programación incluido en Google Colab (que no fue el caso en esta ocasión). Como herramienta-asistente Gemini es de gran interés, aunque es necesario diferenciar el tipo de objetivo que persigamos usándola.

Sin entrar en muchos detalles, diré que en este caso se trataba de desarrollar un script que funcionara correctamente, no de utilizar la tarea como "excusa" para el  aprendizaje ni mucho menos siendo el proceso de aprendizaje el centro de interés.

Sobre estas dos condiciones tendré ocasión de hablar en otros momentos; sobre el objetivo de ésta decir que es posiblemente donde un chatbot-asistente de programación tiene más utilidad, siempre y cuando nos conformemos con lo que nos ofrece sin tratar de indagar mucho en el resultado; en el momento en que eso no es suficiente, deberemos entrar en un diálogo pormenorizado sobre qué y cómo queremos que sea capaz de hacer (y no hacer) el script. Pero esto ya constituye en si mismo un interesante proceso de aprendizaje, así que no se debe considerar un handicap. 

Es más, yo diría que la interacción se vuelve más interesante (claro que a veces llega a serlo "en exceso") cuanto más y mejor sepamos lo que queremos y lo que no queremos, y sepamos identificar las fases del proceso para presentarlas de forma diferenciada y clara en forma de secuencia de objetivos parciales.

El resultado, en todo caso, queda a tu disposición para que lo uses y para que lo estudies, si es de tu interés. Aunque no fue hecho (como dije) sobre G. Colab, te lo presenta en este formato, además de íntegro como enlace al final de la entrada y junto con los documentos utilizados para probarlo.

De hecho, el material sobre G-Colab no sirve directamente para ser usado, pero tiene la ventaja de que es posible descomponer y analizar el código parte por parte, por lo que resulta más didáctico. Y ese es el principal objetivo de usar G. Colab.

Mediante botón de comando que aparece en primer lugar puedes acceder al cuaderno G-Colab y trabajar con él, aunque su función (especialmente en este caso) es meramente explicativa.

**********************************************************

**********************************************************

En resumen, este script permite trabajar de forma similar a como haríamos con Combinar correspondencia, sin necesidad de crear ninguna relación entre documento y base de datos, lo que hace que sea menos frágil y generalizable. 

En cuanto a procedimiento de trabajo, dado que la confidencialidad de los datos no nos permite trabajar directamente con la IA, lo hacemos indirectamente, usándola como proveedora de procedimientos de automatización. Esta explicación es excesivamente simplista y obvia las limitaciones que esta forma de uso de la IA  implica, pero nos sirve de momento.

Documentos
  • Desde [aquí puedes acceder al script] que deberás incorporar al directorio donde vayas a guardar la documentación. Recuerda acceder a él desde tu IDE de Python para ver su contenido y, en su caso, realizar las modificaciones que desees. En caso de proceder de este modo te sugiero que hagas una copia de seguridad del script original.
  • [Aquí tiene la base de datos] y [aquí la plantilla del documento].
  • En [este enlace] puedes descargar un ejemplo de documento resultante.
  • Recuerda que todos estos archivos deben compartir la misma carpeta con el script.
  • Finalmente vuelvo a darte [acceso al cuaderno Colab], por si tienes algún problema de acceso desde el comando anterior.



viernes, 6 de febrero de 2026

Acreditación

Modelo listado (base de datos)

Además de los procedimientos anteriores, también podemos automatizar la generación de acreditaciones basándonos en la elección de un determinado registro de una base de datos (Calc). 


Se trata de una opción basada en el uso de marcadores que tiene como peculiaridad la posibilidad de seleccionar el registro mediante la ubicación previa del cursos en el campos A del registro deseado de nuestra base de datos.

Veamos el script:

Sub TransferirDatosAcreditacion

    Dim oDocCalc As Object
    Dim oSel As Object
    Dim oHoja As Object
    Dim nFila As Integer
    Dim f As Integer
    Dim nRespuesta As Integer 
'Avisos de inicio
MsgBox "Para el correcto funcionamiento del script debe posicionarse en la celda que desee de la columna A"
MsgBox "Por favor, seleccione la primera celda de la fila para posicionarte en el registro a imprimir.", 16, "Error"
  
' 1. CONFIGURACIÓN DE MATRICES
    ' Define aquí los nombres de las columnas (solo para el mensaje) 
    ' y los nombres exactos de los marcadores en Writer.
    Dim vCampos(23) As String
    Dim vMarcadores() As String
    
    vMarcadores = Array("Curso", "fecha", "SEO", "Orienta", "NIE", "Nombre", "Apellidos", "FNac","Edad","CursoS","Madre","DNI","Domicilio","CP","Tlf","nesc","ccent","otras","nee","neae","flugar","Ffecha")
' 2. UBICAR CELDA ACTIVA
    oDocCalc = ThisComponent
    oSel = oDocCalc.CurrentSelection
    
    ' Validar que hay una celda seleccionada
    If Not oSel.supportsService("com.sun.star.sheet.SheetCellRange") Then
        MsgBox "Por favor, seleccione la primera celda de la fila para posicionarte en el registro a imprimir.", 16, "Error"
        Exit Sub
    End If
    
    nFila = oSel.CellAddress.Row
    oHoja = oDocCalc.Sheets(oSel.CellAddress.Sheet)
    
    ' 3. AVISO AL USUARIO
    nRespuesta = MsgBox("Se tomarán los datos de la fila " & (nFila + 1) & "." & Chr(13) & _
                        "¿Desea continuar?", 33, "Confirmar Registro")
    
    If nRespuesta <> 1 Then Exit Sub

 ' 4. RECORRER COLUMNAS DE CALC (Bucle 1)
 ' Guardamos los datos de la fila en una matriz temporal
    Dim nLimite As Integer
    nLimite = UBound(vMarcadores) ' Obtiene el índice máximo de la matriz
    
    Dim vDatosExtraidos(nLimite) As String
    Dim i As Integer
    
    For i = 0 To nLimite
        vCampos(i) = oHoja.getCellByPosition(i, nFila).String
    Next i
    
' 5. ACCESO A WRITER
   Dim oDocWriter As Object
   Dim oMarcadores As Object
   Dim sUrl As String
    
   ' Acceso al documento
   sUrl = convertToURL("C:\Users\acredita_writeb.ott") 'Sustituya esta dirección por la que corresponda según su organización de archivos
   oDocWriter = StarDesktop.loadComponentFromURL(sUrl, "_blank", 0, Array())
    
   If IsNull(oDocWriter) Then
      MsgBox "No se encontró el archivo de destino.", 16, "Error"
      Exit Sub
   End If

   oMarcadores = oDocWriter.Bookmarks

' 6. POSICIONAR CONTENIDOS EN MARCADORES (Bucle 2)
   For i = 0 To nLimite
    Dim sNombreMarcador As String
    sNombreMarcador = vMarcadores(i)
        
    If oMarcadores.hasByName(sNombreMarcador) Then
    ' Insertamos el dato correspondiente de nuestra matriz de datos
      oMarcadores.getByName(sNombreMarcador).getAnchor().setString(vCampos(i))
    Else
    ' Opcional: Avisar si falta un marcador (que no debería)
    MsgBox "Aviso: No se encontró el marcador " & sNombreMarcador, 48
    End If
    Next i

    MsgBox "Se han transferido " & (nLimite + 1) & " campos correctamente.", 64, "Éxito"
    
End Sub

 Acuérdate de cambiar la ruta de tu documento-plantilla acredita_writeb.ott; hazlo como ruta absoluta para evitar fallos. Para ello es suficiente con que, después de descargados los documento y reubicados en tu sistema, selecciones el documento write, hagas clic derecho sobre él y selecciones la opción "Copiar como ruta de acceso"; después sólo tienes que pegar esa ruta como alternativa a la que aparece en la línea de instrucciones del script.

Documentos. Desde aquí y desde aquí accedes a los documentos que deberás descargar. Recuerda que trabajas desde LibreOffice. 

sábado, 11 de marzo de 2023

Documentos. Acreditación.

Acreditación -8. Docap complejo (d2)

En esta entrada explico la segunda fase de la creación del documento Acreditación. Es en ella en la que, precisamente, se genera dicho documento.


No parecen necesarias más explicaciones que dadas en el entrada anterior, ya que ésta viene condicionada por razones de duración de la exposición. 

quisiera insistir en que trabajar con  marcadores nos permite prescindir del control de la ubicación inicial del cursor y de sus desplazamientos a lo largo del script, algo que era crítico en el modelo macro basado en el posicionamiento mediante tablas y celdas.

Otra cuestión de interés es mantener dos objetos abiertos (Hoja del cálculo y Documento de texto), trabajando desde una (la que contiene el script) en la otra (la que recibe el resultado de la acción del script).

Una vez finalizada esta primera fase del proyecto, interesa plantear cuáles podrían ser los desarrollo subsiguientes, cuestiones éstas que podrían necesitar más tiempo del que parece conveniente dedicar en estos momento.

Documentos. Acreditación

Acreditación -7. Docap complejo (d1)

Iniciando con lo prometido nos adentraremos ahora en el análisis del conjunto de script  que conforman esta docap.


Podemos ver en la imagen que sigue los tres módulos que componen la biblioteca Standard y los script individuales que contienen. 


  • Tenemos, en primer lugar, un módulo con script auxiliares cuyas funciones indican sus propios nombres. Dado que no se trata de script centrales del docap actual, no nos detendremos a explicar su funcionamiento.
  • El módulo CapturaDatos reúne los script cuyo cometido es recopilar la información que aporta el usuario o usuaria (fase input)
  • Y el módulo CreaDocum contiene el script que se ocupa de trasladar los datos anteriores al documento Writer que nos sirve de base para crear la acreditación.  

Además del módulo auxiliar, esta estructura revela la existencia de un proceso dividido en dos partes: el acceso a los datos y su ubicación controlada en celdas del soporte Calc y la captura del contenido de las celdas y su traslado al documento Writer.

En esta entrada nos centraremos en los script que forman parte del módulo CapturaDatos: DadosDocum y DatosAlumn; esto es, en la captura de datos del usuario 

Documentos:


sábado, 4 de marzo de 2023

Documentos. Acreditación.

Acreditación -6. Docap complejo (c)

Como paso previo para explicar el código del docap que constituye mi tercera propuesta de automatización del documento Acreditación, voy a dedicar esta entrada a explicar la estructura de elementos que componen la hoja de cálculo.


Calc es el servicio principal en este conjunto interrelacionado de servicios, y lo es por ser quien lleva la carga de gestionar el conjunto de los procesos que se desarrollan en este docap. La posición central que ocupa en la imagen siguiente reflejar esa centralidad funcional, del mismo modo que las flechas representan los flujos de interacciones que tienen lugar en el docap: Calc mantiene con Base (BD) una relación bidireccional tal y como expliqué en la [entrada anterior], y unidireccional con Writer.


Documentos:

Documentos. Acreditación.

Acreditación-5. Docap complejo (b)

Respecto a esta tercera opción, ya conocemos por la [entrada anterior] su forma básica de funcionamiento y cómo está diseñado el documento Acreditación. Ahora analizaremos el papel de la fuente de datos (BD) y cómo se relaciona con el archivo Calc.


Nuestra base de datos (AlumnNE) es la misma que utilizamos en la segunda opción (basada en Combinar correspondencia) y tiene exactamente las mismas características y la misma estructura y contiene los mismos datos; pero ahora es posible lo que en aquella ocasión no llegaba a ser recomendable: mantener una relación bidireccional con el elemento con el que está relacionada (ahora la hoja de cálculo).


Dedicaremos esta entrada a explicar esta relación que, como podrás comprobar, es de carácter bidireccional, mientras que la que se establece entre el hoja Calc y el documento Writer es unidireccional. Esa bidireccionalidad es consecuencia de que la relación se establece mediante formulario vinculado a la BD y no mediante Combinar correspondencia, que era como se establecía en el modelo B. 

Ahora, al utilizar una hoja de cálculo como servicio que intermedia entre la fuente de datos y destinatario final (el documento Writer), podemos aprovechar plenamente lo que implica esa bidireccionalidad sin comprometer las funcionalidades básicas del documento Acreditación.




Aun no hemos abordado el análisis de la hoja de cálculo, que estamos usando como sistema de gestión del docap, por lo que en el vídeo anterior no hemos atendido a nada que no sea la vinculación del formulario (de uno de los formularios) de nuestra hoja de cálculo con la BD

Al análisis al que me refiero el párrafo anterior dedicaré la próxima entrada.

viernes, 3 de marzo de 2023

Documentos. Acreditación.

Acreditación -4. Docap complejo (a)

No se puede decir que lo que presento como tercer procedimiento de automatización de Acreditación suponga un cambio radical respecto a los dos anteriores, no al menos en la lógica de programación subyacente, pero es cierto que transformar la idea en una realidad funcional sí que ha supuesto introducir cambios significativos respecto al diseño de las dos propuestas anteriores.


Para empezar la única novedad en términos de lógica de programación respecto a la segunda de las dos propuestas anteriores es introducir una hoja de cálculo entre la fuente de datos (BD) y el documento final (Acreditación). 


Partiendo de la facilidad con la que podemos conectar un formulario (y sus campos) con una fuente de datos, la idea de introducir una hoja de cálculo como elemento intermedio de conexión (entre la fuente de datos y el documento) es aprovechar la versatilidad de Calc para trabajar con formularios, facilitando la conexión entre los controles de formulario y las celdas, así como la relativa sencillez con la que admite la creación de script de acceso a las celdas.

No obstante, este planteamiento conlleva alguna que otra "complicación" respecto a los modelos precedentes: necesitamos desarrollar mucho más código sobre la hoja de cálculo y sobre el documento Acreditación. Pero también aparecen posibilidades que hasta ahora se han mantenido ocultas: usar referencias y accesos a los marcadores de texto como modo de facilitar la ubicación de los datos en el documento nos evita trabajar con tablas así como las complicaciones de los desplazamientos por las mismas.

Y no es ésta la única ventaja, aunque sí la única de la que me aprovecho en este momento. Para desarrollos posteriores queda el trabajo unificado sobre los otros dos documentos (DE e Informe) y lo que esto supone en el desarrollo de un procedimiento de trabajo que integre los tres en un único proceso de automatización, con el ahorro de tiempo que esto puede suponer...

Aunque suponga empezar la casa por el tejado me centraré en esta entrada en el cambio que para la formulación de Acreditación supone el uso de los marcadores de texto, como trabajar con ellos y cómo acceder a sus posiciones desde OOo Basic.

En el vídeo que sigue voy a explicar cómo afecta el uso de marcadores al diseño del documento Acreditación, que hace innecesarias muchas de las precauciones que debíamos adoptar en las dos propuestas anteriores: una tabla única, por ejemplo. No obstante, también  tiene sus limitaciones y bueno es conocerlas.




Documentos. Acreditación.

Acreditación. Modelo B. Combinar correspondencia.

Disponemos de otras opciones, además de Crear macros para automatizar la el documento Acreditación, por ejemplo establecer una vinculación a fuentes de datos y, a partir de ella, utilizar la función Combinar correspondencia.


En esta ocasión vamos a desarrollar dos formulaciones del mismo principio (vinculación a fuente de datos), partiendo de una tabla de una base de datos (en anteriores ocasiones hemos trabajado con hojas de cálculo como fuentes de datos) que combinaremos con un documento Writer, el que contiene el documento Acreditación. 


Ahora las entradas de Acreditación son tratadas como campos que se vinculan directamente o por medio de un formulario, con los campos de la fuente de datos (BD). 

Para ello necesitamos crear una base de datos y utilizar al menos dos de sus componentes: una tabla y un formulario. También necesitamos registrarla para que quede disponible como fuente de datos. Para todo ello es necesario contar con una serie de conocimientos previos que no son objeto de esta entrada, pero que sí parece conveniente que estén accesibles, por lo que te dejo los enlaces que siguen.

La primera opción se basa en Combinar correspondencia, funcionalidad ya utilizada en este blog, aunque con otros fines. Aunque podríamos haber utilizado este mismo procedimiento, en realidad sólo encaja con los contenidos de la tabla 1 (Datos personales...), la cual ha servido de base para crear la tabla Alumnado de la BD. El resto del documento queda para ser cumplimentado mediante el procesador de textos, aunque caben otras opciones.

La segunda forma se basa en la vinculación entre la base de datos (y su tabla Alumnado) y los controles de un formulario que utilizamos también para cumplimentar la tabla 1 de Acreditación. La diferencia es que también empleamos controles de formulario para facilitar la entrada de datos de otros "campos", aunque no vinculados a la tabla Alumnado. Aunque esta fórmula parece un avance sobre Combinar correspondencia, presenta algunas limitaciones que no la hacen especialmente recomendable.

Para finalizar, y a modo de síntesis he desarrollado una tercera opción que se basa en las dos anteriores: mantengo Combinar correspondencia para cubrir la tabla 1, pero también uso controles de formulario para cumplimentar otros campos (no vinculados a la BD), e incluso propongo el uso directo del procesador de textos como herramienta para cubrir determinados campos. El resultado es una solución satisfactoriamente funcional, conseguida sin hacer uso de OOo Basic o de Grabar macro, lo que puede ser un aliciente para quienes no estén interesado en adentrarse en el mundo de la programación.

Documentos:
NOTA Una mala noticia: no está garantizado el correcto funcionamiento de los vínculos de la BD a los campos utilizados en A ni a los controles de B, dado que la BD no forma parte de las bases de datos vinculadas en tu sistema. Deberás vincular esta base de datos y restablecer las conexiones en los documentos modelos.
 

jueves, 2 de marzo de 2023

Documentos. Acreditación

Acreditación -3. Docap basado en macros (c)

La funcionalidad Grabar macro ha permitido crear un código mediante el cual podemos escribir contenido en cada uno de los campos del documento Acreditación. Las modificaciones posteriores nos han permitido obtener un código funcional y limpio en cuanto a su estructura. Esto permite otras posibilidades de mejora. Pero hasta este momento, no hemos resuelto una cuestión básica: facilitar al usuario la entrada de datos y resolver esto obligando al usuario acceder al IDE y modificar el código (args.valueargumento por argumento no parece una opción aceptable.

Lo malo es que esa es precisamente la solución que, en sentido estricto, podemos esperar del uso de Grabar macro: si queremos ir más allá, deberemos recurrir a nuestros conocimientos de OOo Basic para crear el código de input interactivo.


Podemos resolver este problema mediante la creación de variables String y el uso sistemático de InputBox() para crear un sistema de entrada de datos (input) que convierte nuestra macro en un script, permitiendo al usuario introducir los datos necesarios para cumplimentar el documento Acreditación.

Siguiendo este procedimiento hemos conseguido que Grabar macro sea la base para la creación de un docap de composición del documento Acreditación. Del mismo modo podremos crear un docap para el automatizar los documentos Dictamen e Informe (aunque este último únicamente su carátula).

Si optamos por este procedimiento (macro) posiblemente sea conveniente mejorar su funcionamiento y trabajar con más detalle su estructura, sustituyendo (por ejemplo) la linealidad por la modularidad, esto es: haciendo uso de subrutinas y funciones como alternativa a la secuencia repetitiva que presenta el código actual.

Ahora no me voy a detener en realizar estos cambios, ya que prefiero avanzar presentando otras opciones y me reservo las propuestas de mejora del código para más adelante. 

Lo que sí voy a hacer es dejarte el [docap resultante] de este proceso por si te interesa. Corre de tu cuenta realizar las mejoras que consideres, aunque es de esperar que funcione perfectamente tal y como está.


Documentos. Acreditación.

Acreditación - 2. Docap basado en macros (b)

Una que hemos [creado la macro] necesitamos adaptarla para que nos permita introducir los datos necesarios, dotando al docap de capacidad interactiva. Para ello deberemos modificar el código generado desde Grabar macro.


El trabajo que toca ahora tiene tres objetivos:

  • Eliminar el código "basura" para mejorar el rendimiento de la macro.
  • Estructurar el contenido de la macro para facilitar su comprensión.
  • Generar procedimientos específicos de entrada de datos para dotarle de interactividad.


Las dos primeras partes, aunque necesarias, carecen de interés para lo que ahora nos importa, por lo que las trataré someramente en el vídeo que acompaña a esta entrada, pero la tercera hace necesario que nos detengamos en ella, por lo que bien se merece una explicación que puedes ver en [el vídeo que acompaña esta entrada]



miércoles, 1 de marzo de 2023

Documentos. Acreditación.

Acreditación -1. Docap basado en macro (a)

No puedo asegurar que esta sea la primera alternativa disponible, pero grabar una macro está dentro de las opciones que ya hemos trabajado en este blog como posible forma de automatizar procesos y constituye una evolución lógica de la propuesta de crear un documento-modelo personalizado, puesto que se basa en el mismo principio y supone aplicar una funcionalidad disponible dentro del servicio Writer.


Bueno, lo anterior no es del todo cierto: hacer una macro con Grabar macro no resuelve el problema, pero sí supone un paso en la buena senda... en una de las posibles sendas...

Además, antes de crear la macro es necesario realizar algunas modificaciones al documento original por eso de lo dicho en el [vídeo que acompaña a la entrada]. Es conveniente que el documento cuente con una única tabla para simplificar los desplazamientos... también eliminar los vestigios del uso manual del mismo.


.