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

VBA Cell Value dans Excel — lire et écrire .Value, et l'astuce plage-vers-tableau

|

VBA Cell Value dans Excel — lire et écrire .Value, et l'astuce plage-vers-tableau

TL;DRRange("A1").Value lit ou écrit une cellule. Ce qui compte, c'est ce qui se passe avec plusieurs cellules : arr = Range("A1:C1000").Value lit tout le bloc dans un tableau Variant 2D en base 1 en un seul appel, et Range("A1:C1000").Value = arr le réécrit en un seul appel. Toucher les cellules une à une — Cells(i, j).Value dans une boucle — franchit la frontière de VBA vers Excel à chaque lecture, et c'est ce franchissement, pas l'arithmétique, qui rend les grandes boucles lentes.

Dim v As Variant
v = Range("A1").Value              ' lire une cellule dans une variable
Range("B1").Value = v * 1.08       ' ecrire une cellule

Dim arr As Variant
arr = Range("A1:A10000").Value     ' lire 10 000 cellules en UN appel -> tableau 2D
' ... traiter arr en memoire ...
Range("C1:C10000").Value = arr     ' tout reecrire en UN appel

Lire et écrire des valeurs est la première chose que fait quiconque en VBA, et pour une seule cellule c'est exactement aussi simple que ça en a l'air. L'idée sur laquelle repose ce guide apparaît dès que vous avez plus d'une cellule : .Value sur une plage n'est pas une valeur, c'est un bloc — un tableau à deux dimensions — et déplacer ce bloc en un seul appel plutôt qu'une cellule à la fois, c'est la différence entre une macro qui semble instantanée et une qui se fige. Tenez cela, et les règles de vitesse comme les petits pièges de type se mettent en place.

Ce que vous allez apprendre

  • Le modèle mental — .Value est un bloc, et une plage donne un tableau Variant 2D
  • La règle la plus importante — lire et écrire tout le bloc en un aller-retour, pas cellule par cellule
  • Pourquoi le tableau est en base 1 et en 2D, même pour une seule colonne
  • Le cas particulier de la cellule unique — une cellule est un scalaire, pas un tableau
  • .Value est la propriété par défaut — le raccourci, et pourquoi ne pas s'y fier
  • Affecter une valeur remplace ce qui était dans la cellule, formule comprise

Le modèle mental : .Value est un bloc

Pour une seule cellule, .Value est une valeur unique que vous lisez ou affectez :

Dim name As String
name = Range("A1").Value           ' scalaire en entree
Range("A2").Value = "Total"        ' scalaire en sortie

Pour une plage de plusieurs cellules, .Value est toute la grille d'un coup. Lisez-la dans un Variant et vous obtenez un tableau à deux dimensions ; affectez-lui un tableau à deux dimensions et vous remplissez chaque cellule en un seul geste :

Dim block As Variant
block = Range("A1:C100").Value     ' block est maintenant un tableau Variant 100 x 3

Le mot important est une fois. Chaque fois que votre code lit ou écrit .Value, il franchit la frontière entre le moteur VBA et l'application Excel — un saut relativement coûteux. Une cellule, c'est un saut ; tout un bloc lu dans un tableau, c'est aussi un saut. Ce seul fait — une plage est un bloc que vous pouvez déplacer en un unique franchissement — gouverne la règle de performance ci-dessous et c'est la chose la plus précieuse à savoir sur .Value.

La règle la plus importante : l'aller-retour par tableau, pas la boucle sur les cellules

Voici le même travail fait de deux façons. Additionner une colonne, en majorant chaque valeur de 8 % et en l'écrivant juste à côté.

La façon lente touche Excel à chaque itération :

Dim i As Long
For i = 1 To 10000
    Cells(i, 3).Value = Cells(i, 1).Value * 1.08   ' 2 franchissements par ligne = 20 000 sauts
Next i

La façon rapide franchit la frontière deux fois en tout et fait le travail en mémoire :

Dim src As Variant, out() As Variant, i As Long
src = Range("A1:A10000").Value          ' 1 saut a l'entree
ReDim out(1 To UBound(src, 1), 1 To 1)
For i = 1 To UBound(src, 1)
    out(i, 1) = src(i, 1) * 1.08        ' pur VBA - aucun Excel implique
Next i
Range("C1:C10000").Value = out          ' 1 saut a la sortie

