L'essentiel (TL;DR) — Une feuille a trois poignées et une seule est sûre.
Sheets("Jan")utilise le nom d'onglet — l'utilisateur peut le renommer et votre macro meurt avec « l'indice n'appartient pas à la sélection ».Sheets(1)utilise la position — glissez un onglet et votre macro écrit en silence dans la mauvaise feuille.Sheet1(le CodeName, défini dans le VBE) est celle que l'utilisateur ne peut pas toucher depuis Excel, donc elle ne casse jamais. Capturez une référence une seule fois —Set ws = ThisWorkbook.Worksheets("Data")— et arrêtez.Select/.Activate.
Une feuille se situe un niveau sous le classeur : le classeur contient des feuilles, une feuille contient des plages. La douleur récurrente n'est pas d'utiliser une feuille — c'est de la nommer. Ratez la référence et votre macro soit plante bruyamment, soit, pire, écrit dans le mauvais onglet sans la moindre erreur.
Ce que vous allez apprendre
- Les trois façons de référencer une feuille et lesquelles deux vous trahissent
- Pourquoi le CodeName est la poignée à toute épreuve (et où le définir)
- La différence entre
SheetsetWorksheets(ce ne sont pas des synonymes) - Pourquoi
.Selectet.Activatesont des habitudes d'enregistreur de macros, pas du vrai code
Le modèle mental : trois poignées, deux qui bougent
Une feuille est un objet qu'on peut saisir de trois manières. Deux de ces poignées sont attachées à des choses que l'utilisateur contrôle — le nom d'onglet et l'ordre des onglets — elles bougent donc sous vos pieds. La troisième, le CodeName, est attachée à quelque chose que vous seul contrôlez depuis le VBE.
Sub ThreeWaysToGrabASheet()
' 1) Par NOM d'onglet — l'utilisateur peut le renommer -> casse
Debug.Print Worksheets("Jan").Name
' 2) Par INDEX (position) — l'utilisateur peut réordonner -> mauvaise feuille en silence
Debug.Print Worksheets(1).Name
' 3) Par CODENAME — défini dans le VBE, invisible à l'utilisateur -> à toute épreuve
Debug.Print Sheet1.Name ' "Sheet1" est le CodeName, pas le texte de l'onglet
End Sub
Pourquoi c'est important : les poignées #1 et #2 dépendent du comportement de l'utilisateur. Quelqu'un renomme « Jan » en « Janvier », ou le glisse après « Fév », et votre macro soit lève l'erreur d'exécution 9 (« l'indice n'appartient pas à la sélection »), soit — bien plus dangereux — continue de tourner et modifie le mauvais onglet. La poignée #3 est immunisée car le CodeName vit dans le code, pas sur l'onglet.
La règle : définissez un CodeName, ou capturez la référence une fois
Le mode de défaillance, c'est d'utiliser une poignée mobile au fond de votre macro. La solution est d'épingler la feuille une fois, en haut, puis de ne plus parler qu'à cette variable.
Sub SafeSheetReference()
' Capturez la référence une fois — pleinement qualifiée jusqu'au classeur
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
' À partir d'ici, tout passe par ws. Pas d'« actif », pas de nouvelle recherche.
ws.Range("A1").Value = "Report"
ws.Range("A2:A100").ClearContents
Debug.Print ws.UsedRange.Rows.Count
End Sub
Pour rendre le nom lui-même incassable, donnez un CodeName à la feuille : dans le
VBE, sélectionnez la feuille sous Microsoft Excel Objets, ouvrez la fenêtre
Propriétés (F4) et définissez (Name). Vous pouvez alors écrire
Set ws = SalesData et renommer l'onglet dans Excel ne change rien. Le jugement : si
une macro doit survivre à l'usage du fichier par d'autres, référencez les feuilles par
CodeName — les noms d'onglet sont du contenu utilisateur, pas du code.
Sheets vs Worksheets — pas la même collection
Presque tout le monde y trébuche. Worksheets, ce sont seulement les feuilles de
calcul. Sheets, c'est tout ce qui a un onglet — y compris les feuilles de
graphique. Itérez sur la mauvaise collection et vous tomberez sur une feuille de
graphique qui n'a pas de .Range, et vous plantez.
Sub SheetsVsWorksheets()
' Worksheets : feuilles de calcul UNIQUEMENT — sûres pour .Range / .Cells
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Range("A1").Value = "Vérifié"
Next ws
' Sheets : feuilles de calcul PLUS feuilles de graphique — .Range sur un graphique = plantage
Debug.Print ThisWorkbook.Worksheets.Count ' feuilles de calcul seulement
Debug.Print ThisWorkbook.Sheets.Count ' calcul + graphiques
End Sub
La règle de pouce : si votre boucle touche des cellules, itérez Worksheets, jamais
Sheets. Recourez à Sheets seulement quand vous avez vraiment besoin des feuilles
de graphique.
Arrêtez d'utiliser .Select et .Activate
L'enregistreur de macros écrit Sheets("Data").Select puis Range("A1").Select
parce qu'il ne peut enregistrer que ce que vous avez cliqué. Le vrai code saute le
clic entièrement — il parle directement à l'objet feuille. Sélectionner est lent, fait
clignoter l'écran et (parce que ça change l'ActiveSheet) prépare exactement les bugs
de mauvaise feuille vus plus haut.
' Style enregistreur — sélectionne, puis agit sur la sélection (fragile)
Sheets("Data").Select
Range("A1").Select
Selection.Value = 100
' Vrai code — une ligne, aucune sélection, aucune dépendance à ActiveSheet
ThisWorkbook.Worksheets("Data").Range("A1").Value = 100
Vous n'avez presque jamais besoin de sélectionner une feuille pour la lire ou l'écrire. Pourquoi « actif » est un piège dès le départ : voir VBA ActiveSheet.
Comment ExcelMaster aide
La plupart du VBA multifeuille existe pour déplacer des données entre onglets, régulièrement. ExcelMaster le fait à partir d'une description en langage naturel — « copie les lignes nettoyées de Data vers l'onglet Summary et rafraîchis les totaux » — sans références de feuille à mal nommer. Vous sautez toute la classe de bugs « l'indice n'appartient pas à la sélection ».
VBA garde sa place pour l'automatisation permanente intégrée au classeur. Mais pour le quotidien « déplace ceci de cet onglet vers celui-ci », le décrire est plus rapide et ne casse pas quand quelqu'un renomme une feuille.
Foire aux questions
Pourquoi ai-je « l'indice n'appartient pas à la sélection » en référençant une feuille ?
Le nom d'onglet passé n'existe pas — souvent parce que quelqu'un a renommé la feuille, ou à cause d'un espace de trop ou d'une faute de frappe. Référencez plutôt par CodeName (défini dans le VBE), que l'utilisateur ne peut pas changer, ou encadrez la recherche et vérifiez d'abord que la feuille existe.
Qu'est-ce qu'un CodeName de feuille et où le définir ?
Le CodeName est le nom interne qu'utilise VBA (Sheet1, Sheet2, …), affiché dans
l'Explorateur de projets du VBE. Définissez-le via la fenêtre Propriétés (F4) →
(Name). Contrairement au nom d'onglet, l'utilisateur ne peut pas le changer depuis
Excel, c'est donc la poignée la plus fiable.
Quelle est la différence entre Sheets et Worksheets en VBA ?
Worksheets contient uniquement les feuilles de calcul standard. Sheets contient
tous les types de feuilles, y compris les feuilles de graphique. Si votre code utilise
.Range ou .Cells, itérez Worksheets — une feuille de graphique n'a pas de
cellules et plante.
Dois-je Sélectionner ou Activer une feuille pour la modifier ?
Non. ThisWorkbook.Worksheets("Data").Range("A1").Value = 1 fonctionne sans rien
sélectionner. .Select/.Activate sont des artefacts de l'enregistreur de macros qui
ralentissent la macro et créent des bugs de mauvaise feuille.
Testé sur
Testé sur : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 13/06/2026.
Guides associés : VBA Workbook · VBA ActiveSheet · VBA Range · VBA For Loop · VBA Dictionary
