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

VBA Resize dans Excel — remodeler une plage depuis son ancre (et pourquoi c'est un nombre, pas un delta)

|

VBA Resize dans Excel — remodeler une plage depuis son ancre (et pourquoi c'est un nombre, pas un delta)

TL;DRResize(lignes, colonnes) garde l'ancre en haut à gauche d'une plage fixe et redessine le rectangle pour qu'il fasse exactement ce nombre de lignes de haut et de colonnes de large. Il ne déplace pas la référence (ça, c'est Offset) et il ne sélectionne pas — il renvoie une nouvelle plage au même coin. Le piège : les arguments sont un nombre absolu à base 1 de la taille finale, pas un delta. Range("A1").Resize(5, 3) donne A1:C5 (5 lignes, 3 colonnes au total) ; Resize(0, ...) déclenche l'erreur 1004. Omettez un argument pour laisser cette dimension inchangée.

Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
' L'ancre reste en A1 ; le rectangle est redessine a 5 lignes sur 3 colonnes.
ws.Range("A1").Resize(5, 3).Select        ' selectionne A1:C5
' Omettez le nombre de colonnes pour garder la largeur et n'agrandir que la hauteur :
ws.Range("A1:D1").Resize(10).Select       ' A1:D10 (la largeur reste 4)

Resize, c'est ainsi qu'une macro cesse de coder en dur "A1:D100" et se met à ajuster la référence à ce que sont réellement les données. C'est une petite méthode assortie d'une grande idée fausse : on lit Resize(5) comme « ajoute cinq lignes » alors que cela signifie « fais cinq lignes ». Ce guide s'articule autour de l'idée dont découle chaque règle qui suit : Resize fixe l'ancre et énonce la taille finale. Une fois cette idée acquise, la règle du nombre-pas-un-delta, les arguments omis et l'idiome du retrait d'en-tête cessent tous d'être des surprises.

Ce que vous allez apprendre

  • Le modèle mental — Resize fixe l'ancre en haut à gauche et redessine le rectangle
  • La règle la plus importante — les arguments sont un nombre total, pas un delta à ajouter
  • Omettre un argument pour laisser une dimension inchangée
  • Pourquoi l'ancre est toujours en haut à gauche, même sur une plage multi-cellules
  • Les deux motifs qui paient — retirer un en-tête, et écrire un tableau dans un bloc ajusté
  • Où se place Resize à côté d'Offset et de CurrentRegion

Le modèle mental : Resize fixe l'ancre et redessine le rectangle

Toute plage a une cellule en haut à gauche — son ancre. Resize laisse cette ancre exactement là où elle est et redessine le rectangle à la taille que vous indiquez :

ws.Range("B2").Resize(3, 4)   ' l'ancre B2 reste ; la nouvelle plage est B2:E4 (3 lignes, 4 colonnes)

Imaginez que vous saisissez la poignée en bas à droite d'une sélection et que vous tirez : le coin en haut à gauche est épinglé, et la taille change sous votre main. Voilà toute la méthode. Deux choses qu'elle n'est pas : elle n'est pas Offset, qui fait glisser toute la référence vers une nouvelle position sans en changer la taille ; et elle n'est ni une sélection ni une action — Resize renvoie une plage, et vous devez utiliser le résultat (.Value =, .Select, Set r = ...). Un appel Resize seul sur une ligne ne fait absolument rien.

La règle la plus importante : c'est un nombre, pas un delta

C'est l'idée fausse qui produit des plages de mauvaise taille. Resize(lignes, colonnes) est le total absolu, à base 1 du rectangle final — pas une quantité à ajouter à la taille actuelle :

ws.Range("A1").Resize(5, 3)   ' A1:C5  -> 5 lignes et 3 colonnes AU TOTAL, pas "5 lignes de plus"
ws.Range("A1").Resize(1, 1)   ' A1     -> une seule cellule (1 ligne, 1 colonne)

Ainsi Resize(1) fait une ligne, pas « rétrécis d'une ». Et parce qu'une plage ne peut avoir une taille nulle ou négative, Resize(0, 3) ou Resize(-1, 3) déclenche l'erreur d'exécution 1004. Si vous calculez un nombre de lignes, protégez-le : un bloc de données réduit à sa seule ligne d'en-tête donne Rows.Count - 1 = 0, et passer cela à Resize plante. Vérifiez le cas vide avant de redimensionner.

Omettez un argument pour laisser une dimension intacte

Les deux arguments sont facultatifs, et un argument omis signifie « laisse cette dimension inchangée ». C'est l'usage le plus courant dans la vraie vie — on fige un côté, on change l'autre :

ws.Range("A1:D1").Resize(10)        ' lignes -> 10, les colonnes restent a 4  => A1:D10
ws.Range("A1:D1").Resize(, 6)       ' colonnes -> 6, les lignes restent a 1   => A1:F1

Remarquez la virgule seule dans Resize(, 6) — c'est ainsi que vous sautez le premier argument pour ne définir que le second. Lire Resize(10) comme « 10 lignes, même largeur » est tout à fait juste, et c'est pourquoi faire grandir une ligne d'en-tête en un tableau complet tient en une seule ligne.

L'ancre est toujours en haut à gauche

Resize calcule à partir de l'ancre et ignore la taille existante, sauf pour ce coin. Appelez-le sur une plage multi-cellules et les anciennes dimensions disparaissent :

ws.Range("B2:D10").Resize(1, 1)   ' se reduit a B2 - l'ancre seule

Cela surprend ceux qui s'attendent à ce que Resize ajuste leur bloc existant en fonction de sa taille actuelle. Il n'en fait rien — il redéfinit la taille depuis le coin en haut à gauche. Si vous voulez remodeler à partir de la première cellule d'une plage à dessein, c'est déjà ce qui se produit ; si vous l'avez appelé par erreur sur une grande plage, vous venez de jeter la taille. Quand vous avez besoin de l'ancre explicitement, rng.Cells(1, 1) (voir VBA Cells) vous donne la cellule en haut à gauche depuis laquelle redimensionner.

Les deux motifs qui paient

Presque tout Resize utile est l'un de ces deux-là. D'abord, retirer une ligne d'en-tête — associez-le à Offset, car Offset seul conserve la même hauteur et déborderait d'une ligne sous le bas :

Dim tbl As Range: Set tbl = ws.Range("A1").CurrentRegion   ' tout le bloc, en-tete compris
Dim body As Range
' Descendre sous l'en-tete, PUIS reduire la hauteur d'une unite pour ne pas deborder :
Set body = tbl.Offset(1, 0).Resize(tbl.Rows.Count - 1, tbl.Columns.Count)

Offset déplace, Resize remodèle — ensemble, ils découpent le corps des données dans un bloc. Deuxièmement, réécrire un tableau dans un bloc qui lui va. Affecter un tableau à une seule cellule non redimensionnée ne remplit que cette cellule ; redimensionnez d'abord l'ancre aux dimensions du tableau :

Dim data(1 To 100, 1 To 3) As Variant
' ... remplir data ...
ws.Range("A1").Resize(UBound(data, 1), UBound(data, 2)).Value = data   ' remplit A1:C100 d'un seul coup

Cette unique affectation est plus rapide de plusieurs ordres de grandeur qu'une boucle cellule par cellule, et c'est Resize qui fait correspondre exactement la cible aux données.

Offset déplace, Resize remodèle

Gardez la paire au clair et les plages dynamiques cessent d'être délicates : Offset change se trouve une référence ; Resize change quelle taille elle a. Vous repositionnez avec l'un et remodelez avec l'autre, et presque tout travail réel utilise les deux — trouver une ancre, décaler au-delà de ce que vous voulez sauter, redimensionner pour ajuster ce qui reste. Combinez cela avec CurrentRegion pour détecter le bloc en premier lieu, et vous disposez de toute la boîte à outils pour référencer des données dont vous ignorez la taille d'avance — sans jamais taper une adresse codée en dur qui casse le jour où les données grandissent d'une ligne. La forme vit dans les données ; Resize ne fait que lui ajuster la référence.

Comment ExcelMaster aide

Resize cache une poignée de pièges silencieux : la confusion nombre-contre-delta qui produit un bloc de mauvaise taille, une erreur 1004 quand un nombre de lignes calculé tombe à zéro, une ancre qui écarte votre taille existante, et l'affectation de tableau qui ne remplit qu'une cellule parce que la cible n'a jamais été redimensionnée. Aucun d'eux ne fait apparaître de message utile au moment où vous les commettez.

ExcelMaster vous laisse plutôt décrire le résultat. Dites « écris ce tableau sur la feuille à partir de A1 » ou « sélectionne les données sans la ligne d'en-tête », et il redimensionne l'ancre aux dimensions exactes du tableau, ou décale au-delà de l'en-tête et réduit la hauteur d'une ligne — en protégeant le cas du bloc vide pour que rien ne plante. Vous gardez le classeur et le code ; vous vous épargnez la passe de débogage où seule la première cellule était remplie.

Questions fréquentes

Que fait Resize en VBA Excel ?

Resize(lignes, colonnes) renvoie une nouvelle plage qui garde la cellule en haut à gauche de la plage d'origine (son ancre) et fait exactement lignes de haut et colonnes de large. Il ne déplace pas la référence et ne sélectionne rien par lui-même — vous utilisez la plage renvoyée, par exemple Range("A1").Resize(10, 3).Value = data.

Resize est-il un delta ou une taille absolue ?

C'est un nombre absolu, à base 1 de la taille finale, pas une quantité à ajouter. Range("A1").Resize(5, 3) correspond à A1:C5 (cinq lignes et trois colonnes au total), et Resize(1, 1) est une seule cellule. Parce qu'une plage ne peut pas être vide, Resize(0, ...) ou un nombre négatif déclenche l'erreur d'exécution 1004.

Quelle est la différence entre Resize et Offset en VBA ?

Offset déplace une plage vers une nouvelle position sans changer sa taille ; Resize change la taille tout en gardant l'ancre en haut à gauche fixe. Ils sont complémentaires et souvent utilisés ensemble, comme rng.Offset(1, 0).Resize(rng.Rows.Count - 1, rng.Columns.Count) pour sauter une ligne d'en-tête puis rogner la hauteur afin que le résultat ne déborde pas.

Comment écrire un tableau dans une plage avec Resize ?

Redimensionnez la cellule d'ancre pour qu'elle corresponde aux dimensions du tableau, puis affectez en une seule instruction : Range("A1").Resize(UBound(data, 1), UBound(data, 2)).Value = data. Affecter un tableau à une seule cellule non redimensionnée ne remplit que cette cellule, si bien que c'est le Resize qui fait recevoir les données à tout le bloc, et c'est bien plus rapide qu'une boucle cellule par cellule.

Comment redimensionner seulement le nombre de lignes en gardant les colonnes ?

Omettez le second argument : Range("A1:D1").Resize(10) porte la hauteur à 10 lignes et laisse la largeur à 4, ce qui donne A1:D10. Pour ne changer que les colonnes, sautez le premier argument avec une virgule seule : Range("A1:D1").Resize(, 6) donne A1:F1.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 15/08/2026.

Guides associés : VBA Offset · VBA CurrentRegion · VBA Cells · VBA Range · VBA For Loop