How do you get PowerPoint VBA SetSourceData to work - vba

I am trying to use vba to expand or collapse the source data range of a PowerPoint chart. I can update the data, but when I use SetSourceData, nothing happens.
Example snippet:
With ActivePresentation.Slides(1).Shapes("Chart 5").Chart
.SetSourceData Source:="=Sheet1!$A$1:$D$4"
End With
What am I missing?
I tried using this code...
With ActivePresentation.Slides(1).Shapes("Chart 5").Chart
.SetSourceData Source:="=Sheet1!$A$1:$D$4"
End With

Related

Use VBA to change source file of chart pasted into PowerPoint using Link Data option

I have a PowerPoint presentation in which I create charts in Excel and then link them into the PowerPoint. There are two ways to do this:
Paste Special > Paste Link > Microsoft Excel Chart Object
Paste > Keep Source Formatting and Link Data / Use Destination Theme and Link Data
I would late like to use VBA to change the source Excel file. To do this, consider the following code:
Private Sub PrintLinks()
Dim pptPresentation As Presentation
Dim pptSlide As Slide
Dim pptShape As Shape
Set pptPresentation = ActivePresentation
For Each pptSlide In pptPresentation.Slides
For Each pptShape In pptSlide.Shapes
If pptShape.Type = msoChart Or pptShape.Type = msoLinkedOLEObject Or pptShape.Type = msoLinkedChart Then
Debug.Print pptShape.LinkFormat.SourceFullName
pptShape.LinkFormat.SourceFullName = "PATH/TO/NEW/FILE"
pptShape.LinkFormat.Update
End If
Next
Next
End Sub
This will work for the Paste Link case, but not the Link Data case, in which case pptShape.Type = msoChart. My question is if there is a way to make it work with Link Data as well. Wtih Paste Link, the SourceFullName property will point to a specific chart object, like filename1.xlsx!Chart 1, and changing it to filename2.xlsx!Chart 1 will work as expected. In contrast, under the Link Data option the SourceFullName property only points to filename1.xlsx and I cannot figure out how to see what chart object within the file it is pointing to. Regardless, if I change SourceFullName to filename2.xlsx no error will be thrown, but as far as I can tell the pointer is still to filename1.xlsx, as the chart doesn't change.

SetDataSource of Excel Chart from Access VBA

I haven't been able to find any workable solution for this in a couple hours of searching, so here I go.
I am exporting some data from access to excel via vba, formatting the excel and moving worksheets around, and then generating a chart. When I was testing it all in an excel macro I was able to use the SetDataSource method to adjust the range, but when I moved over to Access it didn't like this method, and will throw a run-time error of 438, "Object doesn't support this property or method". Simplified code below.
Dim xl as Object, wb as Object
Set xl = CreateObject("Excel.Application")
With xl
.Visible = False
.displayalerts = False
Set wb = .workbooks.Open(wbookpath)
'formatting code that all works fine
.Charts.Add
'add was called from sheet 11, popped up before 11 and am moving to end
.Sheets(11).move after:=.Sheets(12)
With Charts(1)
.SetSourceData .Range("Master!$A$1:$G$11")
'other chart formatting code that all works fine
End With
.activeworkbook.Close (True)
.Quit
End With
I have also tried changing the source, e.g.
.SetSourceData .Sheets("Master").Range("$A$1:$G$11")
changing where I call it from, e.g.
.Charts.Add
wb.Charts(1).SetSourceData .Range("Master!$A$1:$G$11")
With .Charts(1)
'rest of code
but it doesn't affect the error being thrown.
How can I get Access to adjust the source of my chart? If I can get this working then I would be able to go forward with making a slew of other charts as well.
This syntax worked for me:
With wb.Charts(1)
.SetSourceData Source:=Sheets("Master").Range("$A$1:$G$11")
'other chart formatting code that all works fine
End With
Reference https://learn.microsoft.com/en-us/office/vba/api/excel.chart.setsourcedata

Referencing Charts By Name Only in PowerPoint VBA

