🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA ReDim dans Excel — Redimensionner des tableaux avec ReDim et ReDim Preserve

|

VBA ReDim dans Excel — Redimensionner des tableaux avec ReDim et ReDim Preserve

TL;DR — Un tableau VBA verrouille sa taille dès l'instant où vous le Dimsauf si vous laissez les crochets vides. Dim a() déclare un tableau dynamique sans taille pour l'instant ; ReDim a(1 To 10) lui en donne une. Un ReDim simple jette toutes les valeurs qu'il contenait, si bien que pour agrandir un tableau sans perdre les données, vous utilisez ReDim Preserve. Le piège : sur un tableau à deux dimensions, ReDim Preserve ne peut redimensionner que la dernière dimension. Les tableaux de taille fixe (Dim a(1 To 10)) ne peuvent jamais être redimensionnés avec ReDim.

Sub GrowAnArray()
    Dim a() As Long                 ' dynamique - pas encore de taille
    ReDim a(1 To 3)                 ' contient maintenant 3 Long
    a(1) = 10: a(2) = 20: a(3) = 30

    ReDim Preserve a(1 To 5)        ' agrandit a 5, GARDE 10, 20, 30
    a(4) = 40: a(5) = 50            ' un ReDim simple ici aurait efface 10-30
End Sub

ReDim est toute l'histoire des tableaux dynamiques. Déclarez le tableau ouvert avec Dim a(), donnez-lui une taille avec ReDim, demandez-lui sa taille avec UBound, et — pour une grille — rappelez-vous que seule la dernière dimension peut grandir (voir VBA 2D Arrays). Trompez-vous sur ReDim et vos données disparaissent en silence, d'où l'intérêt de comprendre quand la taille est fixe et quand elle ne l'est pas.

Ce que vous allez apprendre

  • La seule décision qui gouverne chaque tableau — taille fixe au Dim, ou ouvert avec Dim a()
  • Pourquoi ReDim donne une taille à un tableau dynamique, et pourquoi un ReDim simple efface tout ce qu'il contenait
  • ReDim Preserve — comment agrandir un tableau et conserver les données
  • Le piège numéro un : ReDim Preserve ne peut redimensionner que la dernière dimension d'un tableau 2D
  • Pourquoi vous ne pouvez pas faire un ReDim sur un tableau de taille fixe, et ce que fait réellement Erase
  • Pourquoi agrandir un tableau ligne par ligne dans une boucle est lent, et quoi faire à la place

Le modèle mental : fixe au Dim, ou ouvert avec des crochets vides

Chaque tableau VBA est de l'un des deux types, et vous choisissez lequel à la déclaration :

Dim fixed(1 To 10) As Long   ' FIXE - 10 emplacements pour toujours ; la taille fait partie du type
Dim flex() As Long           ' DYNAMIQUE - pas encore de taille ; vous ferez un ReDim plus tard

