VBA
Copier, retourner et passer des tableaux
Recherche…
Copier des tableaux
Vous pouvez copier un tableau VBA dans un tableau du même type en utilisant l'opérateur =
. Les tableaux doivent être du même type, sinon le code lancera une erreur de compilation "Impossible d'affecter au tableau".
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
Le tableau source peut être fixe ou dynamique, mais le tableau de destination doit être dynamique. Essayer de copier dans un tableau fixe lancera une erreur de compilation "Impossible d’affecter au tableau". Toutes les données préexistantes dans le tableau de réception sont perdues et ses limites et dimenions sont remplacées par celles du tableau source.
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)
Une fois la copie effectuée, les deux tableaux sont séparés en mémoire, c’est-à-dire que les deux variables ne sont pas des références aux mêmes données sous-jacentes, de sorte que les modifications apportées à un tableau n’apparaissent pas dans l’autre.
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
Copie de tableaux d'objets
Avec les tableaux d'objets, les références à ces objets sont copiées, pas les objets eux-mêmes. Si une modification est apportée à un objet dans un tableau, il semblera également être modifié dans l'autre tableau - ils font tous deux référence au même objet. Cependant, définir un élément sur un objet différent dans un tableau ne le définira pas sur cet autre tableau.
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 contenant un tableau
Vous pouvez également copier un tableau dans et à partir d'une variable variante. Lors de la copie à partir d'une variante, il doit contenir un tableau du même type que le tableau de réception, sinon une erreur d'exécution "Incompatibilité de type" apparaîtra.
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
Retour de tableaux à partir de fonctions
Une fonction dans un module normal (mais pas un module Class) peut retourner un tableau en mettant ()
après le type de données.
Function arrayOfPiDigits() As Long()
Dim outputArray(0 To 2) As Long
outputArray(0) = 3
outputArray(1) = 1
outputArray(2) = 4
arrayOfPiDigits = outputArray
End Function
Le résultat de la fonction peut alors être placé dans un tableau dynamique du même type ou d'une variante. Les éléments peuvent également être accédés directement en utilisant un deuxième ensemble de parenthèses, mais cela appellera la fonction à chaque fois, il est donc préférable de stocker les résultats dans un nouveau tableau si vous prévoyez de les utiliser plusieurs fois.
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
Notez que ce qui est retourné est en fait une copie du tableau à l'intérieur de la fonction, pas une référence. Donc, si la fonction renvoie le contenu d'un tableau statique, ses données ne peuvent pas être modifiées par la procédure d'appel.
Sortie d'un tableau via un argument de sortie
Normalement, il est conseillé de coder pour que les arguments d'une procédure soient des entrées et une sortie via la valeur de retour. Cependant, les limitations de VBA obligent parfois une procédure à produire des données via un argument ByRef
.
Sortie vers un tableau fixe
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
Sortie d'un tableau à partir d'une méthode de classe
Un argument de sortie peut également être utilisé pour générer un tableau à partir d’une méthode / procédure dans un module de classe.
' 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
Passer des tableaux à des procédures
Les tableaux peuvent être passés aux procédures en mettant ()
après le nom de la variable de tableau.
Function countElements(ByRef arr() As Double) As Long
countElements = UBound(arr) - LBound(arr) + 1
End Function
Les tableaux doivent être transmis par référence. Si aucun mécanisme de transmission n'est spécifié, par exemple myFunction(arr())
, alors VBA prendra ByRef
par défaut, mais il est ByRef
de le coder pour le rendre explicite. Essayer de passer un tableau par valeur, par exemple myFunction(ByVal arr())
provoquera une erreur de compilation "Array argument doit être ByRef" (ou une erreur de compilation "Syntax error" si l'option Auto Syntax Check
n'est pas cochée dans les options VBE) .
Passer par référence signifie que toute modification apportée à la matrice sera préservée dans la procédure d'appel.
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 vous voulez éviter de changer le tableau d'origine, faites attention à écrire la fonction pour qu'elle ne change aucun élément.
Function doubleAndSum(ByRef arr() As Long)
doubleAndSum = arr(0) * 2 + arr(1) * 2
End Function
Vous pouvez également créer une copie de travail du tableau et travailler avec la copie.
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