Acceso a la tabla de datos
Como paso previo obligado para el análisis de los datos, también en soportes ofimáticos (aquí en Calc) necesitamos acceder a los datos contenidos en las tablas (de datos).
En la [entrada anterior] aprendimos a crear una tabla con ayuda de OOo Basic, así que ahora toca aprender a acceder a su contenido: 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 plantea de forma diferente y se resuelve directamente 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 visto en la entrada anterior, 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 prestaré atención a la entrada y salida de datos mediante escritura en la hoja de cálculo, proceso que únicamente realizaré 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 modo de uso de un lenguaje como OOo Basic, pero es muy común en lenguajes como Python y R (especialmente este último). Empleándolo me quiero acercar a este modo de trabajo, de paso que eludiendo el trabajo (ahora irrelevante) que supone diseñar interfaces de usuario y desarrollar procedimientos de escritura en Calc. Se espera que a estas alturas del proceso de aprendizaje LO-Calc - OOo Basic esta forma de trabajo no te genere ninguna dificultad, aunque te resulte extraña.
Para concretar y ejemplificar estos procedimientos de acceso a los datos (a la tabla de datos previamente creada, sería más exacto decir) 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 empleado más frecuentemente en el análisis de datos.
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
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)
mDatosCol(i) = CInt(oCelda.getString)
ElseIf vTipoDat = "T" Then
mDatosCol(i) = oCelda.getString
Tras declarar las variables, asignamos valores a aquellas que nos permiten dimensionar la matriz de datos (ReDim mDatosCol(vN)) y acceder a la hoja (vHoja = "Datos") y a la columna (vCol = "E") donde se encuentran los 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 dato, según veremos después.
Lo que sigue es acceder a la hoja (oHoja = ThisComponent.getSheets().getByName(vHoja)) y después, mediante 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 una estructura condicional compleja para acceder a números (If vTipoDat = "N" Then) -> (mDatosCol(i) = CInt(oCelda.getString)) y para acceder a textos (ElseIf vTipoDat = "T" Then) -> (mDatosCol(i) = oCelda.getString).
Ahora 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 supone hacer más extenso el script, pero no necesariamente más complejo. Aun así, en caso de que el script resulte demasiado extenso y se haga difícil de manejar, podremos optar por crear una función o una subrutina con la que solventar los procedimientos que se repiten varias veces en el script (4).
El acceso a una determinada fila | registro de la tabla, en principio, no es muy diferente al modo que utilizamos para grabar los datos en una fila, según quedó explicado en entradas anteriores [por ejemplo en esta], y que empleamos para crear el docap de creació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)) asociada 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) e identificamos el Id el registro deseado (vFil = 5).
Después ejecutamos la estructura ciclo-condicional-ciclo que nos permite acceder al contenido de los campos de ese registro. Para ello recorremos la tabla o 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 se deberá repetir 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