Voir le flux RSS

Pierre Fauconnier

[VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!!

Noter ce billet
par , 24/02/2016 à 08h35 (1033 Affichages)
Au risque de me répéter, je le rappelle encore et encore: Pas d'EXIT SUB dans vos codes. Ce n'est pas compliqué de bien coder, tout de même. Et il existe très souvent, même toujours, une alternative à une sortie prématurée de procédure ou de fonction.

Il ne faut qu'une seule sortie de procédure ou de fonction. Pourquoi? Parce qu'avoir deux sorties de procédure, voire plus parfois, c'est risquer de sortir sans "remettre les choses à leur place"! Apparemment, difficile à comprendre, comme dans une réponse fournie dans cette discussion, où c'était pourtant très simple d'éviter Exit Sub.

Examinons le code suivant proposé dans la discussion:
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
Private Sub Worksheet_Change(ByVal Target as Range)
    If Target.Address <> "$A$1" Then Exit Sub
    Range("A2").Value = Range("A2").Value + Target.Value
End Sub

Deux sorties de Proc. Au passage, on notera l'absence de test sur la valeur numérique à ajouter à A2. Si l'utilisateur saisit une valeur textuelle, bardaf c'est l'embardée. Au mieux, selon l'option de gestion des erreurs, on remonte au code appelant (Ah zut, comme c'est une proc événementielle, il y a des chances qu'il n'y ait rien d'autre dans la pile d'appel), au pire l'utilisateur entre dans le VBE et se prend une belle ligne surlignée de jaune. Au passage (bis), on notera l'absence de désactivation des événements, ce qui va amener la procédure à être appelée à nouveau lors de la modification de A2. C'est vrai que ce n'est qu'un appel de plus qui coûte probablement moins d'une milliseconde, alors, pourquoi se gêner?

Pour ma part, j'ai eu suffisamment de fois l'envie d'étriper les "programmeurs" qui pissent du code comme un porc se vautre dans son auge que pour savoir ce que signifie "bien coder". Et je le dis sans ambages, mettre des EXIT SUB dans son code, c'est coder comme un cochon. Ca n'a rien à voir avec "le style", c'est juste sale, chi*** à maintenir, et mettre les mains dans le lisier des autres n'est pas ma tasse de thé. Malheureusement, lorsqu'il s'agit de nettoyer ce code digne d'un goret, c'est moi qu'on appelle, le goret étant parti planter des salades

Pourquoi un Exit Sub, d'ailleurs? Est-ce si compliqué d'écrire:
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
Private Sub Worksheet_Change(ByVal Target as Range)
    If Target.Address = "$A$1" Then
      Range("A2").Value = Range("A2").Value + Target.Value
    End If
End Sub

Bien sûr, le code montré ci-dessus est tellement basique que cela ne sert à rien de faire un caca nerveux! Pierre, du calme, Xanax et Attarax sont tes copains. Oui mais... Quand l'habitude de coder salement est prise, elle est prise...

Examinons le code suivant:
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
Sub MySub()
  Application.DisplayAlerts = False
  ...
  ...
  If ...then Exit Sub
  ...
  Application.DisplayAlerts = True ' <=== On n'est pas certain de passer par cette ligne!!
End Sub

Ai-je besoin de vous faire un dessin? Vous pouvez remplacer Application.DisplayAlerts en début de fonction par Application.EnableEvents=False, c'est assez "amusant" aussi à déboguer, quand vous pestez pendant une heure (ou plus) pour tenter de comprendre pourquoi votre événement n'est pas levé?

Et la gestion d'erreur?
Ah oui, la gestion d'erreur, parlons-en! Je vois souvent ceci:
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Private Sub Worksheet_Change(ByVal Target As Range)
  On Error GoTo ErrHandler
  ...
  If Target.Address = "$A$1" Then
    Application.EnableEvents = False
    ...
    Range("a2") = Range("a2") + Range("a1")
    ...
    Application.EnableEvents = True
  End If
  Exit Sub
 
EndHandler:
  ... ' <== Gestion de l'erreur
End Sub

Pouah!! Et si l'utilisateur a saisi une valeur textuelle en A1, que se passe-t-il? Il passe dans la gestion de l'erreur et hop, il sort de la procédure en laissant la gestion d'événéments à False...

Donc, une bonne façon de coder, c'est, par exemple:
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Private Sub Worksheet_Change(ByVal Target As Range)
  On Error GoTo EndHandler
  ...
  If Target.Address = "$A$1" Then
    Application.EnableEvents = False
    ...
    Range("a2") = Range("a2") + Range("a1")
    ...
  End If
 
EndHandler:
  Application.EnableEvents = True
  If Err <> 0 Then
    ...
  End If
End Sub

Ainsi, on est certain de remettre les choses à leur place avant de sortir de la procédure.


Alors, suivez mon conseil: Pas de EXIT SUB ou de EXIT FUNCTION !!

Capito?

Allez, bon pissage de code

Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Viadeo Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Twitter Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Google Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Facebook Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Digg Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Delicious Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog MySpace Envoyer le billet « [VBA] De grâce, pas d'EXIT SUB dans vos codes, svp! Même pour une gestion d'erreur!! » dans le blog Yahoo

Mis à jour 03/03/2016 à 18h25 par Pierre Fauconnier

Catégories
Programmation

Commentaires

  1. Avatar de kolodz
    • |
    • permalink
    Il a effectivement un certain nombre de cas où la sortie prématuré de fonction n'est pas une bonne idée. Cependant, il me semble que ces cas sont dû à une méconnaissance du langage et donc du comportement impliqué.
    Personnellement, je vois quelque cas où la sortie de fonction peut-être intéressant. Bien qu'il soit totalement possible de faire, quelque chose d’équivalent et propre avec des sous-fonctions.

    Note : Le même principe est présent dans d'autre langage. Notamment pour des questions de libération mémoire.
  2. Avatar de Pierre Fauconnier
    • |
    • permalink
    Salut Patrick

    Citation Envoyé par kolodz
    [...]
    Personnellement, je vois quelque cas où la sortie de fonction peut-être intéressant.[...]
    Tu peux développer un peu?