VBA
Kopiowanie, zwracanie i przekazywanie tablic
Szukaj…
Kopiowanie tablic
Możesz skopiować tablicę VBA do tablicy tego samego typu za pomocą operatora =
. Tablice muszą być tego samego typu, w przeciwnym razie kod zgłosi błąd kompilacji „Nie można przypisać do tablicy”.
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
Tablica źródłowa może być stała lub dynamiczna, ale tablica docelowa musi być dynamiczna. Próba skopiowania do stałej tablicy spowoduje błąd kompilacji „Nie można przypisać do tablicy”. Wszelkie istniejące wcześniej dane w tablicy odbiorczej zostaną utracone, a ich granice i wymiary zostaną zmienione na takie same jak w tablicy źródłowej.
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)
Po utworzeniu kopii dwie tablice są oddzielne w pamięci, tzn. Dwie zmienne nie są odniesieniami do tych samych podstawowych danych, więc zmiany dokonane w jednej tablicy nie pojawiają się w drugiej.
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
Kopiowanie tablic obiektów
W przypadku tablic obiektów odniesienia do tych obiektów są kopiowane, a nie same obiekty. Jeśli zmiana zostanie dokonana na obiekcie w jednej tablicy, będzie się również wydawać, że została zmieniona w drugiej tablicy - oba odnoszą się do tego samego obiektu. Jednak ustawienie elementu na inny obiekt w jednej tablicy nie spowoduje ustawienia tego obiektu na inny obiekt.
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
Warianty zawierające tablicę
Możesz także skopiować tablicę do i ze zmiennej wariantowej. Podczas kopiowania z wariantu musi on zawierać tablicę tego samego typu co tablica odbiorcza, w przeciwnym razie wygeneruje błąd środowiska wykonawczego „Niezgodność typu”.
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
Zwracanie tablic z funkcji
Funkcja w normalnym module (ale nie w module klasy) może zwrócić tablicę, wstawiając ()
po typie danych.
Function arrayOfPiDigits() As Long()
Dim outputArray(0 To 2) As Long
outputArray(0) = 3
outputArray(1) = 1
outputArray(2) = 4
arrayOfPiDigits = outputArray
End Function
Wynik funkcji można następnie umieścić w dynamicznej tablicy tego samego typu lub wariantu. Dostęp do elementów można również uzyskać bezpośrednio za pomocą drugiego zestawu nawiasów, jednak wywoła to funkcję za każdym razem, więc najlepiej przechowywać wyniki w nowej tablicy, jeśli planujesz ich używać więcej niż jeden raz
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
Zwróć uwagę, że zwracana jest w rzeczywistości kopia tablicy wewnątrz funkcji, a nie odwołanie. Jeśli więc funkcja zwraca zawartość tablicy statycznej, jej danych nie można zmienić za pomocą procedury wywołującej.
Wyprowadzanie tablicy za pomocą argumentu wyjściowego
Zwykle dobrą praktyką kodowania jest wprowadzanie argumentów procedury i wprowadzanie ich za pomocą wartości zwracanej. Jednak ograniczenia VBA czasami wymagają procedury generowania danych za pomocą argumentu ByRef
.
Przesyłanie do stałej tablicy
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
Wyprowadzanie tablicy z metody klasy
Argument wyjściowy może być również użyty do wyprowadzenia tablicy z metody / postępowania w module klasy
' 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
Przekazywanie tablic do procedur
Tablice można przekazywać do postępów, wstawiając ()
po nazwie zmiennej tablicowej.
Function countElements(ByRef arr() As Double) As Long
countElements = UBound(arr) - LBound(arr) + 1
End Function
Tablice muszą być przekazywane przez odniesienie. Jeśli nie zostanie określony żaden mechanizm przekazywania, np. myFunction(arr())
, wówczas VBA domyślnie przyjmie ByRef
, jednak dobrą praktyką kodowania jest jawne wyrażanie tego. Próba przekazania tablicy przez wartość, np. myFunction(ByVal arr())
spowoduje błąd kompilacji „Array musi być ByRef” (lub błąd kompilacji „Błąd składni”, jeśli opcja Auto Syntax Check
nie jest zaznaczona w opcjach VBE) .
Przekazywanie przez odniesienie oznacza, że wszelkie zmiany w tablicy zostaną zachowane w procedurze wywołania.
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
Jeśli chcesz uniknąć zmiany oryginalnej tablicy, pamiętaj o napisaniu funkcji, aby nie zmieniała ona żadnych elementów.
Function doubleAndSum(ByRef arr() As Long)
doubleAndSum = arr(0) * 2 + arr(1) * 2
End Function
Alternatywnie utwórz kopię roboczą tablicy i pracuj z kopią.
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