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

Creazione di tabelle pivot con VBA

Scorri per mostrare il menu

Una tabella pivot riassume una tabella trascinando i campi nelle aree Righe, Colonne e Valori — e ognuna di queste azioni di trascinamento ha un equivalente diretto in VBA, il che significa che un intero report di tabella pivot può essere ricostruito da zero da una macro ogni volta che arrivano nuovi dati.

Figura 4.3

Creazione di una tabella pivot

Sub BuildProfitPivot()
    Dim wsData As Worksheet, wsPivot As Worksheet
    Dim tbl As ListObject
    Dim pc As PivotCache
    Dim pt As PivotTable
 
    Set wsData = ThisWorkbook.Worksheets("Reports")
    Set tbl = wsData.ListObjects("tblReports")
 
    ' start clean: remove an existing Pivot sheet if this has run before
    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("Pivot").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0
 
    Set wsPivot = ThisWorkbook.Worksheets.Add
    wsPivot.Name = "Pivot"
 
    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, SourceData:=tbl.Range)
 
    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsPivot.Range("A3"), _
        TableName:="ptProfitByRegion")
 
    With pt
        .PivotFields("Region").Orientation = xlRowField
        .PivotFields("Month").Orientation = xlColumnField
        .AddDataField .PivotFields("Profit"), "Sum of Profit", xlSum
    End With
End Sub
Analisi riga per riga
expand arrow
  • L'uso di On Error Resume Next insieme all'attivazione/disattivazione di DisplayAlerts e .Delete rappresenta un modello sicuro per "eliminare se esiste": eliminare un foglio che non esiste normalmente genererebbe un errore e fermerebbe la macro, ma On Error Resume Next indica a VBA di continuare tranquillamente oltre quell'errore specifico; DisplayAlerts = False sopprime il popup di conferma di Excel "sei sicuro di voler eliminare questo foglio?";
  • L'istruzione Error GoTo 0 subito dopo riattiva la normale segnalazione degli errori — lasciare attivo On Error Resume Next per il resto della Sub farebbe sì che anche errori successivi e non correlati vengano ignorati silenziosamente, una trappola da evitare;
  • ThisWorkbook.PivotCaches.Create crea un'istantanea dei dati della Tabella — il PivotCache, non la PivotTable stessa — che è l'oggetto da cui ogni PivotTable viene effettivamente costruita in background;
  • pc.CreatePivotTable trasforma quell'istantanea in una PivotTable visibile, posizionata a partire dalla cella A3 sul nuovo foglio Pivot e denominata ptProfitByRegion, così che il codice successivo (ad esempio RefreshTable) possa ritrovarla tramite il nome;
  • PivotFields("Region").Orientation = xlRowField e la riga Month immediatamente sotto sono l'equivalente diretto in codice del trascinare Region nella casella Righe e Month nella casella Colonne nell'elenco dei campi;
  • AddDataField popola l'area Valori — il secondo argomento ("Sum of Profit") è solo l'etichetta che Excel mostra come intestazione di colonna, e xlSum indica di sommare i valori invece di calcolarli come media o conteggio.

Aggiornamento dei report

Una volta creata una PivotTable, non viene ricostruita ogni volta che arrivano nuovi dati — viene aggiornata, operazione più veloce che preserva eventuali modifiche manuali all'impaginazione fatte dall'utente:

ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable

Questa singola riga rilegge il PivotCache dallo stato attuale di tblReports e aggiorna ogni numero nella PivotTable di conseguenza — ma lascia la struttura esattamente com'è, incluse eventuali larghezze di colonna, formattazioni numeriche o disposizione dei campi modificate manualmente dopo la creazione della Pivot. Questo è il vantaggio principale rispetto a richiamare BuildProfitPivot: ricostruire da zero ricreerebbe il foglio e cancellerebbe tutte queste modifiche manuali.

Aggiornamento dei PivotChart

Un PivotChart costruito su una PivotTable aggiorna automaticamente i suoi dati ogni volta che la PivotTable viene aggiornata — quindi aggiornare la tabella è di solito tutto ciò che serve a una macro di report per mantenere aggiornato anche un grafico collegato:

Dim pt As PivotTable
Set pt = ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion")
pt.RefreshTable
' any PivotChart based on pt updates automatically — no extra code needed

Vale la pena confrontare questo comportamento con i grafici normali trattati nella prossima sezione: un grafico normale richiede una chiamata esplicita a SetSourceData per puntare ai nuovi dati, mentre un PivotChart è permanentemente collegato alla sua PivotTable e si aggiorna automaticamente. Se un dashboard necessita di un grafico che rifletta sempre i dati più recenti della PivotTable con il minimo codice, costruirlo come PivotChart invece che come grafico indipendente è di solito la scelta migliore.

Attività

  1. Eseguire BuildProfitPivot esattamente come mostrato e verificare che compaia un nuovo foglio "Pivot" con Region nelle righe e Month nelle colonne.
  2. Aggiungere manualmente una nuova riga March a tblReports per una sesta regione fittizia, quindi eseguire solo la riga RefreshTable — verificare che la Pivot si aggiorni senza essere ricostruita da zero.
  3. Modificare BuildProfitPivot per riepilogare Sales invece di Profit e scambiare Region e Month in modo che Month sia nelle righe e Region nelle colonne.
Guida
expand arrow

Ecco il codice per aggiungere una sesta regione come nuova riga di marzo in tblReports, utilizzando ListRows.Add invece di inserirla manualmente:

Sub AddSixthRegion()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "March"        ' Month
    newRow.Range(1, 2).Value = "Southwest"    ' Region
    newRow.Range(1, 3).Value = 41500          ' Sales
    newRow.Range(1, 4).Value = 28200          ' Expenses
    newRow.Range(1, 5).Value = 13300          ' Profit
    newRow.Range(1, 6).Value = 39000          ' Target
End Sub

Esegui questo una volta, poi esegui la Sub RefreshProfitPivot vista in precedenza — la tabella Pivot ora dovrebbe mostrare "Southwest" come una nuova riga insieme a North, South, East, West e Central, senza che tu abbia modificato affatto la macro di creazione della Pivot.

Suggerimento
expand arrow

1. Esecuzione di BuildProfitPivot così com'è

  • Copia la Sub esattamente come scritta nel capitolo nel tuo modulo ed eseguila una volta.
  • Controlla l'Esplora progetti o le schede del foglio — dovrebbe apparire un nuovo foglio chiamato letteralmente "Pivot", con Region elencato sulle righe e Month distribuito sulle colonne, sommando Profit.

2. Aggiunta di una sesta regione e solo aggiornamento

  • Inserisci la nuova riga direttamente nel foglio di lavoro (non tramite codice) — vai in fondo a tblReports e aggiungi una riga di marzo per una regione inventata, ad esempio "Southwest."
  • Non rieseguire BuildProfitPivot — questo eliminerebbe e ricostruirebbe l'intero foglio Pivot da zero, il che vanifica lo scopo di questo esercizio.
  • Invece, esegui solo l'istruzione RefreshTable di una riga dal capitolo — dovrai fare riferimento alla PivotTable esistente per nome, nello stesso modo in cui l'esempio di aggiornamento del capitolo ha fatto.

3. Scambio dei campi e modifica del valore riepilogato

  • Tre righe all'interno del blocco With pt devono essere modificate: quale campo è xlRowField, quale è xlColumnField e a quale campo punta AddDataField.
  • Dai a questa versione modificata un nome Sub diverso e un nome TableName diverso — riutilizzare gli stessi nomi dell'originale causerebbe un errore o sovrascriverebbe silenziosamente la prima tabella Pivot.
  • L'etichetta passata a AddDataField (il secondo argomento, come "Sum of Profit") è solo testo di visualizzazione — aggiornala per riflettere ciò che stai effettivamente riepilogando ora.
Soluzione
expand arrow

Punto 2 — dopo aver aggiunto manualmente la riga della sesta regione, esegui solo questo:

Sub RefreshProfitPivot()
    ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
End Sub

Punto 3 — una versione separata e modificata:

Sub BuildSalesPivotByMonth()
    Dim wsData As Worksheet, wsPivot As Worksheet
    Dim tbl As ListObject
    Dim pc As PivotCache
    Dim pt As PivotTable

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

    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("SalesPivot").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0

    Set wsPivot = ThisWorkbook.Worksheets.Add
    wsPivot.Name = "SalesPivot"

    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, SourceData:=tbl.Range)

    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsPivot.Range("A3"), _
        TableName:="ptSalesByMonth")

    With pt
        .PivotFields("Month").Orientation = xlRowField
        .PivotFields("Region").Orientation = xlColumnField
        .AddDataField .PivotFields("Sales"), "Sum of Sales", xlSum
    End With
End Sub

Esegui BuildSalesPivotByMonth e dovresti ottenere un nuovo foglio "SalesPivot" con Month sulle righe, Region sulle colonne e i totali Sales nel corpo — l'immagine speculare del layout originale.

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 4. Capitolo 3

Chieda ad AI

