Vous êtes sur la page 1sur 9

7

Contrôler les programmes


VBA
Au sommaire de ce chapitre
• Répéter une série d’instructions : les boucles
• Utiliser des instructions conditionnelles
• Définir l’instruction suivante avec GoTo
• Interagir avec l’utilisateur via des boîtes de dialogue
• Utiliser les opérateurs logiques
• Trier des données

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 175 02/05/13 13:11


176 Excel 2013 et VBA

Visual Basic intègre des instructions permettant d’orienter le comportement d’une macro.
Ces instructions sont appelées des structures de contrôle – on parle du flux de contrôle d’un
programme. La connaissance et la maîtrise de ces structures constituent un préalable indispen-
sable à la création de programmes VBA souples et puissants, se comportant différemment selon
l’état du document et de l’application au cours de son exécution, ou des informations fournies
par l’utilisateur.
Ce chapitre aborde une à une les structures de contrôle de Visual Basic. Leur combinaison
permettra de gagner un temps précieux dans vos tâches les plus communes comme les plus
complexes. L’instruction GoTo et les fonctions MsgBox et InputBox, ainsi que la collection Dialogs
sont aussi traitées dans ce chapitre. Il ne s’agit pas de structures de contrôle, mais elles permet-
tront aussi de contrôler le comportement des programmes VBA, et d’interagir avec l’utilisateur.

Répéter une série d’instructions : les boucles


On entend par instructions en boucle, des instructions se répétant en série. Des instructions
en boucles peuvent se répéter un nombre de fois déterminé dans le code ou un nombre de fois
indéterminé, en fonction du contexte au moment de l’exécution du programme.
• Do...Loop et While...Wend. Permettent de généraliser une série d’instructions particulières à
l’ensemble d’un document ; dans ce cas, ce sont l’état du document et l’état de l’application
qui déterminent le nombre de boucles réalisées.
• For...Next. Permet de répéter sur un document une série d’instructions un nombre de fois
déterminé par l’utilisateur.
• For Each...Next. Permet d’exécuter une série d’instructions sur tous les objets d’une
collection.

La boucle While...Wend
La structure de contrôle While...Wend permet de répéter une série d’instructions tant qu’une
condition spécifiée est remplie. C’est l’une des structures les plus utilisées pour automatiser les
tâches répétitives. Elle permet de répéter un traitement sur une chaîne, un format, un objet, etc.,
déterminé dans un document.
La syntaxe de la structure While...Wend est la suivante :
While Condition
Série d’instructions
Wend

où Condition est une expression comparant deux valeurs à l’aide d’un opérateur relationnel.
Lorsque la condition spécifiée après While est réalisée, le programme exécute la Série d’ins-
tructions, placée entre While et Wend. Lorsque l’instruction Wend est atteinte, le programme
retourne à l’instruction While et interroge à nouveau la condition. Si elle est réalisée, la Série
d’instructions s’exécute à nouveau, etc. Dans le cas contraire, les instructions placées entre
While et Wend sont ignorées, et l’exécution du programme se poursuit avec l’instruction située
immédiatement après Wend.

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 176 02/05/13 13:11


Chapitre 7 Contrôler les programmes VBA 177

Pour poser une condition, on conjugue généralement une expression avec un opérateur
relationnel, ou opérateur de comparaison, et une valeur. L’opérateur relationnel permet
d’établir un rapport entre la valeur renvoyée par l’expression et la valeur qui lui est associée. Si
ce rapport est vérifié, la condition est respectée.
Le Tableau 7.1 présente les opérateurs relationnels de Visual Basic.

Tableau 7.1 : Les opérateurs relationnels de Visual Basic

Opérateur relationnel Signification


= Égal à
> Supérieur à
< Inférieur à
<> Différent de
>= Supérieur ou égal à
<= Inférieur ou égal à
Like Identique à (pour comparer des chaînes de caractères)
Is Égal à (pour comparer des variables objet)

Deux chaînes de caractères peuvent être comparées à l’aide des opérateurs relationnels
seil
Con =, <, >, etc. La comparaison s’effectue alors entre les codes ANSI attachés aux carac-
tères comparés. Si vous devez effectuer des comparaisons précises, préférez l’opérateur
Like. Celui-ci permet en effet de prendre ou non en compte la casse et permet l’uti-
lisation de caractères génériques. Consultez l’aide en ligne pour plus de précisions.

La technique d’enregistrement d’instructions en boucle la plus courante consiste à exécuter la


série d’instructions après avoir activé l’Enregistreur de macro, puis à ouvrir la fenêtre Code de
la macro et à y insérer la structure While...Wend.
Nous utiliserons une structure While...Wend pour automatiser la saisie d’informations dans
une feuille de calcul. Considérez le classeur Representants par departements représenté à la
Figure 7.1. La feuille de calcul active (libellée Representants) recense les départements affectés
à chaque représentant de la société. Les noms des représentants apparaissent dans les cellules
de la ligne 3. Pour chaque cellule contenant le nom d’un représentant, nous avons inséré en
commentaires les initiales du représentant. Sous le nom du représentant se trouvent les numéros
des départements dont il a la charge.

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 177 02/05/13 13:11


178 Excel 2013 et VBA

Figure 7.1
La répartition
des représentants
par départements.

Le classeur Representants par clients illustré à la Figure 7.2 contient la liste des clients de la
société (colonne A). La colonne B nous renseigne sur la ville du client, et la colonne D sur son
numéro de client. Les deux premiers chiffres de ce numéro correspondent au département
d’origine du client. La colonne C contient les initiales du représentant en charge du client.
Nous profiterons de ce que ces deux classeurs ont en commun le numéro du département pour
automatiser la mise à jour de la colonne C.

Figure 7.2
Le classeur avec
la répartition des
­représentants par
clients avant mise à jour
de la colonne C.

La macro suivante interroge les deux premiers chiffres du numéro de client. Elle recherche
ensuite cette valeur dans le classeur Representants par departement de façon à identifier le
représentant en charge du client. Les initiales du client sont alors insérées dans la cellule située
à gauche du numéro de client. La structure While...Wend permet de répéter cette procédure en
boucle. Chaque fois que les initiales d’un représentant ont été insérées, la cellule Numéro de
client suivante est activée. La procédure s’exécute TANT QUE la cellule sélectionnée contient
une valeur.

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 178 02/05/13 13:11


Chapitre 7 Contrôler les programmes VBA 179

1: Sub InsererInitialesRepresentants()
2: Dim ClasseurRepresentants As Workbook
3: Dim NumDepartement As String
4: Dim Colonne As Variant
5: Dim Initiales
6: Set ClasseurRepresentants = _
GetObject("C:\Documents and settings\Administrateur\Bureau\Representants par
➥ departements.xlsx")
7: Range("D4").Select
8: While ActiveCell.Value <> ""
9: NumDepartement = Left(ActiveCell.Value, 2)
10: Colonne = ClasseurRepresentants.Sheets(1).Range("A4:I50").Find(What:=
➥ NumDepartement, LookIn:=xlFormulas, LookAt:=xlWhole).Address
11: Colonne = Range(Colonne).Column
12: Colonne = CInt(Colonne)
13: Initiales = ClasseurRepresentants.Sheets(1).Cells(3, Colonne).Comment.Text
14: ActiveCell.Offset(0, -1).Range("A1").Select
15: ActiveCell.FormulaR1C1 = Initiales
16: ActiveCell.Offset(1, 1).Range("A1").Select
17: Wend
18: Set ClasseurRepresentants = Nothing
19: Workbooks("Representants par departements.xlsx").Close
20: End Sub

Lignes 2 à 6, les variables qui seront exploitées par le programme sont déclarées, et à la variable
objet ClasseurReprésentant est affecté le classeur Representants par departements.xlsx, situé sur
le Bureau. Ligne 7, la cellule D4 est sélectionnée.
La boucle While...Wend des lignes 8 à 17 s’exécute tant que la cellule sélectionnée contient des
informations. Ligne 9, la fonction Left affecte à la variable NumDepartement les deux caractères
de gauche (correspondant au numéro de département) de la valeur de la cellule active. Cette
valeur est ensuite recherchée dans le classeur des représentants par départements (ligne 10).
L’objet Range renvoyé par la méthode Find est affecté à la variable Colonne – notez que la variable
Colonne a été déclarée de type Variant de sorte qu’elle puisse recevoir des valeurs de différents
types. Ligne 11, Colonne reçoit la valeur correspondant au numéro de la colonne de la cellule
trouvée. Ligne 12, la fonction CInt convertit la valeur de Colonne en valeur de type Integer.
La variable Colonne peut ainsi être utilisée comme argument de la propriété Cells. Ligne 13, la
variable Initiales reçoit pour valeur les initiales du représentant en charge du département.
On lui affecte pour cela le texte de commentaires de la cellule située dans la même colonne
que l’objet Range renvoyé par la fonction Find, mais sur la ligne 3 – la ligne des noms de repré-
sentants.
Lignes 14 et 16, un déplacement par référence relative aux cellules est effectué. Tout d’abord,
la cellule située à gauche de la cellule active est sélectionnée et reçoit la valeur de la variable
Initiales (ligne 15). Un déplacement d’une cellule vers la droite puis d’une cellule vers le bas
est ensuite effectué. La cellule active est alors la cellule suivante de la colonne D. Le mot clé
Wend renvoie l’exécution du programme à l’instruction While correspondante. Celle-ci vérifie que
la cellule active contient des données. Si tel est le cas, les instructions situées entre While et Wend
sont exécutées, et les initiales du représentant en charge du client insérées.

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 179 02/05/13 13:11


180 Excel 2013 et VBA

Lorsque la condition While n’est plus vérifiée, les instructions situées entre While et Wend sont
ignorées et le programme se termine avec les instructions des lignes 18 et 19. Les ressources
système occupées par la variable objet ClasseurRepresentants sont libérées, et le classeur des
représentants par départements est fermé.

Pour sécuriser définitivement cette macro, commencez par lui faire activer la
seil
Con feuille devant recevoir les informations. Elle devra logiquement être stockée dans
ClasseurRepresentants.xlsx, puisqu’elle ne servira qu’à ce classeur. Ainsi, elle ne s’exé-
cutera que si le classeur est ouvert.

Figure 7.3
La macro a complété
les informations
de la colonne C.

La boucle Do...Loop
La structure de contrôle Do...Loop est semblable à While...Wend, mais offre plus de souplesse
car elle peut se décliner sur quatre modes différents :
• Do While...Loop. Tant que la condition est respectée, la boucle s’exécute.
Do While Condition
Série d’instructions
Loop

• Do Until...Loop. Jusqu’à ce que la condition soit réalisée, la boucle s’exécute.


Do Until Condition
Série d’instructions
Loop

• Do...Loop While. La boucle s’exécute, puis se répète, tant que la condition est respectée.
Do
Série d’instructions
Loop While Condition

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 180 02/05/13 13:11


Chapitre 7 Contrôler les programmes VBA 181

• Do...Loop Until. La boucle s’exécute, puis se répète, jusqu’à ce que la condition soit
respectée.
Do
Série d’instructions
Loop Until Condition

Le programme suivant utilise une boucle Do While...Loop pour supprimer les doublons dans
un classeur Excel. Les Figures 7.4 et 7.5 présentent un classeur contenant des doublons avant
et après passage de la macro. On estime, dans cette première version, qu’il existe un doublon
lorsque deux cellules de la colonne A contiennent les mêmes données. Le programme commence
par faire un tri des données. Le contenu de chaque cellule de la colonne A est ensuite comparé
à celui de la cellule suivante. S’ils sont identiques, la ligne de la cellule courante est supprimée.
1: Sub SuppressionDoublons()
2: Dim CelluleCourante As Range
3: Dim CelluleSuivante As Range
4: Set CelluleCourante = ActiveSheet.Range("A1")
5:
6: ’Tri des données sur la cellule A1
7: ActiveSheet.Range("A1").Sort key1:=Range("A1"), _
8: Order1:=xlAscending, Header:= xlGuess, OrderCustom:=1, _
9: MatchCase:=False, Orientation:=xlTopToBottom
10: ’Boucle
11: Do While Not IsEmpty(CelluleCourante) = True
12: Set CelluleSuivante = CelluleCourante.Offset(1, 0)
13: If CelluleSuivante.Value = CelluleCourante.Value Then
14: CelluleCourante.EntireRow.Delete
15: End If
16: Set CelluleCourante = CelluleSuivante
17: Loop
18: End Sub

Lignes 2 et 3 les variables objet de type Range CelluleCourante et CelluleSuivante sont déclarées.
La variable CelluleCourante reçoit ensuite un objet Range correspondant à la cellule A1 de la
feuille active. L’instruction des lignes 7 à 9 trie les données. On applique pour cela la méthode
Sort. Les arguments Key1 et Order1 définissent respectivement le premier critère de tri et l’ordre
de tri. Header indique s’il existe des lignes de tri et reçoit ici la constante xlGuess (Excel définit
s’il y a ou non une ligne de titre et, dans l’affirmative, de quelle ligne il s’agit). OrderCustom reçoit
la valeur 1 et le tri est donc "Normal". Enfin MatchCase et Orientation correspondent au respect
de la casse lors du tri et à son orientation (ici de haut en bas).
Lignes 11 à 17, une boucle Do While...Loop est utilisée pour tester toutes les cellules. La cellule
stockée dans CelluleCourante est testée, puis CelluleCourante reçoit la cellule stockée dans
CelluleSuivante, soit la cellule située immédiatement en dessous. La boucle s’exécute tant que
la cellule stockée dans CelluleCourante n’est pas vide [Not IsEmpty(CelluleCourante) = True].
Ligne 12, la propriété Offset est utilisée pour attribuer à CelluleSuivante la cellule située
une ligne en dessous, sur la même colonne. Lignes 13 à 15, une instruction conditionnelle sert
à supprimer la ligne de CelluleCourante (CelluleCourante.EntireRow) si la cellule contient les

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 181 02/05/13 13:11


182 Excel 2013 et VBA

mêmes données que la cellule suivante. CelluleCourante reçoit ensuite la cellule stockée dans
CelluleSuivante (ligne 16).
Ligne 17, l’instruction Loop renvoie le programme à l’instruction While correspondante.
L’expression While est de nouveau évaluée et le corps de la boucle s’exécute si elle est vérifiée.
Lorsque l’expression de la ligne 11 n’est plus vérifiée, le programme se poursuit avec l’ins-
truction située immédiatement sous l’instruction Loop. En l’occurrence, il prend fin.

Figure 7.4
La feuille avant passage de la macro.

Figure 7.5
La macro a supprimé les doublons.

Le programme fonctionne correctement, mais ne prend en compte que le contenu des cellules
de la colonne A pour déterminer les doublons. La procédure suivante supprime une ligne
uniquement si les données sont également identiques dans les colonnes B, C et D. Les modifi-
cations apportées à la première version apparaissent en gras.
1: Sub SuppressionDoublons()
2: Dim Cellulecourante As Range
3: Dim Cellulesuivante As Range
4: Set Cellulecourante = ActiveSheet.Range("A1")
5:

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 182 02/05/13 13:11


Chapitre 7 Contrôler les programmes VBA 183

6: ’Tri des données sur la cellule A1


7: ActiveSheet.Range("A1").Sort Key1:=Range("A1"), Order1:=xlAscending,
➥ Key2:=Range("B1"), _
8: Order2:=xlAscending, Key3:=Range("C1"), Order3:=xlAscending,
➥ Header:=xlGuess, _
9: OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
10: ’Boucle et test des cellules
11: Do While Not IsEmpty(Cellulecourante) = True
12: Set Cellulesuivante = Cellulecourante.Offset(1, 0)
13: If Cellulesuivante.Value = Cellulecourante.Value Then
14: If LignesIdentiques(Cellulecourante, Cellulesuivante) = True Then
15: Cellulecourante.EntireRow.Delete
16: End If
17: End If
18: Set Cellulecourante = Cellulesuivante
19: Loop
20: End Sub
21:
22: Function LignesIdentiques(CellCourante As Range, CellSuivante As Range) As
➥ Boolean
23: If CellCourante.Offset(0, 1).Value <> CellSuivante.Offset(0, 1).Value Then
24: LignesIdentiques = False
25: ElseIf CellCourante.Offset(0, 2).Value <> CellSuivante.Offset(0, 2).Value Then
26: LignesIdentiques = False
27: ElseIf CellCourante.Offset(0, 3).Value <> CellSuivante.Offset(0, 3).Value Then
28: LignesIdentiques = False
29: Else
30: LignesIdentiques = True
31: End If
32: End Function

Lignes 15, l’instruction conditionnelle définissant si la ligne est supprimée appelle la


fonction LignesIdentiques en lui passant les arguments CelluleCourante et CelluleSuivante.
La fonction Lignesidentiques est déclarée comme recevant deux arguments de type Range et
renvoyant une valeur de type Boolean (ligne 22).
Ligne 23 à 31, une structure conditionnelle sert à déterminer la valeur renvoyée par la fonction.
Le contenu des cellules décalées d’une, de deux, puis de trois cellules à droite de CelluleCourante
est successivement comparé au contenu des cellules décalées de la même façon par rapport à
CelluleSuivante [Offset(0, 1), Offset(0, 2) et Offset(0,3)]. Si ce contenu diffère, la valeur
False est affectée à la fonction (lignes 24, 26 et 28). Dans le cas contraire, la fonction renvoie
True (ligne 30). La procédure appelante reprend alors la main et l’instruction de la ligne 15 est
exécutée si la fonction a renvoyé True. Dans le cas contraire, la condition n’est pas vérifiée et la
cellule suivante est testée.

Pour interrompre une macro qui ne fonctionne pas correctement (qui exécute une
pel
Rap boucle sans fin, par exemple), appuyez sur Ctrl+Pause, puis voyez le Chapitre 10.

© 2013 Pearson France – Excel et VBA – Mikaël Bidault

2577-Excel_et_VBA.indb 183 02/05/13 13:11

Vous aimerez peut-être aussi