Change Series Values to Named Range - vba

I have a chart in Excel ("Chart 13"), I also have a named range called "nationals".
I'd like to replace one of the chart's series' Y Values with the named range (the chart has three different series, I'm planning to repeat a similar process for all three).
This is what I have been trying with no success:
ActiveWorkbook.Sheets("My_Sheet").ChartObjects("Chart 13").Activate
ActiveChart.SeriesCollection(1).Values = Range("nationals")
I get the following error:
"Run-time error '91': Object variable or With block variable not set"
I feel like I'm close but can't get to the finish line for the life of me! I appreciate any help.
EDIT
This is a line chart (with markers) - sorry that wasn't clear before. Simple version of same situation:

You need to add object to the range like so:
Dim MyChart
Set MyChart = ActiveWorkbook.Sheets("My_Sheet").ChartObjects("Chart 13").Chart
MyChart.SeriesCollection(1).Values = ActiveWorkbook.Sheets("My_Sheet").Range("nationals")
Also, as you note, the ChartObjects().Chart object has the SeriesCollection.

Related

Filling a variant array with charts in Excel VBA

I am working on a file that creates up to 120 charts based on data, variables, and format selections from the user. To do this I create a variant array to hold the charts which allows me to easily reference them for adding data, formatting, etc. This method has worked well for me so far.
Now I would like to let users make small tweaks to formatting (adjust the min and max on the axis, add or remove legend entries, etc.). To do this I would like to continue referencing the charts from an array, but I can't seem to add the existing charts to the variant array.
When I initially create the charts I use this line to add the chart to the array when it is created. I fill in appropriate parameters to place and size the chart and this seems to work fine.
Set charts(graphIndex) = activeSheet.ChartObjects.Add(...)
After creating all the charts, I think the non Global variables used are cleared from the cache (at least that is my current understanding). This means that in order to make these tweaks I need to reinitialize and redefine the variant array that I use to reference the charts. This is what I am struggling with. This is my current attempt to add the existing chart to the variant array.
charts(graphIndex) = Worksheets(activeSheetName).ChartObjects("chart name").Chart
When I run the code I am getting a "Run-time error '438': Object doesn't support property or method."
Hopefully I provided enough context, but any help on this would be greatly appreciated. This feels like it should be fairly easy, but I couldn't find any information online.
I am just guessing that in your code if you had the Set word it would have worked (However, I am not seeing the whole code, thus not sure).
This works, if you make sure to have 3 charts named "Diagramm 1", "Diagramm 2" and "Diagramm 3" on the first worksheet:
Option Explicit
Sub TestMe()
Dim cht2 As Chart
Dim varArray As Variant
With Worksheets(1)
Set cht2 = .ChartObjects("Diagramm 2").Chart
varArray = Array(.ChartObjects("Diagramm 1").Chart, cht2)
ReDim Preserve varArray(2)
Set varArray(2) = .ChartObjects("Diagramm 3").Chart
Dim cnt As Long
For cnt = LBound(varArray) To UBound(varArray)
Debug.Print varArray(cnt).Name
Next cnt
End With
End Sub
The Reedim Preserve increases the array units with one additional, while it keeps what it already has. Thus, at the end this is what we have in the locals:

Powerpoint VBA - Set DataRange for DataLabels

I have no idea how to set DataRange for DataLabels using VBA.
Powerpoint does not have recording capabilities as well.
Can anybody tell me to do this using VBA please?
The code to accomplish this is as follows:
Dim myChart As Chart
Dim mySerCol As SeriesCollection
Dim strRange As String
strRange = "=Sheet1!$F$2:$F$5" 'To hold the range for the new labels
Set myChart = ....[put in code to get the appropriate chart]
Set mySerCol = myChart.SeriesCollection(i)
mySerCol.ApplyDataLabels 'Turn on the datalabels for this series
'The next line sets the range to get the values from
mySerCol.Format.TextFrame2.TextRange.InsertChartField msoChartFieldRange _
, strRange, 0
mySerCol.ShowRange = True 'Show the values from the range
mySerCol.ShowValue = False 'Do not show the actual values of the points
Note that this will only do this for one of the series. To do the other ones, loop through i in the myChart.SeriesCollections(i) line.
****EDIT**** See other answer. I am leaving this here because it provides some information about several objects that could be used, but doesn't actually solve the problem.
This is not a complete answer to the issue, but this is too long for a comment.
I've searched through the documentation for the Datalabels and was unable to figure out how to do this (I assume that you want to be able to define the range that the labels come from using VBA). I was able to "check" the checkbox, but couldn't figure out where the range that is attached to it is. The appropriate code to check.
To check the checkbox, use this code:
myChart.SeriesCollection(i).ApplyDataLabels
where i is the series in question and myChart is a Chart object referencing your chart. There are a bunch of parameters to this method that will allow you to show different items (percentages, values, etc.), but none of the parameters is a range.
This defaults to the values of the series if you do not enter any of the optional parameters
It is then possible to turn this on and off using:
myChart.SeriesCollection(i).DataLabels.ShowRange = True/False
It is possible to change the caption of the Datalabels using:
myChart.SeriesCollection(i).DataLabels(j).Caption = "MY CAPTION"
This will change the caption one at a time, and it will replace the value that the "ApplyDataLabels" method puts in there. It would be possible to loop through the range to set the values, but this is likely not what you are looking for.
There's also this:
myChart.SeriesCollection(i).HasDataLabels = True
but this just seems to turn them on and off and resets the captions that you may have put in there.
MSDN link uses both the hasdatalabels property and the applydatalabels method, but it is not clear why they are using both: https://msdn.microsoft.com/EN-US/library/office/ff745965.aspx
Hopefully this can at least give you something to start with.

