2009-09-13 7 views
3

Je n'ai pas beaucoup lu à ce sujet, mais l'auteur sur le lien ci-dessous recommande que je n'utilise pas "bulle vers le haut" pour centraliser la gestion des erreurs dans VBA.Erreur VBA "Bubble Up"

Excel Programming Weekend Crash Course via Google Books

Mais je ne sais pas pourquoi il recommande, et il n'explique pas vraiment. Quelqu'un peut-il me dire pourquoi je devrais mettre la gestion des erreurs dans chaque procédure au lieu d'utiliser "bulle vers le haut"? Ou au moins, savez-vous pourquoi l'auteur dit de ne pas le faire?

Merci.

+2

-1 Veuillez ne pas utiliser d'URL raccourcies. Personne n'aime suivre les liens aveugles au travail. (+1 disponible sur le lien direct.) – Oorang

Répondre

0

Je ne suis pas sûr de ce que le traitement d'erreur par défaut de VBA est, mais depuis son Visual Basic pour Applications, et ces applications comprennent des choses comme Excel et Word, je suppose juste une boîte de dialogue apparaîtra qui ne sera pas être utile à l'utilisateur.

Je suppose que l'auteur a été mordu par le code ne gère pas les erreurs, il recommande maintenant toutes les procédures pour gérer les erreurs. La réponse complète est que vous devez être conscient de chaque erreur qui peut se produire et avoir le code en place pour le gérer, si elle est aussi faible que possible (où vous ne savez pas quoi faire), ou comme le plus haut possible (ce qui signifie moins d'effort pour écrire le code de gestion des erreurs, mais pas pour savoir pourquoi l'erreur est survenue), ou stratégiquement (juste au bon endroit où vous devriez pouvoir récupérer des erreurs les plus communes) ou juste partout être juste trop d'effort de développement).

+0

VBA _does_ permet aux erreurs de monter en flèche. Il y a des exceptions, mais en général, vous n'avez pas besoin d'avoir une gestion des erreurs dans chaque méthode pour empêcher un pop-up discordant de l'application. –

0

Je vois au moins une raison dans son explication: parce que cela vous prive du bénéfice de Resume (next).
Plus vous ne saurez pas dans quel module l'erreur s'est produite.

0

Il est préférable de ne pas utiliser la partie "bulle d'encre" du traitement des erreurs car les erreurs doivent être traitées & si l'on sait quoi faire, si une telle erreur se produit - est mieux connu à la procédure de quoi pour faire que la procédure d'appel.

Sub test() 
    On Error GoTo e 
    Dim c As Integer 
    Dim d As Integer 
    c = add(5, 0) 
    d = divideWhichManagedItsOwnErrorHandling(5, 0) 
    d = divide(5, 0) 

    Exit Sub 

e: 
    MsgBox "error occurred somewhere for which I don't know what to do: " + Err.Description 
End Sub 

Function add(a As Integer, b As Integer) As Integer 
    add = a + b 
End Function 

Function divide(a As Integer, b As Integer) As Integer 
    divide = a/b 'if error occurs, it will "bubble-up" to the caller. 
End Function 

Function divideWhichManagedItsOwnErrorHandling(a As Integer, b As Integer) As Integer 
    On Error Resume Next 
    Dim result As Integer 
    result = a/b 
    If Err.Number = 11 Then 'if divide by zero occurred, user must have passed 0 for b 
    result = 0 ' return 0 if the divide by zero occurs. 
    End If 
    divideWhichManagedItsOwnErrorHandling = result 
End Function 
+0

a/0 n'est pas 0! Vous venez d'avaler une erreur et de retourner un mauvais résultat. – jtolle

+1

@jtolle: Je ne parle pas ici du résultat de la division. Ceci est juste pour donner un exemple de gestion des erreurs et plus précisément, la gestion de l'erreur où elle se produit. – shahkalpesh

+0

Vous avez besoin d'un meilleur exemple alors. Cette erreur spécifique ne devrait pas être traitée de cette manière. – jtolle

11

La réponse courte à votre première question est "vous ne devrait pas mettre un gestionnaire d'erreur dans chaque procédure". Dire que "chaque procédure doit avoir un gestionnaire d'erreurs" est en général un conseil terrible. Les failles avec la gestion des erreurs VBA ont été beaucoup discutées ailleurs. Conceptuellement, cependant, ce n'est pas si différent de la forme plus standard de gestion des exceptions trouvée dans d'autres langues. La plupart des meilleures pratiques de ces langues s'appliquent. Vous devriez gérer les erreurs au niveau le plus bas où leur manipulation est logique. Parfois, c'est dans la procédure où l'erreur s'est produite, plusieurs fois non. Par exemple, un UDF VBA appelé à partir de votre feuille de calcul doit certainement avoir un EH qui vous assure de renvoyer une valeur d'erreur Excel à la ou les cellules appelantes au lieu de déposer votre utilisateur dans l'éditeur de code avec un message d'erreur. Cependant, le code que vous appelez à partir de ce fichier UDF peut ou non en avoir besoin. En fait, la chose la plus importante qu'une routine interne puisse faire lorsqu'une erreur se produit est souvent de la laisser passer dans la pile pour qu'elle puisse atteindre le code qui sait quoi faire avec. Cela dépend vraiment de la routine.

La réponse à votre deuxième question est que l'auteur ne semble pas très bien comprendre la gestion des exceptions.Il admet que la gestion des erreurs est spécifique au contexte, mais semble suggérer que chaque procédure devrait décider entre "corriger le problème ici et reprendre l'exécution" et "terminer le programme". Il laisse de côté l'option habituellement correcte, qui consiste à «nettoyer localement et lancer le problème à l'étage». Ainsi, les routines qui n'ont pas besoin d'être nettoyées localement devraient simplement laisser les erreurs «exploser».

+0

Pour un exemple non-VBA, voir: http://stackoverflow.com/questions/2737328/why-should-i-not-wrap-every-block-in-try-catch/2737337#2737337 – jtolle

1

Mes 2 cents: Vous devez placer des gestionnaires d'erreurs sur tous les procédures et événements publics. Cela signifie que la procédure au bas de la pile d'appels aura toujours un gestionnaire d'erreur. Ajoutez ensuite des gestionnaires d'erreurs dans vos autres procédures, car cela a du sens. Si une erreur survient dans une procédure qui n'a pas de gestionnaire d'erreur, elle va "remonter" vers le gestionnaire d'erreurs de niveau supérieur où il sera enregistré/affiché de façon professionnelle. Un scénario dans lequel vous pouvez ajouter un gestionnaire d'erreurs à une procédure privée (niveau inférieur) est le suivant: Le code doit être rapide. Vous avez une condition rare qui peut être évitée, mais qui vous forcera à effectuer un test logique coûteux à l'intérieur d'une boucle (ou pire une boucle imbriquée). Vous pouvez effectuer le test logique dans le gestionnaire d'erreurs, et s'il est dit "occurrence rare", effectuez la correction et recommencez. Comme la condition est rare, vous verrez des gains de performance pour la plupart des conditions. Si le gestionnaire d'erreurs n'arrive pas à comprendre et à corriger le problème, relancez l'erreur pour la faire exploser dans la pile.

Évidemment, ce n'est qu'un scénario.