miércoles, 5 de agosto de 2015

VBA: El uso de Arrays en nuestras macros - Citius, Altius, Fortius.

Veremos hoy una de las ventajas de trabajar con Arrays (matrices) en nuestras programaciones de VBA para Excel... y es que sin duda, aportan rapidez y agilidad a nuestros procesos.
Pondré como ejemplo el tratamiento celda a celda, para convertir números almacenados como texto, que expuse en esta entrada.

Si medimos tiempos de ejecución, la macro del link anterior emplea +/- 6 segundos para convertir unas 8.000 celdas con números como texto...
mientras que la macro siguiente sólo necesita 0.20 segundos!!!.

La diferencia es más que importante.


Insertamos el código de nuestra macro en un módulo estándar de nuestro proyecto de VBA desde el editor de VB:

Sub ConvertirNumeros()
Dim TempArray As Variant    'nuestra Array
Dim rw As Long, col As Long
Dim rng As Range

Set rng = Range("A1").CurrentRegion

'Emplearemos la propiedad de Range . Value2
'Sabiendo que la única diferencia que hay entre .Value2 y .Value,
'es que Value2 no utiliza los tipos de datos Currency y Date.
'Puede devolver valores que tengan el formato de estos tipos de datos como números de punto flotante
'usando el tipo de datos Double.

TempArray = rng.Value2
If IsArray(TempArray) Then
    'si es una matriz entonces la recorremos por filas y columnas...
    For rw = LBound(TempArray, 1) To UBound(TempArray, 1)
        For col = LBound(TempArray, 2) To UBound(TempArray, 2)
            'comprobamos si el valor de cada celda es un número
            If IsNumeric(TempArray(rw, col)) Then
                'cargamos la matriz/Array
                TempArray(rw, col) = CDbl(TempArray(rw, col))
            Else
                'o en caso contrario es texto..
                'eliminamos posibles espacios sobrantes
                'cargamos la matriz/Array
                TempArray(rw, col) = Application.Trim(TempArray(rw, col))
            End If
        Next col
    Next rw
Else
    'si NO es una matriz (será una celda sola)
    If IsNumeric(TempArray) Then 'si es un número...
        'cargamos la matriz/Array
        TempArray = CDbl(TempArray)
    Else 'o si es texto....
        'cargamos la matriz/Array
        TempArray = Application.Trim(TempArray)
    End If
End If
  
'Devolvemos al rango de estudio los valores de la matriz/Array
rng.Value2 = TempArray

End Sub



La recomendación es clara, siempre que sea posible, trabajemos con matrices/arrays.

2 comentarios:

  1. Estimado Israel, buenas tardes.

    Intente seguir tu ejemplo para desarrollar una macro que haga lo siguiente:

    Tengo una tabla con 6 columnas (Partida, Codigo, Codigo Auxiliar, Descripción, Unidad y Cantidad).

    En la primer columna hay varias partidas, algunas con el mismo valor, pero con distinto código, el punto es que necesito identificar las celdas con igual partida y código para que sume la cantidad y después borrar las filas que ya sumo sin sair de la partida.
    tengo la tabla para su envio en caso de ser necesario.

    ResponderEliminar
    Respuestas
    1. Hola Marlon,
      no me queda claro la acción, ¿quieres trabajar sobre la misma tabla o obtener otra tabla diferente con el resultado?...
      En todo caso, parece (por lo que entendí) que buscar un acumulado que te aportaría una tabla dinámica agrupando por partida y Código, sumando Unidad y Cantidad...
      Quizá sea esa una solución más limpia...
      Slds

      Eliminar

Nota: solo los miembros de este blog pueden publicar comentarios.