Descriptif des conventions typographiques du code Visual BasicDate de publication : 22/03/2005 , Date de mise à jour : 27/04/2005
Par
Jean-Philippe AMBROSINO (home page)
Ce document a pour objectif de simplifier la compréhension de l'écriture du code Visual Basic en vous montrant comment appliquer des conventions typographiques adaptées au code.
Son but, faire en sorte que votre code soit plus lisible pour vous-même et tous les membres susceptibles de le relire.
1. Avant propos 1-1. Normalisation des noms 1-2. Remerciements 1-3. Contact 2. Pourquoi définir une convention au niveau du code ? 2-1. Syntaxe des conventions 2-1-1. Syntaxe des conventions pour les objets 2-1-2. Syntaxe des conventions pour les variables 2-1-3. Exemples de déclaration de variables 2-1-4. Les constantes de module et les constantes en général 2-1-5. Les variables déclarées comme paramètre dans une procédure ou une fonction 3. Explications sur la portée d'une variable 3-1. Représentation des formats des types de données 4. Conventions générales concernant les noms 4-1. Les variables 4-2. Les fonctions et procédures 5. Conventions générales concernant le nom des contrôles 5-1. Exemple utilisant des objets non nommés : 5-2. Exemple utilisant des objets correctement nommés : 5-3. Exemples d'appellation des contrôles avec leur préfixe 6. Les autres conventions 7. Les conventions de nommage des champs 7-1. Comment faire en sorte que le nom affiché ne soit pas celui du champ ? 8. Quelques recommandations complémentaires 8-1. Les variables de type Entier par défaut (Integer) 8-2. Les instructions Deftype 8-2-1. Le nom de l'instruction détermine le type de données 8-3. L'utilisation de l'IntelliSense 9. Conclusion 1. Avant propos
Il est fortement recommandé voir impératif d'appliquer certaines règles en matière de convention typographiques du code de programmation et uniquement dans le but de faciliter la relecture. Ce document est dédié à vous aider dans cette manœuvre. 1-1. Normalisation des noms Developpez.com vous propose déjà de consulter un fichier de normalisation des noms.Vous pouvez le télécharger en cliquant ici. Il s'agit d'un fichier au format Excel qui récapitule la liste des types de contrôles et des variables dont vous trouverez des détails supplémentaires au sein de ce document. 1-2. Remerciements
Je tiens à remercier tout particulièrement Demco et Tofalu ainsi que toutes celles et ceux qui ont participé à la relecture de ce document en y incluant leurs remarques. 1-3. Contact
Pour tous renseignements complémentaires, veuillez me contacter directement (Argyronet) par MP. 2. Pourquoi définir une convention au niveau du code ?
La raison majeure qui oblige à respecter cette convention est fondée sur l'objectif de standardiser la structure et le style du code du programme d'un projet ou d'une application afin que vous et tout autre personne faisant partie de votre équipe soient à même de lire, analyser et comprendre plus rapidement le contenu. Le fait d'appliquer l'écriture de son code avec de telles conventions permet d'obtenir un code source précis, dépourvu d'ambiguïtés et surtout facile à relire. Ces conventions sont à appliquer pour le cas d'une variable, selon sa portée et d'un objet (Table et ses champs, Formulaire et ses contrôles, Etat et ses contrôles, Module etc...) selon son type.
Cela simplifie grandement le développement en équipe du fait que des normes sont mises en place. La relecture en est (et restera) que plus aisée. Il faut noter au passage que les conventions de dénomination sont à établir au départ. Une fois le développement réalisé, il est difficile de revenir en arrière pour intervenir sur le code dans le seul but d'appliquer ces conventions. 2-1. Syntaxe des conventions
Il existe des normes et des conventions préétablies pour nommer les objets de contrôle, les variables, les procédures et les constantes et tous les objets faisant partie du code. Ces normes sont issues de règles logiques qui permettent en un seul coup d'oeil de repérer ce à quoi on a à faire sans qu'il soit forcément nécessaire de partir à la recherche de la source de l'objet concerné. 2-1-1. Syntaxe des conventions pour les objets
Terminologie des noms d'objets
De manière générale, un objet de contrôle doit obligatoirement être renommé (par défaut un objet de contrôle porte le nom du type de contrôle suivit d'un numéro incrémenté). Par exemple: - Liste13 - Étiquette47 - Texte14 - Commande23 La terminologie standard d'un nom d'objet peut être scindée au minimum en 2 parties et au maximum 4.
La terminologie en 2 parties pour les noms d'objets se compose comme suit: [Une étiquette]Le Nom de l'Objet La terminologie en 3 parties pour les noms d'objets se compose comme suit: [Le Préfixe][Une étiquette]Le Nom de l'Objet La terminologie en 4 parties pour les noms d'objets se compose comme suit: [Le Préfixe][Une étiquette]Le Nom de l'Objet[Le Suffixe]
Pour appliquer la terminologie d'un objet, il suffit de se référer au tableau que vous trouverez sur le site ici ou dans ce même document là. Ce qui est délimité par des crochets est facultatif. Toutefois, cela ne rejoint plus alors l'objectif de ce document. Définition du Préfixe Le préfixe a pour rôle d'identifier le type de l'objet: - On préfixera les objets contrôles mais on apposera pas d'étiquette - On préfixera les objets tables, requêtes, formulaires... - On préfixera les objets de type modules et classes... Quelques préfixes pour un objet de type contrôle - lbl => Label : Étiquette (Ne pas confondre avec l'étiquette de nommination) - txt => Textbox : Zone de texte - cmd => CommandButton : Bouton de commande - shp => Shape : Forme dessinée (rectangle, cercle...) - cbo => Combobox : Liste modifiable - lst => Listbox : Zone de Liste etc... Quelques préfixes pour un objet d'application - tbl => Table : Table - qry => Query : Requête ou Vue - frm => Form : Formulaire - rpt => Report : État - mcr => Macro : Macro - bas => Module : Feuille de module - cls => Classe : Feuille de classe - cmb => CommandBar : Barre de commande - mnu => Menus : Barre de menus etc... Définition de l'Étiquette pour un objet de type contrôle Il n'est pas utile de poser une étiquette pour un contrôle car l'étiquette définie la catégorie. Or, pour un contrôle, le préfixe définissant déjà son type, cela est amplement suffisant. Définition de l'Étiquette pour un objet d'application Une étiquette est un identificateur de catégorie de l'objet mêlant ainsi le rôle de l'objet ou ce à quoi il est destiné. Une étiquette n'aura pas plus de 3 ou 4 caractères et sera représentée par un abrégé conventionnel. A) Par exemple, pour un objet de type Table, on peut imaginer qu'une table de relation soit située comme table intercalée entre une table principale et une table intermédiaire. Elle doit pouvoir alors être identifiée comme telle.
L'étiquette REL définit le fait que la table est une Table de Relation même si l'on devine par son Nom d'Objet que la table sollicite les clients (Customers) et l'historique de ces derniers (History). B) Un autre exemple, relatif à un objet de type requête (Query), où l'on peut étiqueter la requête par son rôle ; Par exemple, le nom qrySumOrderAmountsForFrance où Sum est l'étiquette qui définit qu'il s'agit d'une requête avec une clause GROUP BY et où le Nom de l'Objet informe que cette requête renvoie le total des montants des commandes pour la France.
Définition du Nom de l'Objet Le nom de l'objet sera aussi explicite que possible tout en respectant une limite de caractères. Il commencera toujours par un caractère alphabétique et sera (exceptionnellement) greffé de caractères de soulignement (_) et surtout pas d'espaces. De plus, on apposera une MAJUSCULE à la première lettre de chaque mot qui le constitue.
Exemple:
Définition d'un Suffixe Le suffixe est très optionnel et reste utile pour marquer la différence entre deux objets qui ont le même rôle, le même type mais n'attaquant ou ne retournant pas les mêmes données. Par exemple, il est fréquent de rencontrer des contrôles texte répétés pour un numéro de téléphone ou une adresse: txtAddresse1 et txtAdresse2 où 1 et 2 sont les suffixes au même titre que PhoneNumber1 et PhoneNumber2 Un autre exemple de suffixe, plus précis cette fois, issu d'un nom d'objet qui définit la liste des codes postaux et des villes au sein d'un contrôle ListBox ; comme vous le savez, un contrôle ListBox possède un grand nombre de propriétés mais la plus importante est sa source de contrôle qui lui sert à renvoyer les données. Cette source de contrôle se traduit - soit par une clause SELECT inscrite directement dans la zone prévue à cette effet, - soit par la sélection d'un objet source, en l'occurrence une requête ou une table. Pour cet exemple, il s'agit bien entendu d'une requête... Ci-dessous, vous pouvez constater que selon l'intitulé du bouton [Code postal / Ville] ou [Ville / Code postal] la liste inverse et propose respectivement les codes postaux ou les villes en conséquence des caractères tapés dans le contrôle Textbox au-dessus.
Programmaticalement pour chacun des cas, le contrôle fait appel à deux requêtes que j'ai nommées dans un cas qryCmbListGetOneTown_CPTown et dans l'autre qryCmbListGetOneTown_TownCP. La requête source a pour objectif de renvoyer les mêmes données avec un suffixe différent, donc un ordre de colonne différent. Vous pouvez alors remarquer que le nom que j'ai donné à ma requête est composée de 4 parties :
2-1-2. Syntaxe des conventions pour les variables
Terminologie des noms de variables
De manière générale, une variable est nommée en deux parties La terminologie standard d'un nom de variable peut être scindée au minimum en 2 parties et au maximum 4 tout comme les objets. On reprendra alors la composition de la syntaxe comme suit :
La terminologie en 2 parties pour les noms d'objets se compose comme suit : [Une étiquette]Le Nom de la Variable La terminologie en 3 parties pour les noms d'objets se compose comme suit : [Le Préfixe][Une étiquette]Le Nom de la Variable La terminologie en 4 parties pour les noms d'objets se compose comme suit : [Le Préfixe][Une étiquette]Le Nom de la Variable[Le Suffixe]
Pour bien comprendre la terminologie d'une variable, il est conseillé de lire la section suivante qui relate de leurs portées.
Ce qui est délimité par des crochets est facultatif. Toutefois, cela ne rejoint plus alors l'objectif de ce document. Définition du Préfixe Le préfixe a pour rôle d'identifier la portée de la variable : - On ne préfixera pas les variables de procédures - On préfixera les variables de modules selon une convention - On préfixera les variables publiques selon une autre... Définition d'une Étiquette pour une variable Une étiquette pour une variable est l'identificateur du type de la variable. Elle permet de déterminer celui auquel elle appartient. Une étiquette n'aura pas plus de 3 ou 4 caractères et sera représentée par un abrégé conventionnel comme celles présentes dans le tableau récapitulatif suivant :
Pour résumer... Il est fortement recommandé de s'imposer ces règles. Pour ce qui est de la nomination des préfixes, il est très fréquent de lire du code avec des variables dont le préfixe est tronqué à 1 caractère au lieu de 3. Sur le plan de la lisibilité, cela n'a pas d'importance si toutefois le développeur a respecté celle-ci dans tout son code. Exemples:
En revanche, cette nomination mono-caractère ne peut pas s'appliquer facilement pour les variables comme Byte, Collection, Currency, Date, Single... Donc il est préférable de se tenir la convention des 3 caractères.
Exemple :
2-1-3. Exemples de déclaration de variables
Les variables déclarées dans une procédure ou une fonction
De manière générale, vous devez préfixer les variables déclarées au sein d'une fonction ou d'une procédure avec un préfixe qui en défini le type. Bien que très souvent ces dernières soient dépourvues de tout préfixe, je conseille de passer outre cette dérogation pour une meilleure lisibilité. Exemple :
Les variables déclarées dans un module
Lorsque vous déclarez des variables de module, la convention universelle propose d'apposer un préfixe m suivi ou non d'un caractère de soulignement (Underscore) suivi du type de la variable et enfin, suivi d'un nom explicite.
Exemple :
Les variables publiques
Lorsque vous déclarez des variables publiques dans un module elles sont exploitées dans l'ensemble du projet ; la convention universelle propose alors d'apposer un préfixe g suivi ou non d'un caractère de soulignement (Underscore) suivi du type de la variable et enfin, suivi d'un nom explicite. Il est envisageable d'adjoindre la lettre v derrière le g afin de préfixer gv devant le nom de la variable ce qui donne alors gv, sous entendu Global Variable.
Exemple :
Les variables de module de classe
Lorsque vous déclarez des variables dans une classe, la convention universelle propose d'apposer un préfixe c ou cls suivi ou non d'un caractère de soulignement (Underscore) suivi d'un nom explicite.
Exemple :
2-1-4. Les constantes de module et les constantes en général
Lorsque vous déclarez des constantes dans un module, la convention universelle propose de les écrire en MAJUSCULE avec un nom explicite dont les mots qui constituent le nom peuvent être séparés par un caractère de soulignement (Underscore). Elles peuvent être préfixées pour pouvoir identifier leur type ou leur appartenance commune à un groupe de fonctions par exemple. Exemple :
Les constantes exploitant le style d'une fenêtre sont préfixées SW_ signifiant SHOW :
Les constantes exploitant exploitant la fonction MessageBox() MB_ signifiant MsgBox :
2-1-5. Les variables déclarées comme paramètre dans une procédure ou une fonction
Les variables déclarées comme paramètre dans une fonction ou dans une procédure ne sont en générale précédées d'aucun préfixe. Exemple :
En effet, au moment de la saisie, le fait d'exploiter ou d'appeler une fonction ou une procédure provoque, par l'intermédiaire de l'IntelliSense, l'affichage du type des variables faisant office d'arguments. Exemple :
3. Explications sur la portée d'une variable
Dans une application Visual Basic, les variables peuvent être de portée différente :
- Locale : Au sein d'une procédure ou d'une fonction
- Module : En entête d'une feuille de module
- Public : Dans un module (si possible unique)
Pour ce qui est des variables publiques, je vous recommande de les utiliser que si vous n'avez pas d'autres possibilités de partager des valeurs entre les différents modules. Dans ce cas, il est conseillé de les regrouper ensemble au sein d'un même module (par exemple basDeclaration) et nommées avec un nom explicite. Il est plus conventionnel (et plus propre) de mettre en place des propriétés (Property Let, Property Get).
Portée des déclarations
1 - Au sein d'une procédure ou d'une fonction les variables seront visibles uniquement dans la procédure ou la fonction dans laquelle elles sont déclarées. 2 - Au sein d'un module les variables de module (préfixées m) seront visibles uniquement dans la totalité du module dans laquelle elles sont déclarées. 3 - Au sein d'un module les variables publiques (préfixées g) seront visibles dans la totalité de l'application. 3-1. Représentation des formats des types de données
Lorsque vous déclarez des variables, vous devez leur affecter un type. Le tableau ci-dessous (inspiré de l'aide de Visual Basic) vous donne la liste des types et leur plage de valeur.
4. Conventions générales concernant les noms4-1. Les variables
Typiquement, les noms des variables sont au singulier. On applique le pluriel aux collections. Toutefois, il n'est pas obligatoire de respecter exclusivement cette règle. Pour ma part, j'utilise le pluriel pour des variables de type Long (Integer, Single, Double) devant me retourner par exemple une quantité et où le résultat attendu est au minimum égale à 1. Concernant la longueur du mot représentant le nom de la variable ou de l'objet, on tachera de ne pas dépasser 15 caractères. Exception concernant le nom des tables où la limite est fixée, toute dénomination incluse à 30 caractères et ce pour une compatibilité avec des bases de données externes comme SQL Server. 4-2. Les fonctions et procédures
Les procédures, les méthodes et les noms des fonctions sont écrits sous forme de verbes.
Cela permet d'identifier le rôle de ces derniers. Tout comme les objets, elles doivent être écrites avec une majuscule à chaque mot qui la constitue. On pourra appliquer une terminologie scindée en 2 parties dans la cas ou l'on a besoin dissocier les fonctions et procédures publiques des fonctions et procédures privées ou encore issues de modules de classes.
Exemple :
ChangeStatusButtons (Changer l'état des boutons) GetCurrentUserName (Obtenir le nom de l'utilisateur en cours) StripNullChar (Supprimer l'excédent de caractères de type NullChar) Vous pouvez remarquer que je code systématiquement en anglais. C'est une habitude que je me suis donné parce qu'il n'est pas commode, selon moi, d'écrire le nom de variables, de fonctions et de procédures avec autant de clarté en langue francophone. De plus, le problème de l'accentuation et des apostrophes se pose dans de nombreux cas. Il n'est évidemment pas conseillé d'accentuer les voyelles en programmation pour les nommage des objets en général. ChangeStatusButtons => (ChangerLEtatDesBoutons) GetCurrentUserName => (ObtenirLeNomDeLUtilsateurEnCours) StripNullChar => (SupprimerLesCaracteresNull) On pourra enfin apposer un Suffixe déterminant une particularité de la fonction ou le la procédure. Ce dernier devient nécessaire dans le cas où des fonctions ou des procédures effectuent un traitement similaire mais attaquant un autre type de données par exemple.
5. Conventions générales concernant le nom des contrôles
Tout comme les variables, les contrôles utilisés dans les formulaires (Forms) ou les états (Reports) doivent être nommés correctement. Je vois trop souvent encore de nombreux développeurs qui ne prennent pas la peine de nommer les objets au sein des formulaires ou des états, voire les formulaires et les états eux-mêmes, ce qui provoque automatiquement la colère du relecteur qui se voit obligé de tenter de déchiffrer ce que l'auteur a écrit par le biais d'un basculement intempestif entre la feuille de code et le formulaire ou l'état. J'ai même eu à reprendre, un jour, une base de données Access où des tables s'appelaient Table et ses champs s'appeler Champ et où aucun, mais absolument aucun contrôle ajouté n'était nommé correctement. Le projet de reprise aurait dû durer 5 jours : il a duré plus d'un mois. 5-1. Exemple utilisant des objets non nommés :
Voyez par vous-même, bien que l'on comprenne ce bout de code, il est impossible ici de savoir quels contrôles sont sollicités.
5-2. Exemple utilisant des objets correctement nommés :
Ici, on comprend davantage le code et l'on sait tout de suite quel objet est sollicité ainsi que son type :
5-3. Exemples d'appellation des contrôles avec leur préfixe
Un préfixe est à apposer devant le nom de l'objet selon le tableau suivant :
Cette normalisation est régie par des standards issus de conventions préétablies. Bien que Microsoft Access (entre autres...) accepte toutes les fantaisies en matière de nommage des objets qui composent une application, il est recommandé de perdre cette facilité pour s'adonner à de bonnes habitudes.
6. Les autres conventions
Il existe un grand nombre de conventions possible pour les objets en général. Au vu de la multitude des objets présents dans un outil de développement, il est préférable de se documenter dans l'aide pour obtenir des détails. A titre d'exemple, je liste ci-dessous les conventions à appliquer pour les objets utilisés pour DAO.
7. Les conventions de nommage des champs
Je n'aborde ce sujet qu'en dernier bien qu'il soit un des plus importants au sein d'une base de données. Il est effectivement impératif de respecter les normes en matière de définition de nom des champs d'une table.
Les 6 règles à retenir pour nommer un champ
De manière générale, je nomme aussi mes noms de champs en Anglais. Cela permet de respecter une partie des règles énumérées ci-dessus.
7-1. Comment faire en sorte que le nom affiché ne soit pas celui du champ ?
Effectivement, en s'imposant ces règles, le nom du champ apparaît par défaut dans vos formulaires et vos états ce qui, je vous l'accorde n'est pas joli d'une part et n'est pas explicite d'autre part. Par exemple un nom de champ nommé "BirthDate" fera apparaître par défaut "BirthDate" dans un formulaire ou un état. Si l'on veut voir mentionner "Date de naissance" il faut alors alimenter la propriété Légende dans la table comme le montre la figure ci-dessous: ![]()
En mode feuille de données, vous constatez de suite que le nom de la colonne s'approprie la légende et non le nom du champ.
![]()
L'énorme avantage d'user de cette propriété est que vous pouvez cette fois user de toutes les fantaisies pour renseigner cette propriété Légende:
Les 5 règles à retenir pour la propriété légende
8. Quelques recommandations complémentaires
Pour une convivialité de lecture, je vous recommande d'écrire les mots en entier pour être plus explicite.
Par exemple :
Au lieu de
En revanche, il se peut que la longueur d'un mot désignant une variable soit trop long auquel cas, pour les mots connus, vous pouvez abréger :
Par exemple :
Au lieu de
Afin de séparer les mots désignant une variable, il est conseillé de ne pas utiliser le caractère de soulignement (Underscore) mais plutôt de mettre une MAJUSCULE à chaque mot.
Par exemple :
Au lieu de
Par exemple :
8-1. Les variables de type Entier par défaut (Integer)
Il est très fréquent lire des blocs de code avec des variables I, J ou N déclarées en entier (Integer). C'est une convention typique comme en mathématiques, les professeurs définissaient les point d'une droite x et y.
8-2. Les instructions Deftype
Ce type d'instruction est utilisé au niveau du module et définit le type de donnée par défaut pour l'ensemble des variables, des arguments passés aux procédures et le type de renvoi pour les procédures Function et Property Get dont le nom commence avec les caractères spécifiés. Ceci permet dans un sens de ne pas avoir à déclarer des variables mais ce type de déclaration implicite est à proscrire car il est peut parlant et difficile à interpréter. De plus il oblige à chaque fois à se souvenir que Telle Variable, Telle Procédure [...] qui commence par Tel Caractère est de Tel Type, d'où une conception et une approche du code délicate. Exemple :
8-2-1. Le nom de l'instruction détermine le type de données
8-3. L'utilisation de l'IntelliSense
Usez et abusez de l'IntelliSense. Cet outil magique est traduit par l'auto-complémentation de la syntaxe (auto-completion) au moment de la saisie du code. - Si la saisie en cours est une procédure ou une fonction déjà présente, l'IntelliSense vous affiche une info bulle de couleur jaune pour vous indiquer les arguments faisant office de paramètre à lui passer. Exemple d'IntelliSense : ![]() - Si la saisie en cours est une variable, une constante ou encore une énumération, [...], l'Auto-Completion vous affiche une liste des objets correspondants. Exemple d'auto-completion :
9. Conclusion
Ce document n'est qu'un bref récapitulatif pour les conventions de nommage. Il s'avère toutefois utile d'en prendre note avec un certain sérieux dans le sens où vous serez bien heureux de pouvoir faire évoluer vos projets. La reprise et l'évolution des ces derniers ne seront que facilitées par la simple mise en application de ces petites règles qui, en finalité, deviennent très vite une (bonne) habitude.
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||