L'arithmétique est identique ; la boucle a exactement la même longueur. La seule différence, c'est que la seconde version lit 10 000 cellules en un appel et en écrit 10 000 en un appel, tandis que la première effectue 20 000 trajets séparés à travers la frontière VBA-Excel. Sur des données réelles, la version par tableau est couramment des dizaines de fois plus rapide — souvent la différence entre « instantané » et « regardez tourner le sablier ». Pour un gain encore plus grand, associez-la à la désactivation du recalcul et du rafraîchissement de l'écran pendant l'écriture ; voir VBA Calculation et VBA ScreenUpdating. Le franchissement de la frontière est le coût, et l'aller-retour par tableau est la façon d'arrêter de le payer par cellule.

Pourquoi le tableau est en base 1 et en 2D

Le tableau Variant que vous rend une plage surprend deux fois. D'abord, il est toujours en base 1, quel que soit le réglage Option Basearr(1, 1) est la cellule en haut à gauche. Ensuite, il est toujours à deux dimensions, même quand la plage est une seule colonne ou une seule ligne :

Dim col As Variant
col = Range("A1:A5").Value          ' une seule colonne
Debug.Print col(3, 1)              ' PAS col(3) - c'est (ligne, colonne)

Une plage d'une colonne est un tableau de 5 sur 1, que vous indexez donc col(ligne, 1) ; une plage d'une ligne est de 1 sur 5, indexée ligne(1, colonne). Écrire col(3) au lieu de col(3, 1) déclenche « Subscript out of range » et c'est l'erreur la plus fréquente quand on passe pour la première fois aux tableaux. Si vous voulez réellement un tableau à une dimension à partir d'une seule colonne, enveloppez la lecture dans Application.Transpose — mais sachez que Transpose a ses propres limites (il plafonne autour de 65 536 éléments et convertit les types), si bien que pour de grandes données ou des données mixtes, le tableau 2D simple est plus sûr. Voir VBA Array pour exploiter le résultat.

Le cas particulier de la cellule unique

Il existe un cas limite qui casse le code à base de tableaux : si la plage est une cellule unique, .Value renvoie un simple scalaire, pas un tableau de 1 sur 1.

Dim v As Variant
v = Range("A1").Value              ' A1 seul -> un scalaire, pas v(1, 1)
' v(1, 1) ici declenche une erreur

Ainsi, un code qui lit rng.Value dans un tableau puis indexe arr(1, 1) fonctionne pour un rng de plusieurs cellules mais explose quand rng se trouve être une seule cellule. Si la taille d'une plage peut descendre jusqu'à une cellule, forcez une taille minimale, ou vérifiez rng.Cells.Count > 1 avant de traiter le résultat comme un tableau. C'est une petite incohérence du modèle objet d'Excel, mais elle provoque de vrais bugs du type « marche sur la grande feuille, échoue sur la petite ».

.Value est la propriété par défaut — le raccourci et son risque

.Value est la propriété par défaut d'un Range, ce qui veut dire qu'Excel vous laisse l'omettre :

x = Range("A1")                    ' fonctionne - implicitement .Value
Range("A1") = 42                   ' fonctionne - implicitement .Value

Ça se lit proprement, et beaucoup de code le fait. Le risque, c'est que le raccourci masque quelle opération vous voulez dire. Set rng2 = Range("A1") affecte l'objet Range ; x = Range("A1") affecte sa valeur — la présence ou l'absence de Set change silencieusement le sens. Et If Range("A1") = Range("B1") compare des valeurs, ce qui n'est pas forcément ce qu'un lecteur attend quand le code ne dit rien des valeurs. L'habitude à garder : écrire .Value explicitement quand vous voulez la valeur. Ça coûte six caractères et supprime toute une catégorie d'ambiguïté du genre « voulaient-ils la cellule ou son contenu » — surtout autour de Set, traité dans VBA Range.

Affecter une valeur remplace la formule

Un dernier point qui piège ceux qui mêlent valeurs et formules : écrire .Value dans une cellule écrase ce qui s'y trouvait, formule comprise.

Range("D2").Formula = "=B2*C2"     ' D2 contient maintenant une formule vivante
Range("D2").Value = 100            ' D2 est maintenant le nombre statique 100 - la formule a disparu

