Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Automazione dei grafici | Automazione di Tabelle e Report
Excel VBA per l'Automazione Aziendale

Automazione dei grafici

Scorri per mostrare il menu

I grafici sono forme posizionate sopra un foglio di lavoro e, come tutto il resto in questo capitolo, ogni proprietà che imposteresti manualmente nel riquadro Formato ha un equivalente in VBA.

Figura 4.4

Creazione di un grafico

Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject
 
    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
 
    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent
 
    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub
Analisi riga per riga
expand arrow
  • AddChart2 crea effettivamente la forma del grafico — Style:=201 seleziona uno stile visivo predefinito, XlChartType:=xlColumnClustered seleziona un grafico a colonne standard, e Left/Top/Width/Height ne determinano posizione e dimensioni sul foglio di lavoro in punti, la stessa unità che Excel utilizza internamente per il posizionamento delle forme;
  • AddChart2 restituisce in realtà un oggetto Chart, non il contenitore ChartObject che lo circonda — il .Chart.Parent alla fine di quella riga serve a risalire al contenitore, che è il tipo con cui chartObj è dichiarato; questa particolarità è facile da dimenticare e vale la pena copiarla esattamente;
  • SetSourceData indica alla forma del grafico, altrimenti vuota, quali dati rappresentare — puntando a tbl.ListColumns("Profit").Range si rappresenta la colonna Profit su tutte le righe visibili della Tabella;
  • HasTitle = True deve essere impostato prima di assegnare ChartTitle.Text — provare a impostare il testo del titolo su un grafico che non ha ancora un titolo attivo causerà un errore.

Aggiornamento dei dati del grafico

Quando la tabella sottostante cresce, indirizzare il grafico al nuovo intervallo con SetSourceData invece di eliminarlo e ricostruirlo — questo preserva qualsiasi formattazione manuale già applicata:

Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range

ChartObjects(1) si riferisce alla prima forma grafico sul foglio in base alla posizione — va bene quando c'è un solo grafico, ma diventa fragile nel momento in cui viene aggiunto un secondo grafico, poiché "primo" può silenziosamente significare qualcosa di diverso dopo. Fare riferimento a un grafico tramite un nome impostato esplicitamente (chartObj.Name = "ProfitChart", poi ChartObjects("ProfitChart")) è più robusto quando un foglio contiene più di un grafico.

Formattazione dei grafici

With chartObj.Chart
    .ChartTitle.Font.Size = 14
    .ChartTitle.Font.Bold = True
    .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
    .Axes(xlValue).TickLabels.NumberFormat = "#,##0"
    .HasLegend = False
End With

SeriesCollection(1) è la prima (e qui unica) serie di dati rappresentata — il suo Format.Fill.ForeColor.RGB determina il colore effettivo delle barre, utilizzando la stessa funzione RGB(...) degli esempi di formattazione del Capitolo 1. Axes(xlValue) si riferisce specificamente all'asse numerico (in contrapposizione a xlCategory, l'asse che elenca i nomi delle regioni) — applicare NumberFormat qui controlla come vengono visualizzati i numeri lungo quell'asse, esattamente come NumberFormat su una cella del foglio. HasLegend = False rimuove completamente la legenda, operazione consigliata quando un grafico ha una sola serie, poiché una legenda che spiega un solo colore aggiunge confusione senza fornire informazioni.

Attività

  1. Eseguire BuildProfitChart e verificare che venga visualizzato un grafico a colonne che mostra il Profit per tutte e quindici le righe (tutti e tre i mesi, non filtrati).
  2. Aggiungere tre righe per colorare le barre del grafico di verde scuro (RGB(24,106,60)) e rimuovere la legenda, come mostrato sopra.
  3. Filtrare tblReports solo per gennaio e rieseguire SetSourceData su tbl.ListColumns("Profit").Range — osservare se il grafico rispetta il filtro.
Suggerimento
expand arrow

1. Esecuzione di BuildProfitChart

  • Copiare la Sub esattamente come mostrato nel capitolo ed eseguirla — non sono necessarie modifiche per questa parte.
  • Si dovrebbe vedere un grafico apparire nel foglio Reports che traccia il Profit per ogni riga attualmente visibile nella tabella.

2. Colorazione delle barre e rimozione della legenda

  • Entrambe le proprietà appartengono all'oggetto chart, non al foglio di lavoro — chartObj.Chart è il punto di accesso, come nell'esempio di formattazione nel capitolo.
  • Il colore delle barre si trova su SeriesCollection(1), poiché viene tracciata solo una serie di dati (Profit) — .Format.Fill.ForeColor.RGB è la proprietà specifica da impostare.
  • La rimozione della legenda è una singola proprietà booleana (HasLegend), separata dalla riga del colore di riempimento.

