Bureautique · Excel
Macros
& VBA
Enregistrer, écrire et déboguer des macros Excel — variables, boucles, objets Range/Sheet/Workbook, événements, UserForms et automatisations concrètes.
01 — Premiers pas
Qu'est-ce qu'une macro ?
ℹ️
Une macro est une séquence d'instructions enregistrées ou écrites en VBA (Visual Basic for Applications) qui automatisent des tâches répétitives dans Excel. Une macro peut en quelques secondes faire ce qui prendrait des heures manuellement.
| Cas d'usage typique | Exemple |
|---|---|
| Mise en forme automatique | Colorier en rouge toutes les cellules négatives |
| Traitement de données | Nettoyer 5 000 lignes importées d'un ERP |
| Génération de rapports | Créer un PDF récapitulatif mensuel automatiquement |
| Import/Export | Charger des CSV, les transformer, les consolider |
| Envoi automatique | Envoyer un rapport Outlook à une liste de contacts |
| Validation complexe | Vérifier la cohérence des données à la saisie |
| Interface utilisateur | Formulaire de saisie avec liste déroulante et contrôles |
⚠️
Format de fichier : un classeur contenant des macros doit être enregistré au format .xlsm (Excel avec macros activées), pas .xlsx (qui supprime les macros à la sauvegarde).
Activer l'onglet Développeur
' L'onglet Développeur est masqué par défaut.
Fichier → Options → Personnaliser le ruban
→ Cocher "Développeur" → OK
L'onglet Développeur contient :
Visual Basic → Ouvrir VBE (éditeur)
Macros → Gérer/exécuter les macros
Enregistrer → Démarrer l'enregistrement
Insérer → Boutons, cases à cocher…
Propriétés → Paramètres du contrôle actif
' Raccourcis clavier :
Alt+F8 → Liste des macros
Alt+F11 → Ouvrir VBE (éditeur VBA)
Alt+F4 → Fermer VBE
02
Enregistrer une macro
1
Développeur → Enregistrer une macro
Donner un nom (sans espaces), un raccourci optionnel, choisir où la stocker.
Donner un nom (sans espaces), un raccourci optionnel, choisir où la stocker.
2
Effectuer les actions à enregistrer
Cliquer, taper, formater… Excel traduit chaque action en code VBA.
Cliquer, taper, formater… Excel traduit chaque action en code VBA.
3
Développeur → Arrêter l'enregistrement
Ou cliquer sur le carré ■ dans la barre d'état.
Ou cliquer sur le carré ■ dans la barre d'état.
4
Alt+F8 → Exécuter
Ou utiliser le raccourci clavier défini à l'étape 1.
Ou utiliser le raccourci clavier défini à l'étape 1.
5
Alt+F11 → Modifier le code
Retoucher le VBA généré pour le rendre plus robuste.
Retoucher le VBA généré pour le rendre plus robuste.
| Emplacement | Portée |
|---|---|
| Ce classeur | Disponible uniquement dans ce fichier .xlsm |
| Nouveau classeur | Crée un nouveau fichier pour la macro |
| Classeur de macros perso. | PERSONAL.XLSB — disponible dans TOUS les classeurs Excel |
Code généré — exemple mise en forme
' Macro enregistrée — mise en forme d'un en-tête
Sub MiseEnForme_EnTete()
'
' Raccourci clavier : Ctrl+Shift+E
'
Range("A1:E1").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = -0.249946941783223
.PatternTintAndShade = 0
End With
With Selection.Font
.Bold = True
.Color = -16777216 ' ← code couleur RGB
End With
End Sub
' ⚠ Problèmes du code enregistré :
' - Utilise .Select partout (lent et fragile)
' - Valeurs magiques (ThemeColorAccent1, -0.249...)
' - Pas de commentaires clairs
' → Voir section "Objets Excel" pour la version propre
03
L'éditeur VBE
Projet
📁 VBAProject
Microsoft Excel
📄 ThisWorkbook
📄 Feuil1
📄 Feuil2
Modules
📝 Module1
📝 Module2
Formulaires
🪟 UserForm1
' Module1 — Macros générales
Option Explicit ' ← forcer la déclaration des variables
Sub MaPremiéreMacro()
Dim msg As String
msg = "Bonjour depuis VBA !"
MsgBox msg
End Sub
| Zone VBE | Rôle |
|---|---|
| Explorateur de projet | Arborescence du classeur : feuilles, modules, UserForms |
| Fenêtre de code | Écrire et modifier le code VBA |
| Fenêtre Exécution (Ctrl+G) | Tester des expressions : taper ?ActiveCell.Value |
| Fenêtre Espion | Surveiller la valeur d'une variable pendant l'exécution |
| Fenêtre Variables locales | Voir toutes les variables en mode débogage |
| Raccourci VBE | Action |
|---|---|
| F5 | Exécuter la macro |
| F8 | Pas à pas (ligne par ligne) |
| F9 | Poser/enlever un point d'arrêt |
| Ctrl+G | Fenêtre Exécution |
| Ctrl+Espace | Autocomplétion IntelliSense |
| Shift+F2 | Aller à la définition |
| Ctrl+Z | Annuler (dans l'éditeur) |
04 — Langage VBA
Variables & types
Déclaration et types de données
Option Explicit ' Toujours — interdit les variables non déclarées
Sub DémonstrationVariables()
' Types numériques
Dim i As Integer ' -32 768 à 32 767
Dim l As Long ' ±2 milliards — préférer Long à Integer
Dim d As Double ' décimal double précision
Dim c As Currency ' montants — 4 décimales fixes
' Texte
Dim nom As String
Dim code As String * 5 ' longueur fixe : 5 caractères
' Autres
Dim actif As Boolean ' True / False
Dim dt As Date
Dim obj As Object ' objet générique (liaison tardive)
Dim val As Variant ' n'importe quel type — flexible mais lent
' Affectation
nom = "Alice"
l = 100000
d = 3.14
dt = Date ' date du jour
actif = True
' Constantes
Const TVA As Double = 0.21
Const APPNAME As String = "MonApp"
End Sub
Tableaux & portée des variables
' Tableaux — taille fixe
Dim mois(1 To 12) As String
mois(1) = "Janvier"
mois(2) = "Février"
' Tableaux dynamiques
Dim données() As Double
ReDim données(1 To 100)
ReDim Preserve données(1 To 200) ' garder les valeurs
' Portée des variables
' Local (dans une Sub) :
Sub MaSub()
Dim x As Integer ' visible dans MaSub uniquement
End Sub
' Module (en haut du module, hors Sub) :
Dim compteur As Long ' visible dans tout le module
' Global (tous les modules) :
Public nomApp As String
' Conversion de types :
CStr(42) ' → "42"
CLng("100") ' → 100 (Long)
CDbl("3,14") ' → 3.14
CDate("01/03") ' → date
' Fonctions utiles :
IsNumeric("42") ' True
IsEmpty(val) ' True si Variant non initialisé
IsNull(val) ' True si Null
Len("Bonjour") ' 7
UCase("abc") ' "ABC"
05
Conditions — If / Select Case
If … ElseIf … Else
Sub Conditions()
Dim note As Integer
note = 14
' If simple
If note >= 10 Then
MsgBox "Réussi"
End If
' If/Else
If note >= 10 Then
MsgBox "Réussi"
Else
MsgBox "Échoué"
End If
' If/ElseIf/Else
Dim mention As String
If note >= 16 Then mention = "Distinction"
ElseIf note >= 14 Then mention = "Très bien"
ElseIf note >= 12 Then mention = "Bien"
ElseIf note >= 10 Then mention = "Suffisant"
Else mention = "Insuffisant"
End If
' Opérateurs logiques
If note >= 10 And note <= 20 Then ' ET
If note < 0 Or note > 20 Then ' OU
If Not (note >= 10) Then ' NON
End Sub
Select Case
Sub SelectCase()
Dim pays As String
pays = "BE"
' Select Case sur texte
Select Case pays
Case "BE"
MsgBox "Belgique"
Case "FR"
MsgBox "France"
Case "NL", "LU"
MsgBox "Pays-Bas ou Luxembourg"
Case Else
MsgBox "Autre pays"
End Select
' Select Case sur plages de nombres
Dim note As Integer
note = 14
Select Case note
Case Is >= 16
MsgBox "Distinction"
Case 14 To 15
MsgBox "Très bien"
Case 10 To 13
MsgBox "Bien ou Suffisant"
Case Else
MsgBox "Insuffisant"
End Select
End Sub
06
Boucles — For / Do / While
For Next & For Each
' For Next — compteur numérique
Dim i As Long
For i = 1 To 10
Cells(i, 1).Value = i * 2
Next i
' Décrémenter (Step négatif)
For i = 10 To 1 Step -1
' utile pour supprimer des lignes
If Cells(i, 1).Value = "" Then
Rows(i).Delete
End If
Next i
' For Each — itérer sur une collection
Dim cellule As Range
For Each cellule In Range("A1:A20")
If cellule.Value < 0 Then
cellule.Font.Color = vbRed
End If
Next cellule
' Sortie anticipée
For i = 1 To 1000
If Cells(i, 1).Value = "" Then Exit For
' traitement...
Next i
Do Loop & While
' Do While — vérifier avant
Dim i As Long
i = 1
Do While Cells(i, 1).Value <> ""
' traiter la ligne i
i = i + 1
Loop
' Do Until — jusqu'à ce que
i = 1
Do Until Cells(i, 1).Value = ""
i = i + 1
Loop
' Do Loop While — vérifier après (exécute au moins 1 fois)
Do
i = i + 1
Loop While i <= 100
' Astuce : trouver la dernière ligne non vide
Dim dernLigne As Long
dernLigne = Cells(Rows.Count, "A").End(xlUp).Row
' → Équivalent de Ctrl+↑ depuis A1048576
' Boucle sur toutes les lignes de données
For i = 2 To dernLigne ' 2 = skip l'en-tête
' traiter ligne i...
Next i
07
Sub & Function
Sub — procédures
' Sub = procédure — fait quelque chose, ne retourne rien
' Sub sans paramètre
Sub NettoyerFeuille()
ActiveSheet.Cells.ClearContents
End Sub
' Sub avec paramètres
Sub ColorierPlage(ByVal plage As Range, _
ByVal couleur As Long)
plage.Interior.Color = couleur
End Sub
' Appeler une Sub
NettoyerFeuille
ColorierPlage Range("A1:D10"), vbYellow
Call ColorierPlage(Range("A1"), vbRed)
' ByVal vs ByRef
Sub TestPassage(ByVal x As Integer)
x = 999 ' modifie une copie — original inchangé
End Sub
Sub TestPassage2(ByRef x As Integer)
x = 999 ' modifie l'original !
End Sub
' Paramètre optionnel
Sub Saluer(Optional nom As String = "monde")
MsgBox "Bonjour " & nom
End Sub
Function — fonctions personnalisées
' Function = retourne une valeur
' Utilisable dans les cellules Excel comme =MaFonction()
' Fonction simple
Function TTC(prixHT As Double, tva As Double) _
As Double
TTC = prixHT * (1 + tva)
End Function
' Dans une cellule : =TTC(B2;0,21)
' Retourner une chaîne
Function Mention(note As Integer) As String
Select Case note
Case Is >= 16 : Mention = "Distinction"
Case Is >= 14 : Mention = "Très bien"
Case Is >= 10 : Mention = "Suffisant"
Case Else : Mention = "Insuffisant"
End Select
End Function
' Fonction qui retourne une erreur si invalide
Function DivSafe(a As Double, b As Double) _
As Variant
If b = 0 Then
DivSafe = CVErr(xlErrDiv0) ' retourne #DIV/0!
Else
DivSafe = a / b
End If
End Function
08
Gestion des erreurs
On Error — stratégies
' On Error Resume Next — ignorer l'erreur (dangereux !)
On Error Resume Next
Dim ws As Worksheet
Set ws = Sheets("PeutÊtreInexistante")
On Error GoTo 0 ' ← toujours réactiver après
If ws Is Nothing Then
MsgBox "Feuille introuvable"
End If
' On Error GoTo Label — gestion structurée
Sub ImporterDonnées()
On Error GoTo GestionErreur
' Code principal
Dim val As Double
val = CDbl(ActiveCell.Value) ' peut échouer
MsgBox "Valeur : " & val
Exit Sub ' ← IMPORTANT : ne pas tomber dans GestionErreur
GestionErreur:
MsgBox "Erreur " & Err.Number & " : " & Err.Description
' Err.Clear → effacer l'erreur
' Resume Next → continuer à la ligne suivante
' Resume → réessayer la ligne en erreur
End Sub
Débogage
' Debug.Print — afficher dans la fenêtre Exécution
Dim i As Long
For i = 1 To 5
Debug.Print "Ligne " & i & " : " & Cells(i,1).Value
Next i
' → Ctrl+G pour voir la sortie
' Point d'arrêt (F9) :
' Cliquer dans la marge gauche du code
' Une ligne rouge apparaît
' F5 s'arrête sur cette ligne
' F8 pour avancer pas à pas
' Survoler une variable pour voir sa valeur
' Stop — point d'arrêt dans le code
For i = 1 To 100
If i = 50 Then Stop ' pause quand i=50
Cells(i, 1) = i
Next i
' Tester dans la fenêtre Exécution :
' ? ActiveCell.Value → affiche la valeur
' ? ActiveSheet.Name → nom de la feuille active
' ActiveCell.Value = 99 → modifier directement
09 — Objets Excel
Cellules & plages (Range)
Référencer et manipuler des cellules
' Référencer une cellule
Range("A1") ' par adresse
Range("A1:C10") ' plage
Range("A1:C10").Cells(2,3) ' cellule relative dans la plage
Cells(1, 1) ' Cells(ligne, colonne) — dynamique !
Cells(1, "A") ' colonne par lettre
ActiveCell ' cellule actuellement sélectionnée
' Lire et écrire
Dim val As Variant
val = Range("B2").Value ' lire
Range("B2").Value = 42 ' écrire
Range("C1").Formula = "=A1+B1" ' formule EN
Range("C1").FormulaLocal = "=A1+B1" ' formule FR
Range("C1").FormulaR1C1 = "=R1C1+R1C2"
' Navigation dynamique
Range("A1").Offset(1, 0) ' 1 ligne en dessous
Range("A1").Offset(0, 2) ' 2 colonnes à droite
Range("A1").Resize(10, 3) ' étendre à 10 lignes × 3 colonnes
Range("A1").End(xlDown) ' aller jusqu'en bas (Ctrl+↓)
Range("A1").CurrentRegion ' plage contiguë autour de A1
Mise en forme sans .Select
' ✅ Version propre — sans Select
With Range("A1:E1")
.Interior.Color = RGB(68, 114, 196) ' bleu
.Font.Color = vbWhite
.Font.Bold = True
.Font.Size = 11
.Borders.LineStyle = xlContinuous
.HorizontalAlignment = xlCenter
End With
' Taille de colonne
Columns("A").ColumnWidth = 20
Columns("A:D").AutoFit ' ajustement automatique
Rows(1).RowHeight = 30
' Copier / Coller
Range("A1:D10").Copy Range("F1") ' copier-coller direct
Range("A1:D10").Copy
Range("F1").PasteSpecial xlPasteValues ' valeurs seulement
Application.CutCopyMode = False ' effacer les fourmis
' Effacer
Range("A1:D10").ClearContents ' données seulement
Range("A1:D10").ClearFormats ' formats seulement
Range("A1:D10").Clear ' tout
10
Feuilles & classeurs
Worksheets — manipuler les feuilles
' Référencer une feuille
Sheets("Ventes") ' par nom
Sheets(1) ' par index (1 = première)
ActiveSheet ' feuille active
ThisWorkbook.Sheets("Ventes") ' dans ce classeur
' Accéder à une cellule d'une autre feuille
Sheets("Ventes").Range("A1").Value = 100
' Créer / supprimer
Sheets.Add After:=Sheets(Sheets.Count) ' à la fin
ActiveSheet.Name = "Rapport Mars"
Sheets("Brouillon").Delete ' sans confirmation :
Application.DisplayAlerts = False
Sheets("Brouillon").Delete
Application.DisplayAlerts = True
' Copier / déplacer
Sheets("Modèle").Copy After:=Sheets(Sheets.Count)
Sheets("Feuil1").Move Before:=Sheets(1)
' Masquer / afficher
Sheets("Data").Visible = xlSheetHidden
Sheets("Data").Visible = xlSheetVeryHidden ' non visible dans UI
Sheets("Data").Visible = xlSheetVisible
' Boucler sur toutes les feuilles
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Range("A1").Value = ws.Name
Next ws
Workbooks — classeurs
' Ouvrir un classeur
Dim wb As Workbook
Set wb = Workbooks.Open("C:\data\rapport.xlsx")
Set wb = Workbooks.Open(Application.GetOpenFilename())
' Créer un nouveau classeur
Set wb = Workbooks.Add
' Sauvegarder
ThisWorkbook.Save
ThisWorkbook.SaveAs "C:\exports\rapport.xlsx", xlOpenXMLWorkbook
wb.SaveAs Filename:="export.xlsx", _
FileFormat:=xlOpenXMLWorkbook
' Sauvegarder en PDF
ThisWorkbook.Sheets("Rapport").ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:="C:\rapport.pdf", _
Quality:=xlQualityStandard
' Fermer
wb.Close SaveChanges:=True
wb.Close SaveChanges:=False
' Boucler sur tous les classeurs ouverts
Dim w As Workbook
For Each w In Application.Workbooks
Debug.Print w.Name
Next w
11
Tableaux structurés & TCD
ListObjects — tableaux structurés
' Référencer un tableau structuré
Dim tbl As ListObject
Set tbl = Sheets("Données").ListObjects("TabVentes")
' Propriétés utiles
tbl.Name ' nom du tableau
tbl.DataBodyRange ' données sans en-tête
tbl.HeaderRowRange ' ligne d'en-tête
tbl.ListRows.Count ' nombre de lignes
tbl.ListColumns.Count ' nombre de colonnes
tbl.ListColumns("CA").DataBodyRange ' colonne "CA"
' Ajouter une ligne
Dim newRow As ListRow
Set newRow = tbl.ListRows.Add
newRow.Range(1) = Date
newRow.Range(2) = "Dupont"
newRow.Range(3) = 1500
' Supprimer des lignes avec critère
Dim i As Long
For i = tbl.ListRows.Count To 1 Step -1
If tbl.ListRows(i).Range(3).Value < 100 Then
tbl.ListRows(i).Delete
End If
Next i
' Trier le tableau
tbl.Sort.SortFields.Clear
tbl.Sort.SortFields.Add Key:=tbl.ListColumns("CA").DataBodyRange, _
SortOn:=xlSortOnValues, Order:=xlDescending
tbl.Sort.Apply
Actualiser les TCD
' Actualiser un TCD spécifique
Dim tcd As PivotTable
Set tcd = Sheets("Dashboard").PivotTables("TCD_Ventes")
tcd.RefreshTable
' Actualiser tous les TCD du classeur
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Dim pt As PivotTable
For Each pt In ws.PivotTables
pt.RefreshTable
Next pt
Next ws
' Filtrer un TCD par code VBA
Dim champ As PivotField
Set champ = tcd.PivotFields("Région")
champ.ClearAllFilters
champ.CurrentPage = "Nord"
' Modifier la plage source d'un TCD
tcd.ChangePivotCache _
ThisWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=Sheets("Données").ListObjects("TabVentes"))
12
Événements
Événements de feuille (dans Feuil1)
' Double-clic dans le module de la feuille (pas un Module)
' Déclenché quand une cellule change
Private Sub Worksheet_Change(ByVal Target As Range)
' Target = la cellule (ou plage) qui a changé
If Not Intersect(Target, Range("B:B")) Is Nothing Then
' Quelque chose a changé en colonne B
If Target.Value < 0 Then
Target.Font.Color = vbRed
Else
Target.Font.ColorIndex = xlAutomatic
End If
End If
End Sub
' Déclenché avant modification
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' Surligher la ligne et colonne de la sélection
Cells.Interior.ColorIndex = xlNone
With Target
.EntireRow.Interior.Color = RGB(255,255,200)
.EntireColumn.Interior.Color = RGB(200,255,255)
End With
End Sub
' Double-clic
Private Sub Worksheet_BeforeDoubleClick( _
ByVal Target As Range, Cancel As Boolean)
Cancel = True ' annule le comportement par défaut
MsgBox "Double-clic sur " & Target.Address
End Sub
Événements du classeur (dans ThisWorkbook)
' À l'ouverture du classeur
Private Sub Workbook_Open()
' Actualiser tous les TCD
ThisWorkbook.RefreshAll
' Aller sur le dashboard
Sheets("Dashboard").Activate
MsgBox "Bienvenue — données actualisées"
End Sub
' Avant la sauvegarde
Private Sub Workbook_BeforeSave( _
ByVal SaveAsUI As Boolean, Cancel As Boolean)
' Horodater la dernière sauvegarde
Sheets("Info").Range("A1") = "Sauvegardé : " & Now
End Sub
' Avant la fermeture
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If MsgBox("Sauvegarder avant de fermer ?", _
vbYesNo) = vbYes Then
ThisWorkbook.Save
End If
End Sub
' Changement de feuille active
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name = "Dashboard" Then
Sh.PivotTables(1).RefreshTable
End If
End Sub
13 — Boîtes de dialogue
MsgBox & InputBox
MsgBox — afficher des messages
' Affichage simple
MsgBox "Traitement terminé !"
' Avec titre et icône
MsgBox "Opération réussie", vbInformation, "Succès"
MsgBox "Fichier introuvable", vbCritical, "Erreur"
MsgBox "Voulez-vous continuer ?", vbQuestion, "Attention"
' Boutons disponibles :
vbOKOnly ' OK seul (défaut)
vbOKCancel ' OK + Annuler
vbYesNo ' Oui + Non
vbYesNoCancel ' Oui + Non + Annuler
vbRetryCancel ' Réessayer + Annuler
' Récupérer le choix
Dim réponse As Integer
réponse = MsgBox("Supprimer les données ?", _
vbYesNo + vbCritical, "Confirmation")
If réponse = vbYes Then
Range("A2:Z1000").ClearContents
ElseIf réponse = vbNo Then
MsgBox "Annulé."
End If
InputBox — saisie utilisateur
' InputBox VBA — retourne une chaîne ou "" si Annuler
Dim saisie As String
saisie = InputBox("Entrez votre nom :", _
"Identification", _
"Alice") ' valeur par défaut
If saisie = "" Then
MsgBox "Annulé" : Exit Sub
End If
' Application.InputBox — plus puissant (type strict)
Dim nb As Double
nb = Application.InputBox( _
"Entrez un nombre :", Type:=1) ' Type=1 = nombre
' Types Application.InputBox :
' 0 = formule 1 = nombre 2 = texte
' 4 = booléen 8 = plage 16= erreur
' Sélectionner une plage
Dim plage As Range
On Error Resume Next
Set plage = Application.InputBox( _
"Sélectionnez la plage de données :", _
Type:=8)
On Error GoTo 0
If plage Is Nothing Then Exit Sub
MsgBox plage.Address
14
UserForm — formulaires personnalisés
Créer et utiliser un UserForm
' VBE → Insertion → UserForm
' Ajouter des contrôles depuis la Boîte à outils :
' TextBox, Label, ComboBox, ListBox,
' CommandButton, CheckBox, OptionButton…
' Dans le code du UserForm (double-clic sur bouton) :
' Initialiser la liste déroulante à l'ouverture
Private Sub UserForm_Initialize()
' Remplir un ComboBox
With ComboBox1
.AddItem "Nord"
.AddItem "Sud"
.AddItem "Est"
.AddItem "Ouest"
.Value = "Nord" ' valeur par défaut
End With
' Focus sur le premier champ
TextBox1.SetFocus
End Sub
' Clic sur le bouton "Valider"
Private Sub btnValider_Click()
' Lire les valeurs
Dim nom As String
Dim région As String
Dim montant As Double
nom = TextBox1.Value
région = ComboBox1.Value
montant = CDbl(TextBox2.Value)
' Écrire dans le tableau
Dim tbl As ListObject
Set tbl = Sheets("Données").ListObjects("TabVentes")
Dim r As ListRow
Set r = tbl.ListRows.Add
r.Range(1) = Date
r.Range(2) = nom
r.Range(3) = région
r.Range(4) = montant
MsgBox "Ligne ajoutée !", vbInformation
Unload Me ' fermer le formulaire
End Sub
Ouvrir un UserForm & validation
' Depuis une autre Sub, ouvrir le formulaire
Sub OuvrirFormulaire()
UserForm1.Show ' modal (bloque Excel)
UserForm1.Show vbModeless ' non modal
End Sub
' Validation des champs
Private Sub btnValider_Click()
' Vérifier que les champs sont remplis
If Trim(TextBox1.Value) = "" Then
MsgBox "Le nom est obligatoire", vbExclamation
TextBox1.SetFocus
Exit Sub
End If
If Not IsNumeric(TextBox2.Value) Then
MsgBox "Montant invalide", vbCritical
TextBox2.SetFocus
Exit Sub
End If
' … enregistrer
End Sub
' Bouton Annuler
Private Sub btnAnnuler_Click()
Unload Me
End Sub
' Touche Entrée = valider
' Propriété du formulaire → EnterKeyBehavior = True sur le bouton
' Ou: KeyDown event sur les TextBox
15 — Cas pratiques
Générer un rapport automatiquement
Macro complète — rapport mensuel PDF
Sub GénérerRapportMensuel()
Dim wsDonnées As Worksheet
Dim wsRapport As Worksheet
Dim mois As String
Dim cheminPDF As String
Application.ScreenUpdating = False ' désactiver le rafraîchissement écran → accélère
Application.Calculation = xlCalculationManual ' désactiver le calcul auto pendant la macro
' 1. Référencer les feuilles
Set wsDonnées = ThisWorkbook.Sheets("Données")
Set wsRapport = ThisWorkbook.Sheets("Rapport")
' 2. Déterminer le mois courant
mois = Format(Date, "yyyy-mm")
' 3. Actualiser les TCD
Dim tcd As PivotTable
For Each tcd In wsDonnées.PivotTables
tcd.RefreshTable
Next tcd
' 4. Mettre à jour le titre du rapport
wsRapport.Range("B2").Value = "Rapport des ventes — " & Format(Date, "mmmm yyyy")
' 5. Calculer les KPI
Dim tbl As ListObject
Set tbl = wsDonnées.ListObjects("TabVentes")
wsRapport.Range("D5").Value = Application.WorksheetFunction.Sum( _
tbl.ListColumns("CA").DataBodyRange)
wsRapport.Range("D6").Value = Application.WorksheetFunction.Count( _
tbl.ListColumns("CA").DataBodyRange)
wsRapport.Range("D7").Value = wsRapport.Range("D5") / wsRapport.Range("D6")
' 6. Exporter en PDF
cheminPDF = Environ("USERPROFILE") & "\Desktop\Rapport_" & mois & ".pdf"
wsRapport.ExportAsFixedFormat Type:=xlTypePDF, Filename:=cheminPDF
' 7. Réactiver
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
MsgBox "Rapport généré : " & cheminPDF, vbInformation
End Sub
16
Importer & nettoyer des données
Macro — importer un CSV et nettoyer
Sub ImporterEtNettoyer()
Dim chemin As String
Dim wbSource As Workbook
Dim wsDest As Worksheet
Dim dernLigne As Long
Dim i As Long
' 1. Choisir le fichier
chemin = Application.GetOpenFilename("CSV,*.csv,Excel,*.xlsx", , "Sélectionner le fichier")
If chemin = "Faux" Then Exit Sub ' Annuler
Application.ScreenUpdating = False
' 2. Ouvrir le fichier source
Set wbSource = Workbooks.Open(chemin)
Set wsDest = ThisWorkbook.Sheets("Import")
' 3. Copier les données
wbSource.Sheets(1).UsedRange.Copy
wsDest.Range("A1").PasteSpecial xlPasteValues
Application.CutCopyMode = False
wbSource.Close False
' 4. Nettoyer les données importées
dernLigne = wsDest.Cells(Rows.Count, "A").End(xlUp).Row
' Supprimer les lignes vides (en remontant !)
For i = dernLigne To 2 Step -1
If Application.WorksheetFunction.CountA(wsDest.Rows(i)) = 0 Then
wsDest.Rows(i).Delete
End If
Next i
' Supprimer espaces et harmoniser la casse
Dim cellule As Range
For Each cellule In wsDest.Range("B2:B" & dernLigne)
If cellule.Value <> "" Then
cellule.Value = Application.WorksheetFunction.Trim( _
StrConv(cellule.Value, vbProperCase))
End If
Next cellule
' 5. Convertir en tableau structuré
dernLigne = wsDest.Cells(Rows.Count, "A").End(xlUp).Row
wsDest.ListObjects.Add(xlSrcRange, wsDest.Range("A1:E" & dernLigne), , xlYes).Name = "TabImport"
Application.ScreenUpdating = True
MsgBox dernLigne - 1 & " lignes importées et nettoyées.", vbInformation
End Sub
17
Envoyer un e-mail via Outlook
Macro — envoyer le rapport par e-mail
' Référence requise : Outils → Références → Microsoft Outlook XX.X Object Library
Sub EnvoyerRapportEmail()
Dim olApp As Object ' Outlook.Application (liaison tardive)
Dim olMail As Object ' Outlook.MailItem
Dim pdfPath As String
' 1. Générer le PDF
pdfPath = Environ("TEMP") & "\rapport_temp.pdf"
ThisWorkbook.Sheets("Rapport").ExportAsFixedFormat _
Type:=xlTypePDF, Filename:=pdfPath
' 2. Créer l'objet Outlook (liaison tardive — fonctionne sans référence)
Set olApp = CreateObject("Outlook.Application")
Set olMail = olApp.CreateItem(0) ' 0 = olMailItem
' 3. Configurer l'e-mail
With olMail
.To = "direction@entreprise.com"
.CC = "comptabilite@entreprise.com"
.Subject = "Rapport mensuel — " & Format(Date, "mmmm yyyy")
.Body = "Bonjour," & vbCrLf & vbCrLf & _
"Veuillez trouver en pièce jointe le rapport des ventes du mois." & vbCrLf & _
"Cordialement,"
.Attachments.Add pdfPath
' .Send → envoyer directement
.Display ' → ouvrir pour révision avant envoi
End With
' 4. Libérer les objets
Set olMail = Nothing
Set olApp = Nothing
End Sub
18 — Référence
Cheat sheet VBA
Structure du code
| Option Explicit | Toujours — forcer les déclarations |
| Sub / End Sub | Procédure sans retour |
| Function … As Type | Retourne une valeur |
| With … End With | Agir sur un objet sans répéter |
| On Error GoTo | Gestion d'erreurs structurée |
| Debug.Print | Trace dans la fenêtre Exécution |
Objets clés
| Range("A1") | Cellule ou plage |
| Cells(l, c) | Cellule dynamique |
| Sheets("Nom") | Feuille par nom |
| ThisWorkbook | Le classeur contenant la macro |
| .End(xlDown) | Fin de plage (Ctrl+↓) |
| .Offset(l, c) | Décalage relatif |
Performance
| ScreenUpdating = False | Désactiver le rafraîchissement |
| Calculation = Manual | Désactiver le calcul auto |
| Éviter .Select | Agir directement sur l'objet |
| For i → To dernLigne | Ne pas boucler sur tout |
| Step -1 | Supprimer des lignes en remontant |
Raccourcis VBE
| Alt+F11 | Ouvrir / fermer VBE |
| F5 | Exécuter la macro |
| F8 | Pas à pas |
| F9 | Point d'arrêt |
| Ctrl+G | Fenêtre Exécution |
| Ctrl+Espace | Autocomplétion |