Excel VBA graph based on Series not working properly - excel

I'm using the following VBA code in Excel in order to produce 2 graphs with a data picked up from the sheet and slightly elaborated. As I'm not using ranges directly for the graphs and need to use arrays for X and Y axes, I decided to go for Series. X has Date type and Y has Integer type. First it worked, but then the graphs started giving me wrong data, something random coming directly off the sheet. I suppose there could be something wrong in the way how the charts are declared. Here's the code, what could go wrong with it?
Dim crt1, crt2 As Chart
Dim sr1, sr2 As Series
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered, 60, 50).Select
Set crt1 = ActiveChart
Set s1 = crt1.SeriesCollection.NewSeries()
sr1.Values = dataArray1
sr1.XValues = datesArray1
ActiveSheet.Shapes.AddChart2(332, xlLineMarkers).Select
Set crt2 = ActiveChart
Set s2 = crt2.SeriesCollection.NewSeries()
sr2.Values = dataArray2
sr2.XValues = datesArray2
This problem also persists when I comment the code for the second graph.
P.S. Excel says "Runtime error 424. Object required" underlining "sr1.Values = dataArray1" and then "sr1.XValues = datesArray1"

Related

Excel histogram bins adjustment with VBA doesn't seem to work

I'm trying to automatically create couple histograms for given data. The problem is that I can't change bins width with VBA. How to get around this?
(Excel Version 2210 Build 16.0.15726.20188)
I looked through the docs and tried the macro recorder and this is prototype code I came up with.
Sub generateHistograms()
Dim wsTab As Worksheet
Set wsTab = Worksheets("Tabele")
With wsTab.Shapes.AddChart2(-1, xlHistogram)
.Name = "Test"
.Chart.SeriesCollection.NewSeries
.Chart.FullSeriesCollection(1).Values = wsTab.ListObjects(1).ListColumns(3).DataBodyRange
.Chart.ChartGroups(1).BinsType = xlBinsTypeManual
.Chart.ChartGroups(1).BinWidthValue = 10
.Chart.ChartGroups(1).BinsOverflowEnabled = True
.Chart.ChartGroups(1).BinsOverflowValue = 90
End With
End Sub
Running the code line by line seems like BinsType, BinWidthValue, BinsOverflowEnabled and BinsOverflowValue doesn't do anything.

Change data range in a chart using VBA

It has been hours that I'm struggling with what I think to be a sible problem since Im not familiar at all with Chart object in VBA.
Here's my chart:
What I want to do: Change the data range of the two axis, the problem is that cant figure out a way to edit the series of the chart.
Thanks four your help !
You could use
With Workbooks(bookname).Charts(Chartname)
.SeriesCollection.NewSeries
.SeriesCollection(i).XValues = YourXs
.SeriesCollection(i).values = YourYs
end with
You can choose which series you want to edit by using the index i. This actually sets the (X,Y) pairings while what's below only changes the range shown by the graph.
To change the bounds of your Y axis you can use
.Axes(xlValue).MinimumScale =
.Axes(xlValue).MaximumScale =
To change the bounds of your x axis use
.Axes(xlCategory).MinimumScale =
.Axes(xlCategory).MaximumScale =
You said you wanted to change
=SERIES("SO2 U5",'CEMS_U6_YTD 2018'!$B$2165:$B$2303,'CEMS_U5_YTD 2018'!$D$2165:$D$2312,1)
to this
=SERIES("SO2 U5",'CEMS_U6_YTD 2018'!$C$2165:$C$2303,'CEMS_U5_YTD 2018'!$D$2165:$D$2312,1)
This may be a simple as
ActiveChart.SeriesCollection(1).Formula = _
"=SERIES(""SO2 U5"",'CEMS_U6_YTD 2018'!$C$2165:$C$2303,'CEMS_U5_YTD 2018'!$D$2165:$D$2312,1)"
note doubling of the double quotes around the series name.
However, since you are only changing the X values, you could use this:
ActiveChart.SeriesCollection(1).XValues = "='CEMS_U6_YTD 2018'!$C$2165:$C$2303"
or
ActiveChart.SeriesCollection(1).XValues = Worksheets("CEMS_U6_YTD 2018").Range("$C$2165:$C$2303")
I've written a tutorial about editing series formulas with VBA: Change Series Formula – Improved Routines.

Excel VBA - Get chart data range

