Tester l'initialisation de variables en VBA

Denis Hulo

Objectif : être capable de tester l'initialisation d'une variable en VBA, puis d'appliquer cette méthode pour vérifier si un élément est présent dans une collection.

Niveau requis : débutant.

Commentez cet article : Commentez

- Titre : Tester l'initialisation de variables en VBA

- Auteur : Denis Hulo

- Parution : 23 août 2020

- Public visé :

- Licence : Copyright ® 2020 Denis Hulo. 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'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Tester l'initialisation d'une variable de type Variant

- II. Tester l'initialisation d'une variable objet

- III. Vérifier la présence d'un élément dans une collection

- III-A. Vérifier la présence d'un élément de type Variant

- III-B. Vérifier la présence d'un élément objet

- IV. Applications

- IV-A. Excel : vérifier la présence d'une feuille Excel

- IV-B. Access : rétablir les liens vers des fichiers de données

- V. Base de données à télécharger

- VI. Remerciements

I - Tester l'initialisation d'une variable de type Variant

Le type Variant permet de stocker n'importe quelle valeur de type simple : booléen, numérique (Monétaire, Réel, Entier, ...), chaîne de caractères ou date.

Une variable de ce type peut également contenir des valeurs spéciales comme Empty, Error, Nothing et Null.

Quand une variable de type Variant n'a pas été initialisée, elle contient la valeur Empty, contrairement aux variables de type booléen, numérique, texte ou date, qui sont automatiquement initialisées après leur déclaration.

On utilisera donc ce type de données et la fonction IsEmpty pour tester si une variable a bien été initialisée :

fonction IsEmpty
Renvoie une valeur booléenne indiquant si une variable a été initialisée.

Syntaxe
IsEmpty (Expression)

L’argument expression obligatoire est une valeur de type Variant contenant une expression numérique ou une expression de chaîne. Toutefois, la fonction IsEmpty étant utilisée pour déterminer si des variables individuelles sont initialisées, l'argument expression est souvent un nom de variable unique.

Exemple de code sans initialisation de la variable :

Dim var As Variant

If IsEmpty(var) Then ' on teste si la variable contient la valeur Empty
MsgBox ("Variable non initialisée !") ' la variable  n'a pas été initialisée
Else
MsgBox ("La variable est égale à " & var) ' la variable a été initialisée, on affiche sa valeur
End If

Le code va logiquement afficher "Variable non initialisée !".

Exemple de code avec initialisation de la variable :

Dim var As Variant

var = 100 ' on initialise la variable

If IsEmpty(var) Then ' on teste si la variable contient la valeur Empty
MsgBox ("Variable non initialisée !") ' la variable  n'a pas été initialisée
Else
MsgBox ("La variable est égale à " & var) ' la variable a été initialisée, on affiche sa valeur
End If

Le code va logiquement afficher "La variable est égale à 100".

II - Tester l'initialisation d'une variable objet

Une variable objet stocke une référence à un objet en mémoire.

Un objet étant construit à partir d'une classe, pour créer l'objet on utilise l'instruction :

Set obj = new uneClasse

Pour assigner un objet à une variable, on fait simplement :

Set obj = monObjet

Quand la variable ne fait référence à aucun objet, elle contient la valeur Nothing.

Par défaut, juste après la déclaration d'une variable objet, celle-ci ne fait référence à aucun objet, et contient par conséquent Nothing.

Pour tester l'initialisation d'une variable objet on utilise donc le mot clé Nothing :

If obj Is Nothing Then ' on teste si la variable est à Nothing ou si elle fait référence à un objet

Le mot clé Nothing est aussi utilisé pour dissocier une variable d’objet d’un objet réel.

Utilisez l’instruction Set pour affecter Nothing à une variable d’objet :

Set obj = Nothing  ' on affecte Nothing à la variable objet

Considérons maintenant une variable wkb, pour faire référence à un objet Workbook dans Excel.

Exemple de code dans lequel la variable ne fait référence à aucun objet :

Code pour tester l'initialisation d'une variable objet

im wkb As Workbook ' déclaration de la variable objet

If wkb Is Nothing Then ' on teste si la variable est à Nothing, ou si elle fait référence à un objet
MsgBox ("La variable ne fait référence à aucun objet  !") ' la variable ne fait référence à aucun objet, elle est à Nothing
Else
MsgBox("La variable fait référence à un objet !") ' la variable fait référence à un objet Workbook
End If

Le code va logiquement afficher "La variable fait référence à un objet !".

III - Vérifier la présence d'un élément dans une collection

Objet Collection en VBA
Un objet Collection est un ensemble ordonné d’éléments auquel il est possible de faire référence en tant qu’unité.

Une collection se crée de la même manière que les autres objets :

Dim col As New Collection ' déclaration et création de l'objet Collection

Une fois qu’une collection est créée, les membres peuvent être ajoutés à l’aide de la méthode Add et supprimés à l’aide de la méthode Remove. Des membres spécifiques peuvent être renvoyés à partir de la collection à l’aide de la méthode Item, tandis que la collection entière peut être itérée à l’aide de la boucle for each...Next , instruction.

