Comment présenter les instructions de test
Exemple 1: Tester si une cellule Excel nommée "Nombre" contient un nombre.
Exemple 2: Programmer une fonction qui retourne le nom d'une province, à partir d'un sigle.
Les instructions d'un programme sont normalement exécutées les unes à la suite
des autres, séquentiellement.
Les instructions de test, de boucle et de
branchement permettent de
modifier cet ordre naturel.
If expression Then Où
La première série d'instructions est exécutée si expression vaut Vrai, et la seconde si expression vaut Faux |
À la version de base ci-dessus qui ne permet que 2 alternatives, s'ajoutent les variations suivantes:
If expression Then instructions Où
Il est fortement recommandé de ne JAMAIS utiliser cette forme de IF qui n'ajoute rien et rend le programme plus difficile à comprendre et plus difficile à modifier. Utilisez plutôt:
If expression Then |
If expression
Then Où
Chaque série d'instructions est exécutée si l'expression précédente vaut Vrai, sauf celle qui suit le Else, qui est exécutée quand aucune des précédentes n'est Vraie. Cette variante du If est recommandée si votre programme doit tester plus d'une valeur d'une expression. |
Select Case expression [Case liste/expression [instructions]] ... [Case Else [instructions]] End Select Où
Cette instruction VBA joue le même rôle que le
IF... ELSEIF ... ENDIF précédent, mais est plus difficile à coder et
à comprendre. |
Autres fonctions de test à ne jamais utiliser:
Dim rRéponse rRéponse = Switch(expression1,valeur1[, expression2, valeur2, expression3, valeur3, expression4, valeur4… [, expressionN, valeurN]])
Qui correspond à:
Dim rRéponse |
Dim rRéponse rRéponse = Choose(expression, valeur1[, valeur2, ... [, valeurN]]) Qui correspond à: Dim rRéponse ... |
En VBA, il est convenu de présenter en retrait les instructions à l'intérieur d'un bloc de test.
Exemples à éviter:
If B > A Then A = B 'Ne pas faire de If sans Endif
If B > A Then
A = B 'Mettre les instructions d'un If en retrait
End If
Présentez ce test ainsi:
If B > A Then
A = B 'Le retrait permet d'identifier les
instructions
'Dont l'exécution est conditionnelle au If
End If 'Le
Endif permet d'identifier la fin du If
VBA hérite des anciennes versions de Basic une instruction de branchement, qui
modifie la séquence d'exécution
en effectuant un branchement vers une
ligne identifiée par une étiquette.
La syntaxe de l'étiquette est:
nom:
Où nom respecte la syntaxe d'une variable VBA, et doit être suivi d'un deux points (:)
L'instruction
GoTo étiquette
peut être utilisée n'importe où à l'intérieur de la procédure (pas du
module!) pour indiquer que la suite
du traitement se trouve aux lignes suivant
l'étiquette.
L'utilisation de GoTo n'est vraiment acceptable qu'à l'intérieur d'une
instruction On Error.
Dans d'autres circonstances, elle rend la logique du programme difficile à
comprendre, donc à modifier.
VBA inclut la fonction IIf() qui fonctionne exactement comme la fonction Si() de Excel (français) ou If() (Excel anglais):
IIf(expression, ValeurVrai, ValeurFaux) Où:
|
VBA offre plusieurs séries de fonctions utiles pour valider la nature des données et des variables.
IsNumeric(expression) | Vrai si expression peut être évaluée comme une valeur numérique |
IsDate(expression) | Vrai si expression peut être évaluée comme une date ou une heure |
IsNull(expression) |
Vrai si expression ne contient aucune variable de valeur
Null. Attention: expression = Null expression <> Null sont TOUJOURS faux. Utilisez IsNull(Variable). |
(variableobjet) Is Nothing | Vrai si variableobjet est un objet non initialisé (voir SET). |
IsEmpty(expression) | Vrai si expression est de type Variant et n'est pas initialisée. |
IsMissing(paramètre) |
paramètre doit être le nom d'un paramètre facultatif de la
procédure en cours. Faux si une valeur a été passée dans paramètre. |
IsObject(variable) |
Vrai si variable est de type
Object. Utilisez plutôt la fonction TypeName() |
IsArray(variable) | Vrai si variable est une variable contenant un tableau VBA. |
TypeName(variable) |
Retourne le nom du type de variable, exemples:
|
VarType(variable) |
Retourne une entier indiquant le type de variable. Beaucoup moins intéressant que TypeName(). |
On a vu dans la section Déclarations qu'il est préférable de déclarer Variant les paramètres d'une Function ou d'un Sub paramétré.
En effet, il est impossible de prédire au moment de la programmation quel type de paramètre sera transmis à la Function ou au Sub.
Développons à une fonction fnNomMois qui retourne le nom du mois d'une date fournie en paramètre: |
Function fnNomMois(dDate As
Date) 'Auteur: Michel Berthiaume 'Retourne le nom du mois de la date 'fournie en paramètre fnNomMois = Format(dDate, "mmmm") End Function |
Notez qu'on pourrait
utiliser l'instruction IF et la fonction VBA Month() pour arriver au
même résultat. Mais le code serait plus long et retournerait le nom
de mois dans une seule langue. Le code à gauche utilise la fonction VBA Format pour obtenir le nom du mois de l'environnement Windows (donc dans la langue de l'utilisateur) |
fnNomMois(#2012-1-2#) | retourne janvier | |
fnNomMois(2012-1-2) | retourne juillet | Parce que 2012 moins 1 moins 2 vaut 2009 et que le numéro de jour 2009 correspond au 1er juillet 1905. VBA fait une conversion automatique non souhaitée. |
Il est donc préférable de ne pas déclarer le type du paramètre et de plutôt en tester le type: |
Function
fnNomMois(dDate) 'Auteur: Michel Berthiaume 'Retourne le nom du mois de la date 'fournie en paramètre If IsDate(dDate) Then fnNomMois = Format(dDate, "mmmm") Else fnNomMois = "Date invalide" End If End Function |
L'utilisateur sera alors informé qu'il a mal formulé le paramètre |
Maintenant fnNomMois(2012-1-2) |
retourne Date invalide |
|
Si la cellule Excel A1
contient 2012-01-02 A1 contient 2012-02-31 A1 contient janvier |
et B1 contient =fnNomMois(A1) B1
affiche janvier B1 affiche Date invalide B1 affiche Date invalide |
Sub
sExempleTest1() |
Bien qu'intéressant, ce code n'est pas très fonctionnel.
Il affiche un message lorsque la cellule contient une valeur numérique (ou
nulle),
mais ce qu'on veut probablement, c'est interrompre la suite de la procédure
lorsque la valeur n'est pas numérique.
Sub
sExempleTest2() |
Function
fnNomProvince1(SigleProvince) 'Auteur: Michel Berthiaume 'Retourner le nom d'une province Dim sSigleProvince As String On Error GoTo Erreur: 'D'abord tester la validité du paramètre If TypeName(SigleProvince) = "Range" Then sSigleProvince = UCase(SigleProvince.Value) Else If TypeName(SigleProvince) = "String" Then sSigleProvince = UCase(SigleProvince) Else fnNomProvince1 = "sigle inconnu" Exit Function End If End If 'Rendu ici, sSigleProvince contient une version en majuscules du sigle If sSigleProvince = "AB" Then fnNomProvince1 = "Alberta" Else If sSigleProvince = "BC" Then fnNomProvince1 = "Colombie Britannique" Else If sSigleProvince = "PE" Then fnNomProvince1 = "Île-du-Prince-Édouard" Else If sSigleProvince = "NS" Then fnNomProvince1 = "Nouvelle-Écosse" Else If sSigleProvince = "NU" Then fnNomProvince1 = "Nunavut" Else If sSigleProvince = "ON" Then fnNomProvince1 = "Ontario" Else If sSigleProvince = "QC" Then fnNomProvince1 = "Québec" Else If sSigleProvince = "SK" Then fnNomProvince1 = "Saskatchewan" Else If sSigleProvince = "NF" Then fnNomProvince1 = "Terre Neuve" Else If sSigleProvince = "NT" Then fnNomProvince1 = "Territoires du Nord-Ouest" Else If sSigleProvince = "YK" Then fnNomProvince1 = "Yukon" Else fnNomProvince1 = "Sigle inconnu" End If End If End If End If End If End If End If End If End If End If End If Exit Function Erreur: fnNomProvince1 = "Erreur: " & Err.Description End Function |
Bien que fonctionnel, le code ci-dessus est lourd et répétitif.
Voici une version allégée:
Function fnNomProvince2(SigleProvince) 'Auteur: Michel Berthiaume 'Retourner le nom d'une province Dim sSigleProvince As String On Error GoTo Erreur: 'D'abord tester la validité du paramètre If TypeName(SigleProvince) = "Range" Then sSigleProvince = UCase(SigleProvince.Value) Else If TypeName(SigleProvince) = "String" Then sSigleProvince = UCase(SigleProvince) Else fnNomProvince2 = "sigle inconnu" Exit Function End If End If 'Rendu ici, sSigleProvince contient une version en majuscules du sigle If sSigleProvince = "AB" Then fnNomProvince2 = "Alberta" ElseIf sSigleProvince = "BC" Then fnNomProvince2 = "Colombie Britannique" ElseIf sSigleProvince = "PE" Then fnNomProvince2 = "Île-du-Prince-Édouard" ElseIf sSigleProvince = "NS" Then fnNomProvince2 = "Nouvelle-Écosse" ElseIf sSigleProvince = "NU" Then fnNomProvince2 = "Nunavut" ElseIf sSigleProvince = "ON" Then fnNomProvince2 = "Ontario" ElseIf sSigleProvince = "QC" Then fnNomProvince2 = "Québec" ElseIf sSigleProvince = "SK" Then fnNomProvince2 = "Saskatchewan" ElseIf sSigleProvince = "NF" Then fnNomProvince2 = "Terre Neuve" ElseIf sSigleProvince = "NT" Then fnNomProvince2 = "Territoires du Nord-Ouest" ElseIf sSigleProvince = "YK" Then fnNomProvince2 = "Yukon" Else fnNomProvince2 = "Sigle inconnu" End If Exit Function Erreur: fnNomProvince2 = "Erreur: " & Err.Description End Function |
Il est aussi possible d'utiliser l'Instruction SELECT, mais elle n'offre pas d'avantage important sur la version précédente:
Function fnNomProvince3(SigleProvince) 'Auteur: Michel Berthiaume 'Retourner le nom d'une province Dim sSigleProvince As String On Error GoTo Erreur: 'D'abord tester la validité du paramètre If TypeName(SigleProvince) = "Range" Then sSigleProvince = UCase(SigleProvince.Value) Else If TypeName(SigleProvince) = "String" Then sSigleProvince = UCase(SigleProvince) Else fnNomProvince3 = "sigle inconnu" Exit Function End If End If 'Rendu ici, sSigleProvince contient une version en majuscules du sigle Select Case sSigleProvince Case "AB" fnNomProvince3 = "Alberta" Case "BC" fnNomProvince3 = "Colombie Britannique" Case "PE" fnNomProvince3 = "Île-du-Prince-Édouard" Case "NS" fnNomProvince3 = "Nouvelle-Écosse" Case "NU" fnNomProvince3 = "Nunavut" Case "ON" fnNomProvince3 = "Ontario" Case "QC" fnNomProvince3 = "Québec" Case "SK" fnNomProvince3 = "Saskatchewan" Case "NF" fnNomProvince3 = "Terre Neuve" Case "NT" fnNomProvince3 = "Territoires du Nord-Ouest" Case "YK" fnNomProvince3 = "Yukon" Case Else fnNomProvince3 = "Sigle inconnu" End Select Exit Function Erreur: fnNomProvince3 = "Erreur: " & Err.Description End Function |
VBA offre plusieurs structures contrôlant l'ordre d'exécution des instructions.
Le fichier Excel Exemples Tests.xlsm contient les exemples présentés dans la présente section.