Loop For VBA pour parcourir des cellules vides ou non : méthode efficace

La boucle For en VBA Excel reste la structure de contrôle la plus directe pour itérer sur une plage de cellules et traiter différemment celles qui contiennent une valeur et celles qui sont vides. Nous allons détailler les approches techniques qui permettent de fiabiliser ce parcours, en particulier sur des listes dynamiques où la dernière ligne occupée varie.

Déterminer la dernière ligne dynamiquement avant toute boucle For VBA

Une boucle For qui s’appuie sur une borne fixe (par exemple For i = 1 To 1000) gaspille des cycles sur des lignes inutiles et devient fragile dès qu’on ajoute des données. Nous recommandons de calculer la borne supérieure avant d’entrer dans la boucle.

A lire aussi : Framapad : avantages et utilisations pour une collaboration efficace en ligne

La méthode la plus fiable utilise la propriété End de l’objet Range, qui reproduit le raccourci clavier Ctrl+Fin :

Dim dernLigne As Long
dernLigne = Cells(Rows.Count, 1).End(xlUp).Row

Lire également : Rédiger des actes avec jurivia : méthode complète pour éviter les erreurs

Cette instruction remonte depuis la dernière ligne de la colonne A jusqu’à la première cellule non vide. La variable dernLigne sert ensuite de borne dans la boucle :

Dim cell As Range
For i = 2 To dernLigne
  Set cell = Cells(i, 1)
  'traitement
Next i

Si la colonne de référence peut elle-même contenir des trous, mieux vaut appliquer End(xlUp) sur la colonne la plus densément remplie, ou recourir à UsedRange.Rows.Count en vérifiant que la feuille ne comporte pas de mise en forme résiduelle qui fausserait le calcul.

Femme professionnelle pointant un code VBA sur laptop dans un bureau en open space avec des cellules Excel surlignées

Tester une cellule vide dans une boucle For : trois méthodes VBA comparées

Toutes les façons de vérifier si une cellule est vide ne se valent pas. Le choix dépend de ce que l’on considère comme « vide » : absence totale de contenu, formule renvoyant une chaîne vide, ou cellule contenant uniquement des espaces.

Comparaison avec une chaîne vide

Le test If Cells(i,1).Value = "" Then est le plus répandu. Il détecte les cellules réellement vides et celles dont la formule renvoie une chaîne vide. En revanche, une cellule contenant un espace invisible passera le test comme non vide.

La fonction IsEmpty

IsEmpty(Cells(i,1).Value) renvoie True uniquement quand la cellule n’a jamais reçu de valeur ou a été effacée via Delete. IsEmpty ne reconnaît pas une formule renvoyant «  ». C’est un piège fréquent sur des feuilles alimentées par des formules SI ou INDEX.

Len et Trim combinés

Pour un contrôle strict, If Len(Trim(Cells(i,1).Value)) = 0 Then couvre les trois cas : cellule vide, formule renvoyant «  », et cellule ne contenant que des espaces. Cette approche est plus lente sur de très grandes plages, mais elle élimine les faux positifs.

  • Value = "" : rapide, ne gère pas les espaces seuls
  • IsEmpty : strict, ignore les formules renvoyant «  »
  • Len(Trim(...)) = 0 : le plus complet, légèrement plus coûteux en performance

Boucle For Each sur un Range VBA : quand la préférer au For classique

La syntaxe For Each cell In Range parcourt chaque objet Cell d’une plage sans manipuler d’index numérique. Elle simplifie le code quand on n’a pas besoin du numéro de ligne :

Dim cell As Range
For Each cell In Range("A2:A" & dernLigne)
  If cell.Value <> "" Then
    'traitement sur cellules non vides
  End If
Next cell

For Each itère dans l’ordre ligne par ligne, puis colonne par colonne. Sur une plage unidimensionnelle (une seule colonne), le comportement est prévisible. Sur une plage bidimensionnelle, l’ordre peut surprendre si l’on s’attend à un parcours par ligne complète.

La boucle For Each ne permet pas de modifier la variable d’itération ni d’utiliser Step pour sauter des lignes. Si le traitement nécessite de comparer la cellule courante avec la précédente ou la suivante, le For classique avec un compteur reste plus adapté.

Optimiser la vitesse d’exécution d’une boucle For VBA Excel

Parcourir plusieurs milliers de lignes avec des lectures cellule par cellule ralentit la macro de façon visible. Deux leviers réduisent le temps d’exécution de façon significative.

Charger la plage dans un tableau VBA

Lire un Range entier dans un Variant Array supprime les allers-retours entre VBA et la feuille :

Dim donnees As Variant
donnees = Range("A2:D" & dernLigne).Value
For i = LBound(donnees,1) To UBound(donnees,1)
  If donnees(i,1) <> "" Then
    'traitement en mémoire
  End If
Next i

Chaque accès à Cells depuis une boucle déclenche un appel COM, ce qui est lent. Un tableau en mémoire réduit ces appels à un seul (la lecture initiale) et un seul (la réécriture finale si nécessaire).

Désactiver le rafraîchissement écran

Avant la boucle, nous ajoutons systématiquement :

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

Et après la boucle :

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

  • ScreenUpdating = False empêche Excel de redessiner la feuille à chaque écriture
  • Calculation = xlCalculationManual évite le recalcul de toutes les formules à chaque modification de cellule
  • Rétablir ces paramètres dans un bloc de gestion d’erreur (On Error GoTo) évite de laisser Excel dans un état figé en cas de plantage

Jeune développeur codant une boucle VBA For Loop sur laptop dans un espace de coworking avec notes manuscrites

Gérer les cellules vides au milieu d’une plage avec SpecialCells

Quand l’objectif est de traiter uniquement les cellules non vides (ou uniquement les vides) sans itérer ligne par ligne, SpecialCells offre un filtrage natif côté Excel :

Dim plageDonnees As Range
Set plageDonnees = Range("A2:A" & dernLigne).SpecialCells(xlCellTypeConstants)
For Each cell In plageDonnees
  'ne traite que les cellules contenant une constante
Next cell

Pour cibler les cellules vides, on utilise xlCellTypeBlanks. Cette méthode déclenche une erreur si aucune cellule ne correspond au critère. Un test préalable avec On Error Resume Next ou un comptage via WorksheetFunction.CountBlank protège le code.

SpecialCells renvoie un objet Range potentiellement discontinu (zones non contiguës). Le For Each gère cette discontinuité sans problème, mais toute tentative de lire .Row ou .Column sur l’ensemble du Range renverra uniquement la première zone.

Le choix entre une boucle For avec test conditionnel et SpecialCells dépend du volume de données et de la proportion de cellules vides. Sur une colonne où la majorité des cellules sont remplies et quelques-unes vides, SpecialCells(xlCellTypeBlanks) cible directement les exceptions et évite de parcourir toute la plage.

D'autres articles