IF...THEN ou Comment effectuer des tests logiques simples en VBA [#11 FORMATION EXCEL VBA COMPLETE]
Attention, aujourd’hui nous allons attaquer un point crucial du développement d’applications dans n’importe quel langage de programmation ! En effet, nous allons voir comment aider notre programme à pouvoir prendre des décisions afin de suivre un déroulement logique. Et pour cela, nous allons découvrir l’opérateur If…Then, qui permet de réaliser une opération uniquement lorsqu’une condition est remplie. Restez bien jusqu’au bout de ce chapitre, car nous y découvrirons également une variante encore plus puissante qui est l’opérateur If…Then…Else qui permet également de réaliser une autre opération, lorsque cette fois-ci la condition n’est pas remplie.
Téléchargement
Vous pouvez obtenir le fichier d'exemple de cet article et découvrir la méthode d'apprentissage de VBA pas-à-pas en cliquant sur le lien suivant :
Tutoriel Vidéo
Vous trouverez très régulièrement de nouvelles vidéos sur la chaîne, alors pensez à vous abonner pour ne manquer aucune astuce et devenir rapidement un pro d’Excel (cliquez-ici) !
1. Présentation
Comme nous l’avons vu dans l’introduction de ce chapitre, la structure de programmation If…Then que nous allons voir dès à présent et l’un des éléments principaux sur lequel tout langage de programmation va s’appuyer.
Celle-ci permet en effet de guider le programme sur les opérations à effectuer, en définissant un certain nombre de règles simples, mais également complexes (mais pour ne pas trop vous compliquer la compréhension, nous verrons les cas les plus complexes dans les prochains chapitres, chaque chose en son temps !).
Ainsi la structure If…Then permet d’effectuer un test, lequel ne pourra avoir pour valeur que vrai (True dans le langage de VBA) ou faux (False).
Ensuite, et uniquement lorsque ce résultat est vrai, alors nous pouvons demander à Excel d’exécuter une instruction.
La structure est alors la suivante :
If [Test] Then [Instruction]
Où :
- Test : test logique qui retourne une valeur égale à True (vrai) ou False (faux)
- Instruction : Opération à réaliser lorsque Test est égal à True
Voici un exemple très simple :
If a = 5 Then b = 10
Ici nous cherchons à savoir si la variable a a pour valeur 5.
Lorsque cela est le cas, alors nous affectons la valeur 10 à la variable b.
En revanche, lorsque n’est pas le cas, alors la macro ne va rien faire, et se contenter de suivre son cours à partir de la ligne suivante.
2. Exemple simple
Pour bien comprendre le fonctionnement de la structure If… Then, nous créer une petite fonction très simple qui va se charger d’afficher un message différent en fonction du moment de la journée que nous allons saisir dans une cellule de la feuille de calcul.
Lorsque le moment saisi est égal à « matin », alors nous allons afficher le message « Bonjour ».
Nous n’allons pas nous attarder sur les méthodes qui permettent de créer une fonction personnalisée, si vous avez manqué les chapitres précédents de la formation, je vous invite vivement à les suivre en cliquant ici.
Voici notre fonction personnalisée :
Function bonjour(moment As String) As String
If moment = "matin" Then bonjour = "Bonjour"
End Function
Nous créons donc une fonction qui porte le nom de bonjour qui est de type String (c’est-à-dire que celle-ci va retourner un texte).
Cette fonction demande un argument qui va également être un texte.
Puis nous demandons à VBA de contrôler la valeur contenue dans la variable moment, et lorsque celle-ci est égale à « matin », alors VBA doit retourner à la fonction le texte « Bonjour ».
Ensuite, de retour dans la feuille de calcul, nous appelons la fonction « bonjour », comme nous le ferions pour n’importe quelle autre fonction intégrée dans Excel, en utilisant le signe égal, suivi du nom de la fonction avec l’argument saisi entre guillemets (il s’agit en effet d’un texte) :
=bonjour("matin")
Nous constatons alors que si nous saisissons le texte « matin » en guise d’argument, alors la cellule dans laquelle nous avons saisi la formule prend pour valeur « Bonjour »
En revanche, lorsque nous saisissons un texte différent de « matin », alors la cellule devient vide :
Heureusement, il est tout à fait possible de cumuler plusieurs tests successifs :
Function bonjour(moment As String) As String
If moment = "matin" Then bonjour = "Bonjour"
If moment = "soir" Then bonjour = "Bonsoir"
End Function
3. If…Then…Else : et sinon !
Dans notre exemple, nous cumulons deux tests afin d’adapter la réponse retournée par la fonction par rapport au message saisi en argument.
Plutôt que d’effectuer deux tests successifs, nous pourrions utiliser la clause facultative Else qui permet d’effectuer une instruction lorsque la condition testée dans l’instruction If n’est pas remplie.
Le code deviendrait alors le suivant :
Function bonjour(moment As String) As String
If moment = "matin" Then bonjour = "Bonjour" Else bonjour = "Bonsoir"
End Function
L’avantage d’utiliser la clause Else est que celle-ci peut permettre un gain en termes d’utilisation de ressources.
En effet, dans le cas précédent, la macro réalisait systématiquement les deux tests, quelque soient les résultats obtenus par l’un ou l’autre. Bien sûr, dans notre exemple qui est volontairement simpliste, le gain en terme de vitesse est absolument imperceptible, mais celui-ci deviendra bien plus significatif à mesure que notre application va prendre de l’importance !
Ici, Excel ne réalise qu’un seul test, et adapte l’instruction à appliquer en fonction de son résultat.
Bien sûr, il faut être prudent dans l’usage de cette clause pour ne pas produire de code erroné.
En effet, imaginons que l’utilisateur saisisse pour argument « Après-midi ». Dans ce cas, le test admettra pour valeur False (faux) et exécutera l’instruction précisée dans la partie Else, soit « Bonsoir ».
Ce qui n’est évidemment pas adapté au contexte.
Pas de panique, nous verrons très bientôt comment résoudre ce problème !
4. L’instruction If sous sa forme développée
Dans tous les exemples que nous avons vu jusqu’à maintenant, l’ensembles des éléments constitutifs de l’instruction If étaient saisis sur une seule et même ligne (le test, l’instruction principale et l’instruction secondaire).
Il s’agit d’une forme simplifiée d’utilisation de l’instruction If, la forme complète séparant chaque élément sur une ligne différente, dont la dernière est la clause de fin d’instruction End If.
Voici la forme complète de l’instruction If :
Function bonjour(moment As String) As String
If moment = "matin" Then
bonjour = "Bonjour"
End If
End Function
La forme simplifiée permet de gagner un peu de temps à la saisie, mais ne permet d’insérer qu’une seule instruction à réaliser.
En revanche la forme complexe permet de réaliser un nombre illimité d’instructions, et rend la lecture du code bien plus claire et aérée :
Function bonjour(moment As String) As String
If moment = "matin" Then
MsgBox "Nous sommes le matin, bonjour"
bonjour = "Bonjour"
End If
End Function
Ensuite, la clause Else est également à utiliser une ligne différente :
Function bonjour(moment As String) As String
If moment = "matin" Then
bonjour = "Bonjour"
Else
bonjour = "Bonsoir"
End If
End Function
5. Cumuler les tests grâce à la clause ElseIf…Then
Comme nous l’avons un peu plus tôt dans ce chapitre, la clause Else permet de réaliser une instruction lorsque le test effectué par le If retourne une valeur False.
Mais il peut être utile de souhaiter réaliser une opération uniquement lorsqu’un second test retourne une valeur True !
Pour cela, nous avons à notre disposons une autre clause qui permet de cumuler les effets de If et de Else, il s’agit de la clause ElseIf :
Function bonjour(moment As String) As String
If moment = "matin" Then
bonjour = "Bonjour"
ElseIf moment = "soir" Then
bonjour = "Bonsoir"
End If
End Function
Comme vous pouvez le constater, l’utilisation de ElseIf nécessite également une clause Then en fin de ligne.
Évidemment, la clause ElseIf ne peut être utilisée que dans le cadre d’une utilisation complète de l’instruction If.
Ensuite, sachez que nous pouvons cumuler le nombre de ElseIf pour effectuer un grand nombre de tests :
Function bonjour(moment As String) As String
If moment = "matin" Then
bonjour = "Bonjour"
ElseIf moment = "apres-midi" Then
bonjour = "Bonne apres-midi"
ElseIf moment = "soir" Then
bonjour = "Bonsoir"
End If
End Function
Dans ce cas, VBA va réaliser chacun des tests l’un après l’autre, jusqu’à obtenir un resultat positif (True).
Une fois l’instruction réalisée, la macro va se rendre après la dernière ligne du test (End If).
Il faut donc faire attention à l’ordre suivant lequel les tests se suivent, pour ne pas générer d’anomalies dans le déroulement du code.
Enfin, pour saisir une valeur par défaut à retourner lorsqu’aucun test n’a de retour positif, il suffit d’insérer une clause Else classique en toute fin d’instruction :
Function bonjour(moment As String) As String
If moment = "matin" Then
bonjour = "Bonjour"
ElseIf moment = "apres-midi" Then
bonjour = "Bonne apres-midi"
ElseIf moment = "soir" Then
bonjour = "Bonsoir"
ElseIf moment = "nuit" Then
bonjour = "Bonne nuit"
Else
bonjour = "Moment de la journée inconnu..."
End If
End Function
Ce tour de présentation de l’instruction If est maintenant terminé… du moins pour le moment ! À présent, nous allons pouvoir en découvrir toutes les subtilités, et voir à quel point nous pouvons effectuer des tests complexes
6. Les Opérateurs de comparaison
Jusqu’à maintenant, les tests que nous avons eu à effectuer consistaient uniquement à contrôler l’égalité parfaite entre une variable et une valeur.
Évidemment, il est possible de réaliser des comparaisons plus complexes, notamment en utilisant les différents opérateurs suivants :
Opérateur
Opérateur |
Signification |
Résultat True |
Résultat False |
= |
Est égal à… |
1 = 1 |
1 = 2 |
< |
Est inférieur à… |
1 < 2 |
2 < 1 |
<= |
Est inférieur ou égal à… |
1 <= 2 |
2 <= 1 |
> |
Est supérieur à… |
2 > 1 |
1 > 2 |
>= |
Est supérieur ou égal à… |
2 >= 1 |
1 >= 2 |
<> |
Est différent de… (non égal) |
1 <> 2 |
1 <> 1 |
Like |
Comparaison de chaînes de caractères |
"Hello" Like "Hel*" |
"Hello" Like "Hal*" |
Il existe d’autres opérateurs de comparaisons, spécifiques aux objets en VBA (Is, NotIs), mais nous aurons tout le loisir de revenir sur l’utilisation de ces derniers bien plus tard au cours de la formation, lorsque nous aborderons le sujet de la création et de la manipulation des objets.
6.1. Opérateur d’égalité (=) et d’inégalité (<>)
L’opérateur d’égalité porte très bien son nom, puisqu’il permet de comparer deux éléments en utilisant simplement le signe égal :
(en réalité comme nous le verrons juste après, il est tout à fait possible de comparer plus de deux éléments)
Sub operateursComparaison()
Dim a As Integer, b As Integer
a = 1
b = 5
If a = b Then
Debug.Print a & " est égal a " & b
Else
Debug.Print a & " n'est pas égal a " & b
End If
End Sub
1 n'est pas égal a 5
Note : pour simplifier l’affichage des résultats, nous utilisons ici une fonction bien pratique que nous n’avons pas encore eu l’occasion d’aborder dans cette formation, il s’agit de la Debug.Print, qui permet d’afficher un message directement dans la fenêtre « Exécution » de l’interface de VBE. Contrairement à Msgbox que nous avons plutôt coutume d’utiliser, Debug.Print ne nécessite pas d’interruption du code et permet un gain de temps non négligeable. De plus, il est possible d’effectuer un copier-coller sur les lignes insérées dans la fenêtre Exécution, ce qui peut s’avérer bien pratique dans certains cas.
(Si la fenêtre d’exécution n’est pas affichée sur votre interface, rendez-vous dans le menu Affichage, voir les chapitres précédents de la formation VBA en cliquant ici)
Nous voyons ici rapidement que 1 n’est pas égal à 5.
Nous pourrions également utiliser l’opérateur d’inégalité : « <> » qui permet de vérifier que deux valeurs sont bien différentes l’une de l’autre :
' L'opérateur d'inégalité
If a <> b Then
Debug.Print a & " est différent de " & b
Else
Debug.Print a & " n'est pas différent de " & b
End If
' => 1 est différent de 5
Une attention tout particulière est à prêter au type attribué aux variables. En effet, rappelez-vous, dans le chapitre dédié au typage des variables, nous avions vu que certains types pouvait approcher du zéro, sans toutefois l’attreindre réellement :
Heureusement, lorsque nous comparons un réel simple à un réel double, Excel arrondi automatique le réel Double, ce qui permet une comparaison entre les deux types différents :
Sub operateursComparaisonNumerique()
Dim a As Double
If a = 0 Then
Debug.Print a & " est égal a 0"
Else
Debug.Print a & " n'est pas égal a 0"
End If
' => 0 est égal a 0
End Sub
6.2. Opérateur de comparaison stricte (<, >)
Lorsque nous souhaitons comparer des valeurs entre elles, il peut être nécessaire de recourir aux opérateurs de comparaisons strictes.
L’opérateur inférieur à (« < ») permet de tester si la valeur de gauche est plus petite que la valeur de droite :
Dim a As Integer, b As Integer
a = 1
b = 5
If a < b Then
Debug.Print a & " est inférieur a " & b
Else
Debug.Print a & " n'est pas inférieur a " & b
End If
' => 1 est inférieur a 5
6.3. Opérateurs de comparaisons non strictes (<=, >=)
Maintenant que nous avons vu les opérateurs d’égalité et de comparaison, utiliser un opérateur de comparaison non stricte ne présente aucune difficulté, nous cherchons en effet à savoir si une variable est inférieure ou égale à une autre :
Option Explicit
Option Compare Text
…
Sub operateursComparaisonNumerique()
Dim a As Integer, b As Integer
a = 1
b = 5
If a <= b Then
Debug.Print a & " est inférieur ou égal a " & b
Else
Debug.Print a & " n'est pas inférieur ou égal a " & b
End If
' => 1 est inférieur ou égal a 5
End Sub
6.4. Effectuer des comparaisons en chaîne
Bien évidemment, il est aussi possible de comparer des chaînes de caractères :
Sub operateursComparaison()
Dim a As String, b As String
a = "tomate"
b = "fraise"
' L'opérateur d'inégalité
If a <> b Then
Debug.Print a & " est différent de " & b
Else
Debug.Print a & " n'est pas différent de " & b
End If
End Sub
tomate est différent de fraise
Attention, lorsque nous utilisons les opération d’(in)égalité, nous cherchons à vérifier si les deux valeurs sont STRICTEMENT égales. Aussi ce genre de test s’attache bien évidemment à vérifier également que la casse est également identique (c’est à qu’un caractère en majuscule sera différent du même caractère en minuscule).
Sub operateursComparaison()
Dim a As String, b As String
a = "tomate"
b = "Tomate"
If a <> b Then
Debug.Print a & " est différent de " & b
Else
Debug.Print a & " n'est pas différent de " & b
End If
' => tomate est différent de Tomate
Pour modifier ce comportement, il suffit d’ajouter l’instruction « Option Compare Text » au tout début du module (ou juste en dessous de Option Explicit si celui-ci est présent) :
Option Explicit
Option Compare Text
…
Sub operateursComparaisonTexte()
Dim a As String, b As String
a = "tomate"
b = "Tomate"
If a <> b Then
Debug.Print a & " est différent de " & b
Else
Debug.Print a & " n'est pas différent de " & b
End If
' => tomate n'est pas différent de Tomate
End Sub
La comparaison de chaîne de caractères s’effectue par défaut sur la base d’un tri binaire, c’est-à-dire en fonction de l’ordre d’apparition des caractères dans la table des caractères :
- Tout d’abord les lettres en majuscules : A, B, C,…
- Puis les lettres en minuscules : a, b, c,…
- Puis les lettres accentuées en majuscules : À, Ê,…
- Puis les symboles en majuscules : Ø,…
- Puis les lettres accentuées en minuscules : à, ê,…
- Puis les symboles en majuscules : ø,…
Sub operateursComparaisonTexte()
Dim a As String, b As String
a = "a"
b = "A"
If a > b Then
Debug.Print a & " est supérieur a " & b
Else
Debug.Print a & " n'est pas supérieur a " & b
End If
' => a est supérieur a A
End Sub
En revanche, l’instruction Option Compare Text en haut du module permet d’appliquer un tri alphabétique qui ne tient pas compte de la casse :
Option Explicit
Option Compare Text
…
Sub operateursComparaisonTexte()
Dim a As String, b As String
a = "a"
b = "A"
If a > b Then
Debug.Print a & " est supérieur a " & b
Else
Debug.Print a & " n'est pas supérieur a " & b
End If
' => a n'est pas supérieur a A
End Sub
6.5. Opérateur de comparaison de chaîne de caractères (LIKE)
De plus, sachez qu’il existe un opérateur qui permet d’effectuer des comparaison de chaînes de caractères partielle : il s’agit de l’opérateur LIKE.
Utilisé seul, cet opérateur agit comme l’opérateur d’égalité :
Sub operateursComparaisonTexte()
Dim a As String, b As String
a = "tomate"
b = "tomate"
If a Like b Then
Debug.Print a & " est égal a " & b
Else
Debug.Print a & " n'est pas égal a " & b
End If
' => tomate est égal a tomate
End Sub
En revanche, celui-ci prend tout son intérêt lorsque nous utilisons en plus un des caractères joker qui permet de paramétrer un pattern de comparaison.
Ces caractères sont les suivants :
Caractères |
Usage |
? |
Remplace un seul caractère unique |
* |
Remplace aucun, un seul ou plusieurs caractères |
# |
Remplace un seul chiffre unique (0 à 9) |
[liste] |
Remplace tous les caractères contenus dans la liste |
[!liste] |
Remplace tous les caractères non contenus dans la liste |
Cela peut par exemple permettre de remplacer deux caractères inconnus au milieu du mot par des points d’interrogations (nous savons qu’il y a deux caractères inconnus sans savoir lesquels) :
Sub operateursComparaisonTexte()
Dim a As String, b As String
a = "tomate"
b = "to??te"
If a Like b Then
Debug.Print a & " est égal a " & b
Else
Debug.Print a & " n'est pas égal a " & b
End If
' => tomate est égal a to??te
End Sub
Voici quelques autres exemples :
- Les points d’interrogation correspondent au nombre exact de caractères manquant : « ' => tomate n'est pas égal a to?te »,
- En revanche l’astérisque permet de ne pas être obligé de connaître le nombre exact de caractères manquant : « ' => tomate est égal a to*te »
- Le dièse agit comme le point d’interrogation, mais appliqué aux chiffres : « tomate n55 est égal a tomate n## », « tomate n55 n'est pas égal a tomate n# »
- Les crochets permettent de remplacer uniquement des caractères contenus dans une liste : « b est égal a [abc] », « d n'est pas égal a [abc] »
- Pour exclure une séquence de la liste nous utilisons le point d’exclamation : « a n'est pas égal a [!abc] », « d est égal a [!abc] »
6.6. Inverser une comparaison (NOT)
Enfin, le dernier opérateur que nous allons voir aujourd’hui permet d’inverser le résultat obtenu par un test, il s’agit de l’opérateur Not.
En effet, nous avons déjà vu dans la première partie que le résultat d’un test permet d’obtenir une variable Booléenne (True ou False) qui va permettre de lancer ou non une instruction.
Grâce à l’opérateur NOT, ce résultat sera inversé, c’est-à-dire qu’un True devient False, et une False devient True.
Sub operateursComparaisonNumerique()
Dim a As Integer, b As Integer
a = 1
b = 5
If Not a <= b Then
Debug.Print a & " est inférieur ou égal a " & b
Else
Debug.Print a & " n'est pas inférieur ou égal a " & b
End If
' => 1 n'est pas inférieur ou égal a 5
End Sub
7. Combiner les tests avec les opérateurs logiques (And, Or,…)
À présent, supposions que nous souhaitions effectuer plusieurs tests avant de pouvoir opérer une instruction.
Pour pourrions tout à fait imbriquer plusieurs tests si les uns dans les autres, de la manière suivante :
Sub plusieursTests()
Dim a As String
Dim b As String
a = "France"
b = "Japon"
If a = "France" Then
If b = "Japon" Then
Debug.Print "a = France et b = Japon"
Else
debut.Print "a = France, mais b <> Japon"
End If
Else
Debug.Print "a <> France"
End If
End Sub
Ici, nous commençons par contrôler la valeur de a afin de vérifier que celle-ci est bien égale à France.
Puis dans un second temps, nous vérifions que b a pour valeur Japon.
Sachez que VBA comme tous les autres langages de programmation propose une série d’opérateurs dits « logiques » qui permettent de combiner plusieurs tests en une seule et même opération !
7.1. And : Toutes les conditions sont remplies
Rappelez-vous dans les parties précédentes, nous avons vu que le test réalisé par la formule IF permet de récupérer une variable du type Booléen, c’est-à-dire qui aura pour valeur uniquement VRAI ou FAUX (en réalité True et False dans le langage de VBA).
Les opérateurs logiques permettent de combiner plusieurs variables Booléennes afin d’en extraire un résultat qui sera lui aussi Booléen.
Le premier d’entre eux est l’opérateur And (« And » = « Et » en anglais) qui permet va retourner une valeur True, lorsque deux opérandes auront une valeur déjà égale à true
Note : Comme vous pouvez le voir, il est possible de combiner plusieurs Opérateurs logiques pour effectuer des tests plus complexes. Nous reviendrons dessus un peu plus tard dans ce chapitre.
Comme le montre ce tableau, il suffit qu’un seul opérande soit égal à False pour que le résultat obtenu soit lui aussi égal à False.
Sub testsOperateursLogiques()
Dim a As Boolean
Dim b As Boolean
a = True
b = True
Debug.Print a And b
End Sub
Dans cet exemple, les variables a et b sont égales à True, le résultat de « a And b » sera donc lui aussi égal à True (traduit dans la fenêtre d’Exécution par Vrai).
En revanche, il suffit qu’un élément soit égal à False pour que le résultat devienne lui aussi False :
Une fois cette logique bien intégrée, il est possible d’utiliser les opérateurs logiques directement en guise de test dans une formule If.
L’exemple que nous venons de voir un peu plus tôt peut donc facilement est réduit de la manière suivante :
Sub plusieursTests()
Dim a As String
Dim b As String
a = "France"
b = "Japon"
If a = "France" And b = "Japon" Then
Debug.Print "a = France et b = Japon"
Else
Debug.Print "a <> France ou b <> Japon, ou les deux"
End If
End Sub
7.2. Or : Au moins une condition est remplie
Le second opérateur logique est l’opérateur Or (« Or » = « Ou » en anglais).
Celui-ci retournera comme valeur True, lorsqu’au moins des éléments est égal à True :
Ainsi, le seul cas dans lequel l’opérateur Or renverra une valeur False, c’est lorsque TOUTES LES VALEURS comparées sont égales à False :
7.3. Xor : Le nombre de conditions remplies est impaire
Les cas pour lesquels il est nécessaires de savoir si le nombre de fois au cours desquels le nombre de conditions qui pour valeur True est impair sont très rares, mais VBA prévoit malgré tout un opérateur pour cela.
Il s’agit de l’opérateur Xor, c’est-à-dire le « Ou exclusif » :
L’usage le plus courant dans lequel nous utiliserons cet opérateur sera lorsque nous aurons uniquement deux opérandes, et que nous souhaitons que l’un d’entre eux seulement soit égal à True et que l’autre soit par conséquent égal à False (c’est-à-dire qu’une seule des deux conditions soient remplie).