Ajout d'un élément à la collection :

col.Add "élément", "clé" ' on ajoute à la collection un nouvel élément ayant comme clé "clé"

On y accède en faisant :

itm = col.Item("clé")

Si on souhaite maintenant accéder à un élément qui n'est pas présent dans la collection :

tm = col.Item("clé2")

Un message d'erreur va s'afficher :

Erreur accès élément

La solution pour éviter de déclencher l'erreur est de mettre un On Error Resume Next avant la ligne, pour passer à la ligne suivante en cas d'erreur sur la prochaine ligne, puis de désactiver l'instruction On Error Resume Next en mettant un On Error Goto 0 après la ligne :

On Error Resume Next ' on indique de passer à la ligne suivante en cas d'erreur sur la prochaine ligne
itm = col.Item("clé2") ' on tente d'accéder à un élément avec la clé "clé2", si pas d'élément la variable itm ne sera pas initialisée
On Error GoTo 0 ' désactive l'instruction On error Resume Next

Si une erreur se produit sur la ligne d'affectation de l'élément, alors la variable itm ne sera pas initialisée. Si votre code comporte une gestion d'erreurs, il faut remplacer le On Error Goto 0 par On Error Goto Gestion_Erreur pour rétablir la gestion d'erreurs normale.

III-A - Vérifier la présence d'un élément de type Variant

On tente d'affecter à une variable la valeur d'un élément d'une collection en utilisant sa clé. Si l'élément est présent, la variable contient la valeur de l'élément, dans le cas contraire elle contient la valeur Empty :

Code pour tester la présence d'un élément

Dim col As New Collection ' variable Collection
Dim itm As Variant ' variable de type valeur permettant de tester s'il y a un élément identifié par la clé
Dim cle As String ' variable contenant la valeur de la clé permettant d'identifier l'élément

col.Add "e1", "c1" ' ajout d'un élément à la collection

cle = "c1" ' valeur de la clé identifiant l'élément dans la collection

On Error Resume Next ' on indique de passer à la ligne suivante en cas d'erreur sur la prochaine ligne
itm = col.Item(cle) ' on tente d'accéder à un élément avec la clé "c1", si pas d'élément la variable itm ne sera pas initialisée
On Error GoTo 0 ' désactive l'instruction On Error Resume Next

If IsEmpty(itm) Then ' si la variable  n'a pas été initialisée
MsgBox ("Elément non trouvé dans la collection !") ' on indique que l'élément est introuvable
Else ' sinon
MsgBox ("L'élément a pour valeur " & itm) ' on affiche la valeur de l'élément
End If

Set col = Nothing ' on libère la variable objet

Le code va logiquement afficher "L'élément a pour valeur e1".

III-B - Vérifier la présence d'un élément objet

On tente d'assigner à une variable un objet d'une collection en utilisant sa clé. Si l'élément est présent, la variable contient une référence à cet objet, dans le cas contraire elle contient Nothing :

Code pour tester la présence d'un élément objet

Dim col As New Collection ' variable Collection
Dim itm1 As New Collection ' variable objet : élément de la collection
Dim itm As Object ' variable d'objet permettant de tester s'il y a un élément identifié par la clé
Dim cle As String ' variable contenant la valeur de la clé permettant d'identifier l'élément

col.Add itm1, "c1" ' ajout d'un élément à la collection

cle = "c2" ' valeur de la clé identifiant l'élément dans la collection

On Error Resume Next ' on indique de passer à la ligne suivante en cas d'erreur sur la prochaine ligne
Set itm = col.Item(cle) ' on tente d'accéder à un élément avec la clé "c2", si pas d'élément la variable itm contient Nothing
On Error GoTo 0  ' on désactive l'instruction On Error Resume Next

If itm Is Nothing Then ' on teste si la variable est à Nothing, ou si elle fait référence à un objet
MsgBox ("Elément non trouvé dans la collection !") ' on indique que l'élément est introuvable
Else ' sinon
MsgBox ("Elément présent dans la collection !") ' on indique que l'élément est présent
End If

' on libère les variables objet
Set itm1 = Nothing
Set col = Nothing

Le code va logiquement afficher "Elément non trouvé dans la collection !".

IV - Applications

Nous allons donner pour finir, quelques exemples de mise en application de ces tests.

IV-A - Excel : vérifier la présence d'une feuille Excel

On peut par exemple utiliser cette méthode pour accéder directement à un élément d'une collection d'objets Excel (Feuille de calcul ou autre) ou d'objets Outlook (MailItem ou autre).

Exemple de code pour vérifier la présence d'une feuille dans un classeur Excel :

Code pour tester si une feuille Excel existe

Dim wkb As Workbook ' déclaration de la variable objet Workbook
Dim wks As Worksheet ' déclaration de la variable objet Worksheet

Set wkb = ThisWorkbook ' affectation d'un objet Workbook à la variable

On Error Resume Next ' on indique de passer à la ligne suivante en cas d'erreur sur la prochaine ligne
Set wks = wkb.Sheets("Nom Feuille") ' on tente d'accéder à la feuille nommée "Nom Feuille", si pas de feuille à ce nom, la variable wks contient Nothing
On Error GoTo 0 ' désactive l'instruction On Error Resume Next

