How to reference a dynamic multiple range? - excel

I am trying to create a chart using a source data list (two separate columns) which can vary in column height depending on user inputs.
I am storing my dynamic value in a variable called "chartRange".
I originally made the sub using a fixed range, using a single code line, which works perfectly.
I replaced this single code line:
Set chartRange = ActiveSheet.Range("E8:E69,G8:G69")
with these 3 new lines of code:
Set r1 = Sheets("Sheet1").Range("E8":"E" & chartRange)
Set r2 = Sheets("Sheet1").Range("G8":"G" & chartRange)
Set myMultipleRange = Union(r1, r2)
I am trying to make these 3 new lines of code work, but getting error message.
Can someone help me correct the code problem?
I have included the full sub below.
Thanks in advance.
Dim chartRange As Integer
Dim cht As ChartObject
Dim totalPymts As Integer
Dim r1, r2, myMultipleRange As Range
' this variable is used to define table size
totalPymts = Worksheets("Sheet1").Cells(5, 4).Value
'my data range for the chart using single line
' Set chartRange = ActiveSheet.Range("E8:E69,G8:G69")
' the 3 new lines that dont work
Set r1 = Sheets("Sheet1").Range("E8":"E" & chartRange)
Set r2 = Sheets("Sheet1").Range("G8":"G" & chartRange)
Set myMultipleRange = Union(r1, r2)
'Create a chart
Set cht = ActiveSheet.ChartObjects.add( _
Left:=Range("a1").Left, _
Width:=450, _
Top:=Range("a5").Top, _
Height:=260)
'Give chart some data
cht.Chart.SetSourceData Source:=myMultipleRange
'Determine the chart type
cht.Chart.ChartType = xlLine
'Ensure chart has a title
cht.Chart.HasTitle = True
'Change chart's title
cht.Chart.ChartTitle.Text = "Repayments Schedual"
'Remove X-axis
' remove legend entry 1
Worksheets("sheet1").ChartObjects(1).Chart _
.Legend.LegendEntries(1).Delete
End Sub

Related

VBA Chart set a manuel Y-Axis Scale

I wrote this method to create 2 charts:
Dim rng As Range
Dim cht As ChartObject
Dim pos As Range
Set rng = ActiveSheet.Range(data_range)
Set pos = Range(position)
Set cht = ActiveSheet.ChartObjects.Add( _
Left:=pos.Left, _
Width:=breite, _
Top:=pos.Top, _
Height:=hohe)
cht.Chart.HasTitle = True
cht.Chart.ChartTitle.Text = "Statistik"
cht.Chart.ChartTitle.Characters.Font.size = 11
cht.Chart.Legend.Delete
cht.Chart.SetSourceData Source:=rng
The problem is that when I use this method to create two charts, I have a different Y-Scale values (because of auto-scaling maybe) that makes the comparison difficult:
For this reason I need to set a same value for Y-Axis to have a better result.
You can try with
cht.Axes(xlValue, xlPrimary).MinimumScale = 0
cht.Axes(xlValue, xlPrimary).MaximumScale = 70
I should have added this lines to my code:
Dim yax As Axis
Set yax = cht.Chart.Axes(xlValue)
yax.Minimumscale = 100
Now works everything well.

Labeling last data points across multiple graphs and series

