Le code suivant me donne l'erreur 9 "indice en dehors de la plage". Je voulais déclarer un tableau dynamique afin que la dimension change à mesure que j'y ajoute des éléments. Dois-je créer un "spot" sur le tableau avant de stocker quelque chose comme dans JS?
Sub test_array()
Dim test() As Integer
Dim i As Integer
For i = 0 To 3
test(i) = 3 + i
Next i
End Sub
dans votre boucle for utilisez un Redim sur le tableau comme ici:
For i = 0 to 3
ReDim Preserve test(i)
test(i) = 3 + i
Next i
Oui, vous recherchez l'instruction ReDim
, qui alloue dynamiquement la quantité d'espace requise dans le tableau.
La déclaration suivante
Dim MyArray()
déclare un tableau sans dimensions, ainsi le compilateur ne sait pas quelle est sa taille et ne peut rien y stocker.
Mais vous pouvez utiliser l'instruction ReDim
pour redimensionner le tableau:
ReDim MyArray(0 To 3)
Et si vous avez besoin de redimensionner le tableau avec conservation son contenu, vous pouvez utiliser le mot clé Preserve
avec l'instruction ReDim
:
ReDim Preserve MyArray(0 To 3)
Mais notez que ReDim
et particulièrement ReDim Preserve
ont un coût de performance élevé. Essayez d'éviter de faire cela encore et encore dans une boucle si possible; vos utilisateurs vous remercieront.
Toutefois, dans l'exemple simple présenté dans votre question (s'il ne s'agit pas d'un exemple à jeter), vous n'avez pas du tout besoin de ReDim
. Il suffit de déclarer le tableau avec des dimensions explicites:
Dim MyArray(0 To 3)
Comme Cody et Brett l'ont mentionné, vous pouvez réduire le ralentissement de VBA avec une utilisation judicieuse de Redim Preserve
. Brett a suggéré que Mod
le fasse.
Vous pouvez également utiliser Type
et Sub
définis par l'utilisateur pour ce faire. Considérons mon code ci-dessous:
Public Type dsIntArrayType
eElems() As Integer
eSize As Integer
End Type
Public Sub PushBackIntArray( _
ByRef dsIntArray As dsIntArrayType, _
ByVal intValue As Integer)
With dsIntArray
If UBound(.eElems) < (.eSize + 1) Then
ReDim Preserve .eElems(.eSize * 2 + 1)
End If
.eSize = .eSize + 1
.eElems(.eSize) = intValue
End With
End Sub
Ceci appelle ReDim Preserve
Uniquement lorsque la taille a doublé. La variable membre eSize
assure le suivi de la taille réelle des données de eElems
. Cette approche m'a aidé à améliorer les performances lorsque la longueur de la matrice finale n'est pas connue jusqu'au moment de l'exécution.
J'espère que cela aide les autres aussi.
En plus des commentaires utiles de Cody, il est intéressant de noter que vous ne saurez parfois pas à quel point votre tableau doit être grand. Les deux options dans cette situation sont
Redim Preserve
Le code ci-dessous fournit un exemple de routine qui dimensionnera myArray
conformément à la variable lngSize
, puis ajoutera des éléments supplémentaires (égaux à la taille initiale du tableau) à l'aide de Mod
tester chaque fois que la limite supérieure est sur le point d'être dépassée
Option Base 1
Sub ArraySample()
Dim myArray() As String
Dim lngCnt As Long
Dim lngSize As Long
lngSize = 10
ReDim myArray(1 To lngSize)
For lngCnt = 1 To lngSize*5
If lngCnt Mod lngSize = 0 Then ReDim Preserve myArray(1 To UBound(myArray) + lngSize)
myArray(lngCnt) = "I am record number " & lngCnt
Next
End Sub
Je vois beaucoup (tous) de messages ci-dessus qui s'appuient sur LBound
/UBound
fait appel à un tableau dynamique VBA non encore potentiellement initialisé, ce qui cause la mort inévitable de l'application ...
Code erratique:
Dim x As Long Dim arr1() As SomeType ... x = UBound(arr1) 'crashes
Code correct:
Dim x As Long Dim arr1() As SomeType ... ReDim Preserve arr1(0 To 0) ... x = UBound(arr1)
... c’est-à-dire tout code dans lequel Dim arr1()
est immédiatement suivi de LBound(arr1)
/UBound(arr1)
sans appels de ReDim arr1(...)
, se bloque. Le rond-point doit employer un On Error Resume Next
Et vérifier le Err.Number
Juste après l'appel LBound(arr1)
/UBound(arr1)
- il devrait être 0 si le tableau est initialisé , sinon non nul. Comme il existe certains problèmes de comportement intégrés à VBA, une vérification supplémentaire des limites de array est nécessaire. Des explications détaillées peuvent être lues par tout le monde sur site Web de Chip Pearson (qui devrait être célébré comme un trésor de l'humanité de la sagesse de VBA ...)
Heh, c'est mon premier post, crois que c'est lisible.