Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Oprettelse af Pivottabeller med VBA | Automatisering af Tabeller og Rapporter
Excel VBA til Forretningsautomatisering

Oprettelse af Pivottabeller med VBA

Stryg for at vise menuen

En pivottabel opsummerer en tabel ved at trække felter ind i Rækker, Kolonner og Værdier — og hver af disse træk-og-slip-handlinger har en direkte VBA-ækvivalent, hvilket betyder, at en hel pivottabelrapport kan genopbygges fra bunden af et makro, hver gang nye data ankommer.

Figur 4.3

Oprettelse af en pivottabel

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
Gennemgang linje for linje
expand arrow
  • On Error Resume Next sammen med DisplayAlerts-skiftet og .Delete er et sikkert "slet hvis det findes"-mønster: at slette et ark, der ikke eksisterer, ville normalt udløse en fejl og stoppe makroen, men On Error Resume Next fortæller VBA at fortsætte stille og roligt forbi netop den fejl; DisplayAlerts = False undertrykker Excels egen "er du sikker på, at du vil slette dette ark?"-bekræftelses-popup;
  • On Error GoTo 0 umiddelbart bagefter slår normal fejlrapportering til igen — hvis On Error Resume Next forblev aktiv resten af Sub'en, ville det også skjule andre, ikke-relaterede fejl, hvilket er en fælde, man bør undgå;
  • ThisWorkbook.PivotCaches.Create tager et øjebliksbillede af tabellens data — PivotCache, ikke selve PivotTabellen — som er det objekt, alle PivotTabeller faktisk bygges ud fra i baggrunden;
  • pc.CreatePivotTable omdanner dette øjebliksbillede til en synlig PivotTable, placeret fra celle A3 på det nye Pivot-ark og får navnet ptProfitByRegion, så senere kode (f.eks. RefreshTable) kan finde den igen via navnet;
  • PivotFields("Region").Orientation = xlRowField og linjen med Month lige nedenunder er den direkte kodeækvivalent til at trække Region ind i Rækker-boksen og Month ind i Kolonner-boksen i feltlisten;
  • AddDataField udfylder Værdier-området — det andet argument ("Sum of Profit") er blot den etiket, Excel viser som kolonneoverskrift, og xlSum angiver, at værdierne skal summeres i stedet for at blive gennemsnitligt eller talt.

Opdatering af rapporter

Når en PivotTable først er oprettet, genopbygger du den ikke hver gang nye data tilføjes — du opdaterer den, hvilket er hurtigere og bevarer eventuelle manuelle layoutjusteringer, brugeren har foretaget:

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

Denne ene linje genindlæser PivotCache fra den aktuelle tilstand af tblReports og opdaterer alle tal i PivotTabellen, så de matcher — men den bevarer layoutet præcis, som det er, inklusive kolonnebredder, talformatering eller feltplacering, som brugeren har tilpasset manuelt efter den første oprettelse. Det er den afgørende fordel i forhold til at kalde BuildProfitPivot igen: genopbygning fra bunden ville genskabe arket og slette alle disse manuelle tilpasninger.

Opdatering af PivotCharts

Et PivotChart, der er bygget oven på en PivotTable, opdaterer automatisk sine data, hver gang PivotTabellen opdateres — så det er som regel alt, en rapportmakro behøver at gøre for at holde et tilknyttet diagram opdateret:

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 værd at sammenligne med almindelige diagrammer, som behandles i næste afsnit: et almindeligt diagram kræver et eksplicit SetSourceData-kald for at pege på nye data, mens et PivotChart er permanent forbundet til sin PivotTable og følger automatisk med. Hvis et dashboard skal have et diagram, der altid afspejler de nyeste PivotTable-tal med mindst mulig kode, er det som regel bedst at bygge det som et PivotChart frem for et selvstændigt diagram.

Opgave

  1. Kør BuildProfitPivot præcis som vist og bekræft, at et nyt "Pivot"-ark vises med Region ned ad rækkerne og Month hen over kolonnerne.
  2. Tilføj manuelt en ny March-række til tblReports for en fiktiv sjette region, og kør derefter kun RefreshTable-linjen — bekræft, at PivotTabellen opdateres uden at blive genopbygget fra bunden.
  3. Rediger BuildProfitPivot til at opsummere Sales i stedet for Profit, og byt om på Region og Month, så Month er i rækker og Region i kolonner.
Hjælper
expand arrow

Her er koden til at tilføje en sjette region som en ny marts-række i tblReports, ved at bruge ListRows.Add i stedet for at indtaste den 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

Kør dette én gang, og kør derefter RefreshProfitPivot Sub fra før — Pivot-tabellen bør nu vise "Southwest" som en ny række sammen med North, South, East, West og Central, uden at du har ændret Pivot-makroen overhovedet.

Tip
expand arrow

1. Kørsel af BuildProfitPivot som den er

  • Kopiér Sub-proceduren nøjagtigt som skrevet i kapitlet ind i dit modul og kør den én gang.
  • Tjek Project Explorer eller dine arkfaner — et nyt ark med navnet "Pivot" bør dukke op, med Region listet ned ad rækkerne og Month fordelt over kolonnerne, hvor Profit summeres.

2. Tilføjelse af en sjette region og kun opdatering

  • Indtast den nye række direkte i regnearket (ikke via kode) — gå til bunden af tblReports og tilføj en marts-række for en fiktiv region, f.eks. "Southwest."
  • Kør ikke BuildProfitPivot igen — det ville slette og genskabe hele Pivot-arket fra bunden, hvilket ikke er meningen med denne øvelse.
  • Kør i stedet kun den énlinede RefreshTable-sætning fra kapitlet — du skal referere til den eksisterende PivotTable ved navn, på samme måde som kapitlets eget opdateringseksempel gjorde.

3. Ombytning af felter og ændring af det summerede felt

  • Tre linjer inde i With pt-blokken skal ændres: hvilket felt er xlRowField, hvilket er xlColumnField, og hvilket felt AddDataField peger på.
  • Giv denne ændrede version et andet Sub-navn og et andet TableName — genbrug af de samme navne som originalen vil enten give fejl eller lydløst overskrive den første Pivot-tabel.
  • Mærkaten, der sendes til AddDataField (det andet argument, som "Sum of Profit"), er kun visningstekst — opdater den, så den matcher det, du faktisk opsummerer nu.
Løsning
expand arrow

Punkt 2 — efter manuelt at have tilføjet rækken for den sjette region, kør blot dette:

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

Punkt 3 — en separat, ændret 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, og du bør få et nyt "SalesPivot"-ark med Month ned ad rækkerne, Region hen over kolonnerne og Sales-totaler i kroppen — det spejlvendte layout af den oprindelige opstilling.

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 4. Kapitel 3

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Oprettelse af Pivottabeller med VBA

En pivottabel opsummerer en tabel ved at trække felter ind i Rækker, Kolonner og Værdier — og hver af disse træk-og-slip-handlinger har en direkte VBA-ækvivalent, hvilket betyder, at en hel pivottabelrapport kan genopbygges fra bunden af et makro, hver gang nye data ankommer.

Figur 4.3

Oprettelse af en pivottabel

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
Gennemgang linje for linje
expand arrow
  • On Error Resume Next sammen med DisplayAlerts-skiftet og .Delete er et sikkert "slet hvis det findes"-mønster: at slette et ark, der ikke eksisterer, ville normalt udløse en fejl og stoppe makroen, men On Error Resume Next fortæller VBA at fortsætte stille og roligt forbi netop den fejl; DisplayAlerts = False undertrykker Excels egen "er du sikker på, at du vil slette dette ark?"-bekræftelses-popup;
  • On Error GoTo 0 umiddelbart bagefter slår normal fejlrapportering til igen — hvis On Error Resume Next forblev aktiv resten af Sub'en, ville det også skjule andre, ikke-relaterede fejl, hvilket er en fælde, man bør undgå;
  • ThisWorkbook.PivotCaches.Create tager et øjebliksbillede af tabellens data — PivotCache, ikke selve PivotTabellen — som er det objekt, alle PivotTabeller faktisk bygges ud fra i baggrunden;
  • pc.CreatePivotTable omdanner dette øjebliksbillede til en synlig PivotTable, placeret fra celle A3 på det nye Pivot-ark og får navnet ptProfitByRegion, så senere kode (f.eks. RefreshTable) kan finde den igen via navnet;
  • PivotFields("Region").Orientation = xlRowField og linjen med Month lige nedenunder er den direkte kodeækvivalent til at trække Region ind i Rækker-boksen og Month ind i Kolonner-boksen i feltlisten;
  • AddDataField udfylder Værdier-området — det andet argument ("Sum of Profit") er blot den etiket, Excel viser som kolonneoverskrift, og xlSum angiver, at værdierne skal summeres i stedet for at blive gennemsnitligt eller talt.