I'm currently trying to add a data label to only the last point of each series in each graph on a worksheet. I'm currently adapting one of the solutions proposed here: "https://superuser.com/questions/1285179/adding-data-label-only-to-the-last-value".
However, my code keeps on popping up with the error: "Runtime error '13', type mismatch". When I go in debug mode, it higlights the line "Set chrt = ws.ChartObjects(Chart_Name)".
Sub LastDataLabel()
Dim Chart_Name As String
Dim i, Total_Charts, Total_Series As Integer
Dim ws As Worksheet
Dim chrt As Chart
Dim srs As Series
Dim pnt As Point
Dim p As Integer
Application.ScreenUpdating = False
Set ws = ActiveSheet
Total_Charts = Range("C12").Value
For i = 1 To Total_Charts
Chart_Name = ActiveSheet.Cells(14 + i, 2).Value 'A list of all chart names exists along this range
Set chrt = ws.ChartObjects(Chart_Name)
Total_Series = chrt.SeriesCollection.Count
For j = 1 To Total_Series
Set srs = chrt.SeriesCollection(j)
srs.ApplyDataLabels
For p = 1 To srs.Points.Count - 1
Set pnt = srs.Points(p)
pnt.DataLabel.Text = ""
Next
srs.Points(srs.Points.Count).DataLabel.Format.TextFrame2.TextRange.Font.Size = 10
srs.Points(srs.Points.Count).DataLabel.Format.TextFrame2.TextRange.Font.Name = "Arial"
Next j
Next i
End Sub
Any and all help is greatly appreciated. Thank you!
ChartObject is just a container shape for the chart - it's not the actual chart itself
This should improve things:
Set chrt = ws.ChartObjects(Chart_Name).Chart

Deleting specific ChartObjects by Name Property Excel VBA

I have an excel worksheet with two chart objects (pie chart and line graph). I have separate buttons to generate each graph and I want to delete the according pre-existing graph each time the generation button is pressed. Right now, I am attempting to access the Name property of the chart object to determine if the chart needs to be deleted. The deletion code looks like this:
For i = 1 To ActiveSheet.ChartObjects.Count
If ActiveSheet.ChartObjects(i).Chart.Name = "Genre" Then
ActiveSheet.ChartObjects("Genre").Delete
End If
Next i
Here is the code that generates the piechart:
Range("A2:B16").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlPie 'Exploded
ActiveChart.SetElement (msoElementChartTitleAboveChart)
ActiveChart.ChartTitle.Text = "Genre Breakdown"
ActiveChart.Parent.Name = "Genre"
Dim ChartSize As ChartObject
Set ChartSizing = Worksheets("Graphs and Stats").ChartObjects("Genre")
With ChartSizing
.Top = Range("D2").Top
.Width = Range("D2:H23").Width
.Height = Range("D2:H23").Height
.Left = Range("D2").Left
End With
Currently, the If-statement in the deletion for loop never resolves as true and I don't understand why. What is wrong with that line and/or is there better logic I could be using to check for pre-existing charts? I would prefer not use
ActiveSheet.ChartObjects.Delete
if I can avoid it to keep the generation buttons separate from each other.
EDIT: Corrected code (where worksheet name is "Graphs and Stats") using Dammer15's solution:
For i = 1 To ActiveSheet.ChartObjects.Count
If ActiveSheet.ChartObjects(i).Chart.Name = "Graphs and Stats Genre" Then
ActiveSheet.ChartObjects("Genre").Delete
End If
Next i
Set Rng = ActiveSheet.Range("A2:B16")
Set GenreChart = ActiveSheet.Shapes.AddChart
GenreChart.Name = "Genre"
With GenreChart.Chart
.SetSourceData Source:=Rng
.ChartType = xlPie
.SetElement (msoElementChartTitleAboveChart)
.ChartTitle.Text = "Genre Breakdown"
End With
You never get the correct Chart Name. Use the sheets and indexing you need but here's the general idea. You must remove the Sheet name from the accessed property.
'List of Chart Objects
Dim ChartList As ChartObjects
'The square that holds the chart
Dim MyChartFrame As ChartObject
Dim ChartToDelete As ChartObject
'The Physical chart with data
Dim MyChart As Chart
'Accessing the Objects
Set ChartList = Sheet1.ChartObjects
Set MyChartFrame = Sheet1.ChartObjects(1)
Set MyChart = MyChartFrame.Chart
Dim ChartName As String
'Remove SheetName from ChartName!!!!
ChartName = MyChart.Name
'Deleting Chart
Set ChartToDelete = Sheet1.ChartObjects(ChartName)
ChartToDelete.Delete

how to move a pivot chart with vba

