excel vba chart on a different sheet using that sheet's data - vba

I have a program that creates a new sheet, adds data to that sheet, and the last part it should do is chart that output. When I try the code below, I get "object or variable or with block variable not set"
please let me know where I am going wrong. thank you.
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Shapes.AddChart.Select
ActiveChart.SetSourceData Source:=Range("J2", Sheets(ws.Name).Range("L2").End(xlDown).Address)
ActiveChart.ChartType = xlLine
With ActiveChart.Parent
.Height = 400
.Width = 800
End With
Next

You are using a comma to create your range with strings. That only works with range objects. Try:
ActiveChart.SetSourceData Source:=ws.Range("J2:" & ws.Range("L2").End((xlDown).Address)

With ws.ChartObjects.Add(Left:=100, Width:=375, Top:=75, Height:=225)
.Chart.SetSourceData Source:=ws.Range("J2", Sheets(ws.Name).Range("L2").End(xlDown).Address)
.Chart.ChartType = xlLine
End With

A lot of object accessors in vba return variant.
If you have this issues, for example chart.parent //returns variant btw
the first thing to try is to assign it to a typed variable
At run time if variant is dealt with as if it were a different type you will almost certainly get a runtime error.
dim ws As Worksheet
set ws = ActiveChart.Parent
With ws
'ws operations here
.Name = "My worksheet!"
.Cells(1,1).Value = "cell A1"
End With
Also its worth noting that Workbook.Worksheets collection also contains the chart objects http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.workbook.worksheets.aspx
so when you are adding a chart a worksheet you are essentially adding to the collection you are iterating over which is not advised.

Change to this:
ActiveChart.SetSourceData Source:=Range(Sheets(ws.Name).Range("J2"), Sheets(ws.Name).Range("L2").End(xlDown))

Related

Excel macro for chart based on selection with custom name

I already found macro to create chart based on selection
Sub Charter()
Dim my_range As Range
Set my_range = Selection
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnStacked
ActiveChart.SetSourceData Source:=my_range
Cells(1, 1).Select
End Sub
but cant figure out how to give it custom name (not generic Chart <number>) so that I can build another macros around it. I found couple of ways to create chart with name but I cant figure out how to connect those two macros.
Any ideas what to do?
Thank you
You can't set the Name property of the ActiveChart. You have to go for its parent object:
ActiveChart.Parent.Name = "Bananas"
I would recommend not to use ActiveSheet, Selection, Select and ActiveChart, instead use fully qualified objects, like in the code below:
Option Explicit
Sub Charter()
Dim MyCht As Object
Dim my_range As Range
Dim ws As Worksheet
' avoid using ActiveSheet, instead use fully qualifed objects
Set ws = Worksheets("Sheet1") ' <-- change "Sheet1" to your sheet's name
Set my_range = Selection
' set the Chart
Set MyCht = ws.Shapes.AddChart2
With MyCht ' modify the chart's properties
.Chart.ChartType = xlColumnStacked
.Chart.SetSourceData Source:=my_range
.Name = "My Chart"
End With
End Sub

VBA: Runtime Error - SetSourceData for Second Pivot Chart

I am getting:
Run-time error '-2147467259 (80004005)':
Method 'SetSourceData' of object '_Chart' failed
intermittently when I try to run the following script:
Sub CreatePiePivot()
'Define worksheets
Set PSheet = Sheets("Tools")
Set DSheet = Sheets("Aggregate")
'Define last data points
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
'Selects first to last filled row, and first to last filled column for data
Set PRange = DSheet.Cells(1, 1).Resize(LastRow, LastCol)
'Create pivot cache
Set PCache = ActiveWorkbook.PivotCaches.Create _
(SourceType:=xlDatabase, SourceData:=PRange)
'Moves user to Dashboard
Sheets("Tools").Activate
'Create blank pivot table
Set PTable = PCache.CreatePivotTable _
(TableDestination:=PSheet.Range("F1"), _
TableName:="ExcPT1")
'Create blank pivot chart
PSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlPie
ActiveChart.SetSourceData _
Source:=Range("$F$2:$H$19"), _
PlotBy:=xlRows
ActiveWorkbook.ShowPivotTableFieldList = False
With ActiveChart.PivotLayout.PivotTable.PivotFields("Exception")
.Orientation = xlRowField
.Position = 1
End With
'Insert Data
With PSheet.PivotTables("ExcPT1").PivotFields("Exception")
.Orientation = xlDataField
.Position = 1
.Caption = "Exception Status Count"
.Function = xlCount
End With
'Hide Not Due
With ActiveChart.PivotLayout.PivotTable.PivotFields("Exception Status")
.PivotItems("Not due").Visible = False
End With
'Move bar chart to Dashboard; resize
ActiveChart.ChartArea.Select
ActiveChart.Location Where:=xlLocationAsObject, Name:="Dashboard"
Set ChartWidth = Sheets("Dashboard").Range("B26:L49")
With ActiveChart.Parent
.Height = ChartWidth.Height
.Width = ChartWidth.Width
.Top = ChartWidth.Top
.Left = ChartWidth.Left
End With
With ActiveChart
.HasTitle = False
End With
End Sub
This sub is running after another very similar sub that creates a pivot bar chart using a sub connected to a button:
Sub CreatePivots()
Call CreateBarPivot
Call CreatePiePivot
End Sub
The BarPivot runs perfectly, no problem, every time, and looks almost identical to the PiePivot shown above with the applicable changes to display the appropriate data. If I run those subs separately, it usually runs without a problem. I ran-and-deleted the sub and results three times before I got the error. The debug is pointing at this line:
ActiveChart.SetSourceData _
Source:=Range("$F$2:$H$19"), _
PlotBy:=xlRows
...but it looks exactly like the one used by the BarPivot. Since it's not happening exactly every time, but most of the time, I'm not sure where to start on troubleshooting. The documentation I've looked up (which is sparse by the way, or I'm looking in the wrong places) indicates I'm doing this right.
What's causing the error, and how do I fix it?
This is an example to illustrate how to avoid using Select and Activate in your code, plus a few other (hopefully useful) comments.
Always Use Option Explicit - this can't be emphasized enough
This will turn the first few lines of your Sub into:
Option Explicit
Sub CreatePiePivot()
Dim thisWB As Workbook
Set thisWB = ThisWorkbook
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Set PSheet = thisWB.Sheets("Tools")
Set DSheet = thisWB.Sheets("Aggregate")
Notice that by defining thisWB, you're setting up a workbook reference in a single line that, if you ever needed to change workbooks, change that one line and you're done. Also, this reference can explain why you should use ThisWorkbook over ActiveWorkbook.
Because some of your issues involve assumed references (either workbooks or worksheets or charts), the next lines can help show some necessary references that are easy to miss:
'Define last data points
Dim lastRow As Long
Dim lastCol As Long
lastRow = DSheet.Cells(DSheet.Rows.Count, 1).End(xlUp).Row
lastCol = DSheet.Cells(1, DSheet.Columns.Count).End(xlToLeft).Column
Notice here that you have to reference DSheet inside of the Cells reference to guarantee that you're referring to the same worksheet. Otherwise VBA could assume that you're referring to the ActiveSheet, which may be completely different and give you an incorrect value.
The next few lines become:
'Selects first to last filled row, and first to last filled column for data
Dim PRange As Range
Set PRange = DSheet.Cells(1, 1).Resize(lastRow, lastCol)
'Create pivot cache
Dim PCache As PivotCache
Set PCache = ActiveWorkbook.PivotCaches.Create _
(SourceType:=xlDatabase, SourceData:=PRange)
Your next statement in your code is Sheets("Tools").Activate which, unless there is a specific reason you want to display that worksheet to the user at this time, is completely unnecessary. If you want the user to view this worksheet when all processing is completed, move this statement to the end of the Sub.
Next:
'Create blank pivot table
Dim PTable As PivotTable
Set PTable = PCache.CreatePivotTable _
(TableDestination:=PSheet.Range("F1"), _
TableName:="ExcPT1")
The real fix for your error comes next:
'Create blank pivot chart
Dim PChart As Chart
Set PChart = PSheet.Shapes.AddChart
PChart.ChartType = xlPie
PChart.SetSourceData Source:=PSheet.Range("$F$2:$H$19"), PlotBy:=xlRows
Because you're creating an object for the newly added chart, you never have to use ActiveChart. It follows the same idea of specifying complete references.
And so on... you can hopefully use these examples to finish out the rest of your code and work through some of the issues you're having. Give it a try.

