Deleting specific ChartObjects by Name Property Excel VBA - excel

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

Related

Excel VBA for making multiple graph without using Range

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.

Access VBA Creating and formatting chart macro works in Excel but not in Access

I have a module in Access that makes a new Excel spreadsheet, makes a new table, and copies data from the database into the table. I want to create a chart out of this table and format it. The sub to create the chart is below.
Dim xlapp as Excel.Application
Dim wb as Excel.Workbook
Dim ws as Excel.Worksheet
Set xlapp = New Excel.Application
Set wb = 'created new workbook
Set ws = wb.Worksheets(1)
ws.Range("Results_Table[#All]").Select
ws.Shapes.AddChart2(201, xlColumnClustered).Select
ActiveChart.SetSourceData Source:=Range("Results_Table[#All]")
ActiveChart.FullSeriesCollection(1).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(1).AxisGroup = 1
ActiveChart.FullSeriesCollection(2).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(2).AxisGroup = 1
ActiveChart.FullSeriesCollection(3).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(3).AxisGroup = 1
ActiveChart.FullSeriesCollection(4).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(4).AxisGroup = 1
ActiveChart.FullSeriesCollection(5).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(5).AxisGroup = 1
ActiveChart.FullSeriesCollection(6).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(6).AxisGroup = 1
ActiveChart.FullSeriesCollection(7).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(7).AxisGroup = 1
ActiveChart.FullSeriesCollection(8).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(8).AxisGroup = 2
ActiveChart.FullSeriesCollection(9).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(9).AxisGroup = 2
ActiveChart.FullSeriesCollection(10).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(10).AxisGroup = 2
ActiveChart.FullSeriesCollection(11).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(11).AxisGroup = 2
ActiveChart.FullSeriesCollection(12).ChartType = xlColumnStacked
ActiveChart.FullSeriesCollection(12).AxisGroup = 2
ActiveChart.FullSeriesCollection(13).ChartType = xlXYScatterLines
ActiveChart.FullSeriesCollection(13).AxisGroup = 2
ActiveChart.FullSeriesCollection(14).ChartType = xlXYScatter
ActiveChart.FullSeriesCollection(14).AxisGroup = 2
ActiveChart.ChartGroups(2).Overlap = 100
ActiveChart.ChartGroups(2).GapWidth = 475
ActiveChart.ChartGroups(1).GapWidth = 159
In access, this code can successfully create a chart of the 'Column Clustered' type. However, that's all. Everything below where I attempt to change some parts into stacked columns or scatters does nothing. I can put a print statement at the bottom of it all that registers, so I know the code actually reaches that point.
I can also copy and paste this exact code (changing ws to ActiveSheet) and it works perfect, creating the chart I want and formatting it exactly as it is supposed to.
I am unsure why these commands work in Excel but not in the Access module.
Perhaps the active chart is not the chart you just created? Try something like:
dim chrt as Chart
set chrt = ws.Shapes.AddChart2(201, xlColumnClustered)
chrt.SetSourceData Source:=Range("Results_Table[#All]")
replacing active chart with chrt.
Essentially, your issue is accessing Excel objects outside of Excel. In MS Office applications when you do not qualify methods with a named object, it is assumed you are accessing objects within the host application. See below illustration with the workbook object
Dim xlApp As Excel.Application ' UNNECESSARY IF INSIDE MS EXCEL
Set wb = xlApp.Workbooks.Open(...) ' ASSIGN EXCEL WORKBOOK EXTERNALLY
Set wb = Workbooks.Open(...) ' ASSIGN EXCEL WORKBOOK INTERNALLY
Hence, your ActiveChart is pointing to an MS Access ActiveChart object which may be its OLEDB Chart form/report object or your code is error-ing out but you are suppressing message (i.e., On Error Resume Next) as this does not sound like an MS Access object.
But to access Excel's Chart object, assign it to a defined object with Set operator:
Dim myChart As Object ' LATE BINDING
'Dim myChart As Excel.Chart ' EARLY BINDING
...
ws.Range("Results_Table[#All]").Select
Set myChart = ws.Shapes.AddChart2(201, xlColumnClustered)
myChart.SetSourceData Source:=ws.Range("Results_Table[#All]")
myChart.Select
myChart.FullSeriesCollection(1).ChartType = xlColumnStacked
myChart.FullSeriesCollection(1).AxisGroup = 1
...
Alternatively use the With...End With block and a DRY-er code with a loop
Dim xlApp As Excel.Application
Dim i As Integer
...
ws.Shapes.AddChart2(201, xlColumnClustered).Select
With xlApp.ActiveChart
.SetSourceData Source:=ws.Range("Results_Table[#All]")
For i = 1 To 14
.FullSeriesCollection(i).ChartType = xlColumnStacked
.FullSeriesCollection(i).AxisGroup = 1
Next i
...
End With

