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

VBA With dans Excel — écrire l'objet une seule fois (et le point initial qui fait tout basculer)

|

VBA With dans Excel — écrire l'objet une seule fois (et le point initial qui fait tout basculer)

TL;DRWith object … End With vous laisse nommer un objet une seule fois, puis atteindre ses membres avec un simple point initial : .Value, .Font.Bold, .Interior.Color. Moins de frappe, une lecture plus nette, et c'est réellement plus rapide, car VBA résout la référence d'objet une seule fois au lieu de le faire à chaque ligne. Toute l'astuce tient dans ce point initial : .Font se lie à votre objet With ; Font seul, non — il retombe sur un objet implicite (souvent la feuille active) et modifie en silence la mauvaise chose.

With Sheets("Report").Range("A1")
    .Value = "Total"          ' chaque point signifie : Sheets("Report").Range("A1") . ...
    .Font.Bold = True
    .Font.Size = 14
    .Interior.Color = vbYellow
End With

Les chemins d'objets profonds sont partout en VBA Excel : ThisWorkbook.Worksheets("Data").Range("A1").Font.…. Taper ce préfixe sur dix lignes consécutives est fastidieux, lent à l'exécution et pénible à lire — et si vous devez un jour le rediriger vers une autre cellule, vous modifiez dix endroits. With corrige les trois à la fois : énoncez l'objet sur la première ligne, puis laissez chaque ligne du bloc s'y rattacher par un point. C'est l'une des constructions les plus simples du langage et l'une des plus faciles à rater de peu.

Ce que vous allez apprendre

  • Le modèle mental — With factorise un préfixe répété, comme 2(a+b) en algèbre
  • Pourquoi ce n'est pas qu'une question de propreté : With résout la référence d'objet une seule fois
  • Le piège du point manquant — Font contre .Font — et pourquoi il échoue en silence
  • Comment les blocs With imbriqués résolvent le point, et pourquoi vous arrêter à deux
  • L'idiome With + For Each qui relie tout ce groupe

Le modèle mental : factoriser le préfixe répété

Voyez With comme une factorisation, à la manière dont vous réécrivez 2*a + 2*b + 2*c en 2*(a + b + c). La chose répétée — ici le chemin d'objet Sheets("Report").Range("A1") — est énoncée une fois, et tout ce qui est dans les parenthèses est censé être multiplié par elle. En VBA, les « parenthèses » sont With … End With, et le « multiplier par elle » est le point initial.

' Sans With — le préfixe se répète à chaque ligne
Sheets("Report").Range("A1").Value = "Total"
Sheets("Report").Range("A1").Font.Bold = True
Sheets("Report").Range("A1").Font.Size = 14

' Avec With — énoncez-le une fois, entrez-y par un point
With Sheets("Report").Range("A1")
    .Value = "Total"
    .Font.Bold = True
    .Font.Size = 14
End With

Les deux font exactement la même chose. Le second est plus court, se redirige en une seule modification, et — comme le montre la section suivante — s'exécute bel et bien plus vite. Tout ce qui est dans le bloc est implicitement préfixé par l'objet de la ligne With.

La règle qui en fait plus qu'un artifice cosmétique : l'objet ne se résout qu'une fois

With n'est pas seulement une affaire de moins de frappe. Quand VBA voit Sheets("Report").Range("A1").Font sur dix lignes distinctes, il reparcourt toute cette chaîne dix fois — chercher la feuille, résoudre la plage, récupérer la police — à chaque ligne. À l'intérieur d'un bloc With, VBA résout l'objet une seule fois, à l'entrée, et réutilise cette référence résolue pour chaque membre pointé.

Sur deux ou trois lignes, la différence est invisible. À l'intérieur d'une boucle sur des milliers de cellules, elle est bien réelle :

Dim cell As Range
For Each cell In Range("A1:A10000")
    With cell
        .Value = .Value * 1.1       ' résoudre 'cell' une fois par itération...
        .NumberFormat = "0.00"      ' ...pas trois fois
        .Font.Color = vbBlue
    End With
Next cell

Sans le With, chaque cell. redéréférence l'objet plage à chaque ligne ; avec lui, ce déréférencement n'a lieu qu'une fois par itération. La règle : quand vous touchez trois membres ou plus du même objet — surtout dans une boucle — enveloppez-les dans With. C'est la rare amélioration de lisibilité qui vous achète aussi de la vitesse.

Le piège qui modifie le mauvais objet : le point initial manquant

C'est le bug qui rend With dangereux plutôt que simplement utile. Le point initial est ce qui lie un membre à l'objet With. Omettez-le, et le membre ne déclenche pas d'erreur — il se lie à autre chose :

With Sheets("Report").Range("A1")
    .Value = "Total"
    Font.Bold = True        ' BUG : pas de point initial — ce n'est PAS la police de l'objet With
End With

.Font.Bold signifie Sheets("Report").Range("A1").Font.Bold. Mais Font.Bold — sans point — est une référence non qualifiée. VBA la résout dans le contexte implicite de la feuille active, si bien que vous obtenez soit une erreur de compilation, soit, pire, vous mettez en forme en silence une cellule sur la feuille active du moment. Rien ne vous avertit ; l'objet With reste simplement intact pendant qu'un autre objet change.

La règle est mécanique et mérite d'être gravée : à l'intérieur d'un bloc With, chaque membre qui appartient à l'objet doit commencer par un point. Quand vous relisez un bloc With, balayez la marge de gauche — tout ce qui ne commence pas par . est soit une référence délibérée à un objet différent, soit un bug. (C'est la même famille d'erreur « ActiveSheet implicite » traitée dans VBA ActiveSheet — un Range ou un Cells non qualifié se rattache discrètement à la feuille active.)

La règle d'imbrication : le point se lie au With le plus proche

Vous pouvez imbriquer des blocs With, et c'est réellement utile pour descendre dans un sous-objet. Mais la règle de résolution piège les gens : un point initial se lie toujours au With le plus interne.

With Sheets("Report")
    .Range("A1").Value = "Report"      ' un point -> la feuille
    With .Range("A2").Font             ' ouvrir un With interne sur la police
        .Bold = True                   ' .Bold -> la POLICE (la plus interne), pas la feuille
        .Size = 12
    End With
    .Range("A3").Value = "Done"        ' retour à la feuille après End With
End With

Dans le bloc interne, .Bold est celui de la police, pas de la feuille. C'est correct et lisible à deux niveaux — mais à trois ou quatre, cela devient un jeu de devinettes sur l'objet que désigne chaque point. La règle : n'imbriquez pas plus de deux blocs With. Au-delà, affectez une variable objet intermédiaire (Set fnt = .Range("A2").Font) et donnez au lecteur un nom plutôt qu'une pile de points.

L'idiome qui relie tout le groupe : With + For Each

With et For Each sont des partenaires naturels. For Each vous remet un objet à la fois ; With vous laisse travailler cet objet proprement sans répéter la variable de boucle :

Dim cell As Range
For Each cell In Sheets("Data").Range("B2:B100")
    With cell
        If .Value < 0 Then
            .Interior.Color = vbRed
            .Font.Bold = True
        End If
    End With
Next cell

Lisez-le à voix haute et c'est presque du français : « pour chaque cellule, avec cette cellule — si elle est négative, colore-la en rouge et mets-la en gras ». Ce duo — For Each pour parcourir la collection, With pour agir sur chaque membre — est la colonne vertébrale des macros propres de mise en forme et de marquage de données sur une Range.

Comment ExcelMaster aide

With est une petite chose faite mille fois : factoriser le préfixe, se rappeler le point, ne pas trop imbriquer. C'est exactement le genre de soin mécanique qui sépare les macros lisibles des macros fragiles — et exactement le genre de chose auquel vous préféreriez ne pas penser quand vous voulez juste mettre en forme une feuille.

ExcelMaster vous laisse décrire le résultat à la place. Dites « dans la feuille Data, colore en rouge chaque valeur négative de la colonne B et mets-la en gras », et il écrit et exécute la logique — en qualifiant correctement chaque référence d'objet, pour que le bug silencieux de la « mauvaise feuille » que provoque le point manquant ne puisse tout simplement pas se produire. Quand vous écrivez à la main une macro planifiée, c'est encore vous qui prendrez With ; pour la tâche quotidienne de mise en forme et de marquage, décrire ce que vous voulez vaut mieux que réussir à la main chaque point initial.

Questions fréquentes

Que fait l'instruction With en VBA ?

With object … End With nomme un objet une seule fois pour que vous puissiez accéder à ses membres avec un simple point initial (.Value, .Font.Bold) au lieu de répéter le chemin d'objet complet à chaque ligne. Le code est plus court, plus facile à rediriger et plus rapide — car VBA résout la référence d'objet une seule fois à l'entrée plutôt qu'à chaque ligne.

Pourquoi mon bloc With ne modifie-t-il pas le bon objet ?

Presque toujours un point initial manquant. À l'intérieur de With obj, .Font désigne obj, mais Font sans point est une référence non qualifiée qui se lie au contexte implicite de la feuille active — vous modifiez donc le mauvais objet en silence. Chaque membre qui appartient à l'objet With doit commencer par un point.

L'instruction With rend-elle vraiment VBA plus rapide ?

Oui, modestement, et cela compte dans les boucles. VBA résout l'objet sur la ligne With une seule fois et réutilise cette référence pour chaque membre pointé, au lieu de reparcourir toute la chaîne d'objet à chaque ligne. Sur deux ou trois lignes vous ne le remarquerez pas ; sur des milliers d'itérations, les redéréférencements économisés s'additionnent.

Puis-je imbriquer des instructions With en VBA ?

Oui. Un point initial se lie toujours au With actif le plus interne, donc With .Range("A2").Font à l'intérieur de With Sheets("Report") fait de .Bold celui de la police. C'est lisible à deux niveaux, mais une imbrication plus profonde rend difficile de dire à quel objet renvoie chaque point — affectez une variable objet intermédiaire au lieu d'imbriquer trois niveaux ou plus.

Puis-je changer l'objet With lui-même à l'intérieur du bloc ?

Non — la référence With est figée à l'entrée du bloc. Vous ne pouvez pas réaffecter ce que With désigne en cours de route ; pour travailler sur un autre objet, fermez le bloc avec End With et ouvrez-en un nouveau. Vous pouvez lire et modifier librement les membres de l'objet, mais pas repointer le bloc.

Testé dans

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

Guides associés : VBA For Each · VBA Collection · VBA Range · VBA ActiveSheet · VBA For Loop