I have been searching for hours to try to find the answer to this question, but to no avail, so I'm hoping I can find the answer here.
I want to create a variable that refers to a pre-existing chart in PowerPoint so I can start automating its data. I want to refer to the chart by its name to make things very easy, but no matter what I do I cannot seem to give PPT a satisfactory Chart address.
I have tried almost every possible variation of the below, but without success:
Dim chrtPP As PowerPoint.Chart
Set chrtPP = ActivePresentation.Slides(1).Shapes.Charts("Chart3")
Could someone please tell me what I'm doing wrong?
Thanks!
You need to reference the shape by name (a 'Shape" in PowerPoint is actually any object that is on a slide and can be a simple shape, textbox, table, chart, group, media clip etc.). If you're on PowerPoint 2010 and higher, press Alt+F10 to open the selection pane to find the name of the selected chart object. It may be a standard chart object or a chart within a placeholder object. You can then reference the chart as follows:
Option Explicit
Sub ChartStuff()
Dim oShp As Shape
Dim oCht As Chart
Set oShp = ActivePresentation.Slides(1).Shapes("Chart 3")
If oShp.HasChart Then
Set oCht = oShp.Chart
End If
' Do stuff with your chart
If oCht.HasTitle Then Debug.Print oCht.ChartTitle.Text
' Clean up
Set oShp = Nothing
Set oCht = Nothing
End Sub
The key in programming PowerPoint is to ignore the object name in the Object Model for 'Shape' as it's very misleading!

Chart label doesn't update after running resizing range' macro

I have a Power Point presentation which ~200 slides. Each slide have one chart, which data is updated monthly by a link to a master xlsx file. In order to not show empty values (future months) in the charts, I have to open the data editor (chart right click > Edit data...) of every chart and select the range until the current month.
I wrote a macro for it in Power Point:
Sub Refresh_slides()
For i = 1 To ActivePresentation.Slides.Count
Set ObjSlide = ActivePresentation.Slides(i)
On Error Resume Next
Set mychart = ObjSlide.Shapes("Chart 3").Chart
mychart.Select
mychart.ChartData.Activate
Set wb = mychart.ChartData.Workbook
Set ws = wb.Worksheets(1)
Application.Run "Refresh_slides_AUX.xlsm!atual_slide"
wb.Close True
Next
End Sub
Refresh_slides_AUX.xlsm is an auxiliary macro worksheet to select the correct range of each chart (necessary because Power Point VBA, as long as I know, don't have an option to do it):
Sub atual_slide()
Windows("Gráfico no Microsoft PowerPoint").Activate
ActiveSheet.ListObjects("Table1").Resize Range("$A$1:$I$23")
ActiveWindow.Close SaveChanges:=True
End Sub
It works fine, but even after the range is resized the chart label doesn't reflect this change in source data. How can I force the appearance of the chart label to update? Seems like something is missing between lines
ActiveSheet.ListObjects("Table1").Resize Range("$A$1:$I$23")
and
ActiveWindow.Close SaveChanges:=True
like a "refresh" or "reset", but I can't figure it out...
Any ideas?
PS. By "label" I mean a data table (don't know how they call it in english) which is a label option in Office. Eg. below:

Turning the visibility of chart series on/off using excel Macros/vba

I am making a line graph (chart) in Excel with several data series being plotted onto the same chart.
I need to create a macro/VBA solution that can turn the visibilty of these series on/off via the pressing of a button (or tick box etc)
Similar to this picture (manually done through the excel menu system)
I have tried to look through all the member vars/methods on
https://msdn.microsoft.com/EN-US/library/office/ff837379.aspx
but haven't had much luck.
I have tried playing around with bits like
Charts("Chart1").SeriesCollection(1)
and
Worksheets("Graphical Data").ChartObjects(1)
but I can neither get the chart object ( I get a subscript out of range error) nor able to find any method that would allow me to turn on/off the visibility of individual series.
Any Ideas?
Whenever I don't know how to do something like this, I turn on the macro recorder.
I had a chart with four series, and I used the filter function in Excel 2013 to hide and show the second series, while the macro recorder was running.
Here's the relevant code:
ActiveChart.FullSeriesCollection(2).IsFiltered = True
' series 2 is now hidden
ActiveChart.FullSeriesCollection(2).IsFiltered = False
' series 2 is now visible
The series type (line or column) does not matter, this works for any of them.
I believe the property you are looking for is the SeriesCollection.Format.Line.Visible property. I quickly created an Excel workbook and added a simple data set (just 1-10) and added a line graph "Chart 2" to the sheet Sheet1.
This code turned the visibility of the line off:
Option Explicit
Private Sub Test()
Dim cht As Chart
Dim ser As Series
'Retrieve our chart and seriescollection objects'
Set cht = Worksheets("Sheet1").ChartObjects("Chart 2").Chart
Set ser = cht.SeriesCollection(1)
'Set the first series line to be hidden'
With ser.Format.Line
.Visible = msoFalse
End With
End Sub
And likewise, setting the ser.Format.Line.Visible property to msoTrue made the line visible again.
As for retrieving the chart itself I had to first activate it, then set my cht variable to the ActiveChart. To view the name of your chart, select it and look in the name box (near where you would enter the cell value / formula).
Update
When using the method above, the series name remains in the legend box. I couldn't find a visibility property for the SeriesCollection in the legend, however one workaround is to simply re-name the series as an empty string (this will make the series disappear from the legend) and then rename the series when you want to show it.
This code below will toggle the visibility of the line and series name in the legend.
Option Explicit
Private Sub Test()
Dim cht As Chart
Dim ser As Series
'Retrieve our chart and seriescollection objects'
Set cht = Worksheets("Sheet1").ChartObjects("Chart 1").Chart
Set ser = cht.SeriesCollection(1)
'Set the first series line to be hidden'
With ser.Format.Line
If .Visible = msoTrue Then
.Visible = msoFalse
ser.Name = vbNullString
Else
.Visible = msoTrue
ser.Name = "Series 1"
End If
End With
End Sub
And, whenever you use .Format.Line.Visible = msoTrue just remember to set ser.Name back to whatever the name for your series is.
There is a simple way to on & off the visibility of the series: using filter on your source data.
May it help you easily as follows.
You can insert a new Window. Setone of them to source data sheet and the other window to Chart sheet. Then arrange the two windows to see both at the same time. Now if you filter the series you like on the source data sheet simultaneously you will see the series you desired on the other sheet.