Automatisering av diagrammer
Sveip for å vise menyen
Diagrammer er figurer som ligger oppå et regneark, og som alt annet i dette kapittelet, har hver egenskap du kan angi manuelt i Format-panelet en tilsvarende VBA-egenskap.
Opprette et 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
- AddChart2 oppretter selve diagramformen —
Style:=201velger en innebygd visuell stil,XlChartType:=xlColumnClusteredvelger et standard kolonnediagram, og Left/Top/Width/Height plasserer og størrelsesbestemmer det på regnearket i punkter, samme enhet som Excel bruker internt for plassering av former; - AddChart2 returnerer faktisk et Chart-objekt, ikke ChartObject-beholderen rundt det —
.Chart.Parentpå slutten av linjen går tilbake til beholderen, som er typen chartObj er deklarert som; denne detaljen er lett å glemme og verdt å kopiere nøyaktig; SetSourceDataangir hvilke data det ellers tomme diagrammet skal vise — å peke det mottbl.ListColumns("Profit").Rangebetyr at det viser Profit-kolonnen for alle synlige rader i tabellen;HasTitle = Truemå settes førChartTitle.Texttildeles — å prøve å sette titteltekst på et diagram som ikke har tittel aktivert ennå vil feile.
Oppdatere diagramdata
Når den underliggende tabellen vokser, pek diagrammet mot det nye området med SetSourceData i stedet for å slette og bygge det opp igjen — dette bevarer eventuell manuell formatering som allerede er brukt:
Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range
ChartObjects(1) refererer til den første diagramformen på arket etter posisjon — dette fungerer når det bare er ett diagram, men blir sårbart så snart et andre diagram legges til, siden "første" da plutselig kan bety noe annet. Å referere til et diagram med et navn du har satt eksplisitt (chartObj.Name = "ProfitChart", deretter ChartObjects("ProfitChart")) er mer robust når et ark har mer enn ett diagram.
Formatering av diagrammer
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) er den første (og her eneste) dataserien som vises — dens Format.Fill.ForeColor.RGB bestemmer fargen på selve søylene, ved å bruke samme RGB(...) funksjon som i formateringseksemplene fra kapittel 1. Axes(xlValue) refererer spesifikt til den numeriske aksen (i motsetning til xlCategory, aksen som viser Region-navn) — å bruke NumberFormat der styrer hvordan tallene langs den aksen vises, akkurat som NumberFormat på en celle i regnearket. HasLegend = False fjerner forklaringen helt, noe som er lurt når et diagram bare har én serie, siden en forklaring for én farge bare gir rot uten å tilføre informasjon.
Oppgave
- Kjør
BuildProfitChartog bekreft at et kolonnediagram vises som viser Profit for alle femten rader (alle tre måneder, ufiltrert). - Legg til tre linjer for å farge diagrammets søyler mørkegrønne (RGB(24,106,60)) og fjern forklaringen, som vist ovenfor.
- Filtrer tblReports til kun januar og kjør
SetSourceDatamottbl.ListColumns("Profit").Rangepå nytt — legg merke til om diagrammet respekterer filteret.
1. Kjøre BuildProfitChart
- Kopier
Sub-rutinen nøyaktig som vist i kapitlet og kjør den — ingen endringer er nødvendig for denne delen. - Du skal se et diagram vises på rapportarket som viser fortjeneste for hver rad som for øyeblikket er synlig i tabellen.
2. Fargelegge stolpene og fjerne forklaringen
- Begge egenskapene tilhører diagramobjektet, ikke regnearket —
chartObj.Charter inngangspunktet, akkurat som i formateringseksempelet i kapitlet. - Stolpefargen ligger på
SeriesCollection(1), siden det bare er én dataserie som vises (Profit) —.Format.Fill.ForeColor.RGBer den spesifikke egenskapen som skal settes. - Å fjerne forklaringen er en egen boolsk egenskap (
HasLegend), separat fra linjen for fyllfarge.
3. Filtrere og kjøre SetSourceData på nytt
- Bruk en
AutoFilterpå Month (Field:=1) begrenset til "January" — samme teknikk som i seksjon 4.2. - Kall deretter
SetSourceDataigjen med nøyaktig sammetbl.ListColumns("Profit").Range-uttrykk fraBuildProfitChart— ingenting med den linjen trenger å endres. - Følg nøye med på hva som skjer med diagrammet etterpå: krymper det til bare januar sine fem regioner, eller viser det fortsatt alle femten radene inkludert de som AutoFilter nettopp skjulte? Det er selve poenget med denne oppgaven, ikke bare å kjøre koden.
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
Kjør disse i rekkefølge: BuildProfitChart, deretter FormatProfitChart, så FilterJanuaryAndRefreshChart. For punkt 3 spesielt — følg med på hva som faktisk skjer. Excel-diagrammer respekterer vanligvis en aktiv AutoFilter, og skjuler automatisk stolpene for filtrerte rader, selv uten å kjøre SetSourceData på nytt. Å kjøre den på nytt her bekrefter bare at diagrammet fortsatt peker på hele kolonnen — det er filteret i seg selv som skjuler radene visuelt, ikke SetSourceData-kallet. Det er verdt å teste med filter både på og av for å se forskjellen selv.
Å kjøre BuildProfitChart flere ganger lager et nytt diagram hver gang uten å slette det gamle — så flere diagrammer blir stablet oppå hverandre. ChartObjects(1) refererer alltid til det første som ble laget, som nå kan være skjult under en nyere kopi. Det er derfor formateringsendringer kan kjøres uten feil, men likevel ikke synes.
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår
Automatisering av diagrammer
Diagrammer er figurer som ligger oppå et regneark, og som alt annet i dette kapittelet, har hver egenskap du kan angi manuelt i Format-panelet en tilsvarende VBA-egenskap.
Opprette et 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
- AddChart2 oppretter selve diagramformen —
Style:=201velger en innebygd visuell stil,XlChartType:=xlColumnClusteredvelger et standard kolonnediagram, og Left/Top/Width/Height plasserer og størrelsesbestemmer det på regnearket i punkter, samme enhet som Excel bruker internt for plassering av former; - AddChart2 returnerer faktisk et Chart-objekt, ikke ChartObject-beholderen rundt det —
.Chart.Parentpå slutten av linjen går tilbake til beholderen, som er typen chartObj er deklarert som; denne detaljen er lett å glemme og verdt å kopiere nøyaktig; SetSourceDataangir hvilke data det ellers tomme diagrammet skal vise — å peke det mottbl.ListColumns("Profit").Rangebetyr at det viser Profit-kolonnen for alle synlige rader i tabellen;HasTitle = Truemå settes førChartTitle.Texttildeles — å prøve å sette titteltekst på et diagram som ikke har tittel aktivert ennå vil feile.
Oppdatere diagramdata
Når den underliggende tabellen vokser, pek diagrammet mot det nye området med SetSourceData i stedet for å slette og bygge det opp igjen — dette bevarer eventuell manuell formatering som allerede er brukt:
Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range
ChartObjects(1) refererer til den første diagramformen på arket etter posisjon — dette fungerer når det bare er ett diagram, men blir sårbart så snart et andre diagram legges til, siden "første" da plutselig kan bety noe annet. Å referere til et diagram med et navn du har satt eksplisitt (chartObj.Name = "ProfitChart", deretter ChartObjects("ProfitChart")) er mer robust når et ark har mer enn ett diagram.
Formatering av diagrammer
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) er den første (og her eneste) dataserien som vises — dens Format.Fill.ForeColor.RGB bestemmer fargen på selve søylene, ved å bruke samme RGB(...) funksjon som i formateringseksemplene fra kapittel 1. Axes(xlValue) refererer spesifikt til den numeriske aksen (i motsetning til xlCategory, aksen som viser Region-navn) — å bruke NumberFormat der styrer hvordan tallene langs den aksen vises, akkurat som NumberFormat på en celle i regnearket. HasLegend = False fjerner forklaringen helt, noe som er lurt når et diagram bare har én serie, siden en forklaring for én farge bare gir rot uten å tilføre informasjon.
Oppgave
- Kjør
BuildProfitChartog bekreft at et kolonnediagram vises som viser Profit for alle femten rader (alle tre måneder, ufiltrert). - Legg til tre linjer for å farge diagrammets søyler mørkegrønne (RGB(24,106,60)) og fjern forklaringen, som vist ovenfor.
- Filtrer tblReports til kun januar og kjør
SetSourceDatamottbl.ListColumns("Profit").Rangepå nytt — legg merke til om diagrammet respekterer filteret.
1. Kjøre BuildProfitChart
- Kopier
Sub-rutinen nøyaktig som vist i kapitlet og kjør den — ingen endringer er nødvendig for denne delen. - Du skal se et diagram vises på rapportarket som viser fortjeneste for hver rad som for øyeblikket er synlig i tabellen.
2. Fargelegge stolpene og fjerne forklaringen
- Begge egenskapene tilhører diagramobjektet, ikke regnearket —
chartObj.Charter inngangspunktet, akkurat som i formateringseksempelet i kapitlet. - Stolpefargen ligger på
SeriesCollection(1), siden det bare er én dataserie som vises (Profit) —.Format.Fill.ForeColor.RGBer den spesifikke egenskapen som skal settes. - Å fjerne forklaringen er en egen boolsk egenskap (
HasLegend), separat fra linjen for fyllfarge.
3. Filtrere og kjøre SetSourceData på nytt
- Bruk en
AutoFilterpå Month (Field:=1) begrenset til "January" — samme teknikk som i seksjon 4.2. - Kall deretter
SetSourceDataigjen med nøyaktig sammetbl.ListColumns("Profit").Range-uttrykk fraBuildProfitChart— ingenting med den linjen trenger å endres. - Følg nøye med på hva som skjer med diagrammet etterpå: krymper det til bare januar sine fem regioner, eller viser det fortsatt alle femten radene inkludert de som AutoFilter nettopp skjulte? Det er selve poenget med denne oppgaven, ikke bare å kjøre koden.
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
Kjør disse i rekkefølge: BuildProfitChart, deretter FormatProfitChart, så FilterJanuaryAndRefreshChart. For punkt 3 spesielt — følg med på hva som faktisk skjer. Excel-diagrammer respekterer vanligvis en aktiv AutoFilter, og skjuler automatisk stolpene for filtrerte rader, selv uten å kjøre SetSourceData på nytt. Å kjøre den på nytt her bekrefter bare at diagrammet fortsatt peker på hele kolonnen — det er filteret i seg selv som skjuler radene visuelt, ikke SetSourceData-kallet. Det er verdt å teste med filter både på og av for å se forskjellen selv.
Å kjøre BuildProfitChart flere ganger lager et nytt diagram hver gang uten å slette det gamle — så flere diagrammer blir stablet oppå hverandre. ChartObjects(1) refererer alltid til det første som ble laget, som nå kan være skjult under en nyere kopi. Det er derfor formateringsendringer kan kjøres uten feil, men likevel ikke synes.
Takk for tilbakemeldingene dine!