Excel VBA code for creating a chart object and plotting xyscatterline with data from different worksheets - excel

I couldn't figure out what is wrong with the VBA code I created to plot data from worsheets that satisfying a condition on their name . xyscatter line to be created using data from column G as xvalues and column J as values.
I get error "Run-time error '1004': Application - defined or object-defined error"
Help is much appreciated as I will be doing this very often.
Thank you!
Sub charting()
Dim i, j, last_column, last_row As Integer
Dim sh As Worksheet
Dim cht As Chart
Dim xrng1, yrng1 As Range
Set cht = Charts.Add
i = 0
With cht
.ChartType = xlXYScatterLines
.Name = "cht1"
End With
For Each sh In ThisWorkbook.Worksheets
If LCase(sh.Name) Like "nov*" Or LCase(sh.Name) Like "bh*" Then
i = i + 1
With sh
last_row = .Cells(Rows.Count, 2).End(xlUp).Row
Set xrng1 = .Range(.Cells(2, 7), .Cells(last_row, 7))
Set yrng1 = .Range(.Cells(2, 10), .Cells(last_row, 10))
End With
End If
cht.Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(i).XValues = xrng1
ActiveChart.FullSeriesCollection(i).Values = yrng1
ActiveChart.FullSeriesCollection(i).Name = sh.Name
Next sh
End Sub

Related

Adding new series to a graph automatically

I'm trying to create a dynamic Scatterchart in the worksheet("Graphs") using a button.
The Seriesname has to be equal to Worksheets("VS_P240_X").Cells(1,i), where i is a counter for the columns.
The XValues have to be equal to Worksheets("VS_P240_X").Range(cells(3,i).cells(1000,i)).
The YValues have to be equal to Worksheets("VS_P240_Y").Range(cells(3,i).cells(1000,i)).
When I Update the workbook the counter i will change, and I want that the chart will automatically update with the new series. I wrote this code but it is not working, do you have some suggestions?
Private Sub CommandButton5_Click()
'Graph generation NON COMPLETO
Dim i As Integer
Dim Chart1 As Chart
Set Chart1 = Sheets("Graphs").ChartObjects("Chart 1").Chart
For i = 1 To Lastcolumn
With Chart1
.ChartType = xlXYScatter
.SeriesCollection.NewSeries
'Change to what your series should be called
.SeriesCollection(i).Name = Worksheets("VS_P240_X").Cells(1, i).Value
.SeriesCollection(i).XValues = Worksheets("VS_P240_X").Range(Cells(3, i), Cells(1000, i))
.SeriesCollection(i).Values = Worksheets("VS_P240_Y").Range(Cells(3, i), Cells(1000, i))
End With
Next i
End Sub
To avoid confusion/bugs, it's best to specify a worksheet every time you use Range or Cells()
Something like this should work:
Private Sub CommandButton5_Click()
Dim i As Long, Lastcolumn As Long 'use long not integer
Dim Chart1 As Chart, wsX As Worksheet, wsY As Worksheet
Set wsX = Worksheets("VS_P240_X")
Set wsY = Worksheets("VS_P240_Y")
Set Chart1 = Sheets("Graphs").ChartObjects("Chart 1").Chart
Do While Chart1.SeriesCollection.Count > 0 'remove any existing data
Chart1.SeriesCollection(1).Delete
Loop
Chart1.ChartType = xlXYScatter 'do this outside of the loop...
Lastcolumn = wsX.Cells(1, wsX.Columns.Count).End(xlToLeft).Column
For i = 1 To Lastcolumn
With Chart1.SeriesCollection.NewSeries
.Name = wsX.Cells(1, i).Value
.XValues = wsX.Range(wsX.Cells(3, i), wsX.Cells(1000, i))
.Values = wsY.Range(wsY.Cells(3, i), wsY.Cells(1000, i))
End With
Next i
End Sub

Object variable or With block variable not set in Excel macro