i am trying to make a function that creates a chart next to the pivot table but cant make the chart move =( display the right data and works fine, its just been created to far away from the actual pivot table.
Function chart_from_pivot(a_pivot As PivotTable) As Chart
Debug.Print 0
Dim objChart As Chart
Set objChart = Charts.Add
Debug.Print 1
objChart.SetSourceData a_pivot.TableRange1
Debug.Print 2
objChart.ChartType = xl3DColumn
Debug.Print 3
objChart.Location Where:=xlLocationAsObject, Name:=a_pivot.Parent.Name
Debug.Print 4
'HERE IS THE ISSUE!!!!
'objChart.Parent.Left = Range("D2").Left
'Debug.Print 5
'objChart.Parent.Top = Range("D2").Top
'Debug.Print 6
'objChart.ChartStyle = 294
'Debug.Print 7
chart_from_pivot = objChart
End Function
any recommendations? thanks guys.
I needed to set the objchart with the objchart.Location once i added the set now it works =)
this is the final code in case some one needed in the future.
Function chart_from_pivot(a_pivot As PivotTable) As Chart
Dim objChart As Chart
Set objChart = Charts.Add
objChart.SetSourceData a_pivot.TableRange1
objChart.ChartType = xl3DColumn
Set objChart = objChart.Location(Where:=xlLocationAsObject, Name:=a_pivot.Parent.Name)
objChart.ChartStyle = 294
objChart.ChartArea.Left = ThisWorkbook.Sheets("Charts").Range("B10").Left
objChart.ChartArea.Top = ThisWorkbook.Sheets("Charts").Range("B10").Top
chart_from_pivot = objChart
End Function

Changing the series in excel vba

I have a chart on one of my sheets and I need to change a series in it in code. The problem is that I keep getting the error 1004 message. I've looked around and can't find a reason for it. Here's the code:
Sheets("Charts").ChartObjects(1).Chart.SeriesCollection(1).Formula = "=G49:I" & dblResult & ")"
Are you trying this?
Sheets("Charts").ChartObjects(1).Chart.SeriesCollection(1).Formula = _
"=SERIES(,," & "Charts!G49:I" & dblResult & ",1)"
An alternative that I prefer to manipulating the Series Formula is to just work with the individual properties of the SeriesCollection.
Note I'm writing this from memory/untested so let me know if there's any problems with it!
Inside the With block, you would need to determine the Ranges to use for the Values, XValues, Name, and Order, of course you can omit the parts that you don't need (e.g., I rarely need to manipulate the series .Order)
Dim cht as Chart
Dim srs as Series '# Series variable'
Dim s as Long '# Series iterator'
Dim ws as Worksheet
Set ws = ActiveSheet
Set cht = ws.ChartObjects(1).Chart '## Modify as needed.'
For each srs in cht.SeriesCollection
With srs
s = s+1
.Values = ws.Range("Some_Range_For_Values")
.XValues = ws.Range("Range_For_XValues")
.Name = ws.Range("Range_For_SeriesName")
.Order = s
End With
Next
Practically speaking, here is a pretty simple example. I often build or update a chart dynamically using an approach like this. Assuming that XValues are in column A, while series data is in columns B:F, you could do something like:
Dim rngData as Range '# A range containing all of the series values & xValues'
Dim s as Long
Dim cht as Chart
Dim srs as Series
Dim ws as Worksheet
Set ws = ActiveSheet
Set cht = ws.ChartObjects(1).Chart
Set rngData = Range("A2:F10")
'## I like to remove existing series, and then add in the new data. '
For each srs in cht.SeriesCollection
srs.Delete
Next
'## Iterate over our range and add series back in to the chart.'
For s = 2 to rngData.Columns.Count
Set srs = cht.NewSeries
With srs
.XValues = rngData.Columns(1).Address
.Values = rngData.Columns(s).Address
'Name = rngData.Cells(1,s).Offset(-1,0).Value
'Order = s-1
End With
Next

Resources