Qu'est-ce que l'énumération dans VBA ? Comment en tirer parti ? Quand peut-on l'utiliser et pourquoi ? Peut-elle s'appliquer à l'IHM ? Ce sont toutes ces questions auxquelles nous allons tenter de répondre dans ce tutoriel au travers d'exemples concrets.

Commentez cet article : Commentez

- Titre : VBA : Énumération

- Auteurs : Fabrice CONSTANS, f-leb

- Parution : 25 août 2013

- Mise à jour : 1 septembre 2013

- Licence : Copyright © 2013 Fabrice CONSTANS. CDATA[Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC. Cette page est déposée à la SACD.

Sommaire

- 0. Introduction

- I. Définition

- II. Déclaration

- II-A. Énumération et classe

- II-B. Énumération et bibliothèque

- III. Utilisations

- III-A. Énumération dans les paramètres de fonction

- III-A-1. Astuce

- III-B. Masquer les membres

- III-C. Constantes métiers

- IV. Application à l'interface

- IV-A. Liste, onglet et groupe d'options

- V. Conclusion

- VI. Remerciements

0 - Introduction

Les énumérations peuvent rendre de précieux services dans la conception d'une application. Pourtant elles sont peu utilisées. Est-ce par méconnaissance de leurs possibilités ? Dans ce tutoriel nous allons faire un tour d'horizon des utilisations possibles et de leurs capacités à améliorer la lisibilité du code.

L'énumération dans VBA est apparue avec la version 2000 d'Office. Elle est disponible dans toutes les applications qui utilisent ce langage.

I - Définition

Les énumérations permettent d'attribuer des noms à des valeurs numériques, de la même manière que les constantes, à la différence que ces noms sont regroupés dans un ensemble. Elles sont donc plus faciles à retrouver.

II - Déclaration

Les énumérations se déclarent de la manière suivante :

[Public][Private] Enum Nom_Enumération
MembreEnum1 = [Valeur_Constante]
MembreEnum2 = [Valeur_Constante]
End Enum

L'argument de portée, « Public » ou « Private », est facultatif. S'il est omis l'énumération sera publique.

Les valeurs des constantes sont toujours de type Long, donc un entier positif ou négatif. Elles peuvent être omises mais dans ce cas le premier membre aura pour valeur 0. Les autres membres auront la valeur du membre précédent plus 1.

Les valeurs de l'énumération suivante, qui n'a aucun sens pratique, sont volontairement omises pour démontrer la règle précédente.

Public Enum eMois
Janvier = 1
Fevrier
Mars
End Enum
Debug.Print eMois.Fevrier ' donne 2
Debug.Print eMois.Mars ' donne 3

II-A - Énumération et classe

L'énumération déclarée publique « Public  » dans une classe à la particularité d'être visible dans l'ensemble de l'application. Pour qu'elle ne soit pas visible dans les autres modules, sa portée doit être privée « Private  ».

II-B - Énumération et bibliothèque

Lorsque vous déclarez des énumérations publiques portant le même nom dans une même bibliothèque (ou fichier ACCESS), vous avez un message d'ambigüité.

Dans le cas où les énumérations de même nom sont dans des bibliothèques différentes, c'est celle qui est déclarée dans la bibliothèque qui est utilisée, sinon Microsoft ACCESS utilise l'ordre des références.

Vous pouvez cependant jouer sur la portée (« Public/ Private  ») pour des énumérations différentes portant le même nom au sein de modules différents. Bien qu'elles s'affichent dans la liste d'autocomplétion, les membres seront ceux de l'énumération de la portée courante.

Personnellement, j'évite d'utiliser le même nom pour des énumérations différentes, car cela n'ajoute que de la confusion au code.

III - Utilisations

Les utilisations sont nombreuses, nous n'allons pas en dresser la liste exhaustive mais plutôt démontrer celles qui me paraissent importantes, soit dans un but didactique, soit pour leur côté astucieux ou pratique.

III-A - Énumération dans les paramètres de fonction

Lorsque vous utilisez certaines commandes de VBA, par exemple « Docmd.OpenForm », vous pouvez constater que certaines options comportent des constantes qui sont reprises dans une liste au moment de l'écriture.

Il s'agit de simples énumérations natives. Nous pouvons l'appliquer à nos propres fonctions ou procédures.

Commencez par créer un module VBA, puis créez l'instruction « E num » et ses membres dans l'en-tête du module.

Option Compare Database
Option Explicit
Public Enum efFichierExt
Unite = 8
Chemin = 16
Fichier = 32
Extension = 64
End Enum

Pour le nom de l'énumération, j'utilise un « e » comme « énumération », suivi du nom de la fonction. Il ne s'agit pas là d'une convention mais d'un moyen pour les retrouver facilement dans l'autocomplétion.

Les membres doivent avoir un nom explicite pour s'y retrouver. Ne perdez pas de vue que l'énumération doit permettre une meilleure lisibilité du code.

Maintenant vous avez accès à un nouvel élément dans la liste des objets de VBA.

Pressez F2 et tapez « eff » dans la liste des éléments puis cliquez sur le bouton de recherche.

Notre énumération fait maintenant partie de l'application. Voici ce qui se passe lors de son utilisation :

On indique que le paramètre est du type « efFichierExt », soit notre énumération.

Lorsque vous faites référence au paramètre « iType » dans la fonction, voici ce que vous obtenez :

Je vous livre ici la fonction complète qui utilise l'énumération en paramètre. N'oubliez pas de créer l'énumération fournie précédemment.

Public Function fFichierExt(strCheminFichier As String, iType As efFichierExt) As String
' Fabrice CONSTANS (MVP)
' Page personnelle : http://loufab.developpez.com
' Blog : 2gm.free.fr
' Retourne l'un des éléments suivant le chemin/fichier passé en référence
' strCheminFichier contient le chemin et fichier
' iType = enum efFichierExt
'    64   renvoie l'extension du fichier sans le point
'    32   renvoie le nom du fichier sans son extension
'    16   renvoie le chemin sans le nom ni l'extension
'    8    renvoie l'unité

On Error GoTo errSub
Dim vRetour As String

If iType And Unite Then      ' l'unité
vRetour = Left(strCheminFichier, InStr(strCheminFichier, ":"))
End If

If iType And Chemin Then     ' renvoie le chemin
vRetour = vRetour & Mid(strCheminFichier, 3, InStrRev(strCheminFichier, "\") - 2)
End If

If iType And Fichier Then  ' renvoie le nom du fichier
Dim tmpFic As String
tmpFic = Right(strCheminFichier, Len(strCheminFichier) - InStrRev(strCheminFichier, "\"))
vRetour = vRetour & Left(tmpFic, InStrRev(tmpFic, ".") - 1)
End If
If iType And Extension Then   ' renvoie l'extension
If iType And Fichier Then vRetour = vRetour & "." ' ajoute un point si le nom du fichier est demandé
vRetour = vRetour & Right(strCheminFichier, Len(strCheminFichier) - InStrRev(strCheminFichier, "."))
End If

fFichierExt = vRetour

Exit Function

errSub:
On Error GoTo 0
Exit Function

End Function

Cette fonction traite une chaine contenant un chemin et un nom de fichier. Elle renvoie le ou les composants demandés par le paramètre d'énumération.

Voici son comportement lors de l'appel :

On voit clairement la liste des membres de l'énumération.

L'énumération étant disponible dans l'ensemble du code, on l'utilise pour tester les valeurs passées en argument à l'intérieur de la fonction.

III-A-1 - Astuce

Lorsque vous faites un appel aux commandes, fonctions ou propriétés, vous avez peut-être remarqué que certaines d'entre elles acceptent plusieurs paramètres additionnés, c'est notamment le cas de « Msgbox ».

La fonction « fFichierExt » a le même comportement parce que les valeurs des membres de l'énumération s'y prêtent.

Grâce à l'opérateur de conjonction binaire, soit « And » en VBA, nous traitons les arguments multiples.

Ce traitement est possible grâce à la valeur utilisée dans les constantes (8, 16, 32, 64.) qui correspondent aux décalages de bits suivants :

Bit

7

6

5

4

3

2

1

0

Valeur

64

32

16

8

4

2

1

0

Pour plus d'information sur l'algèbre de Boole et les opérations binaires, référez-vous à un cours d'algèbre de Boole et binaire.

III-B - Masquer les membres

Pour qu'un membre n'apparaisse pas dans la liste ou dans l'explorateur d'objets « F2  » , vous devez ajouter le préfixe « _ » à son nom. En VBA, le caractère « souligné » (_ ou underscore) n'est pas admis au début d'un nom. Le nom doit être entouré de crochets.

[_NomVariable]  = valeur

Dans l'exemple suivant le dernier membre « Unc » est caché.

Public Enum efFichierExt
Unite = 8
Chemin = 16
Fichier = 32
Extension = 64
[_UNC] = 128
End Enum

Comme pour la liste d'autocomplétion, l'explorateur d'objets « F2  » ne l'affiche pas. Cependant vous pouvez faire apparaitre les membres masqués en faisant « clic-droit  » sur la fenêtre de l'explorateur d'objet et choisir d'Afficher les membres masqués.

Il apparait grisé avec le caractère de soulignement, dans l'explorateur et dans la liste.

Attention ! L'option Afficher les membres masqués n'est valable que le temps de la session Microsoft ACCESS.

Pour faire un appel à un membre masqué, vous devez utiliser le nom tel qu'il apparait dans la liste, sans crochet, et non comme il a été déclaré.

efFichierExt._UNC

III-C - Constantes métiers

Dans le code, nous avons souvent besoin de faire appel à des constantes métiers, plutôt que de mettre ces valeurs en dur dans le code. On aura tout intérêt à les associer dans une énumération. D'une part pour la praticité de la relecture du code mais également en cas de modification de celui-ci.

Prenons l'exemple d'alertes pour un circuit de livraison.

Public Enum eLivraison
Achat = -1
EnStock = 0
Emballe = 2
Entrepot = 3
Livraison = 4
Livre = 5
End Enum

Dans le code vous testez les écarts de dates à différents moments du circuit. Voici sans l'utilisation de l'énumération :

Select Case Etat
Case = -1
MsgBox "Cet article est en commande."
Case = 0
MsgBox "Cet article est en stock."
Case = 2
MsgBox "Cet article est emballé."

Le même code avec l'énumération :

Select Case Etat
Case = eLivraison.Achat
MsgBox "Cet article est en commande."
Case = eLivraison.EnStock
MsgBox "Cet article est en stock."
Case = eLivraison.Emballe
MsgBox "Cet article est emballé."

C'est déjà plus clair. Mais là où il y a un sérieux avantage c'est lorsque les valeurs changent ou que vous ajoutez des étapes, vous n'intervenez plus qu'à un seul endroit, dans la déclaration de l'énumération. Vous vous épargnez ainsi de longues recherches dans le code, des oublis possibles et les bugs qui en découlent.

IV - Application à l'interface

L'énumération peut également rendre d'autres services, notamment lors de la relation avec l'interface. En effet, tous les contrôles qui utilisent un entier pour identifier un élément sont potentiellement concernés : les listes modifiables ou non, les onglets et à moindre effet les groupes d'options.

IV-A - Liste, onglet et groupe d'options

L'intérêt principal est d'évoluer vers un code plus clair et donc d'accroitre la rapidité de correction et d'évolution.

Commençons par créer un formulaire avec une zone de liste (liste0) basée sur une table contenant plusieurs colonnes.

Dans mon exemple il s'agit d'une table Contacts avec les colonnes habituelles : Id, Nom, Prénom, etc.

Une fois cette liste définie, nous allons récupérer dans le code quelques informations lors d'un double-clic. Créez l'événement « Sur Double-clic  » et insérez-y le code suivant :

Private Sub Liste0_DblClick(Cancel As Integer)
MsgBox Me.Liste0.Column(0) & vbCrLf & _
Me.Liste0.Column(1) & vbCrLf & _
Me.Liste0.Column(2) & vbCrLf & _
Me.Liste0.Column(3)
End Sub

Comme vous le voyez il n'utilise pas l'énumération. Le code est difficile à analyser au premier coup d'oeil puisqu'il faudra se référer à la liste pour le comprendre. Dans le cas où l'ordre des colonnes change vous devrez, comme dans l'exemple précédent, faire une recherche pour remettre le tout dans le nouvel ordre.

Voici le résultat :

Maintenant en utilisant l'énumération, voici comment ce code serait écrit. D'abord on définit l'énumération puis on l'utilise dans l'évènement.

Private Enum eListe
IdContact
Nom
Prenom
TelephonePro
TelephoneMob
TelephonePerso
Adresse
CodePostal
Ville
End Enum

Private Sub Liste0_DblClick(Cancel As Integer)
MsgBox Me.Liste0.Column(eListe.IdContact) & vbCrLf & _
Me.Liste0.Column(eListe.Nom) & vbCrLf & _
Me.Liste0.Column(eListe.Prenom) & vbCrLf & _
Me.Liste0.Column(eListe.TelephonePro)
End Sub

Avouez que c'est nettement plus lisible !

À présent, vos utilisateurs demandent à réorganiser l'ordre des colonnes en plaçant l'adresse complète avant les numéros de téléphone. Côté IHM vous allez modifier la liste, puis du côté du code, grâce à l'Enum, vous n'aurez qu'à modifier l'ordre de ses membres.

Private Enum eListe
IdContact
Nom
Prenom
Adresse
CodePostal
Ville
TelephonePro
TelephoneMob
TelephonePerso
End Enum

Voici la modification effectuée :

Vous avez gagné un temps précieux et évité des oublis générateurs de retours de la part de vos utilisateurs.

Cette technique peut être appliquée aux listes modifiables, aux onglets et aux groupes d'options dans la mesure où ils sont fortement présents dans votre code.

Le code suivant s'applique à un onglet.

Private Enum eOnglet
Contact
Factures
Reglements
End Enum
Private Sub btnContact_Click()
Me.CtlTab = eOnglet.Contact
End Sub

Private Sub btnFactures_Click()
Me.CtlTab = eOnglet.Factures
End Sub

Private Sub btnReglements_Click()
Me.CtlTab = eOnglet.Reglements
End Sub

Les boutons de commande ont été utilisés à la place des onglets classiques car l'utilisateur souhaitait avoir les étiquettes en bas.

Comme pour la liste, en cas de modification, vous n'intervenez que dans l'IHM et dans la déclaration de l'énumération.

Par exemple, entre les pages Contact et Factures nous rajoutons Commandes.

Voici ce que devient le code :

Private Enum eOnglet
Contact
Factures
Reglements
Commandes
End Enum
Private Sub btnContact_Click()
Me.CtlTab = eOnglet.Contact
End Sub
Private Sub btnFactures_Click()
Me.CtlTab = eOnglet.Factures
End Sub
Private Sub btnReglements_Click()
Me.CtlTab = eOnglet.Reglements
End Sub

Private Sub btnCommandes_Click()
Me.CtlTab = eOnglet.Commandes
End Sub

Nous avons rajouté Commandes dans la déclaration de l'énumération, dans la procédure pour le bouton ainsi que la nouvelle page avec le numéro d'index 3. Nous aurions pu tout aussi bien l'insérer entre Contacts et Factures et décaler les index.

V - Conclusion

Comme nous l'avons vu, l'énumération rend le code plus lisible et l'application plus facile à maintenir. Simple à mettre en oeuvre comme à utiliser, elle peut servir en toute circonstance. Vous n'aurez plus d'excuses pour ne pas l'utiliser.

VI - Remerciements

Je remercie Arkham46 et Pierre Fauconnier pour leur relecture technique et leurs conseils avisés ainsi que Dolphy35 et F-leb pour la correction orthographique.

VBA : Énumération

Comment utiliser l'énumération pour rendre votre code plus lisible et plus facile à maintenir.

Auteurs

| Fabrice CONSTANS | f-leb |