expand

Chieda ad AI

ChatGPT

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

Creazione di tabelle pivot con VBA

Una tabella pivot riassume una tabella trascinando i campi nelle aree Righe, Colonne e Valori — e ognuna di queste azioni di trascinamento ha un equivalente diretto in VBA, il che significa che un intero report di tabella pivot può essere ricostruito da zero da una macro ogni volta che arrivano nuovi dati.

Figura 4.3

Creazione di una tabella pivot

Sub BuildProfitPivot()
    Dim wsData As Worksheet, wsPivot As Worksheet
    Dim tbl As ListObject
    Dim pc As PivotCache
    Dim pt As PivotTable
 
    Set wsData = ThisWorkbook.Worksheets("Reports")
    Set tbl = wsData.ListObjects("tblReports")
 
    ' start clean: remove an existing Pivot sheet if this has run before
    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("Pivot").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0
 
    Set wsPivot = ThisWorkbook.Worksheets.Add
    wsPivot.Name = "Pivot"
 
    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, SourceData:=tbl.Range)
 
    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsPivot.Range("A3"), _
        TableName:="ptProfitByRegion")
 
    With pt
        .PivotFields("Region").Orientation = xlRowField
        .PivotFields("Month").Orientation = xlColumnField
        .AddDataField .PivotFields("Profit"), "Sum of Profit", xlSum
    End With
End Sub
Analisi riga per riga
expand arrow
  • L'uso di On Error Resume Next insieme all'attivazione/disattivazione di DisplayAlerts e .Delete rappresenta un modello sicuro per "eliminare se esiste": eliminare un foglio che non esiste normalmente genererebbe un errore e fermerebbe la macro, ma On Error Resume Next indica a VBA di continuare tranquillamente oltre quell'errore specifico; DisplayAlerts = False sopprime il popup di conferma di Excel "sei sicuro di voler eliminare questo foglio?";
  • L'istruzione Error GoTo 0 subito dopo riattiva la normale segnalazione degli errori — lasciare attivo On Error Resume Next per il resto della Sub farebbe sì che anche errori successivi e non correlati vengano ignorati silenziosamente, una trappola da evitare;
  • ThisWorkbook.PivotCaches.Create crea un'istantanea dei dati della Tabella — il PivotCache, non la PivotTable stessa — che è l'oggetto da cui ogni PivotTable viene effettivamente costruita in background;
  • pc.CreatePivotTable trasforma quell'istantanea in una PivotTable visibile, posizionata a partire dalla cella A3 sul nuovo foglio Pivot e denominata ptProfitByRegion, così che il codice successivo (ad esempio RefreshTable) possa ritrovarla tramite il nome;
  • PivotFields("Region").Orientation = xlRowField e la riga Month immediatamente sotto sono l'equivalente diretto in codice del trascinare Region nella casella Righe e Month nella casella Colonne nell'elenco dei campi;
  • AddDataField popola l'area Valori — il secondo argomento ("Sum of Profit") è solo l'etichetta che Excel mostra come intestazione di colonna, e xlSum indica di sommare i valori invece di calcolarli come media o conteggio.

Aggiornamento dei report

Una volta creata una PivotTable, non viene ricostruita ogni volta che arrivano nuovi dati — viene aggiornata, operazione più veloce che preserva eventuali modifiche manuali all'impaginazione fatte dall'utente:

ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable

Questa singola riga rilegge il PivotCache dallo stato attuale di tblReports e aggiorna ogni numero nella PivotTable di conseguenza — ma lascia la struttura esattamente com'è, incluse eventuali larghezze di colonna, formattazioni numeriche o disposizione dei campi modificate manualmente dopo la creazione della Pivot. Questo è il vantaggio principale rispetto a richiamare BuildProfitPivot: ricostruire da zero ricreerebbe il foglio e cancellerebbe tutte queste modifiche manuali.

Aggiornamento dei PivotChart

Un PivotChart costruito su una PivotTable aggiorna automaticamente i suoi dati ogni volta che la PivotTable viene aggiornata — quindi aggiornare la tabella è di solito tutto ciò che serve a una macro di report per mantenere aggiornato anche un grafico collegato:

Dim pt As PivotTable
Set pt = ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion")
pt.RefreshTable
' any PivotChart based on pt updates automatically — no extra code needed

Vale la pena confrontare questo comportamento con i grafici normali trattati nella prossima sezione: un grafico normale richiede una chiamata esplicita a SetSourceData per puntare ai nuovi dati, mentre un PivotChart è permanentemente collegato alla sua PivotTable e si aggiorna automaticamente. Se un dashboard necessita di un grafico che rifletta sempre i dati più recenti della PivotTable con il minimo codice, costruirlo come PivotChart invece che come grafico indipendente è di solito la scelta migliore.

Attività

  1. Eseguire BuildProfitPivot esattamente come mostrato e verificare che compaia un nuovo foglio "Pivot" con Region nelle righe e Month nelle colonne.
  2. Aggiungere manualmente una nuova riga March a tblReports per una sesta regione fittizia, quindi eseguire solo la riga RefreshTable — verificare che la Pivot si aggiorni senza essere ricostruita da zero.
  3. Modificare BuildProfitPivot per riepilogare Sales invece di Profit e scambiare Region e Month in modo che Month sia nelle righe e Region nelle colonne.
Guida
expand arrow

Ecco il codice per aggiungere una sesta regione come nuova riga di marzo in tblReports, utilizzando ListRows.Add invece di inserirla manualmente:

Sub AddSixthRegion()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "March"        ' Month
    newRow.Range(1, 2).Value = "Southwest"    ' Region
    newRow.Range(1, 3).Value = 41500          ' Sales
    newRow.Range(1, 4).Value = 28200          ' Expenses
    newRow.Range(1, 5).Value = 13300          ' Profit
    newRow.Range(1, 6).Value = 39000          ' Target
End Sub

Esegui questo una volta, poi esegui la Sub RefreshProfitPivot vista in precedenza — la tabella Pivot ora dovrebbe mostrare "Southwest" come una nuova riga insieme a North, South, East, West e Central, senza che tu abbia modificato affatto la macro di creazione della Pivot.

Suggerimento
expand arrow

1. Esecuzione di BuildProfitPivot così com'è

  • Copia la Sub esattamente come scritta nel capitolo nel tuo modulo ed eseguila una volta.
  • Controlla l'Esplora progetti o le schede del foglio — dovrebbe apparire un nuovo foglio chiamato letteralmente "Pivot", con Region elencato sulle righe e Month distribuito sulle colonne, sommando Profit.

2. Aggiunta di una sesta regione e solo aggiornamento

  • Inserisci la nuova riga direttamente nel foglio di lavoro (non tramite codice) — vai in fondo a tblReports e aggiungi una riga di marzo per una regione inventata, ad esempio "Southwest."
  • Non rieseguire BuildProfitPivot — questo eliminerebbe e ricostruirebbe l'intero foglio Pivot da zero, il che vanifica lo scopo di questo esercizio.
  • Invece, esegui solo l'istruzione RefreshTable di una riga dal capitolo — dovrai fare riferimento alla PivotTable esistente per nome, nello stesso modo in cui l'esempio di aggiornamento del capitolo ha fatto.

3. Scambio dei campi e modifica del valore riepilogato

  • Tre righe all'interno del blocco With pt devono essere modificate: quale campo è xlRowField, quale è xlColumnField e a quale campo punta AddDataField.
  • Dai a questa versione modificata un nome Sub diverso e un nome TableName diverso — riutilizzare gli stessi nomi dell'originale causerebbe un errore o sovrascriverebbe silenziosamente la prima tabella Pivot.
  • L'etichetta passata a AddDataField (il secondo argomento, come "Sum of Profit") è solo testo di visualizzazione — aggiornala per riflettere ciò che stai effettivamente riepilogando ora.
Soluzione
expand arrow

Punto 2 — dopo aver aggiunto manualmente la riga della sesta regione, esegui solo questo:

Sub RefreshProfitPivot()
    ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
End Sub

Punto 3 — una versione separata e modificata:

Sub BuildSalesPivotByMonth()
    Dim wsData As Worksheet, wsPivot As Worksheet
    Dim tbl As ListObject
    Dim pc As PivotCache
    Dim pt As PivotTable

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

    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("SalesPivot").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0

    Set wsPivot = ThisWorkbook.Worksheets.Add
    wsPivot.Name = "SalesPivot"

    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, SourceData:=tbl.Range)

    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsPivot.Range("A3"), _
        TableName:="ptSalesByMonth")

    With pt
        .PivotFields("Month").Orientation = xlRowField
        .PivotFields("Region").Orientation = xlColumnField
        .AddDataField .PivotFields("Sales"), "Sum of Sales", xlSum
    End With
End Sub

Esegui BuildSalesPivotByMonth e dovresti ottenere un nuovo foglio "SalesPivot" con Month sulle righe, Region sulle colonne e i totali Sales nel corpo — l'immagine speculare del layout originale.

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 4. Capitolo 3
some-alt