Why does my code work for ActiveChart but not for the chart name?

At the moment, my code reads:
Private Sub Worksheet_Activate()
' This Macro Code for this sheet updates the x axis range for the graph in 'Dashboard' automatically
Dim V_900_SPC As Worksheet
Set V_900_SPC = Sheets("AR Data 900A SPC")
Dim chart1values As String, chart1_xvalues As String
chart1values = Cells(2, 10)
chart1_xvalues = Cells(3, 10)
V_900_SPC.ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection(1).Values = "='AR Data 900A SPC'!" & chart1values
ActiveChart.SeriesCollection(1).XValues = "='AR Data 900A SPC'!" & chart1_xvalues
Cells(1, 1).Activate
End Sub
However if I replace "ActiveChart." with "V_900_SPC.ChartObjects("Chart 1")." (and obviously delete the line that activates the chart object) then the code doesn't work. What's going on??
Try:
V_900_SPC.ChartObjects("Chart 1").Chart.SeriesCollection(1).Values = "='AR Data 900A SPC'!" & chart1values
The reasoning being that ChartObject and Chart isn't the same thing. ChartObject is a container for Chart, and SeriesCollection belongs to Chart.
I recently made a post on SO that is relevant to this, that also contains more information and examples, as well as MSDN links.

VBA Excel 2010 - Assign unknown chart to varible

