Buscar..


Copiando Arrays

Puede copiar una matriz VBA en una matriz del mismo tipo utilizando el operador = . Las matrices deben ser del mismo tipo, de lo contrario, el código arrojará un error de compilación "No se puede asignar a la matriz".

Dim source(0 to 2) As Long
Dim destinationLong() As Long
Dim destinationDouble() As Double

destinationLong = source     ' copies contents of source into destinationLong
destinationDouble = source   ' does not compile

La matriz de origen puede ser fija o dinámica, pero la matriz de destino debe ser dinámica. Si intenta copiar en una matriz fija, se producirá un error de compilación "No se puede asignar a la matriz". Cualquier dato preexistente en la matriz receptora se pierde y sus límites y dimensiones se cambian al mismo que la matriz de origen.

Dim source() As Long
ReDim source(0 To 2)

Dim fixed(0 To 2) As Long
Dim dynamic() As Long

fixed = source   ' does not compile
dynamic = source ' does compile

Dim dynamic2() As Long
ReDim dynamic2(0 to 6, 3 to 99) 

dynamic2 = source ' dynamic2 now has dimension (0 to 2)

Una vez que se realiza la copia, las dos matrices se separan en la memoria, es decir, las dos variables no son referencias a los mismos datos subyacentes, por lo que los cambios realizados en una matriz no aparecen en la otra.

Dim source(0 To 2) As Long
Dim destination() As Long

source(0) = 3
source(1) = 1
source(2) = 4

destination = source
destination(0) = 2

Debug.Print source(0); source(1); source(2)                ' outputs: 3 1 4
Debug.Print destination(0); destination(1); destination(2) ' outputs: 2 1 4

Copiar matrices de objetos

Con matrices de objetos, las referencias a esos objetos se copian, no los objetos en sí. Si se realiza un cambio en un objeto en una matriz, también parecerá que se cambia en la otra matriz; ambos hacen referencia al mismo objeto. Sin embargo, establecer un elemento en un objeto diferente en una matriz no lo establecerá en ese objeto en la otra matriz.

Dim source(0 To 2) As Range
Dim destination() As Range

Set source(0) = Range("A1"): source(0).Value = 3
Set source(1) = Range("A2"): source(1).Value = 1
Set source(2) = Range("A3"): source(2).Value = 4

destination = source

Set destination(0) = Range("A4")   'reference changed in destination but not source

destination(0).Value = 2           'affects an object only in destination
destination(1).Value = 5           'affects an object in both source and destination

Debug.Print source(0); source(1); source(2)                  ' outputs 3 5 4
Debug.Print destination(0); destination(1); destination(2)   ' outputs 2 5 4

Variantes que contienen una matriz

También puede copiar una matriz en y desde una variable variable. Al copiar desde una variante, debe contener una matriz del mismo tipo que la matriz receptora, de lo contrario lanzará un error de tiempo de ejecución "No coincide el tipo".

Dim var As Variant
Dim source(0 To 2) As Range
Dim destination() As Range

var = source
destination = var

var = 5
destination = var  ' throws runtime error

Devolviendo Arrays desde Funciones

Una función en un módulo normal (pero no en un módulo de clase) puede devolver una matriz poniendo () después del tipo de datos.

Function arrayOfPiDigits() As Long()
    Dim outputArray(0 To 2) As Long
    
    outputArray(0) = 3
    outputArray(1) = 1
    outputArray(2) = 4

    arrayOfPiDigits = outputArray
End Function

El resultado de la función se puede colocar en una matriz dinámica del mismo tipo o una variante. También se puede acceder directamente a los elementos utilizando un segundo conjunto de corchetes, sin embargo, esto llamará a la función cada vez, por lo que es mejor almacenar los resultados en una nueva matriz si planea usarlos más de una vez.

Sub arrayExample()

    Dim destination() As Long
    Dim var As Variant
    
    destination = arrayOfPiDigits()
    var = arrayOfPiDigits
    
    Debug.Print destination(0)          ' outputs 3
    Debug.Print var(1)                  ' outputs 1
    Debug.Print arrayOfPiDigits()(2)    ' outputs 4
    
End Sub

Tenga en cuenta que lo que se devuelve es en realidad una copia de la matriz dentro de la función, no una referencia. Por lo tanto, si la función devuelve el contenido de una matriz estática, sus datos no pueden modificarse mediante el procedimiento de llamada.

Salida de una matriz a través de un argumento de salida

Normalmente es una buena práctica de codificación que los argumentos de un procedimiento sean entradas y resultados a través del valor de retorno. Sin embargo, las limitaciones de VBA a veces hacen que sea necesario que un procedimiento genere datos a través de un argumento ByRef .

Salida a una matriz fija

Sub threePiDigits(ByRef destination() As Long)
    destination(0) = 3
    destination(1) = 1
    destination(2) = 4
End Sub

Sub printPiDigits()
    Dim digits(0 To 2) As Long
    
    threePiDigits digits
    Debug.Print digits(0); digits(1); digits(2) ' outputs 3 1 4
End Sub

Salida de una matriz de un método de clase

Un argumento de salida también se puede usar para generar una matriz desde un método / procedimiento en un módulo de clase

' Class Module 'MathConstants'
Sub threePiDigits(ByRef destination() As Long)
    ReDim destination(0 To 2)
    
    destination(0) = 3
    destination(1) = 1
    destination(2) = 4
End Sub

' Standard Code Module
Sub printPiDigits()
    Dim digits() As Long
    Dim mathConsts As New MathConstants
    
    mathConsts.threePiDigits digits
    Debug.Print digits(0); digits(1); digits(2) ' outputs 3 1 4
End Sub

Pasando matrices a procedimientos

Las matrices se pueden pasar a los procedimientos poniendo () después del nombre de la variable de matriz.

Function countElements(ByRef arr() As Double) As Long
    countElements = UBound(arr) - LBound(arr) + 1
End Function

Las matrices deben ser pasadas por referencia. Si no se especifica ningún mecanismo de paso, por ejemplo, myFunction(arr()) , VBA asumirá ByRef de forma predeterminada, sin embargo, es una buena práctica de codificación para hacerlo explícito. Intentar pasar una matriz por valor, por ejemplo, myFunction(ByVal arr()) generará un error de compilación "El argumento de la matriz debe ser ByRef" (o un error de compilación "Error de sintaxis" si la Auto Syntax Check no está marcada en las opciones de VBE) .

Pasar por referencia significa que cualquier cambio en la matriz se conservará en el procedimiento de la llamada.

Sub testArrayPassing()
    Dim source(0 To 1) As Long
    source(0) = 3
    source(1) = 1
    
    Debug.Print doubleAndSum(source)  ' outputs 8
    Debug.Print source(0); source(1)  ' outputs 6 2
End Sub

Function doubleAndSum(ByRef arr() As Long)
    arr(0) = arr(0) * 2
    arr(1) = arr(1) * 2
    doubleAndSum = arr(0) + arr(1)
End Function

Si desea evitar cambiar la matriz original, tenga cuidado de escribir la función para que no cambie ningún elemento.

Function doubleAndSum(ByRef arr() As Long)
    doubleAndSum = arr(0) * 2 + arr(1) * 2
End Function

También puede crear una copia de trabajo de la matriz y trabajar con la copia.

Function doubleAndSum(ByRef arr() As Long)
    Dim copyOfArr() As Long
    copyOfArr = arr
    
    copyOfArr(0) = copyOfArr(0) * 2
    copyOfArr(1) = copyOfArr(1) * 2
    
    doubleAndSum = copyOfArr(0) + copyOfArr(1)
End Function


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow