75 votes

Bons modèles pour la gestion des erreurs VBA

Quels sont les bons modèles pour la gestion des erreurs dans VBA?

En particulier, que dois-je faire dans cette situation:

 ... some code ...
... some code where an error might occur ...
... some code ...
... some other code where a different error might occur ...
... some other code ...
... some code that must always be run (like a finally block) ...
 

Je veux gérer les deux erreurs et reprendre l'exécution après le code où l'erreur peut se produire. En outre, le code finally à la fin doit TOUJOURS être exécuté, quelles que soient les exceptions lancées précédemment. Comment puis-je atteindre ce résultat?

101voto

guillermooo Points 2711

Gestion des erreurs en VBA


  • On Error Goto ErrorHandlerLabel
  • Resume (Next | ErrorHandlerLabel)
  • On Error Goto 0 (désactive l'actuel gestionnaire d'erreur)
  • Err objet

L' Err propriétés de l'objet sont normalement remis à zéro ou une chaîne de longueur nulle dans la routine de gestion des erreurs, mais il peut également être fait explicitement Err.Clear.

Des erreurs dans la routine de gestion des erreurs sont appelé à disparaître.

La gamme 513-65535 est disponible pour les erreurs de l'utilisateur. Pour la classe personnalisée des erreurs, vous ajoutez vbObjectError pour le numéro d'erreur.

Pour ne pas mis en œuvre l'interface de membres dans une dérivée de la classe, vous devez utiliser la constante E_NOTIMPL = &H80004001.


Option Explicit

Sub HandleError()
  Dim a As Integer
  On Error GoTo errMyErrorHandler
    a = 7 / 0
  On Error GoTo 0

  Debug.Print "This line won't be executed."

DoCleanUp:
  a = 0
Exit Sub
errMyErrorHandler:
  MsgBox Err.Description, _
    vbExclamation + vbOKCancel, _
    "Error: " & CStr(Err.Number)
Resume DoCleanUp
End Sub

Sub RaiseAndHandleError()
  On Error GoTo errMyErrorHandler
    ' The range 513-65535 is available for user errors.
    ' For class errors, you add vbObjectError to the error number.
    Err.Raise vbObjectError + 513, "Module1::Test()", "My custom error."
  On Error GoTo 0

  Debug.Print "This line will be executed."

Exit Sub
errMyErrorHandler:
  MsgBox Err.Description, _
    vbExclamation + vbOKCancel, _
    "Error: " & CStr(Err.Number)
  Err.Clear
Resume Next
End Sub

Sub FailInErrorHandler()
  Dim a As Integer
  On Error GoTo errMyErrorHandler
    a = 7 / 0
  On Error GoTo 0

  Debug.Print "This line won't be executed."

DoCleanUp:
  a = 0
Exit Sub
errMyErrorHandler:
  a = 7 / 0 ' <== Terminating error!
  MsgBox Err.Description, _
    vbExclamation + vbOKCancel, _
    "Error: " & CStr(Err.Number)
Resume DoCleanUp
End Sub

Sub DontDoThis()

  ' Any error will go unnoticed!
  On Error Resume Next
  ' Some complex code that fails here.
End Sub

Sub DoThisIfYouMust()

  On Error Resume Next
  ' Some code that can fail but you don't care.
  On Error GoTo 0

  ' More code here
End Sub

38voto

Joel Goodwin Points 3477

J'ajouterais aussi:

  • L’objet global Err est le plus proche d’un objet exception.
  • Vous pouvez effectivement "lancer une exception" avec Err.Raise

Et juste pour le plaisir:

  • On Error Resume Next est le diable incarné et à éviter, car il cache silencieusement les erreurs

18voto

John Nolan Points 16633

Pour que tu puisses faire quelque chose comme ça

 Function Errorthingy(pParam)
On Error GoTo HandleErr

 ' your code here

    ExitHere:
    ' your finally code
    Exit Function

    HandleErr:
        Select Case Err.Number
        ' different error handling here'
        Case Else
            MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, "ErrorThingy"
        End Select


   Resume ExitHere

End Function
 

Si vous souhaitez utiliser des exceptions personnalisées. (par exemple, ceux qui enfreignent les règles de gestion) utilisent l'exemple ci-dessus, mais utilisez le goto pour modifier le flux de la méthode selon vos besoins.

12voto

LimaNightHawk Points 758

Voici mon implémentation standard. J'aime que les étiquettes soient auto-descriptives.

 Public Sub DoSomething()

    On Error GoTo Catch ' Try
    ' normal code here

    Exit Sub
Catch:

    'error code: you can get the specific error by checking Err.Number

End Sub
 

Ou, avec un bloc Finally :

 Public Sub DoSomething()

    On Error GoTo Catch ' Try

    ' normal code here

    GoTo Finally
Catch:

    'error code

Finally:

    'cleanup code

End Sub
 

6voto

Dick Kusleika Points 15230

Professionnel Excel de Développement a une assez bonne gestion des erreurs système. Si vous allez passer du temps en VBA, c'est probablement la peine d'obtenir le livre. Il y a un certain nombre de domaines où VBA est ce qui manque et ce livre a de bonnes suggestions pour la gestion de ces zones.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X