Repasaremos algunos conceptos fundamentales para trabajar con VBA como puede ser la carga de datos en una Array.
No vamos a descubrir ahora a nadie las bondades de trabajar con Arrays en nuestros códigos... la rapidez y agilidad a la hora de trasladar o sencillamente trabajar con datos cargados es simplemente 'brutal'.
Imagina una tabla de datos con 51 campos y 240.000 registros... son muchos datos... de hecho el fichero pesa alrededor de 60 Mb (mucho para un fichero solo con datos y cero cálculo).
Veamos algunos de los procesos habituales de carga de datos desde nuestra celdas a una Array.
Accedemos a un módulo estándar del editor de VBA y escribimos:
Por otra parte crearemos dos módulos de clase.
El primero llamado 'Clase1' que contiene los siguientos procesos:
En este módulo de clase creamos un 'objeto matriz' cargando datos de la hoja de cálculo con un procedimiento 'Sub Class_Initializa', el cual carga el objeto m_Array con los datos de la tabla cuando desde un módulo estandar, por ejemplo, se llame a ese 'objeto' Clase1.
Además he generado distintas propiedades del objeto que permiten obtener un vector, un conjunto de vectores o simplemente la totalidad de la matriz, a partir de la Array cargada.
Necesitamos un módulo de clase más... llamado 'clsCargaArrays', con un simple procedimiento Function:
Si lanzamos varias veces nuestro procedimiento, y vemos el tiempo requerido por cada forma descrita, veremos lo siguiente:
Observamos tiempos de carga prácticamente idénticos, por lo que la decisión de optar por uno u otro es decisión personal...
Nota que estamos simplemente cargando 12.240.000 de celdas con datos, sin ningún otro procesamiento... y que una carga cualquiera de ese volumen de información neutra consume alrededor de 2,5 segundos!!! (asombroso!).
Siempre práctico tener alternativas de trabajo... en este claso incluyendo el trabajo (en varias formas) con Módulos de clase.
No vamos a descubrir ahora a nadie las bondades de trabajar con Arrays en nuestros códigos... la rapidez y agilidad a la hora de trasladar o sencillamente trabajar con datos cargados es simplemente 'brutal'.
Imagina una tabla de datos con 51 campos y 240.000 registros... son muchos datos... de hecho el fichero pesa alrededor de 60 Mb (mucho para un fichero solo con datos y cero cálculo).
Veamos algunos de los procesos habituales de carga de datos desde nuestra celdas a una Array.
Accedemos a un módulo estándar del editor de VBA y escribimos:
Sub OptimizandoCargaDatos()
Start = Timer 'inicia el contador de tiempo
Dim Tbl As ListObject
Set Tbl = ActiveSheet.ListObjects(1)
''A) bien cargamos la matriz directamente
arrDatos1 = Tbl.DataBodyRange.Value
finA = Round(Timer - Start, 3) 'contabilizamos tiempo de carga
Start = Timer 'inicia el contador de tiempo
'
''B)) o alternativamente a través de una función...
'dentro de nuestro módulo estándar
arrDatos2 = CargaArrays
finB = Round(Timer - Start, 3) 'contabilizamos tiempo de carga
Start = Timer 'inicia el contador de tiempo
'
''C) o desde un módulo de clase
Dim arrClase As New clsCargaArrays
arrDatos3 = arrClase.CargaMatrices
finC = Round(Timer - Start, 3) 'contabilizamos tiempo de carga
Start = Timer 'inicia el contador de tiempo
''D) cargándolo usando Properties desde el módulo de clase
Dim arrMatriz As New Clase1
arrDatos5 = arrMatriz.TodaMatriz
Fin_D = Round(Timer - Start, 3) 'contabilizamos tiempo de carga
Start = Timer 'inicia el contador de tiempo
''Tip/bonus: Seleccionar ciertas columnas de la Matriz
Set arrTest = New Clase1
arrDatos1_3 = arrTest.SelectCols(Array(1, 3))
fin_E = Round(Timer - Start, 3) 'contabilizamos tiempo de carga
Debug.Print "A (carga directa clásica): " & finA & vbCrLf & _
"B (a través de UDF): " & finB & vbCrLf & _
"C (1-módulo clase - funcion): " & finC & vbCrLf & _
"D (2-modulo clase Property Get: " & Fin_D & vbCrLf & _
"E (Bonus: Seleccionar columnas de la Array): " & fin_E & vbCrLf & "___________________"
Set Tbl = Nothing
Set arrTest = Nothing
End Sub
''''''''''''''
Function CargaArrays() As Variant
CargaArrays = ActiveSheet.ListObjects(1).DataBodyRange.Value
End Function
Por otra parte crearemos dos módulos de clase.
El primero llamado 'Clase1' que contiene los siguientos procesos:
Dim m_Array As Range
'--------------------------------------------
Private Sub Class_Initialize()
Set m_Array = ActiveSheet.ListObjects(1).DataBodyRange
End Sub
'--------------------------------------------
Private Sub Class_Terminate()
Set m_Array = Nothing
End Sub
'--------------------------------------------
Property Get ColVector(n As Long) As Variant
'funciona y devuelve el vector completo
ColVector = Empty
On Error GoTo Err_Handler
ColVector = m_Array.Columns(n)
Exit Property
Err_Handler:
End Property
'--------------------------------------------
Property Get SelectCols(nCols() As Variant) As Variant
SelectCols = Empty
On Error GoTo Err_Handler
SelectCols = Application.Index(m_Array, Evaluate("Row(1:" & m_Array.Rows.Count & ")"), nCols)
Exit Property
Err_Handler:
End Property
'--------------------------------------------
Property Get TodaMatriz() As Variant
TodaMatriz = Empty
On Error GoTo Err_Handler
TodaMatriz = m_Array
Exit Property
Err_Handler:
End PropertyEn este módulo de clase creamos un 'objeto matriz' cargando datos de la hoja de cálculo con un procedimiento 'Sub Class_Initializa', el cual carga el objeto m_Array con los datos de la tabla cuando desde un módulo estandar, por ejemplo, se llame a ese 'objeto' Clase1.
Además he generado distintas propiedades del objeto que permiten obtener un vector, un conjunto de vectores o simplemente la totalidad de la matriz, a partir de la Array cargada.
Necesitamos un módulo de clase más... llamado 'clsCargaArrays', con un simple procedimiento Function:
Function CargaMatrices() As Variant
CargaMatrices = ActiveSheet.ListObjects(1).DataBodyRange.Value
End FunctionSi lanzamos varias veces nuestro procedimiento, y vemos el tiempo requerido por cada forma descrita, veremos lo siguiente:
Observamos tiempos de carga prácticamente idénticos, por lo que la decisión de optar por uno u otro es decisión personal...
Nota que estamos simplemente cargando 12.240.000 de celdas con datos, sin ningún otro procesamiento... y que una carga cualquiera de ese volumen de información neutra consume alrededor de 2,5 segundos!!! (asombroso!).
Siempre práctico tener alternativas de trabajo... en este claso incluyendo el trabajo (en varias formas) con Módulos de clase.



No hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.