Ressources Excel VBA

Choisissez le niveau qui vous intéresse et parcourez les différentes parties du cours.

Sélectionnez une partie du cours pour commencer

1. Théorie - Introduction à VBA et Macros

Qu'est-ce que VBA ?

  • VBA (Visual Basic for Applications) : Langage de programmation intégré à Microsoft Office, utilisé pour automatiser des tâches répétitives dans Excel.
  • Rôle dans Excel : Automatiser la mise en forme, les calculs, la gestion de données, ou encore créer des interfaces personnalisées.
  • Exemples d'utilisation : Formater des tableaux, générer des rapports, valider des données.

Macros

  • Définition : Une macro est une série d'instructions enregistrées ou écrites en VBA pour exécuter des tâches automatiquement.
  • Enregistrement : Excel peut enregistrer les actions de l'utilisateur (par exemple, mise en forme, saisie de données) pour créer une macro.
  • Exécution : Les macros peuvent être lancées via l'onglet Développeur ou des raccourcis clavier.

Éditeur VBA

  • Accès : Appuyez sur Alt+F11 (sous Windows) pour ouvrir l'éditeur VBA.
  • Composants :
    • Explorateur de projets : Liste des classeurs et modules.
    • Fenêtre de code : Où les macros sont écrites ou modifiées.
    • Fenêtre des propriétés : Pour gérer les noms des objets (et certaines propriétés).
  • Modules : Conteneurs pour le code VBA (Insérer > Module dans l'éditeur).

Sécurité

  • Macros et sécurité : Les macros peuvent contenir du code malveillant, donc activer les macros uniquement pour des fichiers de confiance.
  • Format de fichier : Enregistrer les classeurs avec macros au format .xlsm.
  • Paramètres : Activer les macros via Fichier > Options > Centre de gestion de la confidentialité > Paramètres des macros > Activer toutes les macros (pour les tests, avec prudence).

Bonnes pratiques

  • Toujours sauvegarder une copie du fichier avant de tester une macro.
  • Nommer les macros de manière descriptive (par exemple, FormaterTableau au lieu de Macro1).
  • Tester les macros sur des données fictives pour éviter les pertes de données.

2. Démonstrations avec un exemple

Enregistrer une Macro pour Formater une Liste de Livres

Étapes :

  1. Ouvrez un nouveau classeur Excel et sauvegardez-le sous Librairie.xlsm.
  2. Dans la feuille "Feuil1", entrez les en-têtes suivants dans A1:C1 :
    • A1 : ID
    • B1 : Titre
    • C1 : Prix
  3. Entrez des données fictives dans A2:C3 :
    • A2:C2 : 1, "Le Petit Prince", 12.99
    • A3:C3 : 2, "1984", 15.99
  4. Enregistrez une macro :
    • Allez dans Développeur > Enregistrer une macro.
    • Nommez la macro FormaterListeLivres.
    • Effectuez les actions suivantes :
      • Sélectionnez A1:C3.
      • Appliquez une mise en forme en gras pour A1:C1.
      • Ajoutez des bordures à la plage A1:C3.
      • Appliquez une couleur de fond jaune à A1:C1.
    • Cliquez sur Arrêter l'enregistrement.
  5. Testez la macro :
    • Allez dans Développeur > Macros > FormaterListeLivres > Exécuter.
    • Vérifiez que la mise en forme est appliquée.
  6. 📸 Résultat attendu :

    Résultat de l'exemple

1. Théorie - Bases de la Programmation VBA

Variables

  • Définition : Une variable est un espace mémoire nommé pour stocker des données (nombres, texte, etc.).
  • Déclaration : Utiliser Dim pour déclarer une variable (par exemple, Dim compteur As Integer).
  • Types de données courants :
    • Integer : Nombre entier (par exemple, 1, 10, -5).
    • Double : Nombre décimal (par exemple, 12.99).
    • String : Texte (par exemple, "Le Petit Prince").
    • Boolean : Vrai ou Faux (par exemple, True, False).
  • Bonnes pratiques :
    • Toujours déclarer les variables avant utilisation
    • Utiliser des noms parlants (par exemple, prixLivre au lieu de x).

Boucles

  • Rôle : Permettre l'exécution répétée d'instructions.
  • Types de boucles :
    • For...Next : Répéter un nombre fixe de fois (par exemple, pour parcourir des lignes).
    • Do...Loop : Répéter jusqu'à ce qu'une condition soit remplie.
  • Syntaxe :
📷 Syntaxe des boucles :

For i = 1 To 5
    ' Instructions
Next i

Do While condition
    ' Instructions
Loop

For i = 1 To 5
' Instructions
Next i

Do While condition
' Instructions
Loop

Instructions de base

  • MsgBox : Affiche une boîte de dialogue avec un message (par exemple, MsgBox "Tâche terminée").
  • Range : Manipule les cellules (par exemple, Range("A1").Value = "Texte").
  • Cells : Accède aux cellules par leurs coordonnées (par exemple, Cells(1, 1).Value pour A1).
  • Concaténation : Combiner du texte et des variables avec & (par exemple, "Livre " & i).

Bonnes pratiques

  • Ajouter Option Explicit en haut du module pour forcer la déclaration des variables.
  • Éviter d'utiliser .Select ou .Activate (privilégier Range ou Cells directement).
  • Tester les macros sur des données fictives pour anticiper et éviter les erreurs.
  • Documenter le code avec des commentaires (') pour expliquer chaque étape.

2. Démonstrations avec des exemples

Exemple 1 : Ajouter des Titres de Livres avec une Boucle

Étapes :

  1. Créez un nouveau classeur Excel et sauvegardez-le sous Librairie_Leçon2.xlsm.
  2. Ouvrez l'éditeur VBA (Alt+F11), insérez un nouveau module (Insérer > Module).
  3. Écrivez et exécutez le code suivant :
📷 Code VBA :

Option Explicit

Sub AjouterTitresLivres()
    Dim i As Integer
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Feuil1")

    ' Ajouter des titres dans A1:A5
    For i = 1 To 5
        ws.Range("A" & i).Value = "Livre " & i
    Next i

    MsgBox "Titres ajoutés dans A1:A5"
End Sub

Option Explicit

Sub AjouterTitresLivres()
Dim i As Integer
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Feuil1")

' Ajouter des titres dans A1:A5
For i = 1 To 5
ws.Range("A" & i).Value = "Livre " & i
Next i

MsgBox "Titres ajoutés dans A1:A5"
End Sub

Vérifiez que :

  • Les cellules A1:A5 contiennent "Livre 1", "Livre 2", ..., "Livre 5".
  • Un message s'affiche à la fin.

📸 Résultat attendu :

Résultat de l'exemple

Exemple 2 : Ajouter des Prix avec une Boucle Do...Loop

📷 Code VBA :

Option Explicit

Sub AjouterPrixLivres()
    Dim i As Integer
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Feuil1")

    i = 1
    Do While i <= 5
        ws.Range("B" & i).Value = 10 + i * 2.5 ' Prix : 12.5, 15.0, 17.5, ...
        i = i + 1
    Loop

    MsgBox "Prix ajoutés dans B1:B5"
End Sub

Option Explicit

Sub AjouterPrixLivres()
Dim i As Integer
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Feuil1")

i = 1
Do While i <= 5 ws.Range("B" & i).Value = 10 + i * 2.5 ' Prix : 12.5, 15.0, 17.5, ... i = i + 1 Loop MsgBox "Prix ajoutés dans B1:B5" End Sub

Vérifiez que :

  • Les cellules B1:B5 contiennent 12.5, 15.0, 17.5, 20.0, 22.5.
  • Un message s'affiche à la fin.

📸 Résultat attendu :

Résultat de l'exemple

1. Théorie - Manipulation des Feuilles et Cellules

Objets Excel

  • Workbook : Représente un classeur Excel (par exemple, ThisWorkbook pour le classeur actif).
  • Worksheet : Représente une feuille de calcul (par exemple, ThisWorkbook.Sheets("Feuil1")).
  • Range : Représente une plage de cellules (par exemple, Range("A1:B10") ou Cells(1, 1)).

Propriétés

  • .Value : Lit ou définit la valeur d'une cellule (par exemple, Range("A1").Value = "Texte").
  • .Font.Bold : Met le texte en gras (par exemple, Range("A1").Font.Bold = True).
  • .Interior.Color : Définit la couleur de fond (par exemple, Range("A1").Interior.Color = vbYellow).
  • .Name : Nom de la feuille (par exemple, Sheets("Feuil1").Name = "Livres").

Méthodes

  • .Select : Sélectionne une plage (à éviter si possible pour des performances optimales).
  • .Copy : Copie une plage (par exemple, Range("A1:A10").Copy).
  • .ClearContents : Supprime le contenu d'une plage (par exemple, Range("A1:A10").ClearContents).
  • .Add : Ajoute une nouvelle feuille (par exemple, ThisWorkbook.Sheets.Add).

Accès Dynamique

  • Cells : Accède à une cellule via ses coordonnées (ligne, colonne), par exemple, Cells(1, 2) pour B1.
  • Rows.Count : Nombre total de lignes dans une feuille (par exemple, Sheets("Feuil1").Rows.Count).
  • End(xlUp) : Trouve la dernière ligne non vide (par exemple, Cells(Rows.Count, 1).End(xlUp).Row).

Bonnes pratiques

  • Utiliser Cells au lieu de Range pour les boucles dynamiques.
  • Éviter .Select ou .Activate pour améliorer les performances.
  • Toujours déclarer les variables avec Option Explicit.
  • Tester les macros sur des copies de fichiers pour éviter les pertes de données.

2. Démonstrations avec des exemples

Exemple 1 : Créer une Feuille et Ajouter des En-têtes

📷 Code VBA :

Option Explicit

Sub CreerFeuilleLivres()
    Dim ws As Worksheet

    ' Créer une nouvelle feuille ou utiliser une existante
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets("Livres")
    If ws Is Nothing Then
        Set ws = ThisWorkbook.Sheets.Add
        ws.Name = "Livres"
    End If
    On Error GoTo 0

    ' Ajouter les en-têtes
    ws.Range("A1:D1").Value = Array("ID", "Titre", "Auteur", "Prix")
    ws.Range("A1:D1").Font.Bold = True
    ws.Range("A1:D1").Interior.Color = vbCyan

    MsgBox "Feuille Livres créée avec les en-têtes"
End Sub

Option Explicit

Sub CreerFeuilleLivres()
Dim ws As Worksheet

' Créer une nouvelle feuille ou utiliser une existante
On Error Resume Next
Set ws = ThisWorkbook.Sheets("Livres")
If ws Is Nothing Then
Set ws = ThisWorkbook.Sheets.Add
ws.Name = "Livres"
End If
On Error GoTo 0

' Ajouter les en-têtes
ws.Range("A1:D1").Value = Array("ID", "Titre", "Auteur", "Prix")
ws.Range("A1:D1").Font.Bold = True
ws.Range("A1:D1").Interior.Color = vbCyan

MsgBox "Feuille Livres créée avec les en-têtes"
End Sub

📸 Résultat attendu :

Résultat de l'exemple

Exemple 2 : Ajouter des Données avec Cells

📷 Code VBA :

Option Explicit

Sub AjouterDonneesLivres()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Livres")

    ' Ajouter des données
    ws.Cells(2, 1).Value = 1
    ws.Cells(2, 2).Value = "Le Petit Prince"
    ws.Cells(2, 3).Value = "Antoine de Saint-Exupéry"
    ws.Cells(2, 4).Value = 12.99

    ws.Cells(3, 1).Value = 2
    ws.Cells(3, 2).Value = "1984"
    ws.Cells(3, 3).Value = "George Orwell"
    ws.Cells(3, 4).Value = 15.99

    ' Mettre en forme
    ws.Range("A2:D3").Borders.LineStyle = xlContinuous
    ws.Range("A2:D3").HorizontalAlignment = xlCenter

    MsgBox "Données des livres ajoutées"
End Sub

Option Explicit

Sub AjouterDonneesLivres()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Livres")

' Ajouter des données
ws.Cells(2, 1).Value = 1
ws.Cells(2, 2).Value = "Le Petit Prince"
ws.Cells(2, 3).Value = "Antoine de Saint-Exupéry"
ws.Cells(2, 4).Value = 12.99

ws.Cells(3, 1).Value = 2
ws.Cells(3, 2).Value = "1984"
ws.Cells(3, 3).Value = "George Orwell"
ws.Cells(3, 4).Value = 15.99

' Mettre en forme
ws.Range("A2:D3").Borders.LineStyle = xlContinuous
ws.Range("A2:D3").HorizontalAlignment = xlCenter

MsgBox "Données des livres ajoutées"
End Sub

📸 Résultat attendu :

Résultat de l'exemple

1. Théorie - Conditions et Gestion des Erreurs

Structures Conditionnelles

  • Rôle : Permettre au code de prendre des décisions en fonction de conditions.

Il existe plusieurs structures conditionnelles

  • If...Then...Else :
    • Syntaxe :
📷 Syntaxe If...Then...Else :

If condition Then
    ' Instructions si vrai
Else
    ' Instructions si faux
End If

If condition Then
' Instructions si vrai
Else
' Instructions si faux
End If
  • Exemple d'utilisation: Vérifier si un prix est supérieur à 10.
  • Select Case :
    • Syntaxe :
📷 Syntaxe Select Case :

Select Case variable
    Case valeur1
        ' Instructions
    Case valeur2
        ' Instructions
    Case Else
        ' Instructions par défaut
End Select

Select Case variable
Case valeur1
' Instructions
Case valeur2
' Instructions
Case Else
' Instructions par défaut
End Select
  • Exemple d'utilisation : Attribuer une catégorie de prix (bas, moyen, élevé).
  • Conditions combinées : Vous pouvez utiliser les opérateurs And, Or, Not pour des conditions complexes (par exemple, If prix > 10 And disponible = True Then...).

Gestion des Erreurs

  • Rôle : Anticiper et gérer les erreurs pour éviter que la macro ne s'arrête brutalement.
  • On Error Resume Next : Ignore les erreurs et continue l'exécution.
    • Exemple : Tenter de lire une cellule qui pourrait être vide.
  • On Error GoTo : Redirige l'exécution vers une étiquette en cas d'erreur.
    • Syntaxe :
📷 Syntaxe On Error GoTo :

On Error GoTo Etiquette
' Code
Exit Sub

Etiquette:
' Gestion de l'erreur

On Error GoTo Etiquette
' Code
Exit Sub

Etiquette:
' Gestion de l'erreur

  • Propriété Err : Contient des informations sur l'erreur (Err.Number, Err.Description).
  • Bonnes pratiques :
    • Utiliser On Error avec parcimonie et réactiver la gestion normale des erreurs avec On Error GoTo 0.
    • Afficher des messages d'erreur clairs pour l'utilisateur.

Bonnes pratiques

  • Toujours tester les conditions sur des données fictives.
  • Utiliser des messages (MsgBox) pour informer l'utilisateur des résultats ou erreurs.
  • Documenter les conditions et la gestion des erreurs avec des commentaires.
  • Éviter les boucles infinies dans les conditions complexes.

2. Démonstrations avec des exemples

Exemple 1 : Vérifier le Prix d'un Livre avec If...Then

📷 Code VBA :

Option Explicit

Sub VerifierPrixLivre()
    Dim ws As Worksheet
    Dim prix As Double
    Set ws = ThisWorkbook.Sheets("Livres")

    ' Lire le prix dans D2
    prix = ws.Cells(2, 4).Value

    If prix > 10 Then
        MsgBox "Le livre est cher : " & prix & " €"
    Else
        MsgBox "Le livre est abordable : " & prix & " €"
    End If
End Sub

Option Explicit

Sub VerifierPrixLivre()
Dim ws As Worksheet
Dim prix As Double
Set ws = ThisWorkbook.Sheets("Livres")

' Lire le prix dans D2
prix = ws.Cells(2, 4).Value

If prix > 10 Then
MsgBox "Le livre est cher : " & prix & " €"
Else
MsgBox "Le livre est abordable : " & prix & " €"
End If
End Sub

📸 Résultat attendu :

Résultat de l'exemple

Exemple 2 : Catégoriser les Prix avec Select Case

📷 Code VBA :

Option Explicit

Sub CategoriserPrix()
    Dim ws As Worksheet
    Dim prix As Double
    Dim i As Integer
    Dim categorie As String
    Set ws = ThisWorkbook.Sheets("Livres")

    For i = 2 To 4
        prix = ws.Cells(i, 4).Value

        Select Case prix
            Case Is < 10
                categorie = "Bas"
            Case 10 To 15
                categorie = "Moyen"
            Case Is > 15
                categorie = "Élevé"
            Case Else
                categorie = "Inconnu"
        End Select

        ws.Cells(i, 5).Value = categorie
    Next i

    MsgBox "Catégories de prix ajoutées dans E2:E4"
End Sub

Option Explicit

Sub CategoriserPrix()
Dim ws As Worksheet
Dim prix As Double
Dim i As Integer
Dim categorie As String
Set ws = ThisWorkbook.Sheets("Livres")

For i = 2 To 4
prix = ws.Cells(i, 4).Value

Select Case prix
Case Is < 10 categorie = "Bas" Case 10 To 15 categorie = "Moyen" Case Is > 15
categorie = "Élevé"
Case Else
categorie = "Inconnu"
End Select

ws.Cells(i, 5).Value = categorie
Next i

MsgBox "Catégories de prix ajoutées dans E2:E4"
End Sub

📸 Résultat attendu :

Résultat de l'exemple

1. Théorie - Boucles Avancées et Tableaux

Boucles Avancées

  • Rôle : Parcourir des plages de données dynamiques (par exemple, toutes les lignes non vides d'une colonne).
  • Techniques clés :
    • Trouver la dernière ligne : Utiliser Cells(Rows.Count, colonne).End(xlUp).Row pour trouver la dernière ligne non vide dans une colonne.
    • Boucle dynamique : Parcourir des lignes ou colonnes sans connaître leur taille à l'avance.
    • Boucle imbriquée : Utiliser une boucle à l'intérieur d'une autre (par exemple, parcourir des lignes et des colonnes).
  • Exemple : Parcourir tous les livres dans une feuille pour lister leurs titres.

Tableaux VBA

  • Définition : Un tableau est une variable qui peut stocker plusieurs valeurs (par exemple, une liste de titres).
  • Déclaration :
    • Statique : Dim tableau(4) As String (5 éléments, indices 0 à 4).
    • Dynamique : Dim tableau() As String, redimensionné avec ReDim tableau(n).
  • Manipulation :
    • Stocker des valeurs : tableau(0) = "Livre 1".
    • Redimensionner : ReDim Preserve tableau(n) pour conserver les données existantes.
    • Joindre : Join(tableau, ", ") pour convertir un tableau en texte.
  • Exemple d'application : Stocker les titres des livres dans un tableau et les afficher.

Bonnes pratiques

  • Utiliser Cells avec des boucles pour accéder aux données dynamiquement.
  • Toujours vérifier la taille des tableaux avant d'y accéder pour éviter les erreurs.
  • Combiner boucles et conditions pour filtrer les données (par exemple, lister uniquement les livres disponibles).
  • Documenter le code avec des commentaires pour expliquer les boucles et tableaux.

2. Démonstrations avec des exemples

Exemple 1 : Lister les Titres des Livres avec une Boucle Dynamique

📷 Code VBA :

Option Explicit

Sub ListerTitresLivres()
    Dim ws As Worksheet
    Dim i As Integer, lastRow As Integer
    Dim titres As String
    Set ws = ThisWorkbook.Sheets("Livres")

    lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
    titres = ""

    For i = 2 To lastRow
        titres = titres & ws.Cells(i, 2).Value & vbCrLf
    Next i

    MsgBox "Titres des livres :" & vbCrLf & titres
End Sub

Option Explicit

Sub ListerTitresLivres()
Dim ws As Worksheet
Dim i As Integer, lastRow As Integer
Dim titres As String
Set ws = ThisWorkbook.Sheets("Livres")

lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
titres = ""

For i = 2 To lastRow
titres = titres & ws.Cells(i, 2).Value & vbCrLf
Next i

MsgBox "Titres des livres :" & vbCrLf & titres
End Sub

📸 Résultat attendu :

Résultat de l'exemple

Exemple 2 : Stocker les Prix dans un Tableau

📷 Code VBA :

Option Explicit

Sub CalculerMoyennePrix()
    Dim ws As Worksheet
    Dim i As Integer, lastRow As Integer
    Dim prix() As Double
    Dim somme As Double, moyenne As Double
    Set ws = ThisWorkbook.Sheets("Livres")

    lastRow = ws.Cells(ws.Rows.Count, 4).End(xlUp).Row

    ' Dimensionner le tableau
    ReDim prix(lastRow - 2)

    ' Stocker les prix
    For i = 2 To lastRow
        prix(i - 2) = ws.Cells(i, 4).Value
        somme = somme + prix(i - 2)
    Next i

    ' Calculer la moyenne
    If lastRow > 1 Then
        moyenne = somme / (lastRow - 1)
        MsgBox "Prix moyen des livres : " & Format(moyenne, "0.00") & " €"
    Else
        MsgBox "Aucun livre trouvé"
    End If
End Sub

Option Explicit

Sub CalculerMoyennePrix()
Dim ws As Worksheet
Dim i As Integer, lastRow As Integer
Dim prix() As Double
Dim somme As Double, moyenne As Double
Set ws = ThisWorkbook.Sheets("Livres")

lastRow = ws.Cells(ws.Rows.Count, 4).End(xlUp).Row

' Dimensionner le tableau
ReDim prix(lastRow - 2)

' Stocker les prix
For i = 2 To lastRow
prix(i - 2) = ws.Cells(i, 4).Value
somme = somme + prix(i - 2)
Next i

' Calculer la moyenne
If lastRow > 1 Then
moyenne = somme / (lastRow - 1)
MsgBox "Prix moyen des livres : " & Format(moyenne, "0.00") & " €"
Else
MsgBox "Aucun livre trouvé"
End If
End Sub

📸 Résultat attendu :

Résultat de l'exemple

1. Théorie - Création de Formulaires Utilisateur

UserForms

  • Définition : Un UserForm (formulaire utilisateur) est une interface graphique personnalisée créée dans l'éditeur VBA pour interagir avec l'utilisateur.
  • Accès : Dans l'éditeur VBA (Alt+F11), Insérer > UserForm.
  • Composants :
    • Fenêtre de conception : où les contrôles sont placés visuellement.
    • Boîte à outils : contient les contrôles comme TextBox, Label, Button, ComboBox.
    • Fenêtre des propriétés : permet de configurer les propriétés des contrôles (par exemple, Name, Caption).

Contrôles courants

  • Label : Affiche du texte statique (par exemple, "Titre du livre").
  • TextBox : Permet à l'utilisateur de saisir du texte ou des nombres.
  • ComboBox : Liste déroulante pour sélectionner une option parmi plusieurs.
  • CommandButton : Bouton pour déclencher une action (par exemple, "Ajouter").
  • Propriétés clés :
    • Name : nom du contrôle pour le code VBA.
    • Caption : texte affiché sur le contrôle (par exemple, "Ajouter" pour un bouton).
    • Value : contenu du contrôle (par exemple, texte saisi dans un TextBox).

Interaction avec les feuilles

  • Afficher un UserForm : UserForm1.Show dans une macro.
  • Fermer un UserForm : Unload Me dans le code du formulaire.
  • Écrire dans une feuille : Utiliser Range ou Cells pour insérer les données saisies.
  • Exemple d'application : Ajouter un livre via un formulaire avec des champs pour le titre, l'auteur et le prix.

Bonnes pratiques

  • Nommer les contrôles de manière parlante (par exemple, txtTitre, btnAjouter).
  • Valider les entrées utilisateur pour éviter les erreurs (par exemple, vérifier si un champ est vide).
  • Utiliser des messages (MsgBox) pour confirmer les actions ou signaler des erreurs.
  • Tester les formulaires avec des données fictives.

2. Démonstrations avec des exemples

Exemple 1 : Créer un UserForm pour Ajouter un Livre

Configuration :

  1. Créez un nouveau classeur Excel et sauvegardez-le sous Librairie_lecon6.xlsm.
  2. Dans la feuille "Livres", entrez les en-têtes dans A1:D1 : "ID", "Titre", "Auteur", "Prix".
  3. Ouvrez l'éditeur VBA (Alt+F11), Insérer > UserForm.
  4. Dans le UserForm (nommé UserForm1 par défaut) :
    • Ajoutez un Label (Caption : "Titre"), nommé lblTitre.
    • Ajoutez un TextBox, nommé txtTitre.
    • Ajoutez un Label (Caption : "Auteur"), nommé lblAuteur.
    • Ajoutez un ComboBox, nommé cboAuteur.
    • Ajoutez un Label (Caption : "Prix"), nommé lblPrix.
    • Ajoutez un TextBox, nommé txtPrix.
    • Ajoutez un CommandButton (Caption : "Ajouter"), nommé btnAjouter.

Code du UserForm :

📷 Code VBA :

Option Explicit

Private Sub btnAjouter_Click()
    Dim ws As Worksheet
    Dim lastRow As Long
    Set ws = ThisWorkbook.Sheets("Livres")

    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    ' Valider les entrées
    If txtTitre.Value = "" Or cboAuteur.Value = "" Or txtPrix.Value = "" Then
        MsgBox "Veuillez remplir tous les champs", vbExclamation
        Exit Sub
    End If

    ' Ajouter les données
    ws.Cells(lastRow, 1).Value = lastRow - 1
    ws.Cells(lastRow, 2).Value = txtTitre.Value
    ws.Cells(lastRow, 3).Value = cboAuteur.Value
    ws.Cells(lastRow, 4).Value = CDbl(txtPrix.Value)

    ' Fermer le formulaire
    Unload Me
    MsgBox "Livre ajouté à la ligne " & lastRow
End Sub

Private Sub UserForm_Initialize()
    ' Remplir la ComboBox avec des auteurs
    cboAuteur.AddItem "Antoine de Saint-Exupéry"
    cboAuteur.AddItem "George Orwell"
    cboAuteur.AddItem "Albert Camus"
End Sub

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple

Option Explicit

Private Sub btnAjouter_Click()
Dim ws As Worksheet
Dim lastRow As Long
Set ws = ThisWorkbook.Sheets("Livres")

lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

' Valider les entrées
If txtTitre.Value = "" Or cboAuteur.Value = "" Or txtPrix.Value = "" Then
MsgBox "Veuillez remplir tous les champs", vbExclamation
Exit Sub
End If

' Ajouter les données
ws.Cells(lastRow, 1).Value = lastRow - 1
ws.Cells(lastRow, 2).Value = txtTitre.Value
ws.Cells(lastRow, 3).Value = cboAuteur.Value
ws.Cells(lastRow, 4).Value = CDbl(txtPrix.Value)

' Fermer le formulaire
Unload Me
MsgBox "Livre ajouté à la ligne " & lastRow
End Sub

Private Sub UserForm_Initialize()
' Remplir la ComboBox avec des auteurs
cboAuteur.AddItem "Antoine de Saint-Exupéry"
cboAuteur.AddItem "George Orwell"
cboAuteur.AddItem "Albert Camus"
End Sub

Macro pour afficher le formulaire :

📷 Code VBA :

Option Explicit

Sub AfficherFormulaireLivre()
    UserForm1.Show
End Sub

Option Explicit

Sub AfficherFormulaireLivre()
UserForm1.Show
End Sub

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple

1. Théorie - Événements VBA

Introduction aux Événements

  • Définition : Les événements VBA sont des procédures déclenchées automatiquement en réponse à des actions dans Excel (par exemple, modification d'une cellule, ouverture d'un classeur).
  • Types d'événements :
    • Événements de feuille : déclenchés par des actions dans une feuille spécifique (par exemple, Worksheet_Change pour une modification de cellule).
    • Événements de classeur : déclenchés par des actions au niveau du classeur (par exemple, Workbook_Open lors de l'ouverture).
  • Accès : dans l'éditeur VBA (Alt+F11), double-cliquez sur l'objet ThisWorkbook ou une feuille dans l'Explorateur de projets, puis sélectionnez un événement dans la liste déroulante.

Événements courants

  • Workbook_Open : exécuté à l'ouverture du classeur (par exemple, pour initialiser des paramètres).
  • Worksheet_Change : exécuté lorsqu'une cellule est modifiée dans une feuille.
  • Worksheet_SelectionChange : exécuté lorsqu'une cellule est sélectionnée.
  • Syntaxe :
📷 Syntaxe des événements :

Private Sub Worksheet_Change(ByVal Target As Range)
    ' Code exécuté lors de la modification de la plage Target
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
' Code exécuté lors de la modification de la plage Target
End Sub
  • Target : Représente la plage de cellules modifiées.

Gestion des événements

  • Validation : Utiliser des conditions pour vérifier les modifications (par exemple, si une cellule modifiée est dans une plage spécifique).
  • Désactivation temporaire des événements : Utiliser Application.EnableEvents = False pour éviter les boucles infinies.
  • Bonnes pratiques :
    • Limiter l'utilisation des événements pour éviter de ralentir Excel.
    • Toujours réactiver les événements avec Application.EnableEvents = True après les avoir désactivés.
    • Tester les événements sur des données fictives pour éviter des modifications non désirées.

2. Démonstrations avec des exemples

Exemple 1 : Valider les Prix avec Worksheet_Change

📷 Code VBA :

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim cell As Range

    ' Vérifier si la modification est dans la colonne Prix (D)
    If Not Intersect(Target, Me.Range("D2:D" & Me.Rows.Count)) Is Nothing Then
        Application.EnableEvents = False

        For Each cell In Target
            If cell.Column = 4 And cell.Row >= 2 Then
                On Error Resume Next
                If Not IsNumeric(cell.Value) Or cell.Value <= 0 Then
                    cell.Interior.Color = vbRed
                    MsgBox "Erreur : Prix non valide à la ligne " & cell.Row
                    cell.Value = ""
                Else
                    cell.Interior.ColorIndex = xlNone
                End If
                On Error GoTo 0
            End If
        Next cell

        Application.EnableEvents = True
    End If
End Sub

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range

' Vérifier si la modification est dans la colonne Prix (D)
If Not Intersect(Target, Me.Range("D2:D" & Me.Rows.Count)) Is Nothing Then
Application.EnableEvents = False

For Each cell In Target
If cell.Column = 4 And cell.Row >= 2 Then
On Error Resume Next
If Not IsNumeric(cell.Value) Or cell.Value <= 0 Then cell.Interior.Color = vbRed MsgBox "Erreur : Prix non valide à la ligne " & cell.Row cell.Value = "" Else cell.Interior.ColorIndex = xlNone End If On Error GoTo 0 End If Next cell Application.EnableEvents = True End If End Sub

📸 Résultat attendu :

Résultat de l'exemple

Exemple 2 : Afficher un Message à l'Ouverture avec Workbook_Open

📷 Code VBA :

Option Explicit

Private Sub Workbook_Open()
    MsgBox "Bienvenue dans le classeur de gestion de la librairie !"
End Sub

Option Explicit

Private Sub Workbook_Open()
MsgBox "Bienvenue dans le classeur de gestion de la librairie !"
End Sub

📸 Résultat attendu :

Résultat de l'exemple

1. Théorie - Création de Rapports Automatisés

Concepts des Rapports Automatisés

  • Définition : Un rapport automatisé est une synthèse de données générée par une macro VBA, souvent présentée dans une nouvelle feuille ou un fichier externe.
  • Composants :
    • Collecte de données : parcourir des feuilles avec des boucles pour extraire des informations.
    • Traitement : utiliser des tableaux et des conditions pour calculer des statistiques (par exemple, moyenne, total).
    • Présentation : écrire les résultats dans une feuille avec mise en forme ou les exporter dans un fichier texte.
  • Méthodes clés :
    • Range et Cells pour écrire des données.
    • Worksheets.Add pour créer une feuille de rapport.
    • Open et Print pour écrire dans un fichier texte.

Techniques avancées

  • Mise en forme automatique : appliquer des bordures, couleurs, et polices avec .Borders, .Interior.Color, .Font.
  • Exportation de données : utiliser VBA pour écrire dans un fichier texte avec FileSystemObject ou des méthodes simples comme Open.
  • Gestion des erreurs : anticiper les cas où les feuilles ou les données sont absentes.
  • Interaction utilisateur : utiliser des UserForms pour permettre à l'utilisateur de choisir les paramètres du rapport.

Bonnes pratiques

  • Structurer les rapports avec des en-têtes clairs et une mise en forme lisible.
  • Utiliser des boucles dynamiques pour s'adapter à des données variables.
  • Ajouter des messages pour confirmer la création des rapports.
  • Tester sur des copies de classeurs pour éviter les pertes de données.

Partie 2 : Démonstrations avec Exemples

Exemple 1 : Rapport des Livres Disponibles

📷 Code VBA :

Option Explicit

Sub RapportLivresDisponibles()
    Dim wsLivres As Worksheet, wsRapport As Worksheet
    Dim lastRow As Long, i As Long, rowRapport As Long
    Dim titresDisponibles() As String, count As Long

    ' Configurer les feuilles
    Set wsLivres = ThisWorkbook.Sheets("Livres")
    On Error Resume Next
    Set wsRapport = ThisWorkbook.Sheets("Rapport")
    If wsRapport Is Nothing Then
        Set wsRapport = ThisWorkbook.Sheets.Add
        wsRapport.Name = "Rapport"
    Else
        wsRapport.Cells.Clear
    End If
    On Error GoTo 0

    ' Trouver la dernière ligne
    lastRow = wsLivres.Cells(wsLivres.Rows.Count, 1).End(xlUp).Row

    ' Compter les livres disponibles
    count = 0
    For i = 2 To lastRow
        If wsLivres.Cells(i, 5).Value = True Then count = count + 1
    Next i

    ' Dimensionner le tableau
    ReDim titresDisponibles(count - 1)

    ' Collecter les titres disponibles
    count = 0
    For i = 2 To lastRow
        If wsLivres.Cells(i, 5).Value = True Then
            titresDisponibles(count) = wsLivres.Cells(i, 2).Value
            count = count + 1
        End If
    Next i

    ' Écrire le rapport
    With wsRapport
        .Cells(1, 1).Value = "Rapport des Livres Disponibles"
        .Cells(1, 1).Font.Bold = True
        .Cells(1, 1).Font.Size = 14
        .Cells(2, 1).Value = "Titre"
        .Cells(2, 1).Font.Bold = True
        .Cells(2, 1).Interior.Color = vbCyan

        For i = 0 To count - 1
            .Cells(i + 3, 1).Value = titresDisponibles(i)
        Next i

        .Range("A2:A" & (count + 2)).Borders.LineStyle = xlContinuous
        .Columns("A").AutoFit
    End With

    MsgBox "Rapport des livres disponibles créé dans la feuille Rapport"
End Sub

Option Explicit

Sub RapportLivresDisponibles()
Dim wsLivres As Worksheet, wsRapport As Worksheet
Dim lastRow As Long, i As Long, rowRapport As Long
Dim titresDisponibles() As String, count As Long

' Configurer les feuilles
Set wsLivres = ThisWorkbook.Sheets("Livres")
On Error Resume Next
Set wsRapport = ThisWorkbook.Sheets("Rapport")
If wsRapport Is Nothing Then
Set wsRapport = ThisWorkbook.Sheets.Add
wsRapport.Name = "Rapport"
Else
wsRapport.Cells.Clear
End If
On Error GoTo 0

' Trouver la dernière ligne
lastRow = wsLivres.Cells(wsLivres.Rows.Count, 1).End(xlUp).Row

' Compter les livres disponibles
count = 0
For i = 2 To lastRow
If wsLivres.Cells(i, 5).Value = True Then count = count + 1
Next i

' Dimensionner le tableau
ReDim titresDisponibles(count - 1)

' Collecter les titres disponibles
count = 0
For i = 2 To lastRow
If wsLivres.Cells(i, 5).Value = True Then
titresDisponibles(count) = wsLivres.Cells(i, 2).Value
count = count + 1
End If
Next i

' Écrire le rapport
With wsRapport
.Cells(1, 1).Value = "Rapport des Livres Disponibles"
.Cells(1, 1).Font.Bold = True
.Cells(1, 1).Font.Size = 14
.Cells(2, 1).Value = "Titre"
.Cells(2, 1).Font.Bold = True
.Cells(2, 1).Interior.Color = vbCyan

For i = 0 To count - 1
.Cells(i + 3, 1).Value = titresDisponibles(i)
Next i

.Range("A2:A" & (count + 2)).Borders.LineStyle = xlContinuous
.Columns("A").AutoFit
End With

MsgBox "Rapport des livres disponibles créé dans la feuille Rapport"
End Sub

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple

Exemple 2 : Rapport Statistique des Clients

📷 Code VBA :

Option Explicit

Sub RapportStatistiquesClients()
    Dim wsClients As Worksheet, wsRapport As Worksheet
    Dim lastRow As Long, i As Long
    Dim total As Double, moyenne As Double, count As Long

    Set wsClients = ThisWorkbook.Sheets("Clients")
    On Error Resume Next
    Set wsRapport = ThisWorkbook.Sheets("Rapport")
    If wsRapport Is Nothing Then
        Set wsRapport = ThisWorkbook.Sheets.Add
        wsRapport.Name = "Rapport"
    Else
        wsRapport.Cells.Clear
    End If
    On Error GoTo 0

    lastRow = wsClients.Cells(wsClients.Rows.Count, 1).End(xlUp).Row
    total = 0
    count = 0

    For i = 2 To lastRow
        total = total + wsClients.Cells(i, 3).Value
        count = count + 1
    Next i

    If count > 0 Then
        moyenne = total / count
    End If

    With wsRapport
        .Cells(1, 1).Value = "Rapport des Statistiques Clients"
        .Cells(1, 1).Font.Bold = True
        .Cells(1, 1).Font.Size = 14
        .Cells(2, 1).Value = "Statistique"
        .Cells(2, 2).Value = "Valeur"
        .Cells(2, 1).Font.Bold = True
        .Cells(2, 2).Font.Bold = True
        .Cells(2, 1).Interior.Color = vbGreen
        .Cells(2, 2).Interior.Color = vbGreen
        .Cells(3, 1).Value = "Solde Total"
        .Cells(3, 2).Value = Format(total, "0.00") & " €"
        .Cells(4, 1).Value = "Solde Moyen"
        .Cells(4, 2).Value = Format(moyenne, "0.00") & " €"
        .Cells(5, 1).Value = "Nombre de Clients"
        .Cells(5, 2).Value = count
        .Range("A2:B5").Borders.LineStyle = xlContinuous
        .Columns("A:B").AutoFit
    End With

    MsgBox "Rapport des statistiques clients créé dans la feuille Rapport"
End Sub

Option Explicit

Sub RapportStatistiquesClients()
Dim wsClients As Worksheet, wsRapport As Worksheet
Dim lastRow As Long, i As Long
Dim total As Double, moyenne As Double, count As Long

Set wsClients = ThisWorkbook.Sheets("Clients")
On Error Resume Next
Set wsRapport = ThisWorkbook.Sheets("Rapport")
If wsRapport Is Nothing Then
Set wsRapport = ThisWorkbook.Sheets.Add
wsRapport.Name = "Rapport"
Else
wsRapport.Cells.Clear
End If
On Error GoTo 0

lastRow = wsClients.Cells(wsClients.Rows.Count, 1).End(xlUp).Row
total = 0
count = 0

For i = 2 To lastRow
total = total + wsClients.Cells(i, 3).Value
count = count + 1
Next i

If count > 0 Then
moyenne = total / count
End If

With wsRapport
.Cells(1, 1).Value = "Rapport des Statistiques Clients"
.Cells(1, 1).Font.Bold = True
.Cells(1, 1).Font.Size = 14
.Cells(2, 1).Value = "Statistique"
.Cells(2, 2).Value = "Valeur"
.Cells(2, 1).Font.Bold = True
.Cells(2, 2).Font.Bold = True
.Cells(2, 1).Interior.Color = vbGreen
.Cells(2, 2).Interior.Color = vbGreen
.Cells(3, 1).Value = "Solde Total"
.Cells(3, 2).Value = Format(total, "0.00") & " €"
.Cells(4, 1).Value = "Solde Moyen"
.Cells(4, 2).Value = Format(moyenne, "0.00") & " €"
.Cells(5, 1).Value = "Nombre de Clients"
.Cells(5, 2).Value = count
.Range("A2:B5").Borders.LineStyle = xlContinuous
.Columns("A:B").AutoFit
End With

MsgBox "Rapport des statistiques clients créé dans la feuille Rapport"
End Sub

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple

1. Théorie - Fonctions Personnalisées et Manipulation Avancée des Données

Fonctions Personnalisées (UDF)

  • Définition : Une fonction personnalisée (en anglais User-Defined Function) est une procédure VBA qui peut être utilisée directement dans les formules Excel, comme SUM ou VLOOKUP.
  • Syntaxe :
📷 Syntaxe d'une fonction personnalisée :

Function NomFonction(Param1 As Type, Param2 As Type) As Type
    ' Code de la fonction
    NomFonction = Résultat
End Function

Function NomFonction(Param1 As Type, Param2 As Type) As Type
' Code de la fonction
NomFonction = Résultat
End Function
  • Utilisation : Entrer « =NomFonction(A1, B1) » dans une cellule Excel.
  • Application volatile : Utiliser Application.Volatile pour forcer le recalcul à chaque modification de la feuille.
  • Exemple : Une fonction pour calculer une remise sur le prix d'un livre.

Manipulation Avancée des Données

  • Plages dynamiques :
    • UsedRange : Sélectionne toutes les cellules utilisées dans une feuille.
    • Offset : Déplace la référence d'une plage (par exemple, Range("A1").Offset(1, 0) renvoie A2).
    • Resize : Redimensionne une plage (par exemple, Range("A1").Resize(2, 3) sélectionne A1:C2).
    • CurrentRegion : Sélectionne une région contiguë autour d'une cellule (utile pour les tableaux).
  • Tableaux pour optimisation :
    • Charger une plage dans un tableau VBA avec Range.Value pour réduire les accès aux cellules.
    • Écrire un tableau dans une plage en une seule opération.
  • Exemple d'application : Extraire une liste unique de titres ou d'auteurs à partir d'une feuille.

Bonnes pratiques

  • Nommer les fonctions de manière claire et parlante (par exemple, CalculerRemise).
  • Valider les paramètres des fonctions pour éviter les erreurs (par exemple, vérifier les types de données).
  • Utiliser des tableaux pour traiter de grandes quantités de données rapidement.
  • Documenter les fonctions avec des commentaires pour expliquer leur rôle et leurs paramètres.

2. Démonstrations avec un exemple

Fonction Personnalisée pour Calculer une Remise

Étapes :

  1. Créez un nouveau classeur Excel et sauvegardez-le sous Librairie_lecon1_Intermediaire.xlsm.
  2. Dans la feuille "Livres", entrez les en-têtes dans A1:D1 : "ID", "Titre", "Auteur", "Prix".
  3. Ajoutez des données dans A2:D5 :
    • 1, "Le Petit Prince", "Antoine de Saint-Exupéry", 12.99
    • 2, "1984", "George Orwell", 15.99
    • 3, "L'Étranger", "Albert Camus", 10.50
    • 4, "Animal Farm", "George Orwell", 9.99
  4. Créez une fonction personnalisée pour calculer une remise :
📷 Code VBA :

Option Explicit

Function CalculerRemise(Prix As Double, Pourcentage As Double) As Double
    If Prix < 0 Or Pourcentage < 0 Or Pourcentage > 100 Then
        CalculerRemise = CVErr(xlErrValue)
    Else
        CalculerRemise = Prix * (1 - Pourcentage / 100)
    End If
End Function

Option Explicit

Function CalculerRemise(Prix As Double, Pourcentage As Double) As Double
If Prix < 0 Or Pourcentage < 0 Or Pourcentage > 100 Then
CalculerRemise = CVErr(xlErrValue)
Else
CalculerRemise = Prix * (1 - Pourcentage / 100)
End If
End Function

Utilisation :

  1. Dans la feuille "Livres", entrez =CalculerRemise(D2, 10) dans E2 pour appliquer une remise de 10 % au prix de D2.
  2. Copiez la formule vers E3:E5.
  3. Vérifiez que :
    • E2 affiche 11.69 (12.99 * 0.9), E3 affiche 14.39, etc.
    • Si un prix ou pourcentage est invalide, la fonction renvoie une erreur #VALUE!.

📸 Résultat attendu :

Résultat de l'exemple

1. Théorie - Gestion Avancée des UserForms

UserForms Dynamiques

  • Définition : Les UserForms dynamiques permettent d'ajouter ou de modifier des contrôles (TextBox, ComboBox, etc.) à l'exécution en fonction des données ou des besoins.
  • Ajout de contrôles : Utiliser Controls.Add pour créer des contrôles dynamiquement.
📷 Syntaxe d'ajout de contrôle :

Me.Controls.Add "Forms.TextBox.1", "txtDynamique", True

Me.Controls.Add "Forms.TextBox.1", "txtDynamique", True
  • Propriétés dynamiques : Configurer Top, Left, Width, Height, et autres propriétés des contrôles ajoutés.

Validation Avancée des Entrées

  • Techniques :
    • Vérification des formats avec des expressions régulières (par exemple, vérifier un ISBN).
    • Contrôle d'unicité (par exemple, éviter les doublons de titres dans une feuille).
    • Validation en temps réel avec l'événement Change des contrôles.
  • Gestion des erreurs : Afficher des messages d'erreur via des Labels ou MsgBox.

Événements des Contrôles

  • Événements courants :
    • Change : Déclenché lorsqu'un TextBox ou ComboBox est modifié.
    • Click : Déclenché lorsqu'un bouton ou une case à cocher est cliqué.
    • MouseMove : Déclenché lors du déplacement de la souris sur un contrôle.
  • Utilisation : Associer des actions dynamiques, comme activer/désactiver des boutons en fonction des entrées.

Bonnes pratiques

  • Nommer les contrôles dynamiques avec des préfixes descriptifs (par exemple, txtDynamique1).
  • Valider les entrées dès la saisie pour améliorer l'expérience utilisateur.
  • Utiliser des événements pour réduire les clics inutiles (par exemple, mise à jour automatique des ComboBox).
  • Tester les formulaires avec des données variées pour assurer leur robustesse.

2. Démonstrations avec un exemple

UserForm Dynamique pour Ajouter un Livre

Configuration initiale :

  1. Créez un nouveau classeur Excel et sauvegardez-le sous Librairie_lecon2_Intermediaire.xlsm.
  2. Dans la feuille "Livres", entrez les en-têtes dans A1:E1 : "ID", "Titre", "Auteur", "Prix", "Disponible".
  3. Ajoutez des données dans A2:E6 :
    • 1, "Le Petit Prince", "Antoine de Saint-Exupéry", 12.99, True
    • 2, "1984", "George Orwell", 15.99, False
    • 3, "L'Étranger", "Albert Camus", 10.50, True
    • 4, "Animal Farm", "George Orwell", 9.99, True
    • 5, "La Peste", "Albert Camus", 14.00, True
  4. Créez un UserForm (UserForm1) avec :
    • Un ComboBox (cboChamps) pour choisir le nombre de champs à afficher (1 à 3).
    • Un CommandButton (Caption : "Ajouter"), nommé btnAjouter.
    • Un Label (Caption : ""), nommé lblErreur pour afficher les erreurs.

Code du UserForm :

📷 Code VBA du UserForm :

Option Explicit

Private Sub UserForm_Initialize()
    cboChamps.AddItem "1"
    cboChamps.AddItem "2"
    cboChamps.AddItem "3"
    cboChamps.Value = "1"
    Call cboChamps_Change
End Sub

Private Sub cboChamps_Change()
    Dim i As Integer
    Dim ctrl As Control

    ' Supprimer les contrôles dynamiques existants
    For Each ctrl In Me.Controls
        If Left(ctrl.Name, 8) = "txtChamp" Then
            Me.Controls.Remove ctrl.Name
        End If
    Next ctrl

    ' Ajouter des TextBox dynamiquement
    For i = 1 To CInt(cboChamps.Value)
        Set ctrl = Me.Controls.Add("Forms.TextBox.1", "txtChamp" & i, True)
        ctrl.Top = 20 + (i * 30)
        ctrl.Left = 100
        ctrl.Width = 150
        ctrl.Name = "txtChamp" & i

        Select Case i
            Case 1: ctrl.Text = "Titre"
            Case 2: ctrl.Text = "Auteur"
            Case 3: ctrl.Text = "Prix"
        End Select
    Next i
End Sub

Option Explicit

Private Sub UserForm_Initialize()
cboChamps.AddItem "1"
cboChamps.AddItem "2"
cboChamps.AddItem "3"
cboChamps.Value = "1"
Call cboChamps_Change
End Sub

Private Sub cboChamps_Change()
Dim i As Integer
Dim ctrl As Control

' Supprimer les contrôles dynamiques existants
For Each ctrl In Me.Controls
If Left(ctrl.Name, 8) = "txtChamp" Then
Me.Controls.Remove ctrl.Name
End If
Next ctrl

' Ajouter des TextBox dynamiquement
For i = 1 To CInt(cboChamps.Value)
Set ctrl = Me.Controls.Add("Forms.TextBox.1", "txtChamp" & i, True)
ctrl.Top = 20 + (i * 30)
ctrl.Left = 100
ctrl.Width = 150
ctrl.Name = "txtChamp" & i

Select Case i
Case 1: ctrl.Text = "Titre"
Case 2: ctrl.Text = "Auteur"
Case 3: ctrl.Text = "Prix"
End Select
Next i
End Sub

📷 Code VBA du bouton Ajouter :

Private Sub btnAjouter_Click()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Integer
    Set ws = ThisWorkbook.Sheets("Livres")

    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    ' Valider les entrées
    For Each ctrl In Me.Controls
        If Left(ctrl.Name, 8) = "txtChamp" Then
            If ctrl.Text = "" Then
                lblErreur.Caption = "Tous les champs doivent être remplis"
                Exit Sub
            End If
        End If
    Next ctrl

    ' Ajouter les données
    ws.Cells(lastRow, 1).Value = lastRow - 1
    For i = 1 To CInt(cboChamps.Value)
        ws.Cells(lastRow, i + 1).Value = Me.Controls("txtChamp" & i).Text
    Next i

    lblErreur.Caption = ""
    Unload Me
    MsgBox "Livre ajouté à la ligne " & lastRow
End Sub

Private Sub btnAjouter_Click()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Integer
Set ws = ThisWorkbook.Sheets("Livres")

lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

' Valider les entrées
For Each ctrl In Me.Controls
If Left(ctrl.Name, 8) = "txtChamp" Then
If ctrl.Text = "" Then
lblErreur.Caption = "Tous les champs doivent être remplis"
Exit Sub
End If
End If
Next ctrl

' Ajouter les données
ws.Cells(lastRow, 1).Value = lastRow - 1
For i = 1 To CInt(cboChamps.Value)
ws.Cells(lastRow, i + 1).Value = Me.Controls("txtChamp" & i).Text
Next i

lblErreur.Caption = ""
Unload Me
MsgBox "Livre ajouté à la ligne " & lastRow
End Sub

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple

Macro pour afficher le formulaire :

📷 Code VBA :

Option Explicit

Sub AfficherFormulaireLivre()
    UserForm1.Show
End Sub

Option Explicit

Sub AfficherFormulaireLivre()
UserForm1.Show
End Sub

Test :

  1. Testez en sélectionnant 2 champs dans cboChamps, en entrant un titre et un auteur, puis en cliquant sur "Ajouter".
  2. Vérifiez que :
    • Les TextBox s'affichent dynamiquement en fonction de cboChamps.
    • Les données sont ajoutées dans la feuille "Livres".
    • Un message d'erreur s'affiche si un champ est vide.

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple
Résultat de l'exemple

1. Théorie - Gestion des Fichiers et Connexion avec d'Autres Applications

Gestion des Fichiers avec FileSystemObject

  • Définition : FileSystemObject est un objet de la bibliothèque Scripting permettant de manipuler des fichiers et dossiers (lecture, écriture, création, suppression).
  • Activation : Ajouter une référence à Microsoft Scripting Runtime dans l'éditeur VBA (Outils > Références) ou utiliser CreateObject("Scripting.FileSystemObject").
  • Méthodes clés :
    • OpenTextFile : Ouvre un fichier pour lecture ou écriture.
    • CreateTextFile : Crée un nouveau fichier.
    • FileExists, FolderExists : Vérifie l'existence d'un fichier ou dossier.
  • Exemple : Lire un fichier CSV, écrire un rapport dans un fichier texte.

Connexion avec Microsoft Word

  • Interaction : Utiliser CreateObject("Word.Application") ou GetObject pour contrôler Word depuis VBA.
  • Objets clés :
    • Word.Application : Représente l'application Word.
    • Documents.Add : Crée un nouveau document.
    • Range : Manipule le texte dans un document.
  • Fonctions : Ajouter du texte, formater (gras, tableaux), sauvegarder le document.

Gestion des erreurs

  • Utiliser On Error Resume Next pour gérer les erreurs d'accès aux fichiers ou à Word.
  • Vérifier l'existence des fichiers/dossiers avant toute opération.
  • Fermer les fichiers et quitter Word proprement pour éviter les processus résiduels.

Bonnes pratiques

  • Utiliser des chemins relatifs (par exemple, ThisWorkbook.Path) pour une meilleure portabilité.
  • Valider les données importées pour éviter les erreurs (par exemple, vérifier les formats numériques).
  • Documenter les interactions avec Word pour clarifier le formatage.
  • Tester les macros sur des fichiers/dossiers temporaires pour éviter les pertes de données.

2. Démonstrations avec un exemple

Exemple 1 : Importer des Livres depuis un Fichier CSV

Préparation :

  1. Créez un nouveau classeur Excel et sauvegardez-le sous Librairie_lecon3_Intermediaire.xlsm.
  2. Créez une feuille "Livres" avec A1:E1 : "ID", "Titre", "Auteur", "Prix", "Disponible".
  3. Créez un fichier CSV nommé Livres.csv dans le même dossier que le classeur avec le contenu suivant :
📷 Contenu du fichier Livres.csv :

ID,Titre,Auteur,Prix,Disponible
6,Harry Potter,J.K. Rowling,19.99,True
7,Le Seigneur des Anneaux,J.R.R. Tolkien,24.99,True

ID,Titre,Auteur,Prix,Disponible
6,Harry Potter,J.K. Rowling,19.99,True
7,Le Seigneur des Anneaux,J.R.R. Tolkien,24.99,True

Code pour importer le CSV :

📷 Code VBA :

Option Explicit

Sub ImporterLivresCSV()
    Dim fso As Object, file As Object
    Dim ws As Worksheet
    Dim line As String, data() As String
    Dim lastRow As Long

    Set ws = ThisWorkbook.Sheets("Livres")
    Set fso = CreateObject("Scripting.FileSystemObject")

    ' Vérifier l'existence du fichier
    If Not fso.FileExists(ThisWorkbook.Path & "\Livres.csv") Then
        MsgBox "Fichier Livres.csv introuvable"
        Exit Sub
    End If

    Set file = fso.OpenTextFile(ThisWorkbook.Path & "\Livres.csv", 1)
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    ' Ignorer la ligne d'en-tête
    If Not file.AtEndOfStream Then
        line = file.ReadLine
    End If

    ' Lire et importer les données
    While Not file.AtEndOfStream
        line = file.ReadLine
        data = Split(line, ",")

        ws.Cells(lastRow, 1).Value = data(0)
        ws.Cells(lastRow, 2).Value = data(1)
        ws.Cells(lastRow, 3).Value = data(2)
        If IsNumeric(data(3)) Then
            ws.Cells(lastRow, 4).Value = CDbl(data(3))
        End If
        ws.Cells(lastRow, 5).Value = CBool(data(4))

        lastRow = lastRow + 1
    Wend

    file.Close
    ws.Columns("A:E").AutoFit
    MsgBox "Livres importés dans la feuille Livres"
End Sub

Option Explicit

Sub ImporterLivresCSV()
Dim fso As Object, file As Object
Dim ws As Worksheet
Dim line As String, data() As String
Dim lastRow As Long

Set ws = ThisWorkbook.Sheets("Livres")
Set fso = CreateObject("Scripting.FileSystemObject")

' Vérifier l'existence du fichier
If Not fso.FileExists(ThisWorkbook.Path & "\Livres.csv") Then
MsgBox "Fichier Livres.csv introuvable"
Exit Sub
End If

Set file = fso.OpenTextFile(ThisWorkbook.Path & "\Livres.csv", 1)
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

' Ignorer la ligne d'en-tête
If Not file.AtEndOfStream Then
line = file.ReadLine
End If

' Lire et importer les données
While Not file.AtEndOfStream
line = file.ReadLine
data = Split(line, ",")

ws.Cells(lastRow, 1).Value = data(0)
ws.Cells(lastRow, 2).Value = data(1)
ws.Cells(lastRow, 3).Value = data(2)
If IsNumeric(data(3)) Then
ws.Cells(lastRow, 4).Value = CDbl(data(3))
End If
ws.Cells(lastRow, 5).Value = CBool(data(4))

lastRow = lastRow + 1
Wend

file.Close
ws.Columns("A:E").AutoFit
MsgBox "Livres importés dans la feuille Livres"
End Sub

Test :

  1. Exécutez la macro et vérifiez que :
    • Les livres du CSV sont ajoutés à la feuille "Livres" à partir de la dernière ligne.
    • Les colonnes sont ajustées automatiquement.
    • Un message confirme l'importation.

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple

1. Théorie - Optimisation du Code et Gestion des Performances

Optimisation du Code VBA

  • Réduire les interactions avec les feuilles :
    • Chaque accès à Range ou Cells est coûteux en temps d'exécution.
    • Solution : Charger les données dans un tableau VBA avec Range.Value, les traiter, puis écrire les résultats en une seule opération.
  • Désactiver les mises à jour :
    • Application.ScreenUpdating = False : Désactive le rafraîchissement de l'écran.
    • Application.Calculation = xlCalculationManual : Désactive le calcul automatique des formules.
    • Restaurer les paramètres à la fin avec Application.ScreenUpdating = True et Application.Calculation = xlCalculationAutomatic.
  • Utiliser des structures efficaces :
    • Préférer For Each pour parcourir des collections (par exemple, Worksheets).
    • Utiliser Dictionary pour des recherches rapides au lieu de boucles imbriquées.

Débogage et Profilage

  • Outils de débogage :
    • Points d'arrêt : Cliquez dans la marge de l'éditeur VBA pour arrêter l'exécution à une ligne.
    • Fenêtre Immédiate : Utilisez Debug.Print pour afficher des valeurs pendant l'exécution (Ctrl+G pour ouvrir).
    • Fenêtre Variables locales : Affiche les valeurs des variables en cours d'exécution.
  • Profilage :
    • Mesurer le temps d'exécution avec Timer pour comparer les performances.
    • Identifier les boucles lentes ou les accès répétés aux feuilles.
  • Gestion des erreurs : Utiliser On Error pour capturer les erreurs et Debug.Print pour journaliser les problèmes.

Bonnes pratiques

  • Toujours utiliser Option Explicit pour éviter les erreurs de variables.
  • Minimiser les boucles imbriquées en utilisant des structures comme Dictionary.
  • Documenter les optimisations avec des commentaires pour faciliter la maintenance.
  • Tester sur des copies de classeurs pour éviter les pertes de données.

2. Démonstrations avec un exemple

Exemple 1 : Optimisation d'une Boucle avec un Tableau

Préparation :

  1. Créez un nouveau classeur Excel et sauvegardez-le sous Librairie_Semaine4_Intermediaire.xlsm.
  2. Dans la feuille "Ventes", entrez les en-têtes dans A1:D1 : "ID Vente", "Client", "Livre", "Montant".
  3. Ajoutez des données dans A2:D6 (ou générez 1000 lignes pour tester les performances) :
    • 1, "Alice", "Le Petit Prince", 12.99
    • 2, "Bob", "L'Étranger", 10.50
    • 3, "Charlie", "Animal Farm", 9.99
    • 4, "David", "La Peste", 14.00
    • 5, "Emma", "Harry Potter", 19.99

📸 Résultat attendu :

Résultat de l'exemple

Version non optimisée :

📷 Code VBA non optimisé :

Option Explicit

Sub CalculerTotalVentesNonOptimise()
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim total As Double

    Set ws = ThisWorkbook.Sheets("Ventes")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    total = 0

    For i = 2 To lastRow
        total = total + ws.Cells(i, 4).Value
    Next i

    ws.Cells(1, 6).Value = "Total Non Optimisé"
    ws.Cells(2, 6).Value = Format(total, "0.00 €")

    MsgBox "Total non optimisé : " & Format(total, "0.00 €")
End Sub

Option Explicit

Sub CalculerTotalVentesNonOptimise()
Dim ws As Worksheet
Dim lastRow As Long, i As Long
Dim total As Double

Set ws = ThisWorkbook.Sheets("Ventes")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
total = 0

For i = 2 To lastRow
total = total + ws.Cells(i, 4).Value
Next i

ws.Cells(1, 6).Value = "Total Non Optimisé"
ws.Cells(2, 6).Value = Format(total, "0.00 €")

MsgBox "Total non optimisé : " & Format(total, "0.00 €")
End Sub

Version optimisée :

📷 Code VBA optimisé :

Sub CalculerTotalVentesOptimise()
    Application.ScreenUpdating = False
    Dim ws As Worksheet
    Dim lastRow As Long, i As Long
    Dim data As Variant, total As Double

    Set ws = ThisWorkbook.Sheets("Ventes")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' Charger les données dans un tableau
    data = ws.Range("D2:D" & lastRow).Value
    total = 0

    ' Traiter le tableau en mémoire
    For i = 1 To lastRow - 1
        If IsNumeric(data(i, 1)) Then
            total = total + data(i, 1)
        End If
    Next i

    ' Écrire le résultat en une seule opération
    ws.Cells(1, 7).Value = "Total Optimisé"
    ws.Cells(2, 7).Value = Format(total, "0.00 €")

    Application.ScreenUpdating = True
    MsgBox "Total optimisé : " & Format(total, "0.00 €")
End Sub

Sub CalculerTotalVentesOptimise()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim lastRow As Long, i As Long
Dim data As Variant, total As Double

Set ws = ThisWorkbook.Sheets("Ventes")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

' Charger les données dans un tableau
data = ws.Range("D2:D" & lastRow).Value
total = 0

' Traiter le tableau en mémoire
For i = 1 To lastRow - 1
If IsNumeric(data(i, 1)) Then
total = total + data(i, 1)
End If
Next i

' Écrire le résultat en une seule opération
ws.Cells(1, 7).Value = "Total Optimisé"
ws.Cells(2, 7).Value = Format(total, "0.00 €")

Application.ScreenUpdating = True
MsgBox "Total optimisé : " & Format(total, "0.00 €")
End Sub

Test de performance :

📷 Code VBA pour mesurer les performances :

Sub TesterPerformances()
    Dim tempsDebut As Double, tempsFin As Double

    ' Test version non optimisée
    tempsDebut = Timer
    CalculerTotalVentesNonOptimise
    tempsFin = Timer
    Debug.Print "Version non optimisée : " & Format(tempsFin - tempsDebut, "0.000") & " secondes"

    ' Test version optimisée
    tempsDebut = Timer
    CalculerTotalVentesOptimise
    tempsFin = Timer
    Debug.Print "Version optimisée : " & Format(tempsFin - tempsDebut, "0.000") & " secondes"
End Sub

Sub TesterPerformances()
Dim tempsDebut As Double, tempsFin As Double

' Test version non optimisée
tempsDebut = Timer
CalculerTotalVentesNonOptimise
tempsFin = Timer
Debug.Print "Version non optimisée : " & Format(tempsFin - tempsDebut, "0.000") & " secondes"

' Test version optimisée
tempsDebut = Timer
CalculerTotalVentesOptimise
tempsFin = Timer
Debug.Print "Version optimisée : " & Format(tempsFin - tempsDebut, "0.000") & " secondes"
End Sub

Test :

  1. Exécutez les deux macros et comparez le temps d'exécution (plus notable avec 1000+ lignes).
  2. Vérifiez que :
    • Le total (par exemple, 67.47 €) est affiché dans F2 (non optimisé) et G2 (optimisé).
    • La version optimisée est plus rapide grâce à l'utilisation du tableau et ScreenUpdating.
    • Les temps d'exécution s'affichent dans la fenêtre Immédiate (Ctrl+G).

📸 Résultat attendu :

Résultat de l'exemple
Résultat de l'exemple
Résultat de l'exemple