I created a macro to plot graphs when the workbook is opened.
Sub create_graphs()
Dim wsInput As Worksheet, wsOutput As Worksheet
Dim LRowO As Long, LRowI As Long
Dim LColO As Long, LColI As Long
Dim Count As Integer
Dim LastChartRow As Integer
Set wsOutput = ThisWorkbook.Sheets("Summary")
With wsOutput
LRowI = .Range("A" & .Rows.Count).End(xlUp).Row
LColI = .Cells(1, .Columns.Count).End(xlToLeft).Column
LastChartRow = LRowI + 3
For Count = 2 To LRowI
.Shapes.AddChart2(201, xlColumnClustered).Select
ActiveChart.PlotBy = xlRows
ActiveChart.SetSourceData Source:=Range(.Cells(Count, 1), .Cells(Count,LColI))
ActiveChart.SeriesCollection(1).XValues = Range(.Cells(1, 2), .Cells(1,LColI))
ActiveChart.SetElement (msoElementDataLabelOutSideEnd)
ActiveChart.ChartTitle.Text = .Cells(Count, 1).Value
ActiveChart.Parent.Left = .Cells(LRowI + 5, 2).Left
ActiveChart.Parent.Top = .Cells(LastChartRow, 2).Top
LastChartRow = LastChartRow + 15
Next Count
End With
End Sub
Private Sub Workbook_Open()
Call create_graphs
End Sub
When I open the Excel workbook, it throws error message Object variable or With block variable not set and the graphs are not plotted. Checking from VB guide seems like it's variable issue. Please help to point out the mistake.
Is your sub on the workbook page in the visual editor? If not it needs to be on the same page or in a module vba will not call a sub from a different page.

Invalid parameter error when method is called from another sub

I have the below code that creates charts from some worksheets and put the charts in their own worksheets. When I run the macro on it's own it works perfectly. When I use Call InsertDNCCharts from another macro I get a "Invalid Parameter" error on .Period = 7 from within the With tl block. Why is there a difference? If the code runs on its own shouldn't it run the same way when called from another sub?
Sub InsertDNCCharts()
Dim ws As Worksheet
Dim cws As Worksheet
Dim country As String
Dim lastrow As Long
Dim chrt As Shape
Dim chrtname As String
Dim xvalues As Range
Dim yvalues As Range
Dim tl As Trendline
For Each ws In ThisWorkbook.Worksheets
If Right(ws.Name, 6) = "_Chart" Then
country = Left(ws.Name, Len(ws.Name) - 6)
Set cws = ThisWorkbook.Worksheets(country)
lastrow = cws.Cells(Rows.count, "c").End(xlUp).Row
Set xvalues = cws.Range("c5:c" & lastrow)
Set yvalues = cws.Range("l5:l" & lastrow)
cws.Activate
Application.Union(xvalues, yvalues).Select
Set chrt = cws.Shapes.AddChart2(201, xlColumnClustered, Cells(5, 2).Left, Cells(5, 2).Top, 1000, 420)
chrt.Name = ws.Name
chrtname = chrt.Name
cws.Cells(5, 1).Select
With chrt.Chart
.Location Where:=xlLocationAsObject, Name:=ws.Name
.Axes(xlCategory).HasMajorGridlines = True
.Axes(xlCategory).HasMinorGridlines = False
.Axes(xlValue).HasMajorGridlines = True
.Axes(xlValue).HasMinorGridlines = False
.HasLegend = False
End With
ws.ChartObjects(chrtname).Activate
ActiveChart.ChartWizard Title:=country & " Daily New Cases (DNC)"
Set tl = ws.ChartObjects(chrtname).Chart.SeriesCollection(1).Trendlines.Add
With tl
.Type = xlMovingAvg
.Period = 7 '*******Error on this line. Debug says period=2, which is the default moving average period.
.DisplayEquation = False
.DisplayRSquared = False
.Format.Line.DashStyle = msoLineSysDot
.Format.Line.Weight = 3.5
.Format.Line.ForeColor.RGB = RGB(255, 0, 0)
.Format.Line.Style = msoLineSingle
End With
End If
Next ws
End Sub
If the chart in discussion (the created one) has at least 7 points, it is possible that the code is not referring to the appropriate chart, or the chart has not been created as necessary.
In order to check that, I would suggest you putting a break point on line With tl and visually check if the active chart is the one you need and if it looks as expected. It looks that the problem has to be before the line raising the error.

How to skip empty cells in a range to use as range for a scatterplot?