3. Filtraggio e ri-esecuzione di SetSourceData

  • Applicare un AutoFilter su Month (Field:=1) limitato a "January" — la stessa tecnica della sezione 4.2.
  • Quindi chiamare nuovamente SetSourceData con la stessa espressione tbl.ListColumns("Profit").Range di BuildProfitChart — non è necessario modificare quella riga.
  • Osservare attentamente cosa succede al grafico dopo: si restringe solo alle cinque regioni di January, oppure mostra ancora tutte e quindici le righe comprese quelle appena nascoste da AutoFilter? Questa osservazione è il vero obiettivo di questo esercizio, non solo l'esecuzione del codice.
Soluzione
expand arrow
Option Explicit

' Point 1 — run this exactly as shown in the chapter
Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")

    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent

    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub

' Point 2 — color the bars and remove the legend
Sub FormatProfitChart()
    Dim ws As Worksheet
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set chartObj = ws.ChartObjects(1)

    With chartObj.Chart
        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
        .HasLegend = False
    End With
End Sub

' Point 3 — filter to January, then re-point the chart at the same range
Sub FilterJanuaryAndRefreshChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
    Set chartObj = ws.ChartObjects(1)

    tbl.Range.AutoFilter Field:=1, Criteria1:="January"

    chartObj.Chart.SetSourceData Source:=tbl.ListColumns("Profit").Range
End Sub

Eseguire questi in ordine: BuildProfitChart, poi FormatProfitChart, poi FilterJanuaryAndRefreshChart. Per il punto 3 in particolare — prestare attenzione a ciò che accade realmente. I grafici di Excel generalmente rispettano un AutoFilter attivo, nascondendo automaticamente le barre delle righe filtrate, anche senza rieseguire SetSourceData. Rieseguirlo qui serve principalmente a confermare che il grafico è ancora correttamente puntato sull'intera colonna — è il filtro stesso che gestisce la visualizzazione, non la chiamata a SetSourceData. Vale la pena testare con il filtro sia attivo che disattivo per vedere la differenza.

Note
Nota

Eseguire BuildProfitChart più di una volta crea ogni volta un nuovo grafico senza eliminare quello precedente — quindi diversi grafici finiscono per essere sovrapposti uno sopra l'altro. ChartObjects(1) si riferisce sempre al primo creato, che potrebbe ora essere nascosto sotto una copia più recente. Ecco perché le modifiche di formattazione possono essere eseguite con successo ma sembrare non avere alcun effetto visibile.

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 4. Capitolo 4

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Automazione dei grafici

I grafici sono forme posizionate sopra un foglio di lavoro e, come tutto il resto in questo capitolo, ogni proprietà che imposteresti manualmente nel riquadro Formato ha un equivalente in VBA.

Figura 4.4

Creazione di un grafico

Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject
 
    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
 
    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent
 
    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub
Analisi riga per riga
expand arrow
  • AddChart2 crea effettivamente la forma del grafico — Style:=201 seleziona uno stile visivo predefinito, XlChartType:=xlColumnClustered seleziona un grafico a colonne standard, e Left/Top/Width/Height ne determinano posizione e dimensioni sul foglio di lavoro in punti, la stessa unità che Excel utilizza internamente per il posizionamento delle forme;
  • AddChart2 restituisce in realtà un oggetto Chart, non il contenitore ChartObject che lo circonda — il .Chart.Parent alla fine di quella riga serve a risalire al contenitore, che è il tipo con cui chartObj è dichiarato; questa particolarità è facile da dimenticare e vale la pena copiarla esattamente;
  • SetSourceData indica alla forma del grafico, altrimenti vuota, quali dati rappresentare — puntando a tbl.ListColumns("Profit").Range si rappresenta la colonna Profit su tutte le righe visibili della Tabella;
  • HasTitle = True deve essere impostato prima di assegnare ChartTitle.Text — provare a impostare il testo del titolo su un grafico che non ha ancora un titolo attivo causerà un errore.

Aggiornamento dei dati del grafico

Quando la tabella sottostante cresce, indirizzare il grafico al nuovo intervallo con SetSourceData invece di eliminarlo e ricostruirlo — questo preserva qualsiasi formattazione manuale già applicata:

Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range

ChartObjects(1) si riferisce alla prima forma grafico sul foglio in base alla posizione — va bene quando c'è un solo grafico, ma diventa fragile nel momento in cui viene aggiunto un secondo grafico, poiché "primo" può silenziosamente significare qualcosa di diverso dopo. Fare riferimento a un grafico tramite un nome impostato esplicitamente (chartObj.Name = "ProfitChart", poi ChartObjects("ProfitChart")) è più robusto quando un foglio contiene più di un grafico.

Formattazione dei grafici