I want to add data to a bunch of existing charts. Assume that each chart has a different number of data series and that the location of the raw data is somewhere in the same workbook. Here's what I'm starting with:
For iChart = 1 To iCount
ActiveSheet.ChartObjects("Chart " & iChart).Activate
intSeries = 1
Do Until ActiveChart.SeriesCollection(intSeries).Name = ""
Set rXVal = ActiveChart.SeriesCollection(intSeries).XValues '<- Object Required error
Set rXVal = Range(rXVal, rXVal.End(xlDown))
Set rYVal = ActiveChart.SeriesCollection(intSeries).Values
Set rYVal = Range(rYVal, rYVal.End(xlDown))
ActiveChart.SeriesCollection(intSeries).XValues = rXVal
ActiveChart.SeriesCollection(intSeries).Values = rYVal
intSeries = intSeries + 1
Loop
Next iChart
I know that ActiveChart...XValues = rXVal works, but I'm getting an "Object Required" error on the Set rXVal = ActiveChart....XValues line. I'm assuming that since a range went in to define the data series, I can get that range back out again and then add to it.
UPDATE
To clarify things a little, I have accelerometers in 8 places and FFT software setup to record peak vibration response in 4 separate frequency bands. This yields 32 data points per sample. When exporting, the software spits out an Excel workbook with 4 sheets; one for each frequency band. Each sheet has the accelerometer names going across and sample numbers going down.
I have succeeded using this syntax:
Dim rXVal() As Variant
rXVal = ActiveChart.SeriesCollection(intSeries).XValues
UPDATE
In this case you get an array, because your given statement (ActiveChart.SeriesCollection(intSeries).XValues) is an array and not a range. This is what you see in Locals window if you dig into Series object of ActiveChart.SeriesCollection(intSeries):
(in my dummy data I have rows named r1, r2, r3, r4.)
What I want to say, XValues does not have any property which would indicate its occupied range.
If you actually need a range, I would suggest getting it from the formula property. And the way I would suggest is replacing your error causing line with this one:
Set rXVal = Range(Split(ActiveChart.SeriesCollection(intSeries).Formula, ",")(1))
Next, I see you trying to get the range for Values. Similarly, use this:
Set rYVal = Range(Split(ActiveChart.SeriesCollection(intSeries).Formula, ",")(2))
Another thing.
The following lines will cause you an error finally:
intSeries = 1
Do Until ActiveChart.SeriesCollection(intSeries).Name = ""
...some code...
intSeries = intSeries + 1
Loop
Do change them with:
For intSeries = 1 To ActiveChart.SeriesCollection.Count
...some code...
Next
Yet another thing.
Consider using With and End With, as you repeat a lot ActiveChart.SeriesCollection(intSeries). Then your code will be much more readable, as you would just skip this long line! Wouldn't that be awesome???
This works fine for me:
Dim rXVal() As Variant
Dim rXValMin, rXValMax As Double
rXVal = ActiveChart.SeriesCollection(intSeries).XValues
rXValMin = WorksheetFunction.Min(rXVal)
rXValMax = WorksheetFunction.Max(rXVal)

In an Excel chart: how to "copy" chart line format from one series to another using VBA?

For some x and y such that SeriesCollection(x) exists and SeriesCollection(y) exists, I am trying to do the following:
ActiveChart.SeriesCollection(x).Format.Line = ActiveChart.SeriesCollection(y).Format.Line
But, that gives me an error: "object doesn't support this property or method". How can I copy the line format of one series from a chart, to another series in the chart?
You have to iterate through each property of .Format.Line
(It's confusing to use X and Y as variables indicating series, since X and Y conventionally refer to data of those series.)
Set srsA = ActiveChart.SeriesCollection(A)
Set srsB = ActiveChart.SeriesCollection(B)
srsA.Format.Line.ForeColor = srsB.Format.Line.ForeColor
srsA.Format.Line.Weight = srsB.Format.Line.Weight
etc.

Setting VBA Excel Chart Legend Position Property in MS Access not working

This is a very strange issue I am facing for a while now, when creating some Excel worksheets programmatically from MS Access 2003.
Using this VBA-Code snippet I am not able to set the Position property of an Excel's Legend object (variable definitions and so on are left out to ease understanding).
...
Set ChartObject = myWorksheet.ChartObjects.Add(myRange.Left, myRange.Top, myRange.width, myRange.Height)
Set Chart = ChartObject.Chart
Chart.HasLegend = True
'This line raises an error:
Chart.Legend.Position = -4107 '=xlLegendPositionBottom
...
MS Access always raises the Error 1004:
"Unable to set the Position property of the Legend class"
It confuses me that I can use the exact same code from within Exel VBA and it just works. What confuses me even more is that the property HasLegend can be set whithout any error ocurring.
Someone has a hint to solve this issue?
After building a generic version of my code I found that in Office/Excel 2003 I have to populate my Series of data to the chart before changing the Legend's position. Probably the object hasn't been initiated before. My Code should therefore look like this:
...
Set ChartObject = myWorksheet.ChartObjects.Add(myRange.Left, myRange.Top, myRange.width, myRange.Height)
Set Chart = ChartObject.Chart
Chart.HasLegend = True
...
Chart.SeriesCollection.Add myRange, 1 '=xlRows
'Now this works:
Chart.Legend.Position = -4107 '=xlLegendPositionBottom

Resources