Im trying to set a chart to a varible, however since I have multiple charts in my spreadsheet I need to be able to activate a chart and assign it to a varible.
Ffor the record ChartHandel = ActiveSheet.ChartObject(1) doesn't work,I have also tried .Shape(1) and Chart("Name of chart") and these too dont work
Dim ChartHandel2 As Chart
ActiveSheet.ChartObjects(1).Activate
ChartHandel2 = ActiveChart
Even this gets error '91, Object Variable or with block varible not set' which it looks like it should work and I was sure I had had this working at one point(as a workaround)
My question is basicly can you assign a chart to a varible if it isnt active (and if possible how)?
when assigning object you must use the Set keyword in the left part of the assignment statement
furthemore Chart object is a member of the ChartObject object
here's a small example of dealing with them
Option Explicit
Sub ChartObjects()
Dim chartObj As ChartObject
With ThisWorkbook.Worksheets("charts")
For Each chartObj In .ChartObjects
With chartObj ' to deal with current "ChartObject" object
With .Chart ' to deal with "Chart" object of "ChartObject" object
.ChartType = xlXYScatter ' or another XlChartType Enumeration (https://msdn.microsoft.com/en-us/library/office/ff838409.aspx)
MsgBox .ChartArea.Name
.HasLegend = False
.ChartTitle.Caption = "chart title you need"
End With
End With
Next chartObj
End With
End Sub
You can use for each to loop through charts if you arent sure with indexes. Something like this
Sub testChart()
Dim testSheet As Worksheet
Set testSheet = Sheets("Sheet1")
Dim myChart As ChartObject
Dim chartVariable As Chart
With testSheet
For Each myChart In .ChartObjects
Set chartVariable = myChart.Chart
Next myChart
End With
End Sub
warning: its only demo version, it will need further changes depends on what you need

VBA Excel: Modifying Existing Graph (Errors)

Using a macro, I want to modify the data series of a graph at any given time. Whenever I run the macro, I get an error. "error 438 "object doesn't support this property or method"". My code is attached below. Thanks.
Private Sub CommandButton2_Click()
Dim objChrt As ChartObject
Dim chrt As Chart
Set objChart = ActiveSheet.ChartObjects("Chart 1")
Set chrt = objChart.Chart
With objChart
.SetSourceData (ActiveSheet.Range("D2", Cells(2, N + 3))) '"N" is a user defined range
End With
End Sub
Three layers to this problem, I think.
1) Cells returns a range object, not a range address. When using this as an argument in a Range then you need to ensure that either the returned cell contains a valid address string, or that you refer directly to the .Address of that cell.
It's rare that you'd do the former, but I've seen it done before so I mention it just in case.
2) Parentheses force evaluation, so this line (even as corrected):
.SetSourceData (ActiveSheet.Range("D2", Cells(2, N + 3).Address))
Is functionally equivalent to:
.SetSourceData (ActiveSheet.Range("D2", Cells(2, N + 3).Address)).Value
Which probably raises an error because of the parentheses, since I believe the .SetSourceData requires a range address, so try:
.SetSourceData ActiveSheet.Range("D2", Cells(2, N + 3).Address)
And further:
3) The SetSourceData is a member of the Chart object, not the ChartObject object. Confusing, right?
with chrt
.SetSourceData ActiveSheet.Range("D2", Cells(2, N + 3).Address)
End With