VBA
Copiando, devolviendo y pasando matrices.
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