Sök…


Kopiering av matriser

Du kan kopiera en VBA-matris till en matris av samma typ med = operatören. Matriserna måste vara av samma typ annars kommer koden att kasta ett "Kan inte tilldela till array" kompilationsfel.

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

Källarrayen kan vara fixerad eller dynamisk, men destinationsgruppen måste vara dynamisk. Att försöka kopiera till en fast matris kommer att kasta ett kompilationsfel "Kan inte tilldela till array". All föregående data i den mottagande arrayen går förlorad och dess gränser och dimenioner ändras till samma som källarrayen.

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)

När kopian är gjord är de två matriserna separata i minnet, dvs de två variablerna är inte referenser till samma underliggande data, så ändringar gjorda i en matris visas inte i den andra.

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

Kopiera matriser av objekt

Med matriser av objekt kopieras referenser till dessa objekt, inte själva objekten. Om en förändring görs till ett objekt i en array verkar det också ändras i den andra arrayen - de båda hänvisar till samma objekt. Att ställa ett element till ett annat objekt i en array ställer dock inte in det objektet till det andra arrayet.

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

Varianter som innehåller en matris

Du kan också kopiera en matris till och från en variantvariabel. När du kopierar från en variant måste den innehålla en matris av samma typ som den mottagande matrisen, annars kommer det att kasta ett "typ misslyckande" runtime-fel.

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

Återvända matriser från funktioner

En funktion i en normal modul (men inte en klassmodul) kan returnera en matris genom att sätta () efter datatypen.

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

    arrayOfPiDigits = outputArray
End Function

Resultatet av funktionen kan sedan läggas in i en dynamisk grupp av samma typ eller en variant. Elementen kan också nås direkt genom att använda en andra uppsättning parenteser, men detta kommer att kalla funktionen varje gång, så det är bäst att lagra resultaten i en ny matris om du planerar att använda dem mer än en gång

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

Observera att det som returneras faktiskt är en kopia av matrisen i funktionen, inte en referens. Så om funktionen returnerar innehållet i en statisk matris kan dess data inte ändras med samtalsproceduren.

Skickar ut en matris via ett utgångsargument

Det är normalt bra kodningspraxis för en procedurs argument att vara ingångar och att mata ut via returvärdet. VBA-begränsningarna gör emellertid ibland nödvändigt för en procedur för att mata ut data via ett ByRef argument.

Utmatning till en fast grupp

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

Ange en matris från en klassmetod

Ett utgångsargument kan också användas för att mata ut en matris från en metod / framsteg i en klassmodul

' 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

Vidarebefordra matriser till förfaranden

Matriser kan skickas till förlopp genom att sätta () efter namnet på matrisvariabeln.

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

Matriser måste skickas som referens. Om ingen passeringsmekanism specificeras, t.ex. myFunction(arr()) , kommer VBA att anta ByRef standard, men det är bra kodningssätt att göra det uttryckligt. Att försöka skicka ett array efter värde, t.ex. myFunction(ByVal arr()) kommer att resultera i ett "Array-argument måste vara ByRef" -kompileringsfel (eller ett "Syntax-fel" -kompilationsfel om Auto Syntax Check är inte markerat i VBE-alternativen) .

Om du skickar en referens innebär att alla ändringar i matrisen kommer att bevaras i samtalsprocessen.

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

Om du vill undvika att ändra den ursprungliga arrayen ska du vara noga med att skriva funktionen så att den inte ändrar några element.

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

Skapa alternativt en fungerande kopia av matrisen och arbeta med kopian.

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow