VBA
Arrays kopiëren, retourneren en doorgeven
Zoeken…
Arrays kopiëren
U kunt een VBA-array naar een array van hetzelfde type kopiëren met de operator =
. De arrays moeten van hetzelfde type zijn, anders geeft de code een compilatiefout "Kan niet toewijzen aan array".
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
De bronarray kan vast of dynamisch zijn, maar de doelarray moet dynamisch zijn. Als u probeert te kopiëren naar een vaste array, wordt de compilatiefout 'Kan niet aan array toewijzen' weergegeven. Alle bestaande gegevens in de ontvangende array gaan verloren en de grenzen en dimensies worden gewijzigd in dezelfde als de bronarray.
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)
Nadat de kopie is gemaakt, zijn de twee arrays gescheiden in het geheugen, dat wil zeggen dat de twee variabelen geen verwijzingen zijn naar dezelfde onderliggende gegevens, zodat wijzigingen in de ene array niet in de andere worden weergegeven.
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
Arrays of Objects kopiëren
Bij arrays van objecten worden de verwijzingen naar die objecten gekopieerd, niet de objecten zelf. Als een wijziging wordt aangebracht in een object in de ene array, lijkt het ook te zijn gewijzigd in de andere array - beide verwijzen naar hetzelfde object. Als u een element instelt op een ander object in de ene array, wordt het echter niet ingesteld op dat object in de andere array.
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
Varianten die een array bevatten
U kunt ook een array naar en van een variabelevariabele kopiëren. Bij het kopiëren van een variant moet deze een array van hetzelfde type bevatten als de ontvangende array, anders wordt een runtime-fout "Type mismatch" weergegeven.
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
Arrays uit functies retourneren
Een functie in een normale module (maar geen Class-module) kan een array retourneren door ()
achter het gegevenstype te plaatsen.
Function arrayOfPiDigits() As Long()
Dim outputArray(0 To 2) As Long
outputArray(0) = 3
outputArray(1) = 1
outputArray(2) = 4
arrayOfPiDigits = outputArray
End Function
Het resultaat van de functie kan vervolgens in een dynamische reeks van hetzelfde type of een variant worden geplaatst. De elementen kunnen ook rechtstreeks worden geopend met behulp van een tweede set haakjes, maar dit roept de functie elke keer op, dus het is het beste om de resultaten in een nieuwe array op te slaan als u van plan bent ze meer dan eens te gebruiken
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
Merk op dat wat wordt geretourneerd eigenlijk een kopie is van de array in de functie, geen referentie. Dus als de functie de inhoud van een statische array retourneert, kunnen de gegevens niet worden gewijzigd door de aanroepprocedure.
Een array uitvoeren via een uitvoerargument
Het is normaal gesproken een goede coderingspraktijk om de argumenten van een procedure in te voeren en uit te voeren via de retourwaarde. Vanwege de beperkingen van VBA is het echter soms nodig dat een procedure gegevens uitvoert via een ByRef
argument.
Uitvoer naar een vaste array
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
Een array uitvoeren vanuit een Class-methode
Een uitvoerargument kan ook worden gebruikt om een array uit een methode / procedure in een Class-module uit te voeren
' 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
Arrays doorgeven aan Proceedures
Arrays kunnen worden doorgegeven aan de procedure door ()
achter de naam van de arrayvariabele te plaatsen.
Function countElements(ByRef arr() As Double) As Long
countElements = UBound(arr) - LBound(arr) + 1
End Function
Arrays moeten worden doorgegeven door middel van verwijzing. Als er geen passerend mechanisme is opgegeven, bijvoorbeeld myFunction(arr())
, dan zal VBA standaard ByRef
aannemen, maar het is een goede codeerpraktijk om het expliciet te maken. Als u probeert een array op waarde door te geven, bijvoorbeeld myFunction(ByVal arr())
krijgt u een compilatiefout 'Array-argument moet ByRef' zijn (of een compilatiefout 'Syntaxfout' als Auto Syntax Check
niet is ingeschakeld in de VBE-opties) .
Doorgeven door verwijzing betekent dat alle wijzigingen in de array worden behouden in de aanroepprocedure.
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
Als u wilt voorkomen dat de oorspronkelijke array wordt gewijzigd, moet u de functie zo schrijven dat deze geen elementen verandert.
Function doubleAndSum(ByRef arr() As Long)
doubleAndSum = arr(0) * 2 + arr(1) * 2
End Function
U kunt ook een werkkopie van de array maken en met de kopie werken.
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