ChartObjects and the Chart Inside Them
Lesson 1 of 7 ยท 11 min
A chart on a sheet is two objects
This catches everyone once. The box floating on your worksheet is a ChartObject โ a container, like a picture frame, with a position, a size, a name and a border. The picture inside the frame is the Chart, and that is what owns the series, the axes, the title and the type.
- ChartObject โ
.Left,.Top,.Width,.Height,.Name,.Delete. - Chart โ
.ChartType,.SetSourceData,.SeriesCollection,.Axes,.ChartTitle,.Export. - The bridge โ
co.Chartgets from the frame to the picture,ch.Parentback again. - The rule โ where the chart sits is the ChartObject, what the chart shows is the Chart.
co.ChartTypefails and so doesch.Left.
First, something to look at
Run this once to get a sheet with data and two badly placed charts on it. Lessons 2 and 3 explain these four chart lines properly; here they are only there to give the next macro some work.
Option Explicit
Sub MakeChartDemo()
Dim ws As Worksheet
Dim co As ChartObject
Dim r As Long
Set ws = ThisWorkbook.Worksheets.Add( _
After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
ws.Name = "Chart Demo " & Format(Now, "hhmmss")
ws.Range("A1:B1").Value = Array("Month", "Revenue")
For r = 2 To 13
ws.Cells(r, 1).Value = Format(DateSerial(2026, r - 1, 1), "mmm")
ws.Cells(r, 2).Value = 1000 + r * 137
Next r
Set co = ws.ChartObjects.Add(Left:=200, Top:=20, Width:=300, Height:=180)
co.Chart.SetSourceData Source:=ws.Range("A1:B13")
co.Chart.ChartType = xlColumnClustered
Set co = ws.ChartObjects.Add(Left:=260, Top:=90, Width:=250, Height:=150)
co.Chart.SetSourceData Source:=ws.Range("A1:B13")
co.Chart.ChartType = xlLine
End SubThe macro: line up every chart in the workbook
Dragging charts until they are the same size is a job nobody should do twice. This walks every worksheet, gives each chart a predictable name, snaps it to the same width, height and left edge, stacks the charts down the sheet and prints an inventory.
Sub TidyAllCharts()
Dim ws As Worksheet
Dim co As ChartObject
Dim ch As Chart
Dim anchor As Range
Dim n As Long
Dim total As Long
For Each ws In ThisWorkbook.Worksheets
Set anchor = ws.Range("H2")
n = 0
For Each co In ws.ChartObjects
n = n + 1
total = total + 1
Set ch = co.Chart
co.Name = "cht" & Format(ws.Index, "00") & "_" & Format(n, "00")
co.Left = anchor.Left
co.Top = anchor.Top + (n - 1) * 280
co.Width = 440
co.Height = 260
Debug.Print ws.Name & " | " & co.Name & _
" | type " & ch.ChartType & _
" | series " & ch.SeriesCollection.Count & _
" | has title " & ch.HasTitle
Next co
Next ws
MsgBox total & " chart(s) aligned. Details are in the Immediate window, " & _
"which you open with Ctrl+G in the VBA editor.", vbInformation
End SubLine by line
For Each co In ws.ChartObjectsโChartObjectsis a worksheet collection. Charts on their own full-page tab are not in it: those sit inThisWorkbook.Charts, and this macro leaves them alone.Set ch = co.Chartis the single line that crosses from the frame to the picture. Everything above it is geometry, everything below it is content.co.Name = "cht" & ...gives every frame a predictable name, so later code can sayws.ChartObjects("cht01_01")instead of trusting an index that shifts as soon as somebody deletes a chart. If code in your workbook already refers to charts by name, comment this line out first.co.Left = anchor.Leftandco.Top = anchor.Topposition the frame against cell H2 rather than at a guessed number. Reading geometry off a cell is the trick worth stealing here.+ (n - 1) * 280stacks the charts downwards, leaving 20 points of air between two charts 260 points high.co.Widthandco.Heightare in points, not pixels โ 72 to the inch, identical on every screen. Sizing in code is the only way to make a report look the same on two machines.ch.ChartType,ch.SeriesCollection.Countandch.HasTitleare all read from the Chart. Askcofor any of them and you get error 438.Debug.Printwrites to the Immediate window; theMsgBoxreports only the count, because a message box holding forty charts helps nobody.
The trap: ActiveChart is usually Nothing
Start the macro recorder, click a chart, change its title, and the recording hands you ActiveChart.ChartTitle.Text = "Revenue". It works while the chart is selected. Assign the very same macro to a button and it stops at run-time error 91, "Object variable or With block variable not set" โ clicking the button deselected the chart, so ActiveChart is Nothing. Same code, same workbook, and nothing on screen explains the difference.
' Recorded: depends on whatever happens to be selected ActiveChart.HasTitle = True ActiveChart.ChartTitle.Text = "Revenue" ' Written: depends on nothing at all Dim ch As Chart Set ch = ThisWorkbook.Worksheets(1).ChartObjects(1).Chart ch.HasTitle = True ch.ChartTitle.Text = "Revenue"
Select and Activate are the recorder's way of pointing at things, because pointing is all it can see you do. A variable is better in every way: set the object once, use it as often as you like, and the macro stops caring what the user clicked last โ and runs faster, because Excel is not redrawing a selection each time.
ch.Parent is the ChartObject, so a routine that was handed a Chart can still resize its frame with ch.Parent.Width = 440.How this course goes on
This lesson takes stock of charts that already exist; lesson 2 creates them from nothing, comparing the old ChartObjects.Add with the newer Shapes.AddChart2. Lesson 3 feeds a chart with SetSourceData, including the PlotBy setting that decides whether twelve months become twelve series or one โ the difference between a readable chart and an absurd one. After that come chart types, titles, axes and the legend, formatting individual series, and exporting a finished chart as an image file.
co. Which of these lines raises error 438, "Object doesn't support this property or method"?Sign in to answer and track your progress.
Sign in- ๐ Adding a Chart in Code 7 min
- ๐ Feeding the Chart with SetSourceData 8 min
- ๐ Choosing the Chart Type 7 min
- ๐ Titles, Axes and the Legend 8 min
- ๐ Working with Series and Formatting 8 min
- ๐ Exporting a Chart as an Image 7 min
Pro unlocks these 6 lessons, the final exam and the certificate โ plus every other course.
Unlock all lessons