I'm fairly new to VBA and trying to dynamically select the data i need for my scatter plot. I'm trying skip any rows that have a blank in the "A" column so the scatter plot is continuous.
The code in the commented section is what i tried first, but that gives me a method range of object_global failed error on the setsourcedata line. I expect the code to skip the empty cell and continue through mydatatest variable until it reaches the end. However, the actual output stops at the first empty cell.
Set mydatatest = ActiveWorkbook.Sheets("Data - PLC").Range("A3:A94")
'Set mydata = ActiveWorkbook.Sheets("Data - PLC").Range("A2:C2")
Set mydata = ActiveWorkbook.Sheets("Data - PLC").Range("A2")
For Each mydatapoint In mydatatest
If IsEmpty(mydatapoint) = False Then
'Set mydata = Union(mydata, Range(mydatapoint, mydatapoint.Offset(0, 2)))
Set mydata = Union(mydata, mydatapoint)
End If
Next mydatapoint
ActiveWorkbook.Sheets("Report").Select
Set cht1 = Sheet1.ChartObjects.Add(10, 365, 275, 200)
With cht1.Chart
.ChartType = xlXYScatterLinesNoMarkers
.SeriesCollection.Add Source:=Range(mydata, mydata.Offset(0, 2))
'.SetSourceData Source:=Range(mydata)
End With
The error is in .SetSourceData Source:=Range(mydata). It should be .SetSourceData Source:=myData. myData is already declared as Range(). The rest is quite ok:
Option Explicit
Sub TestMe()
Dim myDataTest As Range
Dim myData As Range
Dim wks As Worksheet
Set wks = Worksheets(1)
Set myDataTest = wks.Range("A3:A94")
Set myData = wks.Range("A2")
Dim myDataPoint As Range
For Each myDataPoint In myDataTest
If Not IsEmpty(myDataPoint) Then
Set myData = Union(myData, myDataPoint)
End If
Next myDataPoint
Dim cht As Object
Set cht = wks.ChartObjects.Add(10, 365, 275, 200)
With cht.Chart
.ChartType = xlXYScatterLinesNoMarkers
.SeriesCollection.Add Source:=wks.Range(myData, myData.Offset(0, 2))
.SetSourceData Source:=myData
End With
End Sub

Making graph - run-time error 424 - Object required

I am trying to make a graph using the following VBa code. But I am getting a Run-time error 424 - Object required at the row:
Set rngChtXVal = .Columns(1).Offset(1).Resize(.Rows.Count - 1)
What is going wrong?
Sub MakeGraph()
Dim myChtObj As ChartObject
Dim rngChtData As Variant
Dim rngChtXVal As Variant
Dim iColumn As Long
sel= Sheets("Data").Range(Cells(1, 1), Cells(200, 2))
rngChtData = sel
' define chart's X values
With rngChtData
Set rngChtXVal = .Columns(1).Offset(1).Resize(.Rows.Count - 1)
End With
' add the chart
Set myChtObj = ActiveSheet.ChartObjects.Add(Left:=250, Width:=425, Top:=10, Height:=240)
With myChtObj.Chart
' make an XY chart
.ChartType = xlLine
' remove extra series
Do Until .SeriesCollection.Count = 0
.SeriesCollection(1).Delete
Loop
' add series from selected range, column by column
For iColumn = 2 To rngChtData.Columns.Count
With .SeriesCollection.NewSeries
.Values = rngChtXVal.Offset(, iColumn - 1)
.XValues = rngChtXVal
.Name = rngChtData(1, iColumn)
End With
Next
End With
End Sub
You've named rngChtData and rngChtXVal like Range objects, but you've declared them as Variant. While Variants can be Ranges, it makes debugging your code much harder. Use explicit variable types whenever possible. To resolve your issue, change your code like this:
Sub MakeGraph()
Dim myChtObj As ChartObject
Dim rngChtData As Range
Dim rngChtXVal As Range
Dim iColumn As Long
With Sheets("Data")
Set rngChtData = .Range(.Cells(1, 1), .Cells(200, 2))
End With
' define chart's X values
With rngChtData
Set rngChtXVal = .Columns(1).Offset(1).Resize(.Rows.Count - 1)
End With

Resources