Voir le flux RSS

Pierre Fauconnier

VBA: Select Case ou If ElseIf?

Noter ce billet
par , 11/08/2019 à 09h15 (258 Affichages)
Sur le forum, je viens de rencontrer une utilisation pour le moins étonnante de Select End Select
Citation Envoyé par ...
Bonjour
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
Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
 Select Case True
    Case Not Intersect(Target, Range("G51:G54")) Is Nothing
    Worksheets("PRESCRIPTION").Range("H51:H54").Formula = Worksheets("PRESCRIPTION").Range("AF51:AF54").Formula
 
    Case Not Intersect(Target, Range("L52:L55")) Is Nothing
    Worksheets("PRESCRIPTION").Range("M52:M55").Formula = Worksheets("PRESCRIPTION").Range("AH52:AH55").Formula
 
    Case Else
    '........
    End Select
    Application.EnableEvents = True
End Sub
Cette utilisation de Select Case, qui ressemble à une "astuce pour l'astuce", est à mon avis impropre et devrait être oubliée, au profit d'un Bloc If End If utilisant ElseIf
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
IF A = 1 Then
  ...
ElseIf B = 2 Then
  ...
Else
  ...
End If

D'abord, pourquoi ces deux possibilités et qu'est-ce qui les différencient?

IF...ElseIF...End IF

Le bloc If...ElseIf...End If est générique lorsqu'il s'agit d'exécuter du code en fonction de conditions qui s'excluent mutuellement et pour lesquelles il existe une priorisation (D'abord A, sinon B, sinon C...).

Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
IF A = 1 Then
  ... ' Code 1
ElseIf B = 2 Then
  ... ' Code 2
Else
  ... ' Code 3
End If

Dans le code ci-dessus, lorsque A = 1 est vérifié, seul Code1 est exécuté. C'est seulement lorsque A = 1 n'est pas vérifié que B = 2 va être testé. Et bien sûr, le même raisonnement s'applique pour la suite du code à l'intérieur du bloc If... End If. Si B = 2 est vérifié, Code2 est exécuté et pas Code3. On remarque donc une priorité des conditions, et un seul des Code1, Code2, code3 est exécuté.

Lorsque les conditions portent sur la même expression, If...ElseIf...End If est parfaitement fonctionnel, mais on remarque une répétition de l'expression A. Si cette expression est courte (ce qui devrait souvent être le cas si l'on suit les bonnes pratiques de programmation), ce n'est pas forcément très grave, mais il y a tout de même répétition, ce que l'on essaie normalement d'éviter, et si l'expression ne se résume pas à une variable mais à un algorithme, le traitement de l'algorithme est répété, ce qui peut nuire aux performances.
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
If A = 1 Then
  ...Code1
ElseIf A = 2 Then
  ...Code2
Else
   Code3
End If

Select Case...End Select

Pour éviter ces répétitions d'écriture et d'évaluation, VBA propose le bloc Select Case ... End Select, lorsque les différentes conditions portent sur la même expression
Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
Select Case A
  Case 1
    ...Code1
  Case 2
    Code2
  Case Else
    Code3
End Select

Ce code produit exactement le même résultat que le bloc If... End If vu juste avant, mais il a l'avantage de n'énoncer de d'évaluer l'expression A une seule fois. On le préférera donc dans le cas particulier où les différentes conditions (qui s'excluent entre elles, je le rappelle) portent sur la même expression.

Pourquoi pas Select Case True ou Select Case "Bonjour"

Si l'on a bien compris ce qui précède, on peut facilement déduire pourquoi cette utilisation est impropre. Le Select Case induit la vérification de différentes valeurs d'une expression qui doit forcément être variable alors qu'ici, l'expression est constante. Il ne saurait donc y avoir plusieurs valeurs pour cette expression. On remarque d'ailleurs que l'expression évalue sur les différents Case est différente, alors que Select End Select a été écrit justement pour le cas où l'expression est la même sur chaque Case.

De l'intention du programmeur

Lorsque j'écris du code, j'aime que mon intention transparaisse de ce dernier, et il en est évidemment de même lorsque je lis le code d'un autre développeur. Si je tombe sur un Select End Select, je sais, au vu des explications de ce billet, que le code va vérifier différentes valeurs d'une même expression dans un certain ordre et n'exécuter qu'un bloc de code, puisque c'est le but de cette construction. Si je tombe sur un If ElseIf End If, je sais que le code va vérifier des conditions portant sur des expressions différentes, dans un certain ordre, et n'exécuter qu'un des blocs.

De ce fait, le code est limpide, clair, lisible, et on en comprend l'intention, la finalité, à la simple lecture, pour peu, bien sûr, que l'on sache programmer...

Conclusions
L'utilisation de "l'astuce pour l'astuce" n'a rien à faire dans du code écrit de façon professionnelle. Un professionnel de la programmation veillera à rendre son code lisible, compréhensible, maintenable et évolutif, en évitant la fioriture inutile.

Je lis souvent sur les forums que les pratiques se valent, mais je suis clairement d'un autre avis. Il y a beaucoup de pratiques pour arriver à un même résultat, mais beaucoup sont brouillonnes, peu sont bonnes et une, voire deux, sont vraiment à ranger dans les bonnes pratiques. Select Case True fait indubitablement partie des mauvaises pratiques de programmation. Le lustre de "l'astuce pour l'astuce" ne brille jamais longtemps.

Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Viadeo Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Twitter Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Google Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Facebook Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Digg Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Delicious Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog MySpace Envoyer le billet « VBA: Select Case ou If ElseIf? » dans le blog Yahoo

Mis à jour 13/08/2019 à 16h52 par Pierre Fauconnier

Catégories
VBA , MS Office , Humeur / Humour , Bonnes pratiques

Commentaires

  1. Avatar de François DORIN
    • |
    • permalink
    Effectivement, c'est une astuce... à éviter ! Du point de vue maintenance j'entends.

    Quand on a ce genre de code, il faut penser à celui qui va le relire après. Les instructions portent une sémantique. S'en éloigner vient perturber grandement la lecture d'un programme. Une boucle for est faite pour faire une itération, et l'itérateur ne devrait pas être modifié par le code de la boucle (certains langages interdisent d'ailleurs cela). S'il faut vraiment le faire, je préfère largement l'utilisation d'un while.

    Ici, c'est pareil, c'est un switch transformé en une cascade de if. Ben on fait des if !
  2. Avatar de Pierre Fauconnier
    • |
    • permalink
    Bonjour François,


    Citation Envoyé par François DORIN
    [...]Une boucle for est faite pour faire une itération, et l'itérateur ne devrait pas être modifié par le code de la boucle (certains langages interdisent d'ailleurs cela). S'il faut vraiment le faire, je préfère largement l'utilisation d'un while[...]
    je ne peux qu'être d'accord avec toi. J'avais d'ailleurs en tête d'écrire un billet sur le sujet, car effectivement, lorsque je rencontre une boucle For Next, je m'attends à ce qu'elle itère sur chaque élément, alors que la boucle DO WHILE m'indique qu'il y a une condition de sortie.

    Merci pour ton avis, toujours pertinent...