Getting a value from a named range in VBA

I want to retrieve a value from named range. Imagine a named range that has X columns and Y rows. I want to return a value, e.g., from column 2, row 3. The issue I experience is that if I write the code and run it, Excel throws an error. If I write the code into the watch window, it returns fine. See below
...
Dim NamedRange As Variant: NamedRange = Range(NamedRangeName)
...
Dim ReturnValue As Object
Set ReturnValue = NamedRange(RowIndex, ColumnToRetrieveIndex) 'Throws Run-time error 424. Object required
If I write
NamedRange(RowIndex, ColumnToRetrieveIndex)
into the watch window, I can see the correct value of the cell.
I don't know VB much so I guess it's just some kind of syntax error how I want to pass it into the ReturnValue but I just can't figure it out.
Use this
ThisWorkbook.Names("myNamedRange").RefersToRange(1,1)
To get the value from the first cell in the named range "myNamedRange"
With ThisWorkbook.Names you can access all named ranges of all the sheets within the current workbook.
With RefersToRange you get a reference to the actual range.
This looks like a good place to put a handy note (as it's a top search result):
If you name a cell "TopLeft", then Sheets(1).Range("TopLeft").Value gets the contents, and Sheets(1).Range("TopLeft").Offset(2,3).Value gets the value from 2 down, 3 across from there.

Subscript out if range VB Excel using Charts

Charts("Vendor").ChartTitle.Text = "Test"
Is throwing subscript error. The chart does exist and is named Vendor.
Any ideas?
Chart is a child object of a ChartObject (which like #DerekCheng alluded to, are contained within a worksheet); therefore, you'll need to get the Chart directly from there. Try this instead.
Worksheets("YourSheetName").ChartObjects("Vendor").Chart.ChartTitle.Text = "Test"

Recorded macro does not work on chart object

I recorded the following macro :
Sheets("Rejets Techniques TGC").Select
ActiveSheet.ChartObjects("Graphique 1").Activate
ActiveChart.Axes(xlCategory).Select
ActiveChart.SeriesCollection(1).Values = "='Données'!$EU$68:$IJ$68"
ActiveChart.SeriesCollection(1).XValues = "='Données'!$EU$1:$IJ$1"
However when I try to lauch it I get this error (translated from french):
Execution error '-2147024809 (80070057)'
There is no element with this name
How can this be? if there was no graph named this way I wouldn't have been able
to record it.
(yes I'm running it from the good sheet)
Thanks.
Here's what it comes down to: Your chart is not an object on the sheet, it is the sheet.
So while you use ActiveSheet.ChartObjects("Graphique 1").Activate to start your code, there are no ChartObjects found in your sheet, because the sheet is the Chart. So here's how you get around it:
Dim CO As Variant
Set CO = ActiveSheet
CO.Axes(xlCategory).Select
CO.SeriesCollection(1).Values = "='Données'!$ET$68:$IJ$68"
CO.SeriesCollection(1).XValues = "='Données'!$ET$1:$IJ$1"
And this should work just fine. I noticed that when I looked at the chart tab, I couldn't get into any cells. This is not abnormal, but it is not the most common way (that I see) to create the chart. To verify, I added a watch on the ActiveSheet and saw that it was indeed a chart (of type Object/Graph2) with all the normal chart methods available to it.
From there, I just plugged in your code, converting to the CO variable (but yours should still work using ActiveSheet across the board), and ran with no errors.
As a side note, using ActiveSheet is not always effective, and it is generally better to explicitly call the sheet, i.e. Set CO = ThisWorkbook.Sheets("Rejets Techniques TGC")
1 - Check if the active sheet is the one that contaisn the chart. Or use the sheet name in code to run it from any sheet.
2 - Check if the good sheet contains the chart with exact "Graphique 1" name. Maybe there's an underline, like "Graphique_1", or no space "Graphique1"...