Opdatering af rapporter

Når en PivotTable først er oprettet, genopbygger du den ikke hver gang nye data tilføjes — du opdaterer den, hvilket er hurtigere og bevarer eventuelle manuelle layoutjusteringer, brugeren har foretaget:

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

Denne ene linje genindlæser PivotCache fra den aktuelle tilstand af tblReports og opdaterer alle tal i PivotTabellen, så de matcher — men den bevarer layoutet præcis, som det er, inklusive kolonnebredder, talformatering eller feltplacering, som brugeren har tilpasset manuelt efter den første oprettelse. Det er den afgørende fordel i forhold til at kalde BuildProfitPivot igen: genopbygning fra bunden ville genskabe arket og slette alle disse manuelle tilpasninger.

Opdatering af PivotCharts

Et PivotChart, der er bygget oven på en PivotTable, opdaterer automatisk sine data, hver gang PivotTabellen opdateres — så det er som regel alt, en rapportmakro behøver at gøre for at holde et tilknyttet diagram opdateret:

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 værd at sammenligne med almindelige diagrammer, som behandles i næste afsnit: et almindeligt diagram kræver et eksplicit SetSourceData-kald for at pege på nye data, mens et PivotChart er permanent forbundet til sin PivotTable og følger automatisk med. Hvis et dashboard skal have et diagram, der altid afspejler de nyeste PivotTable-tal med mindst mulig kode, er det som regel bedst at bygge det som et PivotChart frem for et selvstændigt diagram.

Opgave

  1. Kør BuildProfitPivot præcis som vist og bekræft, at et nyt "Pivot"-ark vises med Region ned ad rækkerne og Month hen over kolonnerne.
  2. Tilføj manuelt en ny March-række til tblReports for en fiktiv sjette region, og kør derefter kun RefreshTable-linjen — bekræft, at PivotTabellen opdateres uden at blive genopbygget fra bunden.
  3. Rediger BuildProfitPivot til at opsummere Sales i stedet for Profit, og byt om på Region og Month, så Month er i rækker og Region i kolonner.
Hjælper
expand arrow

Her er koden til at tilføje en sjette region som en ny marts-række i tblReports, ved at bruge ListRows.Add i stedet for at indtaste den 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

Kør dette én gang, og kør derefter RefreshProfitPivot Sub fra før — Pivot-tabellen bør nu vise "Southwest" som en ny række sammen med North, South, East, West og Central, uden at du har ændret Pivot-makroen overhovedet.

Tip
expand arrow

1. Kørsel af BuildProfitPivot som den er

  • Kopiér Sub-proceduren nøjagtigt som skrevet i kapitlet ind i dit modul og kør den én gang.
  • Tjek Project Explorer eller dine arkfaner — et nyt ark med navnet "Pivot" bør dukke op, med Region listet ned ad rækkerne og Month fordelt over kolonnerne, hvor Profit summeres.

2. Tilføjelse af en sjette region og kun opdatering

  • Indtast den nye række direkte i regnearket (ikke via kode) — gå til bunden af tblReports og tilføj en marts-række for en fiktiv region, f.eks. "Southwest."
  • Kør ikke BuildProfitPivot igen — det ville slette og genskabe hele Pivot-arket fra bunden, hvilket ikke er meningen med denne øvelse.
  • Kør i stedet kun den énlinede RefreshTable-sætning fra kapitlet — du skal referere til den eksisterende PivotTable ved navn, på samme måde som kapitlets eget opdateringseksempel gjorde.

3. Ombytning af felter og ændring af det summerede felt

  • Tre linjer inde i With pt-blokken skal ændres: hvilket felt er xlRowField, hvilket er xlColumnField, og hvilket felt AddDataField peger på.
  • Giv denne ændrede version et andet Sub-navn og et andet TableName — genbrug af de samme navne som originalen vil enten give fejl eller lydløst overskrive den første Pivot-tabel.
  • Mærkaten, der sendes til AddDataField (det andet argument, som "Sum of Profit"), er kun visningstekst — opdater den, så den matcher det, du faktisk opsummerer nu.
Løsning
expand arrow

Punkt 2 — efter manuelt at have tilføjet rækken for den sjette region, kør blot dette:

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

Punkt 3 — en separat, ændret 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, og du bør få et nyt "SalesPivot"-ark med Month ned ad rækkerne, Region hen over kolonnerne og Sales-totaler i kroppen — det spejlvendte layout af den oprindelige opstilling.

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 4. Kapitel 3
some-alt