Excel VBA for making multiple graph without using Range - excel

I want to have multiple series graph.
I made this code to show three lines.
However, it doesn't work, I can't use Range because my data source is sparse at three line ("I1:I30","I51:I80","I101:I131")
With ActiveSheet.Shapes.AddChart.Chart
.HasTitle = True
.ChartTitle.Text = "My Graph"
.ChartType = xlLine
.SetSourceData Range("I1:I30","I51:I80","I101:I131") 'thats the data for three lines I want to show.
.SeriesCollection(1).Name = "item1"
.SeriesCollection(1).XValues = Range("G1:G30")
How can I solve this?

The range setting is wrong.
Range("I1:I30","I51:I80","I101:I131")
The range should be set as follows.
Range("I1:I30, I51:I80, I101:I131")
However, if the range of the x-axis is constant, it will be appropriate to create a scatter chart.
Sub test()
Dim sourRange(1 To 3) As Range
Dim Srs As Series
Dim Cht As Chart
Dim i As Integer
Set sourRange(1) = Range("i1:i30")
Set sourRange(2) = Range("i51:i80")
Set sourRange(3) = Range("i101:i131")
Set Cht = ActiveSheet.Shapes.AddChart.Chart
With Cht
.HasTitle = True
.ChartTitle.Text = "My Graph"
.ChartType = xlXYScatterLinesNoMarkers
For Each Srs In .SeriesCollection
Srs.Delete
Next Srs
For i = 1 To 3
Set Srs = .SeriesCollection.NewSeries
With Srs
.Name = "item" & i
.Values = sourRange(i)
.XValues = Range("G1:G30")
End With
Next i
End With
End Sub

If the data is not in one contiguous range, then you need to add each series separately. It's the same when creating a chart manually with data in different parts of the worksheet. You cannot select a non-contiguous range and then insert a chart. Instead, create the chart with just one series, then use additional, separate commands to add more series to the chart.

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.

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

Rotating the X and Y axes of a Chart

I am trying to rotated my 3D Column chart. So far I have the following:
ActiveChart.Name = "44 Chart 7"
With ActiveChart
.SetSourceData Source:=pzx.Range("L126:M135")
.HasTitle = False
.HasTitle = True
.Shapes("44 Chart 7").ThreeD.RotationX = 0
.ChartTitle.Text = "Classification Actions"
.ChartArea.Font.Color = RGB(0, 0, 140)
.ChartTitle.Font.Name = "Arial"
.ChartTitle.Font.Size = 10
.Legend.Font.Size = 8
.Legend.Font.Name = "Arial"
.ChartStyle = 11
.ChartArea.Format.Line.Visible = msoFalse
End With
I have two questions -
1) what determines how a chart is named if you do not actively name the chart yourself
2) do you know why this code does not work
Here is the error I received -
Run-time error 7
Out of Memory
Thanks so much!
Naming objects have naming conventios that you must follow. For charts: when a chart is on a worksheet the Name property applies to the ChartObject object which is the container for the Chart.
With Chart
.Parent.Name = "myChartName"
End With
or
`Sheets(1).ChartObjects(3).Name = "Name of my Chart"`
or
`Sheets(1).Charts("My old Chart Name").Name = "Name of my Chart"`
If you know where your chart is residing, point to chart with sheet reference to be in the safe side than using ActiveChart. If you do not actively name the chart, then you must use chart's default original name to refer to it. Or its index.
Please try this code piece in your end.
Option Explicit
Sub createMyCharts
Dim mySheet As Worksheet
Dim mychtObject As ChartObject
Dim myChart As Chart
'-- put anything else you need to delcare and set
Set mySheet = Worksheets(1) '-- set according to your sheet
'-- delete any old leftovers to clean up
For Each mychtObject In mySheet.ChartObjects
mychtObject.Delete
Next
'-- create new chart
Set myChart = mySheet.ChartObjects.Add(Left:=30, Width:=500, Top:=30, Height:=200).Chart
With myChart
.ChartType = Excel.XlChartType.xl3DColumn '-- the full chart Type
.SetSourceData(mySheet.Range("L126", "M135"), Excel.XlRowCol.xlColumns)
.Rotation = 30
End With
'-- do anything else you need to do
End Sub
Reference to MSDN Chart Rotation
After trying out, you may comment and happy to help futher if you have any questions. :)

Resources