viernes, 20 de diciembre de 2024

Análisis. Datos.

Acceso a tabla: columnas y filas.

Antes de iniciar el análisis de datos, y como paso previo, trabajando con OOo Basic es necesario aprender a acceder a las columnas (campos o variables, según se prefiera) y a las filas (o registros).


Ambos accesos se circunscriben al trabajo con OOo Basic como herramienta para el análisis de datos, ya que en otros lenguajes (R y Python) no son necesarios como tales, puesto que el proceso se resuelve de forma directa mediante las funciones correspondiente (1).

Lo que sí van a tener los tres lenguajes es que en el proceso de análisis de datos también en OOo Basic trabajaré directamente desde el IDE como espacio para la generación de script y el desarrollo del propio proceso de análisis. Como consecuencia de ello, y al contrario del planteamiento de trabajo que implica el desarrollo de docap, aquí no existirá otra interface que el propio IDE y el recurso a ventanas emergentes (MsgBox) como medio para que OOo Basic genere las salidas de datos. Esto significa que, en principio, no se prestará atención a la entrada de datos y a la salida sólo mediante escritura en la hoja de cálculo cuando resulte pertinente; el resto queda a la escritura de código y a la recopilación manual por parte del usuario. Es este un procedimiento extraño al objetivo para el que fue ideado OOo Basic, pero muy común en los lenguajes Python y R (especialmente este último) y empleándolo me quiero aproximar a ese modo de trabajo, eludiendo de paso la carga de trabajo que supone el diseño de interfaces de usuario. Se espera que a estas alturas del proceso de aprendizaje LO - OOo Basic este modo de uso del lenguaje no suponga ningún problema para el usuario.

Para concretar y ejemplificar ambos procedimientos de acceso a los datos emplearé una tabla ficticia que recoge el registro de actuaciones mensuales de un OE en un determinado centro a lo largo del curso (2). Sobre esta base, empezaré por explicar el acceso a una columna de datos, que es, posiblemente, el procedimiento más empleado en el análisis de datos.

Sub AccesoCol

Dim vN As Integer, i As Integer
Dim vHoja As String, vCol As String, vTipoDat As String
Dim mDatosCol() As Variant
Dim oHoja As Object, oCelda As Object

vN = 9
vHoja = "Datos"
vCol = "E"

ReDim mDatosCol(vN)

vTipoDat = "N" 'Tipo de datos a capturar: T - Texto y N - Numérico

oHoja = ThisComponent.getSheets().getByName(vHoja)

For i = 0 To UBound(mDatosCol())
oCelda = oHoja.getCellRangeByName(vCol & i+2)
If vTipoDat = "N" Then
mDatosCol(i) = CInt(oCelda.getString)
ElseIf vTipoDat = "T" Then
mDatosCol(i) = oCelda.getString
End If
Next

End Sub

Tras la declaración de las variables, asignamos valores a las variables que nos van a permitir dimensionar la matriz de datos (ReDim mDatosCol(vN)) y acceder a la hoja (vHoja = "Datos") y  a la columna (vCol = "E")  donde se encuentran dichos datos. Después seleccionamos el tipo de datos al que se va a acceder (vTipoDat = "N") (3), a fin de facilitar el uso de procedimiento adecuado a ese tipo de datos, según veremos un poco más abajo.

Lo siguiente que hacemos es acceder a la hoja (oHoja = ThisComponent.getSheets().getByName(vHoja)) y después, mednte un bucle (For i = 0 To UBound(mDatosCol())), a cada una de las celdas de la columna seleccionada (oCelda = oHoja.getCellRangeByName(vCol & i+2)). Como la instrucción de acceso es diferente en función del tipo de datos (textos o números), empleamos un condicional para acceder a números (If vTipoDat = "N" Then) -> (mDatosCol(i) = CInt(oCelda.getString)) u otro para acceder a textos (ElseIf vTipoDat = "T" Then) -> (mDatosCol(i) = oCelda.getString).

Y ya estamos en disposición de trabajar con esta matriz de datos que consideramos valores de la variable (en este caso) Actividad Tipo 1 (AT1), sea esta lo que sea.

Si quisiéramos acceder a una segunda variable, deberíamos crear una segunda matriz de datos y proceder del mismo modo, lo que implica complicar el script. En caso de que este script resulte demasiado complejo y se reduzca la funcionalidad de uso, sería conveniente plantearse la creación de una función o una subrutina en la que concretar aquellos procedimientos que se repiten varias veces en dicho script (4).

El acceso a una determinada fila | registro de la tabla, en principio, no es muy diferentes al modo que utilizamos para grabar los datos en una determinada fila, según quedó explicado en entradas anteriores [por ejemplo en esta], y que empleamos para crear el docap de generación de la tabla de datos [ver aquí], pero presenta algunas diferencias debidas al cambio de tratamiento de los datos.

Sub AccesoFil

Dim oHojaBD As Object, oCeldaInicio As Object, oCeldaRegistro As Object
Dim vN As Integer, i As Integer
Dim vHoja As String
Dim a As Integer, b As Integer, c As Integer, vFil As Integer
Dim mDatos() As String

vHoja = "Datos" ' Nombre de la hoja de datos

oHojaBD = ThisComponent.getSheets().getByName(vHoja)

vN = 7 'Nº de elementos de la fila (campos del registro)
ReDim mDatos(vN)

c = 100
vFil = 5 'Id de la fila (registro) a seleccionar

For b = 0 To c
If b + 1 = vFil Then
For i = 0 To UBound(mDatos())
oCeldaRegistro = oHojaBD.getCellByPosition(i,vFil)
mDatos(i) = oCeldaRegistro.getString()
Next
End If
Next

End Sub

Primero accedemos a la hoja (oHojaBD = ThisComponent.getSheets().getByName(vHoja)) identificada previamente en la variable (vHoja = "Datos") y después redimensionamos la matriz (ReDim mDatos(vN)) en función del número de campos del registro (vN = 7) y terminamos identificando el Id el registro deseado (vFil = 5).

Después ejecutamos la estructura ciclo-Condicional-ciclo que nos va a permitir acceder al contenido de los campos de ese registro. Para ello recorremos la base de datos (For b = 0 To c) hasta encontrar el valor del contador b que coincida con el Id del registro buscado (vFil) estableciendo en ese momento la condicionalidad (If b + 1 = vFil Then) dentro de la cual ejecutamos un segundo bucle (For i = 0 To UBound(mDatos())) que recorre las columnas (oCeldaRegistro = oHojaBD.getCellByPosition(i,vFil)) asignando a la matriz el contenido de las celdas correspondientes a ese registro (mDatos(i) = oCeldaRegistro.getString()).

También aquí el script deberá repetirse tantas veces como registros deseemos capturar, por lo que puede volverse poco manejable. En ese caso también será conveniente reconvertir el script en una función (ver nota 4).

Documento. Desde [este enlace] puedes acceder al documento que contiene ambos script.

NOTAS

(1) El trabajo con estos lenguajes se verá en próximas entradas, pero por ahora me voy a limitar a trabajar con OOo Basic.
(2) Aunque la base es el docap para crear una tabla expuesto en [esta entrada], el código que contiene los procedimientos de acceso se ubica en un módulo específico (ModAccesoDatos), diferentes del módulo que contiene los script y subrutinas del docap original (renombrado ahora como ModCrearTabla). Al código anterior no haré mención en la entrada actual.
(3) La forma en que se plantea este subproceso deriva directamente del modelo de trabajo empleado (trabajo en OOo Basic directamente desde el IDE) , incluyendo el uso de un comentario que clarifica cómo se debe proceder. De prestar una mínima atención al modo clásico de trabajo deberíamos crear un formulario de entrada de datos o recurrir a la función InputBox(), pero ahora eso es innecesario, ya que se espera que el usuario introduzca los datos directamente en el script.
(4) Solución que aplicaremos cuando llegue el momento. Por ahora es suficiente con exponer cómo acceder a los datos de una columna | variable | campo y te aconsejo que practiques este procedimiento hasta tener seguridad en su manejo.


No hay comentarios:

Publicar un comentario

Comenta esta entrada