Adding SeriesCollection to a Chart with UserForm (combobox)

I am learning to use VBA for excel in Excel 2016. At the moment I am working through an assignment on this website: http://www.homeandlearn.org/vba_charts_and_user_forms.html in which I want to show a scatter-plot of one of the football teams' results. This is done by selecting the team with a combobox in a user form.
The result of the code (see below) ought to be a scatterplot with One line and a title, like this:
http://www.homeandlearn.org/images/vba_charts/chart_arsenal.gif (cannot upload it for some reason)
However, this is the result of my code.
How is it possible that, with the exact same code as on the website, the Chart isn't able to show the selected data and title? I also wonder where the fifth series came from, since I only have four columns.
The code is as follows (and unique to the code described on the website):
Private Sub cmdLoad_Click()
If cbSelect.Text = "Select a chart" Then
MsgBox "Please select a chart"
Exit Sub
End If
Dim MyChart As Chart
Dim ChartData As Range
Dim ChartIndex As Integer
Dim ChartName As String
ChartIndex = cbSelect.ListIndex
Select Case ChartIndex
Case 0
Set ChartData = ActiveSheet.Range("B2:B20")
ChartName = ActiveSheet.Range("B1").Value
Case 1
Set ChartData = ActiveSheet.Range("C2:C20")
ChartName = ActiveSheet.Range("C1").Value
Case 2
Set ChartData = ActiveSheet.Range("D2:D20")
ChartName = ActiveSheet.Range("D1").Value
Case 3
Set ChartData = ActiveSheet.Range("E2:E20")
ChartName = ActiveSheet.Range("E1").Value
End Select
Application.ScreenUpdating = False
Set MyChart = ActiveSheet.Shapes.AddChart(xlXYScatterLines).Chart
MyChart.SeriesCollection.NewSeries
MyChart.SeriesCollection(1).Name = ChartName
MyChart.SeriesCollection(1).Values = ChartData
MyChart.SeriesCollection(1).XValues = ActiveSheet.Range("A2:A20")
'Save chart as an image, remove the chart, then set updating screen to ON'
Dim imageName As String
imageName = ThisWorkbook.Path & "\gs16_pictures" & Application.PathSeparator & "TempChart.gif"
MyChart.Export Filename:=imageName, FilterName:="GIF"
ActiveSheet.ChartObjects(1).Delete
Application.ScreenUpdating = True
'Load picture in user form
UserForm1.Image1.Picture = LoadPicture(imageName)
cbSelect is initialized as follows
Private Sub UserForm_Initialize()
cbSelect.AddItem Range("B1") 'Arsenal
cbSelect.AddItem Range("C1") 'Man City
cbSelect.AddItem Range("D1") 'Newcastle
cbSelect.AddItem Range("E1") 'Cardiff
cbSelect.TextAlign = fmTextAlignCenter
End Sub
The problem was in the statement
Set MyChart = ActiveSheet.Shapes.AddChart(xlXYScatterLines).Chart
This statement automatically plotted the entire data table. To prevent it, it was necessary to explicitly state the SourceData. Below is the code which you need instead of the lines starting with MyChart.SeriesCollection
With MyChart
.SetSourceData Source:=ChartData
.HasTitle = True
.ChartTitle.Text = ChartName
.SeriesCollection(1).XValues = ActiveSheet.Range("A2:A20")
End With
I am not sure why there is a difference between Excel 2016 and the example from the website. Perhaps Excel is "smarter" than before and interpreted the source data.

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

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