Crear una matriz a partir de un rango en VBA

Resuelto basaltanglia asked hace 8 años • 9 respuestas

Tengo un problema aparentemente básico pero no encuentro ningún recurso para solucionarlo.

En pocas palabras, solo quiero cargar el contenido de un rango de celdas (todas una columna) en una matriz.

Puedo lograr esto por medio de

DirArray = Array(Range("A1"), Range("A2"))

Pero por alguna razón, no puedo crear la matriz cuando se expresa de esta manera:

DirArray = Array(Range("A1:A2"))

Mi rango real es mucho más largo (y puede variar en longitud), por lo que no quiero tener que enumerar las celdas individualmente de esta manera. ¿Alguien puede decirme cómo cargar correctamente un rango completo en una matriz?

Con el último código:

MsgBox UBound(DirArray, 1)

Y

MsgBox UBound(DirArray)

Devuelve 0, mientras que con el primero devuelve 1.

basaltanglia avatar Jun 08 '16 04:06 basaltanglia
Aceptado

Simplemente defina la variable como una variante y hágalas iguales:

Dim DirArray As Variant
DirArray = Range("a1:a5").Value

No es necesario el comando Array.

vacip avatar Jun 07 '2016 21:06 vacip

Si lo hacemos así:

Dim myArr as Variant
myArr = Range("A1:A10")

la nueva matriz tendrá dos dimensiones. Con lo cual no siempre es cómodo trabajar:

ingrese la descripción de la imagen aquí

Para alejarnos de las dos dimensiones, al convertir una sola columna en una matriz, podemos usar la función incorporada de Excel "Transponer". Con él, los datos pasan a tener una dimensión:

ingrese la descripción de la imagen aquí

Si tenemos los datos en una fila, una sola transposición no funcionará. Necesitamos usar la función Transponer dos veces:

ingrese la descripción de la imagen aquí

Nota: Como puede ver en las capturas de pantalla, cuando se generan de esta manera, las matrices comienzan con 1, no con 0. Solo tenga un poco de cuidado.

Edición de junio de 2021: en versiones más nuevas de Excel, la función es:Application.WorksheetFunction.Transpose()

Edición de febrero de 2024: hice un video de YouTube que lo explica: https://www.youtube.com/watch?v=cGKUdKCSQxk

Vityata avatar Sep 23 '2018 14:09 Vityata

El uso Value2proporciona un beneficio de rendimiento. Según el blog de Charles Williams

Range.Value2 funciona de la misma manera que Range.Value, excepto que no verifica el formato de la celda y lo convierte a Fecha o Moneda. Y probablemente por eso es más rápido que .Value al recuperar números.

Entonces

DirArray = [a1:a5].Value2

Lectura adicional

  • Range.Value : Devuelve o establece un valor de variante que representa el valor del rango especificado.
  • Range.Value2 : la única diferencia entre esta propiedad y la propiedad Value es que la propiedad Value2 no utiliza los tipos de datos Moneda y Fecha.
brettdj avatar Jun 08 '2016 01:06 brettdj

Además de las soluciones propuestas, y en caso de que tenga un rango 1D a una matriz 1D, prefiero procesarlo mediante una función como la siguiente. La razón es simple: si por alguna razón su rango se reduce a 1 elemento, hasta donde yo sé, el comando Rango().Valor no devolverá una matriz variante sino solo una variante y no podrá asignar una variante. variable a una matriz variante (previamente declarada).

Tuve que convertir un rango de tamaño variable en una matriz doble, y cuando el rango era de 1 tamaño de celda, no pude usar una construcción como range().value, así que procedo con una función como la siguiente.

Public Function Rng2Array(inputRange As Range) As Double()

    Dim out() As Double    
    ReDim out(inputRange.Columns.Count - 1)

    Dim cell As Range
    Dim i As Long
    For i = 0 To inputRange.Columns.Count - 1
        out(i) = inputRange(1, i + 1) 'loop over a range "row"
    Next

    Rng2Array = out  
End Function
Paolo avatar May 06 '2019 11:05 Paolo

Esta función devuelve una matriz independientemente del tamaño del rango.

Los rangos devolverán una matriz a menos que el rango sea solo de 1 celda y luego devuelva un valor único. Esta función convertirá el valor único en una matriz (basada en 1, igual que la matriz devuelta por rangos)

Esta respuesta mejora las respuestas anteriores, ya que devolverá una matriz de un rango sin importar el tamaño. También es más eficiente que otras respuestas, ya que, si es posible, devolverá la matriz generada por el rango. Funciona con matrices unidimensionales y multidimensionales.

La función funciona intentando encontrar los límites superiores de la matriz. Si eso falla, entonces debe ser un valor único, por lo que crearemos una matriz y le asignaremos el valor.

Public Function RangeToArray(inputRange As Range) As Variant()
Dim size As Integer
Dim inputValue As Variant, outputArray() As Variant

    ' inputValue will either be an variant array for ranges with more than 1 cell
    ' or a single variant value for range will only 1 cell
    inputValue = inputRange

    On Error Resume Next
    size = UBound(inputValue)

    If Err.Number = 0 Then
        RangeToArray = inputValue
    Else
        On Error GoTo 0
        ReDim outputArray(1 To 1, 1 to 1)
        outputArray(1,1) = inputValue
        RangeToArray = outputArray
    End If

    On Error GoTo 0

End Function
Darryls99 avatar Oct 27 '2020 21:10 Darryls99