Taille de police :

×

Lecture de la page :

Lire Test2
|

Macros de mise en forme de graphiques

0
(0)

Demande initiale de l'utilisatrice : Une macro permettant d'uniformiser la couleur de remplissage de plusieurs graphiques.

1ère idée : Utiliser un modèle de graphique (.crtx)

  • Les graphiques doivent être du même type.
  • L'ordre des séries et catégorie doit être le même pour tous les graphiques.

2ème idée : Utiliser un thème ou une palette de couleurs

  • Fonctionne bien pour les couleurs de remplissage et de bordure
  • Nombre de couleurs limité (10 couleurs + 5*10 variations).
  • Pas de possibilité de gérer des hachures ou une épaisseur de trait (demande de l'utilisatrice).

3ème idée : Utiliser du VBA (macro)

Principe

Via une feuille de paramétrages on va donner au code les informations de formatage désirées ainsi que la liste des graphiques à modifier.

Utilisation

  1. Remplir la liste des graphiques à formater via le tableau "TabListeGraphs" dans la feuille désignée par STR_SHEET_PARAM.
    • La 1ère colonne donne le nom de la feuille où se trouve le graphique,
    • La 2ème colonne le nom du graphique,
    • Attention : Il faut forcément renommer tous les graphiques (via le volet Sélection -Ruban Accueil>Rechercher et sélectionner (groupe Édition)) sinon les noms "externes" ne correspondront pas forcément à leurs noms "internes" (exemple : "Graphique 1" s'appellera "Graph 1" en interne).
  2. À partir de la cellule A2, B2, C2 de la feuille désignée par STR_SHEET_PARAM, saisir :
    • En colonne A : Le nom des séries ou des catégories,
    • En colonne B : L'épaisseur de la bordure (facultatif) et remplir la cellule de la couleur de bordure ou de remplissage à utiliser.
    • En colonne C : Le nom de la hachure à utiliser en remplissage et utiliser.
Exemple de feuille de paramétrage de la macro

Le code

Option Explicit
Dim TAB_TYPE_BORDERS                ' Liste des graphiques où la couleur correspond à la bordure
Dim TAB_GRAPH_HS                    ' Liste des graphiques non compatibles
Dim DIC_FORMATAGE       As Object

Const STR_SHEET_PARAM   As String = "Catégories" ' Nom de la feuille de paramétrage
Const BO_GREY_OTHER_BAR  As Boolean = False      ' Si True, le code grise les catégories inconnues
                                                 ' Si False, le code ne modifie pas les catégories inconnues

Sub FormatAllGraph()
    ' Objectif    : Formater de manière uniforme plusieurs graphiques en se basant sur le nom des séries et catégories
    ' Utilisation : Dresser les listes des graphiques à modifier et des formatages à appliquer puis lancer la macro.
    ' Retour      : Néant.
    ' Auteur      : Arnaud (www.1forme.fr).
    ' Licence     : CC-BY-NC-SA (Vous pouvez diffuser/partager/modifier cette macro dans les
    '               même conditions, seulement à titre personnel et citant l'auteur/site d'origine.
    Const TabListeGraphs    As String = "TabListeGraphs" ' Nom du tableau des graphiques à modifier
                                                         ' Toujours les renommer via le volet de sélection
    Dim objSheetParam       As Worksheet    ' Feuille de paramétrage
    Dim objLo               As ListObject   ' Tableau des graphiques à modifier
    Dim rgCell              As Range        '
    Dim lgLastRow           As Long         ' Dernière ligne du tableau en A2 dans STR_SHEET_PARAM
    Dim TabFormatage(1 To 5) ' Couleur de fond, type de hachure, couleur des hachures, épaisseur de bordure, couleur de bordure
    Dim i                   As Long
    
    On Error GoTo erreur
    'Application.ScreenUpdating = False
    Set DIC_FORMATAGE = Nothing
    TAB_TYPE_BORDERS = Array(xlLine, xlLineMarkers, xlLineStacked, _
                            xlLineMarkersStacked, xlLineMarkersStacked100, _
                            xlXYScatterLines, xlXYScatterLinesNoMarkers, _
                            xlXYScatterSmooth, xlXYScatterSmoothNoMarkers, _
                            xlRadar, xlRadarMarkers, xlSurfaceWireframe)
    TAB_GRAPH_HS = Array(xlWaterfall, xlFunnel, xlTreemap, xlSunburst, xlHistogram, _
                        xlSurface, xlSurfaceWireframe, xlSurfaceTopView, xlSurfaceTopViewWireframe, _
                        xlBoxwhisker, xlPareto)
    On Error Resume Next
    Set objSheetParam = ActiveWorkbook.Worksheets(STR_SHEET_PARAM)
    If objSheetParam Is Nothing Then _
        MsgBox "La feuille de paramétrage '" & STR_SHEET_PARAM & "' n'est pas présente !", _
            vbCritical, "Exécution impossible": Exit Sub
    On Error GoTo erreur
    lgLastRow = objSheetParam.Cells(70000, "A").End(xlUp).Row
    
    Set DIC_FORMATAGE = CreateObject("Scripting.Dictionary") ' Création du dictionnaire
    With objSheetParam
        For i = 2 To lgLastRow ' Remplissage du dictionnaire
            If .Cells(i, 1).Value <> "" Then
                TabFormatage(1) = IIf(.Cells(i, 2).Interior.Pattern = xlNone, -1, .Cells(i, 2).Interior.Color)   ' Couleur de fond
                TabFormatage(2) = IIf(.Cells(i, 2).Value = "", "", GetPatternValueFromTable(.Cells(i, 2).Value)) ' Type de hachure
                TabFormatage(3) = IIf(.Cells(i, 2).Font.ColorIndex = xlAutomatic, -1, .Cells(i, 2).Font.Color)   ' Couleur de hachure
                TabFormatage(4) = .Cells(i, 3).Value                                                             ' Epaisseur de bordure
                TabFormatage(5) = IIf(.Cells(i, 3).Interior.Pattern = xlNone, -1, .Cells(i, 3).Interior.Color)   ' Couleur de bordure
                If TabFormatage(4) < 0 Or TabFormatage(4) > 1584 Then _
                    MsgBox "L'épaisseur doit être entre 0 et 1584 pour " & .Cells(i, 1).Value, _
                        vbCritical, "Valeur non utilisable": Exit Sub
                DIC_FORMATAGE(Trim(LCase(.Cells(i, 1).Value))) = TabFormatage()
            End If
        Next i
        On Error Resume Next
        Set objLo = .ListObjects(TabListeGraphs)
        If objLo Is Nothing Then _
            MsgBox "La liste de graphique '" & TabListeGraphs & "' n'est pas présent dans '" & _
                STR_SHEET_PARAM & "' !", vbCritical, "Exécution impossible": Exit Sub
        On Error GoTo erreur
    End With
    ' Boucle sur la liste des graphiques à modifier
    For Each rgCell In objLo.ListColumns(1).DataBodyRange
        Call FormatAGraph(rgCell.Value, rgCell.Offset(0, 1).Value, objSheetParam, lgLastRow)
    Next rgCell
    Set objLo = Nothing
    Set DIC_FORMATAGE = Nothing
    Set objSheetParam = Nothing
    MsgBox "Couleurs mises à jour pour les graphiques désignés.", vbInformation
    Exit Sub
erreur:
    MsgBox Err.Description & "(" & Err.Number & ")", vbCritical, "Erreur FormatAllGraph"
End Sub

Sub FormatAGraph(strSheetName As String, strGraphName As String, objSheetParam As Object, lgLastRow As Long)
    ' Procédure de formatage d'un graphique unique
    Dim objChart            As ChartObject      ' Le graphique
    Dim objSeries           As Series           ' Les séries du graphique
    Dim j                   As Long
    Dim strCatName          As String           ' Nom de la catégorie ou de la série
    Dim boChartTypesBorders As Boolean          ' Flag graphique où la couleur correspond à la bordure
    
    On Error Resume Next
    Set objChart = ActiveWorkbook.Worksheets(strSheetName).ChartObjects(strGraphName)
    If Not objChart Is Nothing Then
        If Not IsChartTypeInList(objChart.chart.chartType, TAB_GRAPH_HS) Then
            On Error GoTo erreur
            For Each objSeries In objChart.chart.SeriesCollection ' Parcourt toutes les séries du graphique
                boChartTypesBorders = IsChartTypeInList(objSeries.chartType, TAB_TYPE_BORDERS) ' Test Remplissage ou bordure
                strCatName = Trim(LCase(objSeries.Name)) ' On uniformise la casse et supprime les espaces
                If DIC_FORMATAGE.exists(strCatName) Then ' Cas traitement par série
                    Call FormatItem(boChartTypesBorders, strCatName, objSeries)
                Else                                     ' Cas traitement par catégorie
                    For j = 1 To objSeries.Points.Count  ' Parcourt des catégories
                        strCatName = Trim(LCase(objSeries.XValues(j)))
                        If DIC_FORMATAGE.exists(strCatName) Then ' Catégorie référencée
                            Call FormatItem(boChartTypesBorders, strCatName, objSeries.Points(j))
                        Else                                     ' Catégorie non référencée
                            If BO_GREY_OTHER_BAR And Not boChartTypesBorders Then _
                                objSeries.Points(j).Format.Fill.ForeColor.RGB = RGB(200, 200, 200)
                        End If
                    Next j
                End If
            Next objSeries
        End If
        Set objChart = Nothing
    End If
    Exit Sub
erreur:
    MsgBox Err.Description & "(" & Err.Number & ")", vbCritical, "Erreur FormatAGraph"
End Sub

Sub FormatItem(boChartTypesBorders As Boolean, strCatName As String, objToFormat As Object)
    ' Procédure de formatage d'un élément d'un graphique (série ou catégorie)
    On Error GoTo erreur
    If boChartTypesBorders Then          ' Formatage seulement des bordures
        With objToFormat.Format.Line
            If DIC_FORMATAGE(strCatName)(5) <> -1 Then .ForeColor.RGB = DIC_FORMATAGE(strCatName)(5)
            If DIC_FORMATAGE(strCatName)(4) <> "" Then
                If DIC_FORMATAGE(strCatName)(4) = 0 Then
                    .Visible = msoFalse
                Else
                    .Visible = msoTrue
                    .Weight = DIC_FORMATAGE(strCatName)(4)
                End If
            End If
        End With
    Else                                 ' Formatage du remplissage et des bordures
        With objToFormat.Format.Fill
            If DIC_FORMATAGE(strCatName)(2) <> "" Then   ' Hachure précisés => modification hachures
                If DIC_FORMATAGE(strCatName)(2) = 0 Then ' Supprime hachures
                    .Solid
                Else
                    .Patterned DIC_FORMATAGE(strCatName)(2) ' Modifie hachures
                End If
            End If
            If DIC_FORMATAGE(strCatName)(1) <> -1 Then ' Fond pas en Aucun remplissage => Modification couleur fond
                If DIC_FORMATAGE(strCatName)(2) <> "" Or .Pattern <> msoPatternMixed Then  ' Avec hachures
                    .BackColor.RGB = DIC_FORMATAGE(strCatName)(1)
                Else                                                                        ' Sans hachures
                    .ForeColor.RGB = DIC_FORMATAGE(strCatName)(1)    ' Sans hachure ForeColor
                End If
            End If
            If DIC_FORMATAGE(strCatName)(3) <> -1 Then ' Couleur pas en Automatique => Modif couleur hachures
                .ForeColor.RGB = DIC_FORMATAGE(strCatName)(3)
            End If
        End With
        With objToFormat.Format.Line
            If DIC_FORMATAGE(strCatName)(5) <> -1 Then .ForeColor.RGB = DIC_FORMATAGE(strCatName)(5)
            If DIC_FORMATAGE(strCatName)(4) <> "" Then
                If DIC_FORMATAGE(strCatName)(4) = 0 Then
                    .Visible = msoFalse
                Else
                    .Visible = msoTrue
                    .Weight = DIC_FORMATAGE(strCatName)(4)
                End If
            End If
        End With
    End If
    Exit Sub
erreur:
    MsgBox Err.Description & "(" & Err.Number & ")", vbCritical, "Erreur FormatItem"
End Sub

Function IsChartTypeInList(chartType As XlChartType, typeList As Variant) As Boolean
    ' Cherche si un type de graphique est dans une liste
    Dim t
    
    For Each t In typeList
        If chartType = t Then IsChartTypeInList = True: Exit Function
    Next
End Function

Function GetPatternValueFromTable(StrNomConstante As String) As Variant
    ' Conversion NomHachure/Valeur
    Dim objTabConstHachures As ListObject
    Dim tabData             As Variant
    Dim i                   As Long

    Set objTabConstHachures = ActiveWorkbook.Sheets(STR_SHEET_PARAM).ListObjects("TabConstHachures")
    tabData = objTabConstHachures.DataBodyRange.Value  ' Charge tout dans un tableau (1 to n, 1 to 3)
    For i = 1 To UBound(tabData, 1)
        If tabData(i, 1) = StrNomConstante Then
                    GetPatternValueFromTable = tabData(i, 2): Exit Function
        End If
    Next
     GetPatternValueFromTable = "" ' Si non trouvé
End Function

Merci pour votre attention bienveillante.

Article intéressant ?

Cliquez sur une étoile pour noter cet article !

Note moyenne 0 / 5. Nombre de votes : 0

Aucun vote pour l'instant ! Soyez le premier à noter ce post.

Nous sommes désolés que cet article ne vous ait pas été utile !

Améliorons cet article !

Dites nous comment nous pouvons améliorer cet article ?

Publications similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *