Using dynamic named range in VBA for scatter chart labeling - vba

I'm trying to make a macro that will change the data labels on a scatter chart to the title of each point. Eg:
(source: wiseowl.co.uk)
In this case I would like the data labels to show the movie title. The code I used comes from this website, but my scatter chart has two series of data. I would like to use dynamic named ranges to tell the macro the range of cells where the names are, in my code the dynamic named ranges are FONames & BONames. Here's my code:
Sub CreateDataLabels()
'holds the entire film data series in the chart
Dim FilmDataSeries As Series
Dim FilmDataSeries2 As Series
'holds one cell at a time
Dim SingleCell As Range
'holds the full list of cells containing film names
Dim FilmList As Range
Dim FilmList2 As Range
'keeps track of which datapoint we're labelling
Dim FilmCounter As Integer
Dim FilmCounter2 As Integer
'The sheet in which the graph is on
Dim ws As Worksheet
Set ws = Worksheets("Datos Gráfico")
'set the counter to start at 1
FilmCounter = 1
FilmCounter2 = 1
'set a reference to the cells containing the list of films
Set FilmList = Range("FONames")
Set FilmList2 = Range("BONames")
'set a reference to the chart data series
Set FilmDataSeries = ws.ChartObjects(1).Chart.SeriesCollection(1)
Set FilmDataSeries2 = ws.ChartObjects(1).Chart.SeriesCollection(2)
'make sure data labels are turned on
FilmDataSeries.HasDataLabels = True
FilmDataSeries2.HasDataLabels = True
'loop over the cells in the list of films
For Each SingleCell In FilmList
FilmDataSeries.Points(FilmCounter).DataLabel.Text = SingleCell.Value
FilmCounter = FilmCounter + 1
Next SingleCell
For Each SingleCell In FilmList2
FilmDataSeries2.Points(FilmCounter2).DataLabel.Text = SingleCell.Value
FilmCounter2 = FilmCounter2 + 1
Next SingleCell
End Sub
I'm getting a 1004 error saying the dimension specified is not valid. When I replace FONames or BONames with an actual range of cells, Eg. Range("A5","A11"), everything works perfectly. How do I use those dynamic named ranges in my code?

What is the definition of your dynamic named range? I defined a named range for column A like so:
=OFFSET(Sheet1!$A$1,1,0,COUNTA(Sheet1!$A:$A)-1,1)
and it worked just fine.

For example :
'---------------------------------------------------------------------------
' In order to add label at scatter graph. You must selected a graph before.
' #param void
'---------------------------------------------------------------------------
Sub add_label_on_graph()
Dim Counter As Integer
Dim xVals As String
Dim reponse As Integer
If ActiveChart Is Nothing Then
reponse = MsgBox("Attention, vous devez au préalable sélectionner un graphique avant de lancer cette commande.", vbExclamation, "Information")
Exit Sub
End If
Application.ScreenUpdating = False
' Récupération de la range des données que l'on stocke dans la variable xVals.
xVals = ActiveChart.SeriesCollection(1).Formula
xVals = Mid(xVals, InStr(InStr(xVals, ","), xVals, Mid(Left(xVals, InStr(xVals, "!") - 1), 9)))
xVals = Left(xVals, InStr(InStr(xVals, "!"), xVals, ",") - 1)
Do While Left(xVals, 1) = ","
xVals = Mid(xVals, 2)
Loop
' Ajoute un label à chaque point du graphique
For Counter = 1 To Range(xVals).Cells.Count
ActiveChart.SeriesCollection(1).Points(Counter).HasDataLabel = True
ActiveChart.SeriesCollection(1).Points(Counter).DataLabel.text = Range(xVals).Cells(Counter, 1).Offset(0, -1).Value
Next Counter
Application.ScreenUpdating = True
End Sub

Related

Using named ranges with embedded formulas for excel chart data

I have two drop-down menus that list a range of dates. One date identifies the beginning of the range and the other the end. I also created two named ranges as follows:
chart_Dates=INDEX(Dates,MATCH(Home!$A$7,Dates,0)):INDEX(Dates,MATCH(Home!$A$9,Dates,0))
chart_Frequency=INDEX(Frequency,MATCH(Home!$A$7,Dates,0)):INDEX(Frequency,MATCH(Home!$A$9,Dates,0))
Dates, and Frequency from those formulas are named ranges with set boundaries. If I manually enter the y-values as "Home!chart_Frequency" and the horizontal values as Home!chart_Dates the macro works just fine. I can adjust the start and end dates using the drop-down menus and the graph updates accordingly.
However, the macro recorder doesn't translate those action into code. I've attempted the following code without success (there is no error generated but the graph only references the first cell in my range).
ActiveChart.SeriesCollection(1).Values = Range("chart_Frequency")
ActiveChart.SeriesCollection(1).XValues = Range("chart_Dates")
How do I get the code to replicate what I can do manually? Any advice is greatly appreciated!
Try this:
Sub testing()
Dim freqRange As String
Dim datesRange As String
Dim Name As Variant
For Each Name In ThisWorkbook.Names
If Name.Name = "chart_Frequency" Then
freqRange = Name.Value
ElseIf Name.Name = "chart_Dates" Then
datesRange = Name.Value
End If
Next Name
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(1).Name = "=Sheet1!$B$1"
ActiveChart.FullSeriesCollection(1).Values = datesRange
ActiveChart.FullSeriesCollection(1).XValues = freqRange
End Sub
My chart didnt have any series so it adds a new series and it updates the Name, Values and XValues with no issues.
Here is the code I have right now. After it runs when I check the y-values and horizontal values on the graph itself and they are both blank.
'Create chart
Dim rng As Range
Dim cht As ChartObject
'Data range for the chart
Set rng = ActiveSheet.Range("$E$7:$F$501")
'Designates which cell to place the top left corner of the graph in
ActiveSheet.Range("N5").Select
'Create a chart
Set cht = ActiveSheet.ChartObjects.Add( _
Left:=ActiveCell.Left, _
Width:=360, _
Top:=ActiveCell.Top, _
Height:=216)
'Give chart some data
'I was using the line below to set the range but comment blocked it out and entered the suggested code
' cht.Chart.SetSourceData Source:=rng
Dim freqRange As String
Dim datesRange As String
Dim Name As Variant
For Each Name In ThisWorkbook.Names
If Name.Name = "chart_Frequency" Then
freqRange = Name.Value
ElseIf Name.Name = "chart_Dates" Then
datesRange = Name.Value
End If
Next Name
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(1).Name = "=Home!$A$5"
ActiveChart.FullSeriesCollection(1).Values = datesRange
ActiveChart.FullSeriesCollection(1).XValues = freqRange
'Determine the chart type
cht.Chart.ChartType = xlLineMarkersStacked
'Remove Major Gridlines
cht.Chart.Axes(xlValue).MajorGridlines.Delete
'Sets the legend to the bottom of the graph
cht.Chart.SetElement (msoElementLegendBottom)
cht.Name = "Frequency_Chart"
'Add title and reference A5 for name
ActiveSheet.ChartObjects("Frequency_Chart").Activate
ActiveChart.SetElement (msoElementChartTitleAboveChart)
Application.CutCopyMode = False
Selection.Caption = "=Home!R5C1"

Power Point VBA - Change color of each bar

I need to change color of bar to red or green based on value.
Code works fine on Column chart but does not work on waterfall chart. It says "This action is not supported."
Please help making below code waterfall chart compatible:
Sub UpdateBarColor()
Dim p As Point
Dim s As Series
Dim c As Chart
Set c = ActiveWindow.Selection.ShapeRange(1).Chart
Set s = c.SeriesCollection(1)
For Each p In s.Points
Debug.Print p.Format.Fill.ForeColor.RGB
Next
End Sub
This changes the bars in a waterfall chart to be gray (that's the RGB)
You should be able to modify it to suit your needs
Set c = ActivePresentation.Slides(1).Shapes(1).Chart.SeriesCollection(1)
For Each p In c.Points
p.Format.Fill.ForeColor.RGB = RGB(169, 169, 169)
Next
Getting xvalues from the chart, try this
Dim arr As Variant
Dim i As Integer
With ActivePresentation.Slides(1).Shapes(1).Chart.SeriesCollection(1)
arr = .XValues
For i = LBound(arr) To UBound(arr)
Debug.Print arr(i)
Next
End With

How can I extend a chart in Excel by a certain amount of months including named ranges?

I'm trying to extend all charts in a sheet by 12 months to add another year on a monthly line graph. This is what I have so far.
Sub Chart_Extender()
Dim Rng_Extension As Integer
Dim Series_Formula As String
Dim StartPoint As String
Dim EndPoint As String
Dim CommaSplit As Variant
Dim ColonSplit As Variant
Dim grph As ChartObject
Dim ser As Series
'Determine the length of the extension (in cells)
On Error GoTo BadEntry
Rng_Extension = InputBox( _
"How many cells do you want to extend your chart's series?", _
"Chart Extender")
On Error GoTo 0
For Each grph In ActiveSheet.ChartObjects
For Each ser In grph.Chart.SeriesCollection
Series_Formula = ser.Formula
CommaSplit = Split(Series_Formula, ",")
ColonSplit = Split(CommaSplit(2), ":")
StartPoint = ColonSplit(0)
EndPoint = ColonSplit(1)
EndPoint = Range(EndPoint).Offset(0, Rng_Extension).Address
ser.Values = StartPoint & ":" & EndPoint 'Combine Start and End Point & Set Series = To It
If CommaSplit(1) <> "" Then
ColonSplit = Split(CommaSplit(1), ":")
StartPoint = ColonSplit(0)
EndPoint = ColonSplit(1)
EndPoint = Range(EndPoint).Offset(0, Rng_Extension).Address 'Extended Ending Point Range
ser.XValues = StartPoint & ":" & EndPoint 'Combine Start and End Point & Set Series = To It
End If
End If
Next ser
Next grph
MsgBox "Your chart has been Extended by " & Rng_Extension & " positions."
Exit Sub
End Sub
However, since there are named ranges in the graphs as well it seems to get stuck and has an error at EndPoint=ColonSplit(1) saying "Subscript out of range". Is there a way to fix this? Also is there a way to add another loop to have this go through each sheet in the workbook and extend all of them?
After you have validated user input and are sure that you do need to extend the charts, create a workbook and worksheet object:
Dim oWB As Workbook: Set oWB = ThisWorkbook
Dim oWS As Worksheet
Now add the following loop before any of your FOR loops:
For Each oWS In oWB.Worksheets
' Your FOR loops here
Next
This will go through all the sheets in your workbook.
NOTE: Don't forget to add oWS before you reference a Range or Cell

Excel failling to recognize type of chart

I have following code to copy all charts on one sheet into another.
Problem is that in spite of the fact that my charts have numeric(timeseries) data for horizontal axis Excel treats it as categorical. I can tell that is does that because it tries to display every single date on the axis( in spite of my code swtiching it to once a month), and once select "Format Axis" I only see fields for Categorical data( I am missing fields like Maximim, Major Unit etc.).
This is the code I am using, to be hones I copeid most of it of some forum but I cannot recall where if I do find it again I'll post a link:
Sub CopyCharts(Source As Worksheet, Target As Worksheet)
Dim SChart As ChartObject
Dim NChart As ChartObject
Dim NewSheetNChart As ChartObjects
Dim ChartTop As Single
Dim ChartLeft As Single
Dim ChartIndex As Integer
Dim ChartSeries As Series
Dim XAxis As Axis
For Each SChart In Source.ChartObjects
'Save chart's current position
ChartTop = SChart.Top
ChartLeft = SChart.Left
'Copy and paste the chart
SChart.Copy
Target.Paste
'Find the chart in a new spreadsheet
ChartIndex = ChartIndex + 1
Set NewSheetNChart = Target.ChartObjects
Set NChart = NewSheetNChart(ChartIndex)
'Align the charts
NChart.Top = ChartTop
NChart.Left = ChartLeft
'Delink sereis from source
For Each ChartSeries In NChart.Chart.SeriesCollection
ChartSeries.XValues = ChartSeries.XValues
ChartSeries.Values = ChartSeries.Values
ChartSeries.Name = ChartSeries.Name
Next ChartSeries
'Set the X axis to correct values
Set XAxis = NChart.Chart.Axes(xlCategory, xlPrimary)
With XAxis
.CategoryType = xlTimeScale
.BaseUnit = xlMonths
.MajorUnit = 1
End With
Next SChart
End Sub

how to use variable in range using vba

Hello I have written code for generating graph using vba. everything working correctly ,but problem is i want to use variable for selecting particular column
the code is :
Set x = Range("$CF$2", Range("$CF$2").End(xlDown))
Set y = Range("$CG$2", Range("$CG$2").End(xlDown))
Dim c As Chart
Set c = ActiveWorkbook.Charts.Add
Set c = c.Location(Where:=xlLocationAsObject, Name:=assume)
With c
.ChartType = xlXYScatterLines
' set other chart properties
With .Parent
.Top = Range("cl1").Top
.Left = Range("cl12").Left
.Name = "c"
End With
End With
Dim s As Series
Set s = c.SeriesCollection(1)
With s
.Values = y
.XValues = x
' set other series properties
End With
I want to use variable COLs in first to line they are
Set x = Range("$CF$2", Range("$CF$2").End(xlDown))
Set y = Range("$CG$2", Range("$CG$2").End(xlDown))
COLs is variable of string
I'm not sure I understand, but if you want a Range object based on a string, why not try this:
Option Explicit
Sub TestRange()
'***** Declare variables
Dim oX As Range
Dim sCOLs As String
'***** Select column
sCOLs = "A"
'***** Set Range based on column from sCOLs
Set oX = Range(sCOLs & "2", Range(sCOLs & "2").End(xlDown))
'***** Do something with oX
Debug.Print TypeName(oX)
'***** Clean up
Set oX = Nothing
End Sub
You could also try and have the whole range as a string, maybe a bit cleaner code?
Dim sRange as String
sRange = "A2"
Set oX = Range(sRange, Range(sRange).End(xlDown))
You could also use Inputbox to have the user click on a certain cell. This then creates a variable "UserRange" which contains the cell reference you can use.
Sub test()
Dim UserRange As Range
Set UserRange = Application.InputBox(Prompt:="Please Select Range", Title:="Range Select", Type:=8)
UserRange.Value = "Test"
End Sub