C'est en général ce que vous voulez — c'est exactement ainsi qu'on « convertit une formule en son résultat » dans une seule cellule (réaffecter la valeur par-dessus elle-même). Mais cela signifie que vous ne pouvez pas ajuster une valeur sans détruire la formule qui l'a produite. Quand il vous faut une formule vivante dans la cellule, affectez .Formula, pas .Value — les deux sont des faces différentes de la même cellule, traitées dans VBA Formula. Et quand le nombre précis que vous relisez compte — argent, dates, longues décimales — le choix entre .Value et .Value2 commence à peser, ce qui fait l'objet de VBA Value vs Value2 vs Text.

Comment ExcelMaster aide

Les erreurs de .Value qui coûtent vraiment du temps ne sont pas des fautes de frappe — c'est la boucle lente cellule par cellule sur une grande feuille, le arr(3) qui aurait dû être arr(3, 1), le code à base de tableaux qui casse sur une plage d'une seule cellule, et le .Value implicite qui a comparé la mauvaise chose sans bruit. Chacune s'exécute ; elle s'exécute juste mal ou lentement.

ExcelMaster écrit d'emblée la version rapide et correcte. Demandez-lui de « majorer la colonne A de 8 % vers la colonne C », et il lit le bloc dans un tableau Variant, le traite en mémoire, et le réécrit en une seule affectation — avec le recalcul et le rafraîchissement de l'écran gérés autour de l'écriture. Il indexe correctement le tableau 2D, protège le cas de la cellule unique, et écrit .Value explicitement pour que le code dise ce qu'il veut dire. Vous décrivez la transformation ; il écrit l'aller-retour qui s'exécute en un clin d'œil au lieu d'une boucle qui traîne.

Questions fréquentes

Comment obtenir la valeur d'une cellule en VBA Excel ?

Lisez la propriété Value d'un Range : x = Range("A1").Value ou x = Cells(1, 1).Value. Pour plusieurs cellules d'un coup, lisez toute la plage dans un Variantarr = Range("A1:C100").Value — ce qui donne un tableau à deux dimensions en base 1 (arr(ligne, colonne)). Lire un bloc dans un tableau est bien plus rapide que lire chaque cellule dans une boucle, car chaque accès individuel à .Value franchit la frontière de VBA vers Excel.

Comment écrire une valeur dans une cellule en VBA ?

Affectez à Value : Range("A1").Value = 42 ou Cells(1, 1).Value = "Total". Pour écrire plusieurs cellules d'un coup, construisez un tableau Variant 2D et affectez-le à une plage de même forme : Range("A1:A100").Value = arr. Cela écrit les 100 cellules en une seule opération au lieu de boucler, ce qui est radicalement plus rapide sur les grandes plages.

Pourquoi la valeur de ma plage VBA est-elle un tableau 2D ?

Parce qu'une plage de plusieurs cellules est une grille : son .Value est donc un tableau à deux dimensions indexé arr(ligne, colonne) et toujours en base 1 — même une seule colonne est un tableau de N sur 1, que vous indexez donc arr(3, 1), pas arr(3). Indexer avec un seul indice déclenche « Subscript out of range ». La cellule unique est l'exception : Range("A1").Value renvoie un simple scalaire, pas un tableau de 1 sur 1.

Pourquoi la lecture des cellules dans une boucle VBA est-elle si lente ?

Chaque accès Cells(i, j).Value franchit la frontière entre le moteur VBA et l'application Excel, et c'est ce saut qui coûte cher — pas l'arithmétique. Une boucle sur 10 000 lignes qui lit et écrit chaque cellule effectue 20 000 franchissements. Lire la plage dans un tableau, la traiter en mémoire, puis réécrire le tableau ne fait que deux franchissements, et c'est pourquoi c'est souvent des dizaines de fois plus rapide.

Quelle est la différence entre .Value et un simple Range("A1") en VBA ?

.Value est la propriété par défaut d'un Range, donc x = Range("A1") est traité comme x = Range("A1").Value. Les deux se lisent pareil pour les valeurs, mais omettre .Value masque votre intention : Set rng = Range("A1") affecte l'objet Range, tandis que x = Range("A1") affecte sa valeur, et la seule différence est le mot-clé Set. Écrire .Value explicitement rend le code sans ambiguïté.

Testé dans

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

Guides connexes : VBA Range · VBA Cells · VBA Formula · VBA Value vs Value2 vs Text · VBA Array