Excel - Power Query - Power Pivot - VBA

VBA15 | Sécuriser et analyser les demandes d'achat

Énoncé

  • Thème : fonctionnalités d'Excel (validation, tri, filtre, protection, TCD) | Durée : 40 min | Niveau : intermédiaire.
  • Classeur de départ : VBA15_achats.xlsm (feuilles Demandes et Analyse).
  • Contexte : le service achats centralise les demandes dans un classeur partagé. Vous automatisez les fonctionnalités d'Excel : liste de validation pour le statut, tri, filtre, protection de la feuille et du classeur, puis un tableau croisé dynamique de synthèse par service.

Travail demandé

  • Ouvrir le classeur, puis l'éditeur Visual Basic (Alt+F11) et le module Module1.
  • Créer la liste déroulante du statut : macro CreerListeStatut.
  • Trier les demandes par montant décroissant : macro TrierParMontant.
  • Filtrer les demandes de la production : macro FiltrerProduction.
  • Protéger la feuille et le classeur : macro ProtegerSaisie.
  • Créer le tableau croisé dynamique : macro CreerTCD.
  • Filtrer le TCD : macro FiltrerTCD.
  • Répondre au questionnaire de fin de lab (5 questions, 80 % pour valider).

Corrigé

Créer la liste déroulante du statut

Sub CreerListeStatut()
    With Worksheets("Demandes").Range("F2:F50").Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
            Operator:=xlBetween, Formula1:="En attente;Validée;Refusée"
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = "Statut"
        .InputMessage = "Choisissez un statut dans la liste."
        .ErrorTitle = "Statut inconnu"
        .ErrorMessage = "Utilisez la liste : En attente, Validée ou Refusée."
        .ShowInput = True
        .ShowError = True
    End With
End Sub
  • Validation.Add échoue si une validation existe déjà sur la plage : .Delete d'abord rend la macro relançable. Formula1 contient les valeurs de la liste séparées par un point-virgule.
  • Résultat attendu :
    • F2:F50 porte une validation de type Liste : En attente, Validée, Refusée
    • Un message de saisie (titre Statut) et un message d'erreur sont définis

Trier les demandes par montant décroissant

Sub TrierParMontant()
    With Worksheets("Demandes").Sort
        .SortFields.Clear
        .SortFields.Add Key:=Range("E2:E13"), SortOn:=xlSortOnValues, _
            Order:=xlDescending, DataOption:=xlSortNormal
        .SetRange Range("A1:F13")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub
  • Le tri d'une plage passe par l'objet Sort de la feuille : SortFields définit les clés, SetRange la plage, Header = xlYes protège la ligne d'en-têtes, Apply lance le tri.
  • Résultat attendu :
    • La première demande est la plus élevée (DA-105, 7 350 €)
    • Les montants sont rangés du plus grand au plus petit, en-têtes en ligne 1

Filtrer les demandes de la production

Sub FiltrerProduction()
    Worksheets("Demandes").Range("$A$1:$F$13").AutoFilter Field:=2, Criteria1:="Production"
End Sub
  • AutoFilter pose le filtre automatique sur la plage. Field:=2 désigne la deuxième colonne de la plage (Service), Criteria1 la valeur à garder.
  • Résultat attendu :
    • Seules les 5 demandes du service Production restent visibles

Protéger la feuille et le classeur

Sub ProtegerSaisie()
    With Worksheets("Demandes")
        .Range("F2:F50").Locked = False
        .Protect DrawingObjects:=False, Contents:=True, Scenarios:=True, _
            AllowFiltering:=True
        .EnableSelection = xlUnlockedCells
    End With
    ActiveWorkbook.Protect Structure:=True, Windows:=False
End Sub
  • Toutes les cellules sont verrouillées par défaut, mais le verrou n'agit qu'une fois la feuille protégée. On déverrouille la colonne Statut avant Protect. EnableSelection = xlUnlockedCells empêche même de sélectionner les autres cellules.
  • Résultat attendu :
    • La feuille Demandes est protégée, la colonne Statut (F2:F50) reste modifiable
    • Seules les cellules déverrouillées sont sélectionnables, le filtre reste utilisable
    • La structure du classeur est protégée

Créer le tableau croisé dynamique

Sub CreerTCD()
    Dim objPivotCache As PivotCache
    Dim objPivotTable As PivotTable
    Set objPivotCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, _
        SourceData:="Demandes!A1:F13", Version:=xlPivotTableVersion14)
    Set objPivotTable = objPivotCache.CreatePivotTable(TableDestination:=Range("Analyse!A3"), _
        TableName:="TCD_Achats", DefaultVersion:=xlPivotTableVersion14)
    With objPivotTable.PivotFields("Service")
        .Orientation = xlRowField
        .Position = 1
    End With
    With objPivotTable.PivotFields("Catégorie")
        .Orientation = xlPageField
        .Position = 1
    End With
    objPivotTable.AddDataField objPivotTable.PivotFields("Montant"), Caption:="Total Montant", Function:=xlSum
End Sub
  • Un TCD se crée en deux temps : PivotCaches.Create mémorise les données sources, CreatePivotTable place le TCD. Chaque champ prend ensuite une orientation : ligne (xlRowField), filtre (xlPageField) ou valeur (AddDataField).
  • La structure du classeur est protégée : le TCD se place donc sur la feuille Analyse existante (Analyse!A3), et non sur une nouvelle feuille.
  • Résultat attendu :
    • Le TCD TCD_Achats est placé en Analyse!A3, avec le filtre Catégorie en A1
    • Service en lignes, Catégorie en filtre, somme de Montant en valeurs

Filtrer le TCD

Sub FiltrerTCD()
    Dim objPivotTable As PivotTable
    Set objPivotTable = Worksheets("Analyse").PivotTables("TCD_Achats")
    objPivotTable.PivotFields("Catégorie").ClearAllFilters
    objPivotTable.PivotFields("Catégorie").CurrentPage = "Informatique"
    With objPivotTable.PivotFields("Service")
        .PivotItems("Direction").Visible = False
    End With
End Sub
  • CurrentPage choisit la valeur d'un champ de filtre. PivotItems("Direction").Visible = False masque un élément d'un champ de ligne. ClearAllFilters remet le champ à zéro : la macro donne le même résultat à chaque exécution.
  • Résultat attendu :
    • Le filtre Catégorie affiche Informatique
    • Le service Direction est masqué dans les lignes du TCD (Maintenance 2 120, Production 1 450, Qualité 1 890, total 5 460)

Pour aller plus loin