Testé sur : Excel 365 v2509 · Excel 2021 · Excel 2019 · dernière vérification le 08/06/2026
En bref — Quand une erreur d'exécution survient, VBA remplit un objet global unique — Err — avec tout ce qu'il sait du plantage. Vous le lisez dans un gestionnaire pour décider quoi faire ; vous pouvez aussi y écrire avec Err.Raise pour déclencher votre propre erreur :
Sub LirePrix()
On Error Resume Next
Dim prix As Double
prix = CDbl(Range("A1").Value) ' échoue si A1 n'est pas numérique
If Err.Number <> 0 Then
MsgBox "Erreur " & Err.Number & " : " & Err.Description
Err.Clear ' on réinitialise pour que la vérif suivante soit propre
End If
On Error GoTo 0
End Sub
L'objet entier, en un seul endroit :
Err.Number ' le code d'erreur — 0 signifie « aucune erreur »
Err.Description ' le message lisible par un humain
Err.Source ' qui l'a déclenchée (nom du projet / de l'objet)
Err.Raise 513 ' DÉCLENCHER vous-même une erreur
Err.Clear ' remettre Err dans un état propre
Le modèle mental : Err est la boîte noire du dernier plantage
Err est un objet unique, global, toujours présent. Voyez-le comme l'enregistreur de vol de votre macro : à l'instant où une erreur d'exécution survient, VBA y inscrit trois faits avant que le contrôle ne saute vers votre gestionnaire —
Err.Number— le code numérique (1004,13,9…).0signifie « rien n'a mal tourné ».Err.Description— le même texte que vous verriez dans la boîte rouge (« Incompatibilité de type », « L'indice n'appartient pas à la sélection »).Err.Source— quel projet ou objet l'a déclenchée.
Il n'y a qu'un seul objet Err pour toute la session, et il contient l'erreur la plus récente. Voilà pourquoi le moment où vous le lisez compte autant que ce que vous lisez — et pourquoi il se vide automatiquement (voir plus bas).
La seule règle : Err.Number est le seul « a-t-elle vraiment échoué ? » fiable
Après On Error Resume Next, votre code continue à tourner, que la ligne ait fonctionné ou non. La seule façon de savoir ce qui s'est passé est de lire Err.Number :
On Error Resume Next
Set wb = Workbooks("Budget.xlsx") ' ce classeur est-il déjà ouvert ?
If Err.Number = 0 Then
MsgBox "Déjà ouvert."
Else
Err.Clear
Set wb = Workbooks.Open("C:\Donnees\Budget.xlsx")
End If
On Error GoTo 0
Un Resume Next sans vérification de Err.Number est du gâchis : vous avez dit à VBA d'ignorer les échecs, mais vous ne saurez jamais qu'un échec a eu lieu. La vérification est la gestion. C'est la règle compagne de On Error Resume Next — les deux ne fonctionnent qu'en couple.
Vous pouvez aussi vous brancher sur le code précis, car des numéros différents signalent des problèmes différents :
Select Case Err.Number
Case 0: ' aucune erreur
Case 9: MsgBox "Cette feuille ou cet indice n'existe pas." ' L'indice n'appartient pas à la sélection
Case 13: MsgBox "Cette valeur n'est pas du bon type." ' Incompatibilité de type
Case 1004: MsgBox "Excel a refusé cette opération." ' erreur d'automation générique
Case Else: MsgBox "Erreur inattendue " & Err.Number & " : " & Err.Description
End Select
Le piège : Err se vide quand vous vous y attendez le moins
Err ne reste pas rempli jusqu'à ce que vous en ayez fini. VBA le remet à Number = 0 automatiquement sur n'importe lequel de ces événements :
- une instruction
On Errorde toute sorte (y comprisOn Error GoTo 0) - un
ResumeouResume Next Exit Sub/Exit Function- la prochaine erreur d'exécution (il est écrasé, pas accumulé)
Donc si vous avez besoin du numéro ou de la description après l'un de ceux-là — pour le journaliser, l'afficher plus tard, le faire remonter — capturez-le dans vos propres variables dès que votre gestionnaire démarre :
Gestionnaire:
Dim numErr As Long, msgErr As String
numErr = Err.Number ' on l'attrape MAINTENANT
msgErr = Err.Description
On Error Resume Next ' ← cette ligne viderait Err...
Application.ScreenUpdating = True ' ...donc le nettoyage ne peut plus lire Err
JournaliserDansFeuille numErr, msgErr ' on utilise les copies sauvegardées, pas Err.*
Ce seul piège est derrière la plupart des tickets « mon journal d'erreurs affiche erreur 0 ».
Déclencher vos propres erreurs avec Err.Raise
Lire Err, c'est la moitié de l'objet. L'autre moitié, c'est d'y écrire — déclencher délibérément une erreur quand vos règles sont violées, pas seulement celles de VBA :
Function PrixNet(prixBrut As Double, tauxTaxe As Double) As Double
If tauxTaxe < 0 Or tauxTaxe > 1 Then
Err.Raise vbObjectError + 513, "PrixNet", _
"tauxTaxe doit être entre 0 et 1, reçu " & tauxTaxe
End If
PrixNet = prixBrut / (1 + tauxTaxe)
End Function
Err.Raise Number, Source, Description génère une vraie erreur d'exécution — le gestionnaire On Error de l'appelant l'attrape exactement comme une erreur native. Utilisez vbObjectError + n (avec n de 513 à 65535) pour les erreurs personnalisées ; cette constante vous décale nettement hors de la plage 0–512 que VBA réserve aux codes système, vous n'entrez donc jamais en collision avec une vraie erreur.
L'avis tranché : renvoyer un code d'erreur, c'est espérer ; en déclencher une, c'est imposer
Beaucoup de code VBA « valide » en renvoyant une valeur témoin — -1, False, une chaîne vide — et fait confiance à chaque appelant pour penser à la vérifier. Il n'y pensera pas. Six mois plus tard, quelqu'un appelle votre fonction, ignore le -1 et divise par lui.
Err.Raise supprime le choix. Une erreur déclenchée ne peut pas être ignorée en silence — soit elle heurte un gestionnaire, soit elle arrête la macro. C'est tout l'intérêt. Lire Err.Number vous rend compétent en gestion des erreurs ; déclencher vos propres erreurs sur de mauvaises entrées et règles métier est ce qui rend votre code défensif au lieu de simplement poli. Si une valeur corromprait le résultat en aval, ne renvoyez pas un drapeau en espérant — déclenchez.
Erreurs fréquentes avec Err (et la correction)
| Symptôme | Cause | Correction |
|---|---|---|
| Le journal affiche toujours « erreur 0 » | Err lu après qu'un Resume / On Error / nettoyage l'a vidé |
Sauvegarder d'abord Err.Number / Err.Description dans des variables |
Resume Next « n'attrape » rien |
On n'a jamais vérifié Err.Number après la ligne risquée |
Ajouter If Err.Number <> 0 Then … |
| L'erreur personnalisée entre en collision avec une erreur système | On a utilisé un petit nombre brut comme Err.Raise 5 |
Utiliser Err.Raise vbObjectError + 513 et au-dessus |
| Une seconde vérification se déclenche sur une erreur périmée | On a oublié Err.Clear après avoir traité la première |
Appeler Err.Clear une fois l'erreur traitée |
Err.Description est vide |
Lu après Err.Clear ou une réinitialisation |
Lire la description avant de vider |
Arrêtez de coder à la main la plomberie des erreurs — décrivez plutôt la règle
La moitié d'un VBA robuste, c'est ceci : lire Err.Number, sauvegarder la description, déclencher ses propres erreurs sur de mauvaises données, vider, recommencer. C'est nécessaire et c'est fastidieux. ExcelMaster Agent vous laisse dire « vérifie que le taux de taxe est entre 0 et 1 et arrête-toi avec un message clair sinon » en français courant — et le Python généré déclenche et signale l'erreur pour vous, le fichier ayant d'abord été sauvegardé. Essayer gratuitement →
Guides liés
- VBA On Error — Resume Next vs GoTo & pourquoi les macros cachent les bugs
- Gestion des erreurs VBA — Le seul motif que toute macro fiable emploie
- VBA Function dans Excel — Valeurs de retour & fonctions personnalisées
- VBA Boucle For dans Excel — 8 exemples concrets
FAQ
Qu'est-ce que l'objet Err en VBA ?
Err est un objet global qui détient les informations sur l'erreur d'exécution la plus récente. Ses membres principaux sont Err.Number (le code d'erreur, 0 = aucune erreur), Err.Description (le message) et Err.Source (ce qui l'a déclenchée). Vous le lisez dans un gestionnaire d'erreurs pour décider quoi faire.
Comment vérifier le numéro d'erreur en VBA ?
Lisez Err.Number. Après On Error Resume Next, testez If Err.Number <> 0 Then pour voir si la ligne précédente a échoué. Une valeur de 0 signifie qu'aucune erreur n'est survenue. Vous pouvez utiliser Select Case Err.Number pour réagir différemment à des codes précis comme 9 (l'indice n'appartient pas à la sélection) ou 13 (incompatibilité de type).
Quand l'objet Err se réinitialise-t-il ?
Automatiquement sur toute instruction On Error, sur Resume / Resume Next, sur Exit Sub / Exit Function, et lorsque la prochaine erreur l'écrase. Si vous avez besoin des valeurs ensuite, copiez Err.Number et Err.Description dans vos propres variables aussitôt. Vous pouvez aussi le réinitialiser manuellement avec Err.Clear.
Comment déclencher une erreur personnalisée en VBA ?
Utilisez Err.Raise Number, Source, Description. Pour les erreurs personnalisées, employez vbObjectError + n où n est entre 513 et 65535, p. ex. Err.Raise vbObjectError + 513, "MaFonction", "Entrée invalide". Cela évite la plage 0–512 réservée aux erreurs système et permet au gestionnaire de l'appelant de l'attraper comme n'importe quelle erreur native.
Quelle différence entre Err.Clear et On Error GoTo 0 ?
Err.Clear remet les propriétés de l'objet Err dans un état propre mais laisse votre mode de piégeage d'erreurs inchangé. On Error GoTo 0 réinitialise le mode de piégeage au défaut (s'arrêter sur erreur) — et, en effet de bord, vide aussi Err. Utilisez Err.Clear pour réutiliser Err dans le même gestionnaire ; utilisez On Error GoTo 0 pour cesser d'ignorer les erreurs.
