TL;DR —
GoTo labelfait sauter l'exécution vers une ligne marquéelabel:dans la même procédure, sans aucune condition. Il n'a qu'une seule place où il a encore sa raison d'être dans le VBA moderne :On Error GoTopour la gestion des erreurs. Pour tout le reste — boucles, sauts d'itération, branchements — un saut est plus difficile à suivre que les outils structurés (If,Exit For,Exit Sub,Do), et sauter vers l'intérieur ou l'extérieur d'une boucle corrompt silencieusement la boucle. Apprenez la syntaxe pour savoir lire le vieux code ; recourez à la version structurée quand vous écrivez du code neuf.
Sub GoToBasics()
Dim x As Long
x = 5
If x > 0 Then GoTo Positive
Debug.Print "zero or negative"
Exit Sub ' s'arreter avant de tomber dans le label ci-dessous
Positive: ' un label - un nom suivi d'un deux-points
Debug.Print "positive"
End Sub
GoTo est le plus vieil outil de flux de contrôle qui soit : il déplace l'exécution vers un label nommé,
sans condition et dans la direction de votre choix. VBA le prend toujours en charge, et une fonctionnalité
moderne — On Error GoTo — repose dessus. Mais pour le flux ordinaire, un saut produit du code que vous
ne pouvez pas lire de haut en bas, et c'est pourquoi presque chaque GoTo dans du code neuf devrait être
plutôt un Exit ou un If.
Ce que vous allez apprendre
- La syntaxe du label et du saut : comment vous écrivez un label et comment
GoTol'atteint - Le seul endroit où
GoToa vraiment sa place aujourd'hui — la gestion des erreursOn Error GoTo - Pourquoi sauter vers l'intérieur ou vers l'extérieur d'une boucle corrompt le compteur et laisse le travail à moitié fait
- Comment on détourne
GoTopour simuler unContinueque VBA n'a pas, et l'alternative propre - Pourquoi vous ne pouvez pas faire un
GoTovers un label d'une autre procédure - Les remplacements structurés qui se lisent mieux que n'importe quel saut
Le modèle mental : un saut inconditionnel à sens unique
Un label est un nom suivi d'un deux-points, seul sur une ligne ; GoTo label y amène l'exécution
directement :
GoTo CleanUp ' sauter en avant (ou en arriere) vers la ligne marquee CleanUp:
' ... les lignes ici sont ignorees ...
CleanUp: ' <-- l'execution reprend ici
Deux propriétés rendent GoTo à la fois puissant et dangereux. Il est inconditionnel — livré à
lui-même, il saute toujours, si bien que brancher exige de l'envelopper dans un If — et c'est un
déplacement à sens unique qui ne laisse aucune trace : rien n'indique d'où venait le contrôle, si bien
qu'un lecteur qui suit le code doit parcourir toute la procédure pour trouver chaque GoTo capable
d'atterrir sur un label. Une instruction structurée comme Exit For vous dit exactement où va le contrôle
(juste après Next) ; un GoTo peut venir de n'importe où. Cette différence est tout le procès qu'on lui
fait.
Le seul endroit où GoTo a sa place : On Error GoTo
Voici l'exception, et elle est réelle. La gestion des erreurs de VBA repose sur GoTo : On Error GoTo
indique à VBA vers quel label sauter lorsqu'une erreur d'exécution survient. C'est idiomatique, attendu,
et cela n'a aucune alternative structurée dans le langage :
Sub SafeOpen()
On Error GoTo Failed
Workbooks.Open "C:\reports\data.xlsx"
Exit Sub
Failed:
MsgBox "Could not open the file."
End Sub
Remarquez l'Exit Sub avant le label Failed: — sans lui, le chemin normal retomberait dans le
gestionnaire d'erreurs même quand rien n'a échoué. Cette retombée est le bug classique du code sous label
avec GoTo, et elle vaut pour chaque label, pas seulement les gestionnaires d'erreurs. Pour le mécanisme
complet, voyez VBA On Error. En dehors d'On Error, un GoTo est un signal
d'alerte, pas un outil.
Le piège : sauter vers l'intérieur ou l'extérieur d'une boucle
La pire chose à faire avec GoTo, c'est sauter par-dessus la frontière d'une boucle For ou Do. Sautez
hors d'une boucle avec GoTo et vous court-circuitez sa sortie normale — le compteur reste à la valeur
qu'il avait, et tout ce que la boucle devait terminer est sauté. Sautez au milieu d'une boucle et le
résultat est pire : le compteur n'a jamais été initialisé, si bien que le comportement est indéfini :
' NE PAS faire ceci - sauter hors d'une boucle avec GoTo
For i = 1 To 100
If Cells(i, 1).Value = "X" Then GoTo AfterLoop ' court-circuite la sortie propre
Next i
AfterLoop:
La ligne ci-dessus se trouve fonctionner, mais la version honnête est Exit For, qui quitte la boucle par
sa porte prévue et rend l'intention évidente. Tout « saut hors d'une boucle » s'écrit mieux avec
Exit For ou Exit Do ; tout « quitter la procédure maintenant » s'écrit mieux
avec Exit Sub. Ceux-là nomment la structure qu'ils quittent et posent le contrôle à un endroit
prévisible — un GoTo ne fait ni l'un ni l'autre.
Simuler Continue avec GoTo — et l'alternative propre
VBA n'a pas d'instruction Continue pour passer à l'itération suivante, si bien que le vieux code le
simule souvent en plaçant un label juste avant Next et en y sautant :
' la maniere GoTo de "continue" - fonctionne, mais c'est un saut
For i = 1 To n
If Cells(i, 1).Value = "" Then GoTo NextRow
' ... traiter la ligne ...
NextRow:
Next i
Cela fonctionne, mais oblige le lecteur à sauter de-ci de-là pour comprendre une boucle. La version
structurée inverse simplement le test, de sorte que les itérations sautées ne font rien et poursuivent
vers Next :
' la maniere structuree - pas de label, pas de saut
For i = 1 To n
If Cells(i, 1).Value <> "" Then
' ... traiter la ligne ...
End If
Next i
Même comportement, lu de haut en bas. Quand la condition de saut est un test unique, le If l'emporte
toujours. Réservez le motif du label-avant-Next au cas rare où la logique de saut est trop compliquée
pour un seul If — et même alors, envisagez de scinder le corps dans sa propre procédure.
Vous ne pouvez pas faire un GoTo entre procédures
Un label est local à la procédure où il vit. GoTo ne peut sauter que vers un label du même Sub ou
de la même Function ; vous ne pouvez pas sauter d'une procédure dans une autre (VBA lève une erreur
de compilation, « Label not defined »). Si vous vous surprenez à vouloir sauter dans une autre procédure,
ce que vous voulez en réalité, c'est l'appeler — MyCleanup ou Call MyCleanup — ce qui vous rend le
contrôle ensuite, exactement ce qu'un saut ne peut pas faire. Cette limitation est un atout : elle garde
chaque saut dans une seule unité lisible.
Quand un saut est vraiment l'option la moins mauvaise
L'honnêteté impose une concession : sortir de boucles profondément imbriquées est la seule situation
de flux de contrôle où un GoTo vers un label au-delà de la boucle externe peut être plus propre que les
alternatives, car VBA ne peut pas faire un Exit de plus d'un niveau de boucle à la fois. Même ici,
extraire les boucles imbriquées dans une Function et utiliser Exit Function est d'ordinaire plus
clair. La règle empirique : si vous tendez la main vers GoTo et que ce n'est pas On Error GoTo,
arrêtez-vous et demandez-vous si un Exit, un If ou une petite procédure d'aide ne dirait pas la même
chose sans saut. Quatre-vingt-dix-neuf fois sur cent, ce sera le cas.
Comment ExcelMaster vous aide
GoTo est facile à écrire et difficile à lire, ce qui est exactement la combinaison qui produit des
macros que personne ne peut maintenir six mois plus tard. Les deux erreurs qui piquent sont la retombée
dans un label quand un Exit Sub préalable manque, et les sauts par-dessus les frontières de boucle qui
laissent compteurs et travail dans un état indéfini.
ExcelMaster écrit un flux que vous pouvez
lire de haut en bas : Exit For là où une boucle doit s'arrêter, des clauses de garde là où une procédure
doit se retirer, et On Error GoTo uniquement là où il a sa place — dans la gestion des erreurs, avec
l'Exit Sub qui tient le chemin normal à l'écart du gestionnaire. Vous gardez le classeur et le code.
Questions fréquentes
Que fait GoTo en VBA ?
GoTo label transfère l'exécution sans condition vers une ligne marquée label: dans la même procédure.
Un label est un nom suivi d'un deux-points, seul sur sa ligne. Comme GoTo saute toujours, brancher exige
de l'envelopper dans un If, comme dans If x < 0 Then GoTo Negative. L'exécution se poursuit ensuite à
partir du label.
GoTo est-il une mauvaise pratique en VBA ?
Pour le flux de contrôle ordinaire, oui — un saut est plus difficile à suivre que les instructions
structurées, et sauter vers l'intérieur ou l'extérieur d'une boucle peut corrompre le compteur.
L'exception importante est On Error GoTo, la façon idiomatique et attendue d'acheminer les erreurs
d'exécution vers un gestionnaire. Apprenez GoTo pour lire le vieux code ; préférez Exit, If et les
boucles Do quand vous écrivez du code neuf.
Comment écrire un label pour GoTo ?
Placez un nom suivi d'un deux-points sur sa propre ligne, comme CleanUp:, et sautez-y avec
GoTo CleanUp. Les labels sont insensibles à la casse et locaux à la procédure. Placez toujours un
Exit Sub avant un label situé à la fin d'une procédure, sinon le chemin normal retombera dans le code
sous label même quand aucun saut n'était voulu.
GoTo peut-il sauter vers un autre Sub ou une autre Function ?
Non. Un GoTo ne peut atteindre qu'un label de la même procédure ; sauter dans un autre Sub ou une
autre Function est une erreur de compilation. Pour exécuter du code dans une autre procédure, appelez-la
par son nom — l'appel vous rend le contrôle une fois terminé, ce que vous voulez d'ordinaire et ce qu'un
saut ne peut jamais faire.
Comment sortir d'une boucle sans GoTo ?
Utilisez Exit For pour une boucle For ou Exit Do pour une boucle Do — les deux quittent la boucle
par sa sortie prévue et continuent à la ligne suivante. Pour sauter une seule itération plutôt que quitter
la boucle, enveloppez le corps dans un If pour que les passages sautés ne fassent rien. Voyez
VBA Exit For pour l'ensemble complet.
Testé dans
Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 24/09/2026.
Guides associés : VBA Exit For · VBA End · VBA On Error · VBA For Loop · VBA If Then Else