Un tableau de taille fixe est dimensionné une fois et ne change jamais — la taille vit dans la déclaration, si bien que VBA ne vous laissera pas le ReDim plus tard (vous obtenez l'erreur de compilation « Array already dimensioned »). Un tableau dynamique est déclaré avec des crochets vides : il a un type mais aucune taille, et ReDim est le moyen de lui en donner une. Ce seul choix — crochets pleins ou vides au Dim — décide de tout le reste sur cette page. Si vous ne savez pas encore combien d'éléments vous aurez, déclarez-le ouvert.

ReDim donne une taille à un tableau dynamique

ReDim alloue un nouvel espace de stockage pour un tableau dynamique. Vous pouvez ReDim le même tableau autant de fois que vous voulez, et chaque ReDim peut même changer les bornes :

Dim a() As String
ReDim a(1 To 3)      ' 3 elements, indices 1..3
ReDim a(0 To 99)     ' maintenant 100 elements, indices 0..99

Il y a une chose à garder en tête, et c'est la source de la plupart des bugs « mes données ont disparu » : un ReDim simple réinitialise tout le tableau. Chaque élément revient à sa valeur par défaut — 0 pour les nombres, "" pour les chaînes, Nothing pour les objets — comme si vous veniez de le créer :

Dim a() As Long
ReDim a(1 To 3)
a(1) = 10: a(2) = 20: a(3) = 30
ReDim a(1 To 5)      ' a(1..3) valent 0 de nouveau - les valeurs ont DISPARU

Si vous vouliez conserver les données, c'est exactement à cela que sert Preserve.

ReDim Preserve : agrandir sans perdre de données

ReDim Preserve copie les valeurs existantes dans le tableau redimensionné avant de vous le rendre :

Dim a() As Long
ReDim a(1 To 3)
a(1) = 10: a(2) = 20: a(3) = 30
ReDim Preserve a(1 To 5)   ' a(1..3) contiennent encore 10, 20, 30 ; a(4), a(5) valent 0

Utilisez Preserve chaque fois que vous étendez un tableau que vous avez déjà rempli. Cela fonctionne quand vous agrandissez et quand vous rétrécissez — rétrécir se contente de supprimer les éléments au-delà de la nouvelle borne supérieure. La seule règle à respecter concerne les dimensions, et c'est là que presque tout le monde se fait piéger.

Le piège numéro un : Preserve ne redimensionne que la dernière dimension

Sur un tableau à une dimension, ReDim Preserve est libre de changer la borne. Sur un tableau à deux dimensions, ReDim Preserve ne peut changer que la dernière dimension. Essayez de changer la première, et VBA lève l'erreur d'exécution 9, « Subscript out of range » :

Dim g() As Long
ReDim g(1 To 3, 1 To 2)          ' 3 lignes, 2 colonnes
ReDim Preserve g(1 To 5, 1 To 2) ' erreur 9 - impossible de redimensionner la PREMIERE dimension
ReDim Preserve g(1 To 3, 1 To 4) ' OK - la DERNIERE dimension (colonne) peut grandir

Ce n'est pas un bug que vous pouvez contourner avec un ReDim plus malin ; c'est la façon dont VBA stocke les tableaux en mémoire. Cela heurte aussi l'intuition, car une feuille, c'est lignes × colonnes, si bien que l'« agrandissement » que vous voulez d'ordinaire — ajouter des lignes — porte sur la première dimension, celle que vous n'avez pas le droit de toucher. Deux issues : déclarer la grille en colonnes × lignes pour que la dimension que vous agrandissez soit la dernière, ou, plus couramment, dimensionner le tableau une seule fois à son nombre de lignes final avant la boucle et vous passer entièrement de Preserve. S'il vous faut vraiment ajouter des lignes à un tableau 2D existant, vous le reconstruisez (ou transposez, redimensionnez la dernière dimension, retransposez). Plus de détails dans VBA 2D Arrays.

Vous ne pouvez pas faire un ReDim sur un tableau de taille fixe

ReDim ne vaut que pour les tableaux déclarés avec des crochets vides. Si vous avez dimensionné le tableau dans son Dim, la taille est scellée dans la déclaration et ReDim est une erreur de compilation :

Dim a(1 To 10) As Long
ReDim a(1 To 20)      ' erreur de compilation - "Array already dimensioned"

Si vous vous surprenez à vouloir redimensionner un tableau, c'est le signe qu'il aurait dû être déclaré dynamique (Dim a()) dès le départ. Un tableau dynamique que vous ReDim une seule fois, juste après avoir appris le nombre d'éléments, vous donne le meilleur des deux mondes : une taille de travail fixe et nette, choisie à l'exécution.

Erase : réinitialiser ou libérer

Erase fait deux choses différentes selon le type de tableau. Sur un tableau de taille fixe, il réinitialise chaque élément à sa valeur par défaut mais garde le tableau à la même taille. Sur un tableau dynamique, il va plus loin — il libère la mémoire et ramène le tableau à son état sans taille, comme si vous n'aviez jamais écrit que Dim a() :

Dim fixed(1 To 3) As Long
Erase fixed            ' les trois elements valent 0 de nouveau ; toujours de taille 3

Dim flex() As Long
ReDim flex(1 To 3)
Erase flex             ' memoire liberee ; flex n'a plus de taille - faire un ReDim avant reutilisation

Après avoir effacé un tableau dynamique, appeler UBound sur lui lève l'erreur 9 jusqu'à ce que vous le ReDim de nouveau — le tableau n'a véritablement aucune borne à signaler.

Dimensionnez une fois, n'agrandissez pas un par un

Parce que chaque ReDim Preserve alloue un nouveau bloc et y copie l'ancien contenu, agrandir un tableau d'un élément à chaque passage d'une boucle transforme un travail en O(n) en O(n²) — acceptable pour 50 éléments, pénible pour 50 000. Le correctif idiomatique consiste à dimensionner le tableau une seule fois, d'entrée, à partir d'un nombre que vous avez déjà (une dernière ligne, la taille d'une collection), et à ne le rogner qu'à la fin si nécessaire :

