Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Oppretting av pivottabeller med VBA | Automatisering av tabeller og rapporter
Excel VBA for Forretningsautomatisering

Oppretting av pivottabeller med VBA

Sveip for å vise menyen

En pivottabell oppsummerer en tabell ved å dra felt inn i Rader, Kolonner og Verdier — og hver av disse dra-og-slipp-handlingene har en direkte VBA-ekvivalent, noe som betyr at en hel pivottabellrapport kan bygges opp fra bunnen av med en makro hver gang nye data kommer inn.

Figur 4.3

Bygge 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
Gjennomgang linje for linje
expand arrow
  • On Error Resume Next sammen med DisplayAlerts-bryteren og .Delete er et trygt "slett hvis den finnes"-mønster: å slette et ark som ikke eksisterer vil normalt kaste en feil og stoppe makroen, men On Error Resume Next forteller VBA å fortsette stille forbi akkurat den feilen; DisplayAlerts = False undertrykker Excels egen "er du sikker på at du vil slette dette arket?"-bekreftelsesvindu;
  • On Error GoTo 0 rett etterpå slår normal feilrapportering på igjen — hvis du lar On Error Resume Next være aktiv for resten av Sub, vil det stille svelge alle senere, ikke-relaterte feil også, noe som er en felle det er verdt å unngå;
  • ThisWorkbook.PivotCaches.Create tar et øyeblikksbilde av tabellens data — PivotCache, ikke selve PivotTable — som er objektet alle PivotTable faktisk bygges fra i bakgrunnen;
  • pc.CreatePivotTable er det som gjør øyeblikksbildet om til en synlig PivotTable, plassert fra celle A3 på det nye Pivot-arket og gitt navnet ptProfitByRegion slik at senere kode (for eksempel RefreshTable) kan finne den igjen ved navn;
  • PivotFields("Region").Orientation = xlRowField og linjen med Month rett under er den direkte kodeekvivalenten til å dra Region inn i Rad-boksen og Month inn i Kolonne-boksen i feltlisten;
  • AddDataField er det som fyller ut Verdier-området — det andre argumentet ("Sum of Profit") er bare etiketten Excel viser som kolonneoverskrift, og xlSum forteller den å summere verdiene i stedet for å ta gjennomsnitt eller telle dem.

Oppdatere rapporter

Når en PivotTable eksisterer, bygger du den ikke opp på nytt hver gang nye data kommer — du oppdaterer den, noe som er raskere og bevarer eventuelle manuelle oppsettendringer en bruker har gjort:

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

Denne ene linjen leser PivotCache på nytt fra nåværende tilstand av tblReports og oppdaterer alle tallene i PivotTable slik at de samsvarer — men den lar oppsettet være nøyaktig som det er, inkludert kolonnebredder, tallformatering eller feltplassering som en bruker har justert manuelt etter at Pivot først ble opprettet. Det er den viktigste fordelen sammenlignet med å kalle BuildProfitPivot igjen: å bygge opp fra bunnen av ville gjenskapt arket og fjernet alle slike manuelle endringer.

Oppdatere PivotCharts

Et PivotChart bygget på toppen av en PivotTable oppdaterer dataene sine automatisk hver gang PivotTable oppdateres — så å oppdatere tabellen er vanligvis alt en rapportmakro trenger å gjøre for å holde et tilknyttet diagram oppdatert også:

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

Dette er verdt å sammenligne med vanlige diagrammer som dekkes i neste seksjon: et vanlig diagram trenger et eksplisitt SetSourceData-kall for å peke på nye data, mens et PivotChart er permanent koblet til sin PivotTable og følger bare med automatisk. Hvis et dashbord trenger et diagram som alltid gjenspeiler de siste PivotTable-tallene med minst mulig kode, er det vanligvis bedre å bygge det som et PivotChart i stedet for et frittstående diagram.

Oppgave

  1. Kjør BuildProfitPivot nøyaktig som vist og bekreft at et nytt "Pivot"-ark vises med Region nedover radene og Month bortover kolonnene.
  2. Legg manuelt til en ny March-rad i tblReports for en fiktiv sjette region, og kjør deretter kun RefreshTable-linjen — bekreft at Pivot oppdateres uten å bygge den opp på nytt.
  3. Endre BuildProfitPivot til å oppsummere Sales i stedet for Profit, og bytt Region og Month slik at Month er i rader og Region er i kolonner.
Hjelper
expand arrow

Her er koden for å legge til en sjette region som en ny Mars-rad i tblReports, ved å bruke ListRows.Add i stedet for å skrive den inn manuelt:

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

