Automatisierung von Diagrammen
Swipe um das Menü anzuzeigen
Diagramme sind Formen, die auf einem Arbeitsblatt liegen, und wie alles andere in diesem Kapitel hat jede Eigenschaft, die man manuell im Formatierungsbereich einstellt, ein entsprechendes VBA-Pendant.
Diagramm erstellen
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 erstellt die Diagrammform selbst —
Style:=201wählt einen integrierten visuellen Stil,XlChartType:=xlColumnClusteredwählt ein Standard-Säulendiagramm, und Left/Top/Width/Height positionieren und dimensionieren es auf dem Arbeitsblatt in Punkt, derselben Einheit, die Excel intern für die Platzierung von Formen verwendet; - AddChart2 gibt tatsächlich ein Chart-Objekt zurück, nicht den ChartObject-Container darum herum — das
.Chart.Parentam Ende dieser Zeile springt wieder zum Container zurück, als dessen Typ chartObj deklariert ist; diese Besonderheit ist leicht zu vergessen und sollte exakt so übernommen werden; SetSourceDatagibt der ansonsten leeren Diagrammform an, welche Daten dargestellt werden sollen — die Angabe vontbl.ListColumns("Profit").Rangebedeutet, dass die Profit-Spalte über alle sichtbaren Zeilen der Tabelle dargestellt wird;HasTitle = Truemuss gesetzt werden, bevorChartTitle.Textzugewiesen wird — versucht man, den Titeltext bei einem Diagramm zu setzen, das noch keinen Titel hat, schlägt dies fehl.
Aktualisieren von Diagrammdaten
Wenn die zugrunde liegende Tabelle wächst, sollte das Diagramm mit SetSourceData auf den neuen Bereich verwiesen werden, anstatt es zu löschen und neu zu erstellen — so bleiben alle manuell vorgenommenen Formatierungen erhalten:
Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range
ChartObjects(1) bezieht sich auf die erste Diagrammform auf dem Blatt nach Position — das ist in Ordnung, solange es nur ein Diagramm gibt, wird aber problematisch, sobald ein zweites Diagramm hinzugefügt wird, da "erstes" dann stillschweigend etwas anderes bedeuten kann. Ein Diagramm über einen explizit vergebenen Namen zu referenzieren (chartObj.Name = "ProfitChart", dann ChartObjects("ProfitChart"))) ist robuster, sobald ein Blatt mehr als ein Diagramm enthält.
Diagramme formatieren
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) ist die erste (und hier einzige) dargestellte Datenreihe — deren Format.Fill.ForeColor.RGB legt die Farbe der Balken fest, wobei dieselbe RGB(...) Funktion wie in den Formatierungsbeispielen aus Kapitel 1 verwendet wird. Axes(xlValue) bezieht sich speziell auf die Zahlenachse (im Gegensatz zu xlCategory, der Achse mit den Regionsnamen) — die Anwendung von NumberFormat steuert, wie die Zahlen entlang dieser Achse angezeigt werden, genau wie NumberFormat in einer Tabellenzelle. HasLegend = False entfernt die Legende vollständig, was immer sinnvoll ist, wenn ein Diagramm nur eine Datenreihe enthält, da eine Legende für eine einzige Farbe nur unnötige Unübersichtlichkeit schafft.
Aufgabe
BuildProfitChartausführen und bestätigen, dass ein Säulendiagramm erscheint, das den Profit für alle fünfzehn Zeilen (alle drei Monate, ungefiltert) anzeigt.- Drei Zeilen hinzufügen, um die Balken des Diagramms dunkelgrün (RGB(24,106,60)) einzufärben und die Legende zu entfernen, wie oben gezeigt.
- tblReports auf nur Januar filtern und
SetSourceDataerneut auftbl.ListColumns("Profit").Rangeanwenden — beobachten, ob das Diagramm den Filter berücksichtigt.
1. Ausführen von BuildProfitChart
- Kopiere das
Subexakt wie im Kapitel gezeigt und führe es aus — für diesen Teil sind keine Änderungen nötig. - Es sollte ein Diagramm auf dem Blatt Reports erscheinen, das den Gewinn für jede aktuell sichtbare Zeile in der Tabelle darstellt.
2. Balken einfärben und Legende entfernen
- Beide Eigenschaften gehören zum Diagrammobjekt, nicht zum Arbeitsblatt —
chartObj.Chartist der Einstiegspunkt, wie im Formatierungsbeispiel im Kapitel. - Die Balkenfarbe befindet sich bei
SeriesCollection(1), da nur eine Datenreihe (Profit) dargestellt wird —.Format.Fill.ForeColor.RGBist die spezifische Eigenschaft zum Setzen. - Das Entfernen der Legende ist eine einzelne boolesche Eigenschaft (
HasLegend), getrennt von der Zeile für die Füllfarbe.
3. Filtern und SetSourceData erneut ausführen
- Wende einen
AutoFilterauf Month (Field:=1) an, eingeschränkt auf "January" — dieselbe Technik wie in Abschnitt 4.2. - Rufe dann erneut
SetSourceDatamit dem exakt gleichen Ausdrucktbl.ListColumns("Profit").RangeausBuildProfitChartauf — an dieser Zeile muss nichts geändert werden. - Beobachte genau, was danach mit dem Diagramm passiert: Schrumpft es auf nur die fünf Regionen des Januars oder zeigt es immer noch alle fünfzehn Zeilen, einschließlich der gerade durch AutoFilter ausgeblendeten? Diese Beobachtung ist der eigentliche Zweck dieser Aufgabe, nicht nur das Ausführen des Codes.
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
Führe diese in der Reihenfolge aus: BuildProfitChart, dann FormatProfitChart, dann FilterJanuaryAndRefreshChart. Speziell bei Punkt 3 — achte darauf, was tatsächlich passiert. Excel-Diagramme berücksichtigen in der Regel einen aktiven AutoFilter und blenden die Balken der herausgefilterten Zeilen automatisch aus, auch ohne dass SetSourceData erneut ausgeführt wird. Das erneute Ausführen bestätigt hier hauptsächlich, dass das Diagramm weiterhin korrekt auf die gesamte Spalte verweist — der Filter selbst sorgt für das Ausblenden, nicht der Aufruf von SetSourceData. Es lohnt sich, den Unterschied mit aktiviertem und deaktiviertem Filter selbst zu testen.
Das mehrfache Ausführen von BuildProfitChart erstellt jedes Mal ein neues Diagramm, ohne das alte zu löschen — so werden mehrere Diagramme übereinander gestapelt. ChartObjects(1) bezieht sich immer auf das erste erstellte Diagramm, das nun möglicherweise unter einer neueren Kopie verborgen ist. Deshalb können Formatierungsänderungen erfolgreich ausgeführt werden, aber scheinbar keine sichtbare Wirkung haben.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Automatisierung von Diagrammen
Diagramme sind Formen, die auf einem Arbeitsblatt liegen, und wie alles andere in diesem Kapitel hat jede Eigenschaft, die man manuell im Formatierungsbereich einstellt, ein entsprechendes VBA-Pendant.
Diagramm erstellen
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 erstellt die Diagrammform selbst —
Style:=201wählt einen integrierten visuellen Stil,XlChartType:=xlColumnClusteredwählt ein Standard-Säulendiagramm, und Left/Top/Width/Height positionieren und dimensionieren es auf dem Arbeitsblatt in Punkt, derselben Einheit, die Excel intern für die Platzierung von Formen verwendet; - AddChart2 gibt tatsächlich ein Chart-Objekt zurück, nicht den ChartObject-Container darum herum — das
.Chart.Parentam Ende dieser Zeile springt wieder zum Container zurück, als dessen Typ chartObj deklariert ist; diese Besonderheit ist leicht zu vergessen und sollte exakt so übernommen werden; SetSourceDatagibt der ansonsten leeren Diagrammform an, welche Daten dargestellt werden sollen — die Angabe vontbl.ListColumns("Profit").Rangebedeutet, dass die Profit-Spalte über alle sichtbaren Zeilen der Tabelle dargestellt wird;HasTitle = Truemuss gesetzt werden, bevorChartTitle.Textzugewiesen wird — versucht man, den Titeltext bei einem Diagramm zu setzen, das noch keinen Titel hat, schlägt dies fehl.
Aktualisieren von Diagrammdaten
Wenn die zugrunde liegende Tabelle wächst, sollte das Diagramm mit SetSourceData auf den neuen Bereich verwiesen werden, anstatt es zu löschen und neu zu erstellen — so bleiben alle manuell vorgenommenen Formatierungen erhalten:
Dim cht As Chart
Set cht = ThisWorkbook.Worksheets("Reports").ChartObjects(1).Chart
cht.SetSourceData Source:=tbl.ListColumns("Profit").Range
ChartObjects(1) bezieht sich auf die erste Diagrammform auf dem Blatt nach Position — das ist in Ordnung, solange es nur ein Diagramm gibt, wird aber problematisch, sobald ein zweites Diagramm hinzugefügt wird, da "erstes" dann stillschweigend etwas anderes bedeuten kann. Ein Diagramm über einen explizit vergebenen Namen zu referenzieren (chartObj.Name = "ProfitChart", dann ChartObjects("ProfitChart"))) ist robuster, sobald ein Blatt mehr als ein Diagramm enthält.
Diagramme formatieren
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) ist die erste (und hier einzige) dargestellte Datenreihe — deren Format.Fill.ForeColor.RGB legt die Farbe der Balken fest, wobei dieselbe RGB(...) Funktion wie in den Formatierungsbeispielen aus Kapitel 1 verwendet wird. Axes(xlValue) bezieht sich speziell auf die Zahlenachse (im Gegensatz zu xlCategory, der Achse mit den Regionsnamen) — die Anwendung von NumberFormat steuert, wie die Zahlen entlang dieser Achse angezeigt werden, genau wie NumberFormat in einer Tabellenzelle. HasLegend = False entfernt die Legende vollständig, was immer sinnvoll ist, wenn ein Diagramm nur eine Datenreihe enthält, da eine Legende für eine einzige Farbe nur unnötige Unübersichtlichkeit schafft.
Aufgabe
BuildProfitChartausführen und bestätigen, dass ein Säulendiagramm erscheint, das den Profit für alle fünfzehn Zeilen (alle drei Monate, ungefiltert) anzeigt.- Drei Zeilen hinzufügen, um die Balken des Diagramms dunkelgrün (RGB(24,106,60)) einzufärben und die Legende zu entfernen, wie oben gezeigt.
- tblReports auf nur Januar filtern und
SetSourceDataerneut auftbl.ListColumns("Profit").Rangeanwenden — beobachten, ob das Diagramm den Filter berücksichtigt.
1. Ausführen von BuildProfitChart
- Kopiere das
Subexakt wie im Kapitel gezeigt und führe es aus — für diesen Teil sind keine Änderungen nötig. - Es sollte ein Diagramm auf dem Blatt Reports erscheinen, das den Gewinn für jede aktuell sichtbare Zeile in der Tabelle darstellt.
2. Balken einfärben und Legende entfernen
- Beide Eigenschaften gehören zum Diagrammobjekt, nicht zum Arbeitsblatt —
chartObj.Chartist der Einstiegspunkt, wie im Formatierungsbeispiel im Kapitel. - Die Balkenfarbe befindet sich bei
SeriesCollection(1), da nur eine Datenreihe (Profit) dargestellt wird —.Format.Fill.ForeColor.RGBist die spezifische Eigenschaft zum Setzen. - Das Entfernen der Legende ist eine einzelne boolesche Eigenschaft (
HasLegend), getrennt von der Zeile für die Füllfarbe.
3. Filtern und SetSourceData erneut ausführen
- Wende einen
AutoFilterauf Month (Field:=1) an, eingeschränkt auf "January" — dieselbe Technik wie in Abschnitt 4.2. - Rufe dann erneut
SetSourceDatamit dem exakt gleichen Ausdrucktbl.ListColumns("Profit").RangeausBuildProfitChartauf — an dieser Zeile muss nichts geändert werden. - Beobachte genau, was danach mit dem Diagramm passiert: Schrumpft es auf nur die fünf Regionen des Januars oder zeigt es immer noch alle fünfzehn Zeilen, einschließlich der gerade durch AutoFilter ausgeblendeten? Diese Beobachtung ist der eigentliche Zweck dieser Aufgabe, nicht nur das Ausführen des Codes.
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
Führe diese in der Reihenfolge aus: BuildProfitChart, dann FormatProfitChart, dann FilterJanuaryAndRefreshChart. Speziell bei Punkt 3 — achte darauf, was tatsächlich passiert. Excel-Diagramme berücksichtigen in der Regel einen aktiven AutoFilter und blenden die Balken der herausgefilterten Zeilen automatisch aus, auch ohne dass SetSourceData erneut ausgeführt wird. Das erneute Ausführen bestätigt hier hauptsächlich, dass das Diagramm weiterhin korrekt auf die gesamte Spalte verweist — der Filter selbst sorgt für das Ausblenden, nicht der Aufruf von SetSourceData. Es lohnt sich, den Unterschied mit aktiviertem und deaktiviertem Filter selbst zu testen.
Das mehrfache Ausführen von BuildProfitChart erstellt jedes Mal ein neues Diagramm, ohne das alte zu löschen — so werden mehrere Diagramme übereinander gestapelt. ChartObjects(1) bezieht sich immer auf das erste erstellte Diagramm, das nun möglicherweise unter einer neueren Kopie verborgen ist. Deshalb können Formatierungsänderungen erfolgreich ausgeführt werden, aber scheinbar keine sichtbare Wirkung haben.
Danke für Ihr Feedback!