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 Property
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:
Function CargaMatrices() As Variant CargaMatrices = ActiveSheet.ListObjects(1).DataBodyRange.Value End 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 hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.