par , 24/02/2016 à 07h35 (4818 Affichages)
Au risque de me répéter (Arf, je me répète), 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:
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:
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:
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:
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:
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?
Dans ce billet plus récent, je vous parle de la philosophie des boucles…
Allez, bon pissage de code