If wks Is Nothing Then ' on teste si la variable est à Nothing, ou si elle fait référence à un objet
MsgBox ("La feuille n'est pas présente !") ' la variable ne fait référence à aucun objet, elle est à Nothing
Else
MsgBox ("La feuille est présente !") ' la variable fait référence à un objet Worksheet
End If

' on libère les variables objet
Set wks = Nothing
Set wkb = Nothing

Si la feuille existe, son accès est donc direct et on peut par exemple la mettre à jour, dans le cas contraire, on peut imaginer de la créer. Il n'est donc pas nécessaire de parcourir la liste des feuilles du classeur.

IV-B - Access : rétablir les liens vers des fichiers de données

Contexte

La base de données est utilisée en mode multi-utilisateurs, avec sur le serveur le fichier de données et sur les postes clients l'interface utilisateurs :

Installation en réseau

Si maintenant, on souhaite déplacer le ou les fichiers de données dans un autre dossier sur le serveur, il nous faut mettre à jour les liens vers les tables, afin de pouvoir rétablir la connexion aux données.

Fonction permettant de tester si un élément est présent dans une collection :

Public Function IsItem(col As Collection, key As String) As Boolean
Dim itm As Variant ' variable permettant de tester s'il y a un élément avec cette clé

On Error Resume Next ' on indique de paser à la ligne suivante en cas d'erreur sur la prochaine ligne
itm = col.Item(key) ' on recherche un élément avec la clé key, si pas d'élément la variable itm sera vide
On Error GoTo 0 ' on rétablit une gestion d'erreur normale

IsItem = Not IsEmpty(itm) ' si la variable est vide renvoie false (l'élément n'existe pas), dans le cas contraire elle renvoie true

End Function

Dans notre exemple, la collection contient les correspondances entre anciens et nouveaux chemin d'accès aux fichiers. On utilise cette fonction pour vérifier si un chemin d'accès est déjà présent dans la collection.

Déroulé de la fonction principale

1. parcours des tables liées ;

2. pour chaque table, on teste si le lien est à jour ;

3. si le lien est à jour aller en 7, sinon, si l'emplacement du fichier de données n'as pas encore été enregistré alors aller en 4, sinon aller en 6 ;

4. on propose à l'utilisateur de choisir un nouvel emplacement pour la dorsale ;

5. on enregistre dans une collection la correspondance entre l'ancien et le nouvel emplacement ;

6. on met à jour le lien de la table ;

7. on passe à l'enregistrement suivant.

Fonction permettant de rétablir les liens vers des fichiers de données

Function RefreshLinks()
' met à jour les liens vers les fichiers de données
On Error GoTo err_RefreshLinks
Dim dbs As DAO.Database ' variable objet pour faire référence à la base de données
Dim tdf As DAO.TableDef ' variable objet pour faire référence aux tables de la base de données
Dim strDBPath1 As String, strDBPath2 As String ' variable contenant l'ancien et le nouvel emplacement du fichier de données
Dim colLinks As Collection

' référence à la base courante
Set dbs = CurrentDb

' on crée l'objet collection
Set colLinks = New Collection

' parcours de la liste des tables
For Each tdf In dbs.TableDefs
If (tdf.Attributes And dbSystemObject) = 0 Then ' si ce n'est pas une table système
strDBPath1 = extractDBPath(tdf.Connect) ' on récupère dans la propriété Connect, le chemin du dossier contenant le fichier de données.
If (Dir(strDBPath1) = "") Then ' si le fichier mentionné dans la propriété Connect n'existe pas, il faut rétablir le lien.
If Not IsItem(colLinks, strDBPath1) Then  ' si ce fichier n'a pas encore été choisi : non présent dans la collection.
strDBPath2 = ChooseFile(tdf.Name, strDBPath1) ' on choisit le fichier sur le serveur à l'aide de FileDialog.
colLinks.Add strDBPath2, strDBPath1 ' on l'ajoute à la collection le nouvel emplacement pour les données : clé = strDBPath1 ; valeur = strDBPath2.
Else ' sinon
strDBPath2 = colLinks.Item(strDBPath1) ' on recherche le nouveau chemin déjà présent dans la collection
End If
tdf.Connect = ";Database=" & strDBPath2 ' on copie le nouveau chemin du fichier dans la propriété Connect de la base
tdf.RefreshLink ' on rafraîchit le lien
End If
End If
Next

RefreshLinks = True ' on renvoie True pour indiquer que les liens ont été rafraîchis

err_RefreshLinks:

If Err.Number <> 0 Then ' gestion d'erreur
MsgBox Err.Description, vbExclamation ' en cas d'erreur on affiche sa description
End If

On Error Resume Next

' on libère les variables objet
Set colLinks = Nothing
Set dbs = Nothing

End Function

V - Base de données à télécharger

La base jointe est au format accdb, elle contient les exemples d'appication pour rétablir les liens externes.

VI - Remerciements

Je tiens à remercier ... pour m’avoir conseillé pour la réalisation de cet article, ainsi que ... pour sa relecture.