Dim a() As Long, n As Long, i As Long
n = Cells(Rows.Count, 1).End(xlUp).Row   ' combien de lignes de donnees
ReDim a(1 To n)                          ' une seule allocation
For i = 1 To n
    a(i) = Cells(i, 1).Value
Next i

Quand vous ne pouvez vraiment pas connaître le nombre à l'avance, un motif courant consiste à ReDim par blocs généreux (par exemple, doubler la taille quand vous êtes à court) puis à ReDim Preserve jusqu'au nombre exact une seule fois à la fin — bien moins de copies qu'en agrandissant d'un à chaque fois.

Comment ExcelMaster vous aide

Toute l'histoire de ReDim tient en une décision — ce tableau a-t-il une taille fixe, ou grandit-il ? — et les deux erreurs classiques sont un ReDim simple qui efface vos données en silence et un ReDim Preserve qui bute sur l'erreur 9 à cause de la mauvaise dimension.

ExcelMaster vous laisse décrire la tâche — « lis la colonne A dans un tableau, garde les valeurs non vides, écris-les dans la colonne C » — et il déclare le tableau dynamique, le dimensionne une seule fois à partir du vrai nombre de lignes, n'utilise ReDim Preserve que là où la dimension le permet, et lit la plage d'un seul coup plutôt que cellule par cellule. Vous gardez le classeur et le code.

Questions fréquentes

Que fait ReDim en VBA ?

ReDim définit ou change la taille d'un tableau dynamique — un tableau déclaré avec des crochets vides, comme Dim a() As Long. ReDim a(1 To 10) donne dix éléments au tableau. Vous pouvez ReDim le même tableau à répétition, et chaque ReDim peut changer les bornes. Un ReDim simple réinitialise aussi chaque élément à sa valeur par défaut, alors utilisez ReDim Preserve quand vous devez conserver les données existantes.

Quelle est la différence entre ReDim et ReDim Preserve ?

Un ReDim simple alloue la nouvelle taille et remet chaque élément à sa valeur par défaut, en jetant tout ce que le tableau contenait. ReDim Preserve copie d'abord les valeurs existantes dans le tableau redimensionné, si bien que les données survivent. Utilisez un ReDim simple pour le premier dimensionnement, et ReDim Preserve chaque fois que vous étendez un tableau que vous avez déjà rempli.

Pourquoi ReDim Preserve donne-t-il l'erreur 9 sur un tableau 2D ?

Parce que ReDim Preserve ne peut redimensionner que la dernière dimension d'un tableau multidimensionnel. Changer la première dimension lève l'erreur d'exécution 9, « Subscript out of range ». Pour ajouter des « lignes » à une grille, déclarez-la en colonnes × lignes pour que la dimension qui grandit soit la dernière, dimensionnez-la à son nombre de lignes final avant la boucle, ou reconstruisez le tableau.

Puis-je faire un ReDim sur un tableau de taille fixe ?

Non. Si vous avez déclaré le tableau avec une taille, comme Dim a(1 To 10), cette taille fait partie du type et ReDim est une erreur de compilation, « Array already dimensioned ». Seuls les tableaux déclarés avec des crochets vides (Dim a()) peuvent être dimensionnés et redimensionnés avec ReDim.

Comment ajouter un élément à un tableau VBA ?

Suivez le nombre vous-même et faites un ReDim Preserve pour faire de la place : ReDim Preserve a(1 To n + 1): a(n + 1) = value: n = n + 1. Cela fonctionne, mais redimensionner à chaque élément est lent parce que chaque ReDim Preserve copie tout le tableau. Pour les grandes boucles, dimensionnez le tableau une seule fois à partir d'un nombre connu, ou agrandissez-le par blocs et rognez une fois à la fin. Une Collection est souvent plus simple quand le nombre est vraiment inconnu.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 24/09/2026.

Guides associés : VBA UBound · VBA 2D Arrays · VBA Array · VBA Dim · VBA For Loop