With chartObj.Chart
    .ChartTitle.Font.Size = 14
    .ChartTitle.Font.Bold = True
    .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
    .Axes(xlValue).TickLabels.NumberFormat = "#,##0"
    .HasLegend = False
End With

SeriesCollection(1) è la prima (e qui unica) serie di dati rappresentata — il suo Format.Fill.ForeColor.RGB determina il colore effettivo delle barre, utilizzando la stessa funzione RGB(...) degli esempi di formattazione del Capitolo 1. Axes(xlValue) si riferisce specificamente all'asse numerico (in contrapposizione a xlCategory, l'asse che elenca i nomi delle regioni) — applicare NumberFormat qui controlla come vengono visualizzati i numeri lungo quell'asse, esattamente come NumberFormat su una cella del foglio. HasLegend = False rimuove completamente la legenda, operazione consigliata quando un grafico ha una sola serie, poiché una legenda che spiega un solo colore aggiunge confusione senza fornire informazioni.

Attività

  1. Eseguire BuildProfitChart e verificare che venga visualizzato un grafico a colonne che mostra il Profit per tutte e quindici le righe (tutti e tre i mesi, non filtrati).
  2. Aggiungere tre righe per colorare le barre del grafico di verde scuro (RGB(24,106,60)) e rimuovere la legenda, come mostrato sopra.
  3. Filtrare tblReports solo per gennaio e rieseguire SetSourceData su tbl.ListColumns("Profit").Range — osservare se il grafico rispetta il filtro.
Suggerimento
expand arrow

1. Esecuzione di BuildProfitChart

  • Copiare la Sub esattamente come mostrato nel capitolo ed eseguirla — non sono necessarie modifiche per questa parte.
  • Si dovrebbe vedere un grafico apparire nel foglio Reports che traccia il Profit per ogni riga attualmente visibile nella tabella.

2. Colorazione delle barre e rimozione della legenda

  • Entrambe le proprietà appartengono all'oggetto chart, non al foglio di lavoro — chartObj.Chart è il punto di accesso, come nell'esempio di formattazione nel capitolo.
  • Il colore delle barre si trova su SeriesCollection(1), poiché viene tracciata solo una serie di dati (Profit) — .Format.Fill.ForeColor.RGB è la proprietà specifica da impostare.
  • La rimozione della legenda è una singola proprietà booleana (HasLegend), separata dalla riga del colore di riempimento.

3. Filtraggio e ri-esecuzione di SetSourceData

  • Applicare un AutoFilter su Month (Field:=1) limitato a "January" — la stessa tecnica della sezione 4.2.
  • Quindi chiamare nuovamente SetSourceData con la stessa espressione tbl.ListColumns("Profit").Range di BuildProfitChart — non è necessario modificare quella riga.
  • Osservare attentamente cosa succede al grafico dopo: si restringe solo alle cinque regioni di January, oppure mostra ancora tutte e quindici le righe comprese quelle appena nascoste da AutoFilter? Questa osservazione è il vero obiettivo di questo esercizio, non solo l'esecuzione del codice.
Soluzione
expand arrow
Option Explicit

' Point 1 — run this exactly as shown in the chapter
Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")

    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent

    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub

' Point 2 — color the bars and remove the legend
Sub FormatProfitChart()
    Dim ws As Worksheet
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set chartObj = ws.ChartObjects(1)

    With chartObj.Chart
        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
        .HasLegend = False
    End With
End Sub

' Point 3 — filter to January, then re-point the chart at the same range
Sub FilterJanuaryAndRefreshChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
    Set chartObj = ws.ChartObjects(1)

    tbl.Range.AutoFilter Field:=1, Criteria1:="January"

    chartObj.Chart.SetSourceData Source:=tbl.ListColumns("Profit").Range
End Sub

Eseguire questi in ordine: BuildProfitChart, poi FormatProfitChart, poi FilterJanuaryAndRefreshChart. Per il punto 3 in particolare — prestare attenzione a ciò che accade realmente. I grafici di Excel generalmente rispettano un AutoFilter attivo, nascondendo automaticamente le barre delle righe filtrate, anche senza rieseguire SetSourceData. Rieseguirlo qui serve principalmente a confermare che il grafico è ancora correttamente puntato sull'intera colonna — è il filtro stesso che gestisce la visualizzazione, non la chiamata a SetSourceData. Vale la pena testare con il filtro sia attivo che disattivo per vedere la differenza.

Note
Nota

Eseguire BuildProfitChart più di una volta crea ogni volta un nuovo grafico senza eliminare quello precedente — quindi diversi grafici finiscono per essere sovrapposti uno sopra l'altro. ChartObjects(1) si riferisce sempre al primo creato, che potrebbe ora essere nascosto sotto una copia più recente. Ecco perché le modifiche di formattazione possono essere eseguite con successo ma sembrare non avere alcun effetto visibile.

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 4. Capitolo 4
some-alt