[vb6] portées des variables

Les variables et leurs portées

Introduction

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".

PORTÉE DES VARIABLES

Qu'est ce que la portée d'une variable ?

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.

Qu'est ce que la 'déclaration implicite' et la 'déclaration explicite' d'une variable ?

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'.

QU'EST-CE QU'UNE VARIABLE LOCALE?

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.

QU'EST-CE EXACTEMENT QU'UNE VARIABLE 'STATIC' ?

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.

QU'EST-CE QU'UNE VARIABLE PRIVÉE ?

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.

QU'EST-CE QU'UNE VARIABLE PUBLIQUE/GLOBALE ?

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.

Dans un module


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...").

Dans une feuille

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 !

VARIABLES LOCALES ET VARIABLES PRIVÉES/PUBLIQUES/GLOBALES AYANT LE MÊME NOM

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.

POUR ALLER ENCORE PLUS LOIN...

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

CONCLUSION

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.

A voir également
Ce document intitulé « [vb6] portées des variables » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous