Écrire ses Propres Macros VBA
L’enregistreur de macros d’Excel est très puissant, mais il a ses limites. Comme nous l’avons vu dans un autre article, l’enregistreur de macros enregistre souvent du code inutile et ne peut pas enregistrer des éléments tels que la logique ou les interactions avec d’autres programmes. Il peut également s’avérer difficile à utiliser pour des macros plus longues – vous devrez peut-être faire un storyboard de vos actions au préalable pour éviter de faire des erreurs coûteuses.
Cet article a pour but de vous aider à commencer à coder des macros à partir de zéro en VBA. Vous découvrirez où sont stockées les macros, vous écrirez une macro de base et vous apprendrez les fondements de la programmation en VBA à l’aide de variables, de logique et de boucles.
Mise en route
VBA et l’Éditeur Visual Basic
VBA, ou « Visual Basic for Applications », est le langage dans lequel les macros sont écrites. Toutes les macros sont stockées sous forme de code VBA, qu’elles soient codées manuellement ou créées à l’aide de l’enregistreur de macros.
Vous pouvez accéder à tout le code VBA d’un classeur à l’aide de l’éditeur Visual Basic. Il s’agit d’un éditeur de texte spécial et d’un débogueur intégré à toutes les applications bureautiques, y compris Excel. En général, vous ouvrez cet éditeur à l’aide du raccourci clavier ALT+F11 dans Excel, mais vous pouvez également y accéder à partir de l’onglet Développeur d’Excel si celui-ci est activé.
L’explorateur de projet
L’Explorateur de Projets est une fenêtre de l’éditeur VB qui vous montre tous les éléments pouvant contenir du code VBA. Si vous ne voyez pas cette fenêtre, appuyez sur Ctrl+R pour la faire apparaître ou sélectionnez Explorateur de Projets dans le menu Affichage.
En double-cliquant sur un élément dans l’Explorateur de Projets, le code de cet élément s’affiche. Il y a plusieurs types d’éléments qui peuvent apparaître dans l’Explorateur de Projets :
- Classeurs
- Feuilles de calculs
- Formulaires Utilisateur
- Modules de Classe
- Modules (les macros sont stockées dans ces éléments)
Bien que tous ces types d’éléments puissent inclure du code VBA, la meilleure pratique consiste à coder les macros dans des modules.
Créer votre première macro
En Utilisant la Liste des Macros
La liste des macros affiche toutes les macros de votre classeur. À partir de cette liste, vous pouvez modifier une macro existante ou en créer une nouvelle. Pour créer une nouvelle macro à l’aide de la liste des macros :
- Sélectionnez l’onglet Développeur et cliquez sur Macros (ou appuyez sur ALT+F8)
- Saisissez un nouveau nom pour votre macro, puis cliquez sur « Créer »
Après avoir cliqué sur « Créer », l’éditeur VB apparaît, montrant la macro nouvellement créée. Excel créera un nouveau module pour la macro si nécessaire.
Manuellement dans l’Éditeur VB
Vous pouvez ajouter une nouvelle macro manuellement sans utiliser la liste des macros. C’est la meilleure option si vous souhaitez spécifier le module dans lequel la macro est enregistrée. Pour ajouter une macro manuellement :
- Ouvrez l’éditeur VB (ALT+F11)
- Soit :
- Ajoutez un nouveau module en cliquant sur Insertion > Module dans le menu (le module s’ouvre automatiquement)
-
- OU, double-cliquez sur un module existant dans l’explorateur de projet pour l’ouvrir
- Dans le module, saisissez le code de votre nouvelle macro
Sub MaMacro()
End Sub
Ces deux lignes indiquent le début et la fin d’une macro nommée « MaMacro » (notez les parenthèses, qui sont obligatoires). Elle apparaîtra dans la boîte de dialogue « Afficher les macros » d’Excel et pourra être affectée à un bouton (même si elle ne fait rien pour l’instant).
Ajoutez du code à la macro
Maintenant, ajoutons du code entre les lignes « Sub » et « End Sub » pour que cette macro fasse quelque chose :
Sub MaMacro()
Range("A1").Value = "Hello World !"
End Sub
Structures de Code de Base
L’Objet Range
Excel VBA utilise l’Objet Range pour représenter les cellules d’une feuille de calcul. Dans l’exemple ci-dessus, un objet Range est créé avec le code Range(« A1 ») afin d’accéder à la valeur de la cellule A1. Les Objects Range sont principalement utilisés pour définir les valeurs des cellules :
Range("A1").Value = 1
Range("A1").Value = "Première Cellule"
Notez que lorsque vous définissez des valeurs de cellule sous forme de nombres, il vous suffit de saisir le nombre, mais que lorsque vous saisissez du texte, vous devez l’entourer de guillemets.
Les Objets Range peuvent également être utilisées pour accéder à de nombreuses propriétés des cellules, telles que leur police, leurs bordures, leurs formules, etc. Par exemple, vous pouvez définir la police d’une cellule en Gras comme suit :
Range("A1").Font.Bold = True
Vous pouvez également définir la formule d’une cellule :
Range("A1").Formula = "=Sum(A2:A10)"
Dans Excel, vous pouvez sélectionner un bloc de cellules avec le curseur (par exemple, de A1 à D10) et toutes les mettre en gras. Les objets Range peuvent accéder à des blocs de cellules comme ceci :
Range("A1:D10").Font.Bold = True
Vous pouvez également faire référence à plusieurs cellules/blocs à la fois :
Range("A1:D10,A12:D12,G1").Font.Bold = True
Le format est le même que celui que vous utilisez pour sélectionner des cellules pour la formule SOMME() dans Excel. Chaque bloc est séparé par une virgule, et les blocs sont définis par la cellule en haut à gauche et celle en bas à droite, séparées par un deux-points.
Enfin, les objets Range disposent de méthodes intégrées permettant d’effectuer des opérations courantes sur une feuille de calcul. Par exemple, vous pouvez vouloir copier certaines données d’un endroit à un autre. Voici un exemple :
Range("A1:D10").Copy
Range("F1").PasteSpecial xlPasteValues
Range("F1").PasteSpecial xlPasteFormats
Cet exemple copie les cellules A1:D10 dans le presse-papiers, puis effectue un collage spécial ( PasteSpecial() ) à partir de la cellule C1, comme vous le feriez manuellement dans Excel. Notez que cet exemple montre comment utiliser PasteSpecial() pour coller uniquement les Valeurs et Formats – il existe des paramètres pour toutes les options que vous verriez dans la boîte de dialogue de collage spécial.
Voici un exemple de collage de « Tout » dans une feuille de calcul différente :
Range("A1:D10").Copy
Sheets("Feuille2").Range("A1").PasteSpecial xlPasteAll
Instructions If
Avec une instruction If, vous pouvez faire en sorte qu’une section de code ne soit exécutée que « si » une certaine instruction est vraie.
Par exemple, vous pouvez mettre une cellule en gras et la colorer en rouge, mais uniquement « si » la valeur de la cellule est inférieure à 100.
If Range("A4").Value < 100 Then
Range("A4").Font.Bold = True
Range("A4").Interior.Color = vbRed
End If
La structure correcte d’une instruction If est la suivante (les crochets indiquent les composants facultatifs) :
If <condition> Then
[ElseIf <autre condition> Then]
[Else]
End If
Vous pouvez inclure autant de blocs ElseIf que vous le souhaitez pour tester plusieurs conditions. Vous pouvez également ajouter un bloc Else qui ne s’exécute que si aucune des autres conditions de l’instruction If n’est remplie.
Voici un autre exemple basé sur le précédent, dans lequel la cellule est formatée de plusieurs manières différentes en fonction de la valeur :
If Range("A4").Value < 100 Then
Range("A4").Font.Bold = True
Range("A4").Interior.Color = vbRed
ElseIf Range("A4").Value < 200 Then
Range("A4").Font.Bold = False
Range("A4").Interior.Color = vbYellow
Else
Range("A4").Font.Bold = False
Range("A4").Interior.Color = vbGreen
End If
Dans l’exemple ci-dessus, le formatage en gras de la cellule est enlevé dans les blocs ElseIf lorsque la valeur n’est pas inférieure à 100. Vous pouvez imbriquer les instructions If pour éviter de dupliquer du code, comme ceci :
If Range("A4").Value < 100 Then
Range("A4").Font.Bold = True
Range("A4").Interior.Color = vbRed
Else
Range("A4").Font.Bold = False ' Enlève le formatage en gras de la police une seule fois
If Range("A4").Value < 200 Then
Range("A4").Interior.Color = vbYellow
Else
Range("A4").Interior.Color = vbGreen
End If
End If
Variables
Une variable est un morceau de mémoire utilisé pour stocker des informations temporaires pendant l’exécution d’une macro. Elles sont souvent utilisées dans les boucles comme itérateurs, ou pour contenir le résultat d’une opération que vous souhaitez utiliser plusieurs fois dans une macro.
Voici un exemple de variable et la façon dont vous pouvez l’utiliser :
Sub ExtraireNuméroSérie()
Dim strSérie As String 'C'est la déclaration de la variable
' "As String" signifie que cette variable est destinée à contenir du texte
' Mise en place d'un faux numéro de série :
Range("A4").Value = "Série# 804567-88"
' Extraire le numéro de série de la cellule A4 et l'affecter à la variable
strSérie = Mid(Range("A4").Value, 8)
'Maintenant, utilisez la variable deux fois, au lieu de devoir analyser deux fois le numéro de série
Range("B4").Value = strSérie
MsgBox strSérie
End Sub
Dans cet exemple de base, la variable ‘strSérie’ est utilisée pour extraire le numéro de série de la cellule A4 à l’aide de la fonction Mid(), puis est utilisée à deux autres endroits.
La manière standard de déclarer une variable est la suivante : Dim nomquelconque [As type]
- nomquelconque est le nom que vous décidez de donner à votre variable
- type est le type de donnée de la variable
La partie « [As type] » peut être omise. Dans ce cas, la variable est déclarée comme un type Variant, qui peut contenir n’importe quel type de données. Bien qu’ils soient parfaitement valables, les types Variant doivent être évités car ils peuvent conduire à des résultats inattendus si vous ne faites pas attention.
Il existe des règles pour nommer des variables. Elles doivent commencer par une lettre ou un caractère de soulignement ( « _ » ) et ne peuvent pas contenir d’espaces, de points, de virgules, de guillemets ou les caractères suivants : » ! @ & $ #”.
Voici quelques exemples de déclarations de variables :
Dim strNomFichier As String ' bon style de nom - descriptif et utilisant un préfixe
Dim i As Long ' mauvais style de nom - acceptable uniquement pour certains itérateurs
Dim PrixVente As Double ' style de nom correct - descriptif, mais n'utilise pas de préfixe
Dim iCompteur ' nom correct - pas trop descriptif, utilise un préfixe, pas de type de données
Tous ces exemples utilisent des schémas de dénomination légèrement différents, mais tous sont valables. Ce n’est pas une mauvaise idée de préfixer le nom d’une variable par une forme courte de son type de données (comme dans certains de ces exemples), car cela rend votre code plus lisible au premier coup d’œil.
VBA comprend un grand nombre de types de données de base. Les plus populaires sont les suivants :
- String (utilisé pour contenir des données textuelles)
- Long (utilisé pour contenir des nombres entiers, c’est-à-dire sans décimales)
- Double (utilisé pour contenir des nombres à virgule flottante, c’est-à-dire avec des décimales)
Vous trouverez une liste complète des types de données intrinsèques de VBA à l’adresse suivante : https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/data-type-summary
Variables de l’Objet Range
Il est également possible de créer des variables qui font référence à des Objets Range. Ceci est utile si vous souhaitez faire référence à une plage de cellules spécifique à plusieurs endroits dans votre code – de cette façon, si vous devez modifier la plage, vous ne devez le faire qu’à un seul endroit.
Lorsque vous créez une variable d’Objet Range, vous devez la définir en utilisant l’instruction « Set » sur une instance d’un « Range ». Par exemple :
Dim rMaPlage As Range
Set rMaPlage = Range("A1:A10;D1:J10")
L’omission de l’instruction « Set » lors de l’affectation d’une variable de plage entraînera une erreur.
Boucles
Les boucles sont des blocs qui répètent le code qu’ils contiennent un certain nombre de fois. Elles sont utiles pour réduire la quantité de code à écrire, et vous permettent d’écrire un morceau de code qui effectue les mêmes actions sur de nombreux éléments différents.
Boucle « For-Next »
Un bloc For-Next est une boucle qui se répète un certain nombre de fois. Il utilise une variable comme itérateur pour compter le nombre de fois qu’il doit être exécuté, et cette variable itérative peut être utilisée à l’intérieur de la boucle. Les boucles For-Next sont donc très utiles pour parcourir des cellules ou des tableaux.
Voici un exemple qui parcourt en boucle les cellules des lignes 1 à 100, colonne 1, et définit leurs valeurs en fonction de la valeur de la variable iteratrice :
Dim i As Long
For i = 1 To 100
Cells(i, 1).Value = i
Next i
La ligne « For i = 1 To 100 » signifie que la boucle commence à 1 et se termine lorsque la valeur de « i » atteint 100. Vous pouvez définir les nombres de début et de fin que vous souhaitez ; vous pouvez également utiliser des variables pour ces nombres.
Par défaut, les boucles For-Next comptent par 1. Si vous voulez incrémenter le compteur par un nombre différent, vous pouvez écrire la boucle avec une clause Step explicite :
For i = 5 To 100 Step 5
Cette boucle commence à 5, puis ajoute 5 à la valeur de ‘i’ chaque fois que la boucle se répète (ainsi ‘i’ sera 10 à la deuxième répétition, 15 à la troisième, et ainsi de suite).
En utilisant Step, vous pouvez également faire en sorte qu’une boucle compte à rebours :
For i = 100 To 1 Step -1
Vous pouvez également imbriquer des boucles For-Next. Chaque bloc nécessite sa propre variable pour compter, mais vous pouvez utiliser ces variables comme bon vous semble. Voici un exemple de l’utilité de cette méthode dans Excel VBA :
Dim i As Long, j As Long
For i = 1 To 100
For j = 1 To 100
Cells(i, j).Value = i * j
Next j
Next i
Cela vous permet de boucler à la fois sur les lignes et les colonnes.
ATTENTION: bien que cela soit autorisé, vous ne devez JAMAIS MODIFIER la variable itératrice à l’intérieur d’un bloc For-Next, car il utilise cet variable pour garder le compte de la boucle. La modification de l’itérateur peut provoquer une boucle infinie et bloquer votre macro. Par exemple :
For i = 1 To 100
i = 1
Next i
Dans cette boucle, ‘i’ ne dépassera jamais 2 avant d’être remis à 1, et la boucle se répétera indéfiniment.
Boucle « For-Each »
Les blocs For-Each sont très similaires aux blocs For-Next, sauf qu’ils n’utilisent pas de compteur pour spécifier le nombre d’exécutions de la boucle. Un bloc For-Each prend plutôt une « collection » d’objets (comme une plage de cellules) et s’exécute autant de fois qu’il y a d’objets dans cette collection.
Voici un exemple :
Dim r As Range
For Each r In Range("A15:J54")
If r.Value > 0 Then
r.Font.Bold = True
End If
Next r
Remarquez l’utilisation de la variable d’objet Range ‘r’. Il s’agit de la variable itérative utilisée dans la boucle For-Each : à chaque fois que la boucle est parcourue, ‘r’ reçoit une référence à la cellule suivante de la plage définie.
Un des avantages de l’utilisation des boucles For-Each dans Excel VBA est que vous pouvez parcourir toutes les cellules d’une plage sans imbriquer les boucles. Cela peut être pratique si vous devez parcourir toutes les cellules d’une plage complexe comme Range(« A1:D12,J13, M1:Y12 »).
Un inconvénient des boucles For-Each est que vous n’avez aucun contrôle sur l’ordre dans lequel les cellules sont traitées. Bien qu’en pratique, Excel parcourt les cellules dans l’ordre, en théorie, il pourrait traiter les cellules dans un ordre complètement aléatoire. Si vous devez traiter les cellules dans un ordre particulier, utilisez plutôt les boucles For-Next.
Boucle « Do-Loop »
Alors que les blocs For-Next utilisent des compteurs pour savoir quand s’arrêter, les blocs Do-Loop fonctionnent jusqu’à ce qu’une condition soit remplie. Pour ce faire, une clause Until est utilisée au début ou à la fin du bloc, qui teste la condition et provoque l’arrêt de la boucle lorsque cette condition est remplie.
Exemple :
Dim str As String
str = "Buffalo"
Do Until str = “Buffalo Buffalo Buffalo Buffalo Buffalo Buffalo Buffalo”
str = str & " " & "Buffalo"
Loop
Range("A1").Value = str
Dans cette boucle, « Buffalo » est concaténé à « str » à chaque fois que la boucle est parcourue jusqu’à ce qu’elle corresponde à la phrase attendue. Dans ce cas, le test est effectué au début de la boucle – si ‘str’ était déjà la phrase attendue (ce qui n’est pas le cas car sa valeur initiale n’a pas été définie ainsi, mais si elle l’avait été), la boucle ne serait pas exécutée.
Vous pouvez faire en sorte que la boucle s’exécute au moins une fois en déplaçant la clause Until à la fin, comme ceci :
Do
str = str & " " & "Buffalo"
Loop Until str = “Buffalo Buffalo Buffalo Buffalo Buffalo Buffalo Buffalo”
Vous pouvez utiliser la version qui convient le mieux à votre macro.
AVERTISSEMENT: vous pouvez provoquer une boucle infinie avec un bloc Do-Loop si la condition Until n’est jamais remplie. Rédigez toujours votre code de manière à ce que la condition Until soit remplie lorsque vous utilisez ce type de boucle.
Ensuite?
Une fois que vous avez maîtrisé les bases, pourquoi ne pas essayer d’apprendre des techniques plus avancées? Notre tutoriel sur https://www.automateexcel.com/excel/learn-vba-tutorial/ s’appuiera sur tout ce que vous avez appris ici et développera vos compétences avec les événements, les formulaires utilisateur, l’optimisation de code et bien plus encore!