Salut à tous,
ce petit tuto sur la portée des variables car il en a été question il y a quelques temps dans le forum, et j'ai le coeur de m'y coller.
J'espère qu'il sera utile aux débutants et servira de révision pour les autres. Mes explications et exemples sont donc volontairement 'basiques' pour être compris de tous.
Il est à noter que ce tuto est pour VB6, et se base sur le livre "Le Platinium VB6" de chez "Sybex".
Avec VB6, l'endroit et la façon dont vous déclarez explicitement une variable avec les mots clefs 'Dim', 'Private', 'Static' et 'Public' déterminera sa portée, c'est à dire les partie du code de votre projet où elle sera reconnue.
Pour maîtriser parfaitement la porté d'une variable, et faire en sorte qu'une même variable puisse être utilisée dans diverses procédures, il faut avoir recours à la déclaration explicite (voir plus bas).
Dans ce cas, la portée dépend de l'endroit où la variable est déclarée :
Public (feuille ou module 1)
|
| Private/Dim (feuille ou module 2)
| |
| | Sub
| | Dim/Private/Static
| | |
| | |
| | |
| | |
| | End Sub
| |
| | Function
| | Dim/Private/Static
| | |
| | |
| | |
| | |
| | End Function
| |
|
|
et dépend donc aussi du mot clef avec lequel elle est déclarée. Nous allons voir tous ces cas en détails !
Il est à noter qu'il est possible de gérer différemment une variable, en temps que propriété d'une feuille ou d'un module de classe par exemple. Mais ce n'est pas le but de ce tuto.
Visual Basic permet l'utilisation d'une variable qui n'a pas été déclarée préalablement, c'est une 'variable implicite'. Au contraire, les variables préalablement déclarées sont dites 'variables explicites'.
Note :
L'utilisation de variables implicites n'est pas possible si 'Option Explicit' est employé.
En effet, 'Option Explicit' impose la déclaration explicite d'une variable avant son utilisation, dans le cas contraire, une erreur est provoquée. L'utilisation de cette option est d'ailleurs fortement recommandée !
Une variable implicite n'est connue qu'à l'intérieur de la fonction ou de la procédure où elle a été initialement utilisée. Une variable implicite est donc locale à cette fonction/procédure. Si l'on fait référence à cette variable dans une autre procédure, il s'agira d'une variable différente.
Exemple 1 :
Private Sub Command1_Click()
Texte= Text1.Text
'Traitement de la variable 'Texte'...
MsgBox Texte
End Sub
<code>
Si l'on clique sur le bouton 'Command1' une boite de message affichera le contenu de la TextBox 'Text1' (après traitements éventuels).
Ici la variable 'Texte' n'a pas été déclarée. Visual Basic lui appliquera le type le plus approprié, dans cet exemple 'String'. Une fois la fin de la procédure, la variable 'Texte' n'existera plus.
La variable 'Texte' est donc implicite, et locale à la procédure 'Command1_Click'.
Exemple 2 :
<code vb>
Private Sub Command2_Click()
MsgBox Texte
End Sub
Si plus tard on clique sur le bouton 'Command2' pour essayer d'afficher la variable 'Texte', elle vaudra "". En effet, VB générera une nouvelle variable locale (à cette procédure) nommée 'Texte' qui vaudra initialement "" et qui n'aura rien à voir avec la variable locale 'Texte' de la procédure 'Command1_Click'.
Cette autre variable 'Texte' est aussi implicite mais locale à la procédure 'Command2_Click'.
C'est une variable déclarée avec 'Dim', 'Private' ou 'Static' dans une fonction/procédure. Elle est alors dite 'locale' à cette fonction/procédure et ne sera pas connue à l'extérieur.
Note : Dans ce cas, les deux mots 'Dim' et 'Private' sont équivalents.
Exemple 3 :
Public Function RepDuFic(ChemFic As String) As String Dim TempStr As String TempStr = fso.GetParentFolderName(ChemFic) RepDuFic = TempStr & "\" End Function
Cette fonction, qui utilise FSO, renvoie le répertoire d'un fichier dont le chemin est passé en paramètre.
Ici, la variable 'TempStr' est locale à cette fonction. Pour rappel, on pourra dire aussi qu'elle est déclarée explicitement.
Lorsque vous déclarez une variable locale dans une fonction/procédure avec les mots 'Dim' et 'Private', à chaque fois que dans cette procédure, le mot 'Dim' ou 'Private' est exécuté, la variable correspondante est réinitialisée à 0 s'il s'agit d'une variable numérique, à une chaine vide s'il s'agit d'une 'String', à la valeur 'Empty' s'il s'agit d'une variable 'Variant', etc.
Si vous souhaitez qu'une variable garde sa valeur de façon permanente, il faut remplacer le 'Dim' ou 'Private' par 'Static'.
Par exemple :
Function Combien() as Long Dim Lng as Long Lng = Lng + 1 Combien = Lng End Function
Ici, à chaque appel de la fonction, la variable Lng est réinitialisée à 0 et vaut 1 à la sortie de la fonction. par contre, si on écrit :
Function Combien() as Long Static Lng as Long Lng = Lng + 1 Combien = Lng End Function
Lng est initialisée à 0 lors du lancement de l'application, puis garde sa valeur précédente d'un appel à l'autre, donc Lng (et donc Combien()) sera incrémenté de 1 à chaque appel.
C'est une variable déclarée dans la section des déclarations d'une feuille ou d'un module avec 'Dim' ou 'Private'. Elle est alors connue dans toutes les procédures de la feuille ou du module, mais pas dans les autres.
Exemple 4 :
' Dans la section des déclarations d'une feuille Private Ok as Boolean 'Procédures de la feuille Private Sub IsOk() If Ok = True Then exit Sub ' 'Traitements... Ok = True End Sub Private Sub IsNotOk() If Ok = False Then exit Sub ' 'Traitements... Ok = False End Sub
Dans cet exemple, la variable 'Ok' est reconnue dans toutes les fonctions/procédures de la feuille ; il est donc possible de tester et d'affecter cette variable dans n'importe quelle procédure de cette feuille.
C'est une variable déclarée dans la section des déclarations d'un module avec 'Public'. Elle peut-être utilisée dans toutes les feuilles et tous les modules. Il s'agit d'une variable globale.
On peut aussi déclarer une variable publique avec 'Public' dans la section des déclarations d'une feuille, mais il y a une grande différence d'utilisation à déclarer une variable 'Public' dans un module ou dans une feuille !
Note : Les versions précédentes de Visual Basic (1 à 3) utilisaient le mot 'Global' pour la déclaration d'une variable globale. Il est remplacé par 'Public' depuis la version 4.
Exemple 5 :
' Dans la section des déclarations d'un module nommé "MonModule" Public MaString as String
Dans cet exemple, la variable 'MaString' pourra directement être testée/affectée depuis n'importe quelle fonction/procédure du projet :
MaString = "oui"
Il est aussi possible, pour une meilleure lisiblilité du code, de préciser lors de son utilisation, le nom de son module d'origine :
MonModule.MaString = "oui aussi"
Il est à noter d'ailleurs que dans ce cas, l'éditeur de VB affiche une liste déroulante des procédures/variables/constantes du module, lorsque l'on tape "MonModule.", ce qui peut être pratique.
Certains codeurs ont pris systématiquement cette habitude dans leurs projets de grande ampleur, mais ce n'est pas obligatoire, sauf dans certain cas (voir plus bas : "Pour aller encore plus loin...").
Exemple 6 :
' Dans la section des déclarations d'une feuille nommée "MaForm" Public MaString
Pour utiliser cette variable à l'intérieur de "MaForm", il suffira de la désigner directement :
MaString = "un peu"
Par contre, pour l'utiliser depuis une autre feuille ou un autre module, il faudra désigner explicitement la feuille d'origine :
MaForm.MaString = "beaucoup"
Un exemple pour le prouver :
'----------- Feuille "Form1" ' Dans la section des déclarations d'une feuille nommée "Form1" Public MaString as String 'Click d'un bouton nommé 'Command1' Private Sub Command1_Click() MsgBox Bidon End Sub '----------- Module1 Public Function Bidon() As String MaString = "marche pas" Bidon = MaString End Function
Pour que cela fonctionne :
'----------- Module1 Public Function Bidon() As String MaString = "ca marche !" Bidon = Form1.MaString End Function
En effet, si vous testez la PREMIERE VERSION avec 'option explicit', VB affichera une erreur dans la fonction 'Bidon' : MaString = variable non définie
Hé oui, il s'agit là d'une variable locale, et qui plus est implicite !
Exemple 7 :
' Dans la section des déclarations d'une feuille Public MaString As String ' Dans la feuille Private Sub Form_Load() MaString = "public Form1" End Sub Private Sub Command1_Click() 'qui va être afficher ? MsgBox MaString End Sub Private Sub Command2_Click() Dim MaString As String MaString = "locale à Command2_Click" 'qui va être afficher ? MsgBox MaString End Sub
Dans cet exemple, on utilise 2 variables de même nom 'MaString'. La première, déclarée dans la section des déclarations de la feuille, est une variable publique (Public MaString), la seconde, déclarée dans la proc. "Command2_Click" est locale à cette procédure (Dim MaString As String).
Dans 'Command1_Click', c'est bien sûr la variable publique (Form1) qui sera affichée : "public Form1".
Dans 'Command2_Click', la variable locale a priorité sur la variable privée, et affichera donc : "locale à Command2_Click".
Dans cet exemple j'utilise une variable locale contre une variable publique d'une feuille, il en est de même entre les variables locales et les variables privées/globales.
Et que ce passe t'il si dans l'exemple 7, vous ajouter un 'Module1' avec dans les déclarations : "Public MaString As String" ?
Est-il possible d'avoir 2 variables 'Public' de même nom ??
Hé bien oui !
L'une sera en réalité 'Form1.MaString' et l'autre 'Module1.MaString'.
Testez à nouveau l'exemple 7 avec ce module, et ajoutez : Module1.MaString = "globale (Module1)" dans le "Form.Load".
Qui est affiché quand on clique sur "Command1" ?
Toujours "public Form1" car à l'intérieur de Form1 la variable publique originaire de Form1 est prioritaire à la variable publique (globale) du module.
Pour faire référence à 'MaString' du Module1 à l'intérieur de 'Form1' il faudra absolument indiquer "Module1.MaString".
En effet, testez un 3eme bouton :
Private Sub Command3_Click() 'pas de suspens MsgBox Module1.MaString End Sub
Le mot 'Dim' peut toujours être remplacé par 'Private' ou 'Public' (sauf dans certain cas particuliers). Il est alors préférable d'utiliser ces 2 derniers mots, qui présentent l'avantage d'expliciter la portée de la variable et de rendre la lecture du code plus aisée.