Kjør denne én gang, og kjør deretter RefreshProfitPivot-suben fra tidligere — Pivot-tabellen skal nå vise "Southwest" som en ny rad sammen med North, South, East, West og Central, uten at du har rørt makroen som bygger Pivot-tabellen.

Tips
expand arrow

1. Kjøre BuildProfitPivot som den er

  • Kopier Sub-rutinen nøyaktig slik den står i kapittelet inn i modulen din og kjør den én gang.
  • Sjekk Prosjektutforskeren eller arkfanene — et nytt ark med navnet "Pivot" skal dukke opp, med Region listet nedover radene og Month spredt over kolonnene, med summering av Profit.

2. Legge til en sjette region og kun oppdatere

  • Skriv inn den nye raden direkte i regnearket (ikke via kode) — gå til bunnen av tblReports og legg til en Mars-rad for en oppdiktet region, for eksempel "Southwest."
  • Ikke kjør BuildProfitPivot på nytt — det ville slettet og bygget hele Pivot-arket på nytt, noe som motvirker hensikten med denne øvelsen.
  • Kjør i stedet kun den énlinjes RefreshTable-setningen fra kapittelet — du må referere til den eksisterende PivotTable med navn, på samme måte som kapittelets eget oppdateringseksempel gjorde.

3. Bytte felt og endre oppsummert verdi

  • Tre linjer inne i With pt-blokken må endres: hvilket felt som er xlRowField, hvilket som er xlColumnField, og hvilket felt AddDataField peker på.
  • Gi denne modifiserte versjonen et annet Sub-navn og et annet TableName — å bruke de samme navnene som originalen vil enten gi feil eller stille overskrive den første Pivot-tabellen.
  • Merk at etiketten som sendes til AddDataField (det andre argumentet, som "Sum of Profit") kun er visningstekst — oppdater den til å matche det du faktisk oppsummerer nå.
Løsning
expand arrow

Punkt 2 — etter at du manuelt har lagt til raden for den sjette regionen, kjør bare dette:

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

Punkt 3 — en separat, modifisert versjon:

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

Kjør BuildSalesPivotByMonth og du skal få et nytt ark "SalesPivot" med Month nedover radene, Region over kolonnene og Sales-totalsummer i tabellen — speilvendt av den opprinnelige oppsettet.

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 4. Kapittel 3

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

Oppretting av pivottabeller med VBA

En pivottabell oppsummerer en tabell ved å dra felt inn i Rader, Kolonner og Verdier — og hver av disse dra-og-slipp-handlingene har en direkte VBA-ekvivalent, noe som betyr at en hel pivottabellrapport kan bygges opp fra bunnen av med en makro hver gang nye data kommer inn.

Figur 4.3

Bygge 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
Gjennomgang linje for linje
expand arrow
  • On Error Resume Next sammen med DisplayAlerts-bryteren og .Delete er et trygt "slett hvis den finnes"-mønster: å slette et ark som ikke eksisterer vil normalt kaste en feil og stoppe makroen, men On Error Resume Next forteller VBA å fortsette stille forbi akkurat den feilen; DisplayAlerts = False undertrykker Excels egen "er du sikker på at du vil slette dette arket?"-bekreftelsesvindu;
  • On Error GoTo 0 rett etterpå slår normal feilrapportering på igjen — hvis du lar On Error Resume Next være aktiv for resten av Sub, vil det stille svelge alle senere, ikke-relaterte feil også, noe som er en felle det er verdt å unngå;
  • ThisWorkbook.PivotCaches.Create tar et øyeblikksbilde av tabellens data — PivotCache, ikke selve PivotTable — som er objektet alle PivotTable faktisk bygges fra i bakgrunnen;
  • pc.CreatePivotTable er det som gjør øyeblikksbildet om til en synlig PivotTable, plassert fra celle A3 på det nye Pivot-arket og gitt navnet ptProfitByRegion slik at senere kode (for eksempel RefreshTable) kan finne den igjen ved navn;
  • PivotFields("Region").Orientation = xlRowField og linjen med Month rett under er den direkte kodeekvivalenten til å dra Region inn i Rad-boksen og Month inn i Kolonne-boksen i feltlisten;
  • AddDataField er det som fyller ut Verdier-området — det andre argumentet ("Sum of Profit") er bare etiketten Excel viser som kolonneoverskrift, og xlSum forteller den å summere verdiene i stedet for å ta gjennomsnitt eller telle dem.

Oppdatere rapporter

