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.
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
- L'uso di On Error Resume Next insieme all'attivazione/disattivazione di
DisplayAlertse.Deleterappresenta 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 = Falsesopprime il popup di conferma di Excel "sei sicuro di voler eliminare questo foglio?"; - L'istruzione
Error GoTo 0subito dopo riattiva la normale segnalazione degli errori — lasciare attivoOn Error Resume Nextper il resto dellaSubfarebbe sì che anche errori successivi e non correlati vengano ignorati silenziosamente, una trappola da evitare; ThisWorkbook.PivotCaches.Createcrea 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.CreatePivotTabletrasforma 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 = xlRowFielde 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;AddDataFieldpopola 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à
- Eseguire
BuildProfitPivotesattamente come mostrato e verificare che compaia un nuovo foglio "Pivot" con Region nelle righe e Month nelle colonne. - Aggiungere manualmente una nuova riga March a
tblReportsper una sesta regione fittizia, quindi eseguire solo la riga RefreshTable — verificare che la Pivot si aggiorni senza essere ricostruita da zero. - Modificare
BuildProfitPivotper riepilogare Sales invece di Profit e scambiare Region e Month in modo che Month sia nelle righe e Region nelle colonne.
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.
1. Esecuzione di BuildProfitPivot così com'è
- Copia la
Subesattamente 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
tblReportse 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
RefreshTabledi 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 ptdevono essere modificate: quale campo èxlRowField, quale èxlColumnFielde a quale campo puntaAddDataField. - Dai a questa versione modificata un nome
Subdiverso e un nomeTableNamediverso — 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.
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.
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
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.
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
- L'uso di On Error Resume Next insieme all'attivazione/disattivazione di
DisplayAlertse.Deleterappresenta 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 = Falsesopprime il popup di conferma di Excel "sei sicuro di voler eliminare questo foglio?"; - L'istruzione
Error GoTo 0subito dopo riattiva la normale segnalazione degli errori — lasciare attivoOn Error Resume Nextper il resto dellaSubfarebbe sì che anche errori successivi e non correlati vengano ignorati silenziosamente, una trappola da evitare; ThisWorkbook.PivotCaches.Createcrea 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.CreatePivotTabletrasforma 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 = xlRowFielde 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;AddDataFieldpopola 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à
- Eseguire
BuildProfitPivotesattamente come mostrato e verificare che compaia un nuovo foglio "Pivot" con Region nelle righe e Month nelle colonne. - Aggiungere manualmente una nuova riga March a
tblReportsper una sesta regione fittizia, quindi eseguire solo la riga RefreshTable — verificare che la Pivot si aggiorni senza essere ricostruita da zero. - Modificare
BuildProfitPivotper riepilogare Sales invece di Profit e scambiare Region e Month in modo che Month sia nelle righe e Region nelle colonne.
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.
1. Esecuzione di BuildProfitPivot così com'è
- Copia la
Subesattamente 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
tblReportse 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
RefreshTabledi 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 ptdevono essere modificate: quale campo èxlRowField, quale èxlColumnFielde a quale campo puntaAddDataField. - Dai a questa versione modificata un nome
Subdiverso e un nomeTableNamediverso — 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.
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.
Grazie per i tuoi commenti!