Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Automatisering av diagram | Automatisering av Tabeller och Rapporter
Excel VBA för affärsautomatisering

Automatisering av diagram

Svep för att visa menyn

Diagram är former som ligger ovanpå ett kalkylblad, och precis som allt annat i detta kapitel har varje egenskap du ställer in manuellt i formateringspanelen en motsvarighet i VBA.

Figur 4.4

Skapa ett diagram

Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject
 
    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
 
    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent
 
    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub
Genomgång rad för rad
expand arrow
  • AddChart2 skapar själva diagramformen — Style:=201 väljer en inbyggd visuell stil, XlChartType:=xlColumnClustered väljer ett standardkolumndiagram, och Left/Top/Width/Height placerar och storleksanpassar det på kalkylbladet i punkter, samma enhet som Excel använder internt för formplacering;
  • AddChart2 returnerar faktiskt ett Chart-objekt, inte behållaren ChartObject runt det — .Chart.Parent i slutet av raden kliver tillbaka upp till behållaren, vilket är den typ som chartObj är deklarerad som; denna detalj är lätt att glömma och värd att kopiera exakt;
  • SetSourceData anger vilken data det annars tomma diagrammet ska visa — att peka på tbl.ListColumns("Profit").Range innebär att det diagrammerar kolumnen Profit över varje synlig rad i tabellen;
  • HasTitle = True måste anges innan ChartTitle.Text tilldelas — att försöka ange titeltext på ett diagram som ännu inte har en titel aktiverad kommer att misslyckas.

Uppdatera diagramdata

När den underliggande tabellen växer, peka diagrammet mot det nya området med SetSourceData istället för att ta bort och återskapa det — detta bevarar eventuell manuell formatering som redan har tillämpats:

Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range

ChartObjects(1) syftar på den första diagramformen på bladet efter position — fungerar när det bara finns ett diagram, men är känsligt så fort ett andra diagram läggs till, eftersom "första" då kan betyda något annat. Att referera till ett diagram med ett namn du själv sätter (chartObj.Name = "ProfitChart", sedan ChartObjects("ProfitChart")) är mer robust när ett blad har fler än ett diagram.

Formatera diagram

With chartObj.Chart
    .ChartTitle.Font.Size = 14
    .ChartTitle.Font.Bold = True
    .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
    .Axes(xlValue).TickLabels.NumberFormat = "#,##0"
    .HasLegend = False
End With

SeriesCollection(1) är den första (och här enda) dataserien som plottas — dess Format.Fill.ForeColor.RGB färglägger själva staplarna, med samma RGB(...) funktion som i kapitel 1:s formateringsexempel. Axes(xlValue) syftar specifikt på den numeriska axeln (till skillnad från xlCategory, axeln som listar Region-namn) — att tillämpa NumberFormat där styr hur siffrorna längs den axeln visas, precis som NumberFormat på en kalkylbladscell. HasLegend = False tar bort förklaringen helt, vilket är värt att göra när ett diagram bara har en serie, eftersom en förklaring för en enda färg bara tillför onödig information.

Uppgift

  1. Kör BuildProfitChart och bekräfta att ett kolumndiagram visas som visar Profit för alla femton rader (alla tre månader, ofiltrerat).
  2. Lägg till tre rader för att färglägga diagrammets staplar mörkgrönt (RGB(24,106,60)) och ta bort förklaringen, enligt ovan.
  3. Filtrera tblReports till endast januari och kör SetSourceData igen mot tbl.ListColumns("Profit").Range — observera om diagrammet respekterar filtret.
Tips
expand arrow

1. Köra BuildProfitChart

  • Kopiera Sub exakt som den visas i kapitlet och kör den — inga ändringar behövs för denna del.
  • Du bör se ett diagram visas på bladet Reports som visar vinst för varje rad som för närvarande är synlig i tabellen.

2. Färglägga staplar och ta bort förklaringen

  • Båda egenskaperna tillhör diagramobjektet, inte kalkylbladet — chartObj.Chart är din ingångspunkt, precis som i formaterings­exemplet i kapitlet.
  • Stapelfärgen finns på SeriesCollection(1), eftersom det bara finns en dataserie som plottas (Profit) — .Format.Fill.ForeColor.RGB är den specifika egenskapen att sätta.
  • Att ta bort förklaringen är en separat boolesk egenskap (HasLegend), separat från raden för fyllnadsfärg.

3. Filtrera och köra SetSourceData igen

  • Använd en AutoFilter på Month (Field:=1) begränsad till "January" — samma teknik som i avsnitt 4.2.
  • Anropa sedan SetSourceData igen med exakt samma uttryck tbl.ListColumns("Profit").Range från BuildProfitChart — inget i den raden behöver ändras.
  • Titta noga på vad som händer med diagrammet efteråt: krymper det till endast januaris fem regioner, eller visar det fortfarande alla femton rader inklusive de som AutoFilter just dolde? Den observationen är själva poängen med denna uppgift, inte bara att köra koden.
Lösning
expand arrow
Option Explicit

' Point 1 — run this exactly as shown in the chapter
Sub BuildProfitChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

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

    Set chartObj = ws.Shapes.AddChart2(Style:=201, _
        XlChartType:=xlColumnClustered, _
        Left:=400, Top:=20, Width:=400, Height:=250).Chart.Parent

    With chartObj.Chart
        .SetSourceData Source:=tbl.ListColumns("Profit").Range
        .HasTitle = True
        .ChartTitle.Text = "Profit by Region"
    End With
End Sub

' Point 2 — color the bars and remove the legend
Sub FormatProfitChart()
    Dim ws As Worksheet
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set chartObj = ws.ChartObjects(1)

    With chartObj.Chart
        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(24, 106, 60)
        .HasLegend = False
    End With
End Sub

' Point 3 — filter to January, then re-point the chart at the same range
Sub FilterJanuaryAndRefreshChart()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim chartObj As ChartObject

    Set ws = ThisWorkbook.Worksheets("Reports")
    Set tbl = ws.ListObjects("tblReports")
    Set chartObj = ws.ChartObjects(1)

    tbl.Range.AutoFilter Field:=1, Criteria1:="January"

    chartObj.Chart.SetSourceData Source:=tbl.ListColumns("Profit").Range
End Sub

Kör dessa i ordning: BuildProfitChart, sedan FormatProfitChart, sedan FilterJanuaryAndRefreshChart. För punkt 3 specifikt — var uppmärksam på vad som faktiskt händer. Excel-diagram respekterar generellt en aktiv AutoFilter och döljer automatiskt staplar för filtrerade rader, även utan att köra SetSourceData igen. Att köra den igen här bekräftar mest att diagrammet fortfarande pekar på hela kolumnen — det är själva filtret som gör den visuella döljen, inte anropet till SetSourceData. Det är värt att testa med filtret både på och av för att se skillnaden själv.

Note
Obs

Att köra BuildProfitChart mer än en gång skapar ett nytt diagram varje gång utan att ta bort det gamla — så flera diagram hamnar staplade ovanpå varandra. ChartObjects(1) syftar alltid på det första som skapades, vilket nu kan vara dolt under en nyare kopia. Det är därför formateringsändringar kan köras utan fel men ändå inte synas.

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 4

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Avsnitt 4. Kapitel 4
some-alt