Når en PivotTable eksisterer, bygger du den ikke opp på nytt hver gang nye data kommer — du oppdaterer den, noe som er raskere og bevarer eventuelle manuelle oppsettendringer en bruker har gjort:

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

Denne ene linjen leser PivotCache på nytt fra nåværende tilstand av tblReports og oppdaterer alle tallene i PivotTable slik at de samsvarer — men den lar oppsettet være nøyaktig som det er, inkludert kolonnebredder, tallformatering eller feltplassering som en bruker har justert manuelt etter at Pivot først ble opprettet. Det er den viktigste fordelen sammenlignet med å kalle BuildProfitPivot igjen: å bygge opp fra bunnen av ville gjenskapt arket og fjernet alle slike manuelle endringer.

Oppdatere PivotCharts

Et PivotChart bygget på toppen av en PivotTable oppdaterer dataene sine automatisk hver gang PivotTable oppdateres — så å oppdatere tabellen er vanligvis alt en rapportmakro trenger å gjøre for å holde et tilknyttet diagram oppdatert også:

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

Dette er verdt å sammenligne med vanlige diagrammer som dekkes i neste seksjon: et vanlig diagram trenger et eksplisitt SetSourceData-kall for å peke på nye data, mens et PivotChart er permanent koblet til sin PivotTable og følger bare med automatisk. Hvis et dashbord trenger et diagram som alltid gjenspeiler de siste PivotTable-tallene med minst mulig kode, er det vanligvis bedre å bygge det som et PivotChart i stedet for et frittstående diagram.

Oppgave

  1. Kjør BuildProfitPivot nøyaktig som vist og bekreft at et nytt "Pivot"-ark vises med Region nedover radene og Month bortover kolonnene.
  2. Legg manuelt til en ny March-rad i tblReports for en fiktiv sjette region, og kjør deretter kun RefreshTable-linjen — bekreft at Pivot oppdateres uten å bygge den opp på nytt.
  3. Endre BuildProfitPivot til å oppsummere Sales i stedet for Profit, og bytt Region og Month slik at Month er i rader og Region er i kolonner.
Hjelper
expand arrow

Her er koden for å legge til en sjette region som en ny Mars-rad i tblReports, ved å bruke ListRows.Add i stedet for å skrive den inn manuelt:

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

Kjør denne én gang, og kjør deretter RefreshProfitPivot-suben fra tidligere — Pivot-tabellen skal nå vise "Southwest" som en ny rad sammen med North, South, East, West og Central, uten at du har rørt makroen som bygger Pivot-tabellen.

Tips
expand arrow

1. Kjøre BuildProfitPivot som den er

  • Kopier Sub-rutinen nøyaktig slik den står i kapittelet inn i modulen din og kjør den én gang.
  • Sjekk Prosjektutforskeren eller arkfanene — et nytt ark med navnet "Pivot" skal dukke opp, med Region listet nedover radene og Month spredt over kolonnene, med summering av Profit.

2. Legge til en sjette region og kun oppdatere

  • Skriv inn den nye raden direkte i regnearket (ikke via kode) — gå til bunnen av tblReports og legg til en Mars-rad for en oppdiktet region, for eksempel "Southwest."
  • Ikke kjør BuildProfitPivot på nytt — det ville slettet og bygget hele Pivot-arket på nytt, noe som motvirker hensikten med denne øvelsen.
  • Kjør i stedet kun den énlinjes RefreshTable-setningen fra kapittelet — du må referere til den eksisterende PivotTable med navn, på samme måte som kapittelets eget oppdateringseksempel gjorde.

3. Bytte felt og endre oppsummert verdi

  • Tre linjer inne i With pt-blokken må endres: hvilket felt som er xlRowField, hvilket som er xlColumnField, og hvilket felt AddDataField peker på.
  • Gi denne modifiserte versjonen et annet Sub-navn og et annet TableName — å bruke de samme navnene som originalen vil enten gi feil eller stille overskrive den første Pivot-tabellen.
  • Merk at etiketten som sendes til AddDataField (det andre argumentet, som "Sum of Profit") kun er visningstekst — oppdater den til å matche det du faktisk oppsummerer nå.
Løsning
expand arrow

Punkt 2 — etter at du manuelt har lagt til raden for den sjette regionen, kjør bare dette:

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

Punkt 3 — en separat, modifisert versjon:

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

Kjør BuildSalesPivotByMonth og du skal få et nytt ark "SalesPivot" med Month nedover radene, Region over kolonnene og Sales-totalsummer i tabellen — speilvendt av den opprinnelige oppsettet.

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 4. Kapittel 3
some-alt