Skapa pivottabeller med VBA
Svep för att visa menyn
En pivottabell sammanfattar en tabell genom att dra fält till Rader, Kolumner och Värden — och varje sådan dra-och-släpp-åtgärd har en direkt VBA-motsvarighet, vilket innebär att en hel pivottabellsrapport kan återskapas från grunden av en makro varje gång ny data anländer.
Skapa en pivottabell
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
- On Error Resume Next i kombination med
DisplayAlertsoch.Deleteär ett säkert "ta bort om det finns"-mönster: att ta bort ett blad som inte finns skulle normalt ge ett fel och stoppa makrot, men On Error Resume Next instruerar VBA att tyst fortsätta förbi just det felet;DisplayAlerts = Falseundertrycker Excels egen "är du säker på att du vill ta bort det här bladet?"-bekräftelse; - On
Error GoTo 0direkt efteråt återställer normal felrapportering — omOn Error Resume Nextlämnas aktiv för resten avSubskulle även senare, orelaterade fel tyst ignoreras, vilket är en fälla att undvika; ThisWorkbook.PivotCaches.Createtar en ögonblicksbild av tabellens data — PivotCache, inte själva PivotTable — vilket är objektet som varje PivotTable faktiskt byggs från i bakgrunden;pc.CreatePivotTableomvandlar ögonblicksbilden till en synlig pivottabell, placerad med start i cell A3 på det nya Pivot-bladet och får namnet ptProfitByRegion så att senare kod (t.ex. RefreshTable) kan hitta den igen via namnet;PivotFields("Region").Orientation = xlRowFieldoch raden med Month direkt under är den direkta kodmotsvarigheten till att dra Region till radrutan och Month till kolumnrutan i fältlistan;AddDataFieldfyller i värdeområdet — det andra argumentet ("Sum of Profit") är bara etiketten som Excel visar som kolumnrubrik, och xlSum anger att värdena ska summeras istället för att medelvärdesberäknas eller räknas.
Uppdatera rapporter
När en pivottabell finns behöver du inte bygga om den varje gång ny data tillkommer — du uppdaterar den, vilket går snabbare och bevarar alla manuella layoutändringar som en användare gjort:
ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
Den här enstaka raden läser om PivotCache från det aktuella läget i tblReports och uppdaterar alla siffror i pivottabellen så att de stämmer — men lämnar layouten exakt som den är, inklusive kolumnbredder, talformat eller fältplaceringar som användaren justerat för hand efter att pivottabellen först skapades. Det är den stora fördelen jämfört med att anropa BuildProfitPivot igen: att bygga om från grunden skulle återskapa bladet och radera alla sådana manuella ändringar.
Uppdatera pivottabeller
Ett pivottabell-diagram som bygger på en pivottabell uppdaterar sina data automatiskt varje gång pivottabellen uppdateras — så att uppdatera tabellen är oftast allt en rapportmakro behöver göra för att hålla ett kopplat diagram aktuellt:
Dim pt As PivotTable
Set pt = ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion")
pt.RefreshTable
' any PivotChart based on pt updates automatically — no extra code needed
Detta är värt att jämföra med vanliga diagram som behandlas i nästa avsnitt: ett vanligt diagram kräver ett explicit SetSourceData-anrop för att peka på ny data, medan ett pivottabell-diagram är permanent länkat till sin pivottabell och följer med automatiskt. Om en dashboard behöver ett diagram som alltid speglar de senaste pivottabell-siffrorna med minsta möjliga kod är det oftast bättre att bygga det som ett pivottabell-diagram istället för ett fristående diagram.
Uppgift
- Kör
BuildProfitPivotexakt som visat och bekräfta att ett nytt "Pivot"-blad visas med Region längs raderna och Month över kolumnerna. - Lägg manuellt till en ny March-rad i
tblReportsför en fiktiv sjätte region, kör sedan endast RefreshTable-raden — bekräfta att pivottabellen uppdateras utan att byggas om från början. - Ändra
BuildProfitPivotså att den summerar Sales istället för Profit, och byt plats på Region och Month så att Month hamnar i rader och Region i kolumner.
Här är koden för att lägga till en sjätte region som en ny Mars-rad i tblReports, med hjälp av ListRows.Add istället för att skriva in den manuellt:
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
Kör detta en gång och kör sedan RefreshProfitPivot-Sub:en från tidigare — pivottabellen ska nu visa "Southwest" som en ny rad tillsammans med North, South, East, West och Central, utan att du har ändrat något i makrot som bygger pivottabellen.
1. Köra BuildProfitPivot som den är
- Kopiera
Sub-proceduren exakt som den står i kapitlet till din modul och kör den en gång. - Kontrollera Project Explorer eller dina bladflikar — ett nytt blad med namnet "Pivot" ska nu finnas, med Region listat nedåt i raderna och Month utspritt över kolumnerna, summerande Profit.
2. Lägga till en sjätte region och endast uppdatera
- Skriv in den nya raden direkt i kalkylbladet (inte via kod) — gå längst ner i
tblReportsoch lägg till en Mars-rad för en påhittad region, t.ex. "Southwest." - Kör inte om
BuildProfitPivot— det skulle ta bort och bygga om hela Pivot-bladet från början, vilket motverkar syftet med denna övning. - Kör istället endast den enradiga
RefreshTable-satsen från kapitlet — du behöver referera till den befintliga pivottabellen med namn, på samma sätt som kapitlets eget exempel för uppdatering gjorde.
3. Byta fält och ändra summerat värde
- Tre rader inuti
With pt-blocket behöver ändras: vilket fält som ärxlRowField, vilket som ärxlColumnFieldoch vilket fältAddDataFieldpekar på. - Ge denna modifierade version ett annat
Sub-namn och ett annatTableName— att återanvända samma namn som originalet skulle antingen ge fel eller tyst skriva över den första pivottabellen. - Etiketten som skickas till
AddDataField(det andra argumentet, som"Sum of Profit") är bara visningstext — uppdatera den så att den matchar det du faktiskt summerar nu.
Punkt 2 — efter att du manuellt lagt till raden för den sjätte regionen, kör bara detta:
Sub RefreshProfitPivot()
ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
End Sub
Punkt 3 — en separat, modifierad version:
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
Kör BuildSalesPivotByMonth och du ska få ett nytt "SalesPivot"-blad med Month nedåt i raderna, Region över kolumnerna och Sales-totaler i tabellkroppen — spegelbilden av den ursprungliga layouten.
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal