How to use VBA in PowerPoint to open an embedded OLE object - vba

I think this is a simple question, but I have spent days searching for an answer and nothing yet.
I have an OLE object embedded into a PowerPoint presentation (created using PPT 2010). I embedded it (a pdf file) through the insert>object>create from file>display as icon method, so that it displays as a little icon on a slide.
My goal is to open it on click of a shape, where the shape is on a different slide from the slide the pdf is on. The pdf is on slide 5, the trigger shape is on slide 6. The goal is to open it during slideshow viewing (and it must be done through VBA instead of animations for other reasons).
I thought the following would work:
Sub OpenMyDoc()
ActivePresentation.Slides(5).Shapes("My Doc").OLEFormat.DoVerb(1)
End Sub
I had assigned that macro as an on click "action" through the insert>links method.
I have also tried the following variations, with no luck (nothing happens at all when I click on the triggering shape):
ActivePresentation.SlideShowWindow.View.Slide.Shapes("My Doc").OLEFormat.DoVerb(1)
I also tried:
With SlideShowWindows(1).Presentation.Slides(5).Shapes("My Doc")
OLEFormat.DoVerb(1)
End With
I also tried:
ActivePresentation.Slides.Item(5).Shapes.Item("My Doc").OLEFormat.DoVerb(1)
Other macros (mostly message boxes) in the presentation, and on the same slide work, so I'm sure it's not a permissions or other setting issue.
I am using master slides, but can't seem to trace the problem to that.

You probably saw an error message when you ran your code; the error message explains the problem, though in somewhat Microsoftcryptic fashion. You can only activate OLE objects from Slide or Notes view.
Instead, you can do this:
ActivePresentation.Slides(1).Shapes(4).ActionSettings(1).Hyperlink.Follow
where Shapes(4) is hyperlinked to the PDF you want to launch.
[EDIT]
But since hyperlinking isn't an option, and since you have to be in slide view to activate the embedded object, this works here:
' Activate the presentation window
' You might need to make sure it's in normal view
ActivePresentation.Windows(1).Activate
' Launch the OLE object:
ActivePresentation.Slides(1).Shapes(1).OLEFormat.DoVerb (1)
' And immediately switch back to slide show view
SlideShowWindows(1).Activate

Related

VBA for Powerpoint: Change Slide in One Powerpoint by Selecting Button in Another

I am a beginner at VBA.
I am designing a somewhat interactive Powerpoint presentation/s. I want to be able to have three separate Powerpoint presentations open that will link together. I have been trying (without success) to create, in VBA, code which will change the current displayed slide on one Powerpoint file by clicking a button in another. I can hyperlink to the set slide but this causes this slide to pop up on the same screen in which it is clicked, despite it being already open in another screen (I don't want this).
Thanks in advance for any help,
Holly
VBA uses an object model that is a huge hierarchy of attributes and functions that represent the application. You can use this model to view and update attributes to get text, resize, and modify the application. You should look at some tutorials to get you started. When editing your code, you can press F2 to see and explore this object model. You can press F8 to run your code line by line (debug mode) and see what is happening.
To your question, you can access the open presentations in the application.presentations object (https://learn.microsoft.com/en-us/office/vba/api/powerpoint.presentations). You could then use a presentation in that list and use the ActiveWindow.View.goToSlide function (https://learn.microsoft.com/en-us/office/vba/api/powerpoint.view.gotoslide). Here is a free tutorial that I've used in my VBA journey (https://www.tutorialspoint.com/vba/index.htm).
PowerPoint has a Presentations collection that contains all currently open presentations. You can get a reference to any of them via Presentations("name") where "name" is the filename of the presentation, sans extension.
So ... assuming you've got three presentations open, a.pptx, b.pptx, c.pptx you can do something like this:
Sub SlideChange()
With Presentations("c")
.SlideShowWindow.View.GotoSlide (3)
End With
End Sub
If you run the above in any of the presentations, it will change the slide show window displaying presentation c to the third slide.

Using PowerPoint VBA to change from a Kiosk presentation type to a Speaker presentation type

I have a PowerPoint loaded with VBA and quite a few slides. I would like to be able to manually advance the slides by pressing the {Page Down} key when I am the user running the presentation, but, I want the {Page Down} key not to work when any other user is running the presentation.
I know the following:
I have a function that easily will return the name of the user, so, I can easily compare the current user to myself and execute code based on the match/lack of match. No problem here.
I know that I can set the presentation type by using: ActivePresentation.SlideShowSettings.ShowType = ppShowTypeSpeaker.
I know that I can set the way slides are advanced by using: ActivePresentation.SlideShowSettings.AdvanceMode = ppSlideShowManualAdvance
The problem and things I've tried:
Once the PowerPoint has started, using VBA code to change the value of ShowType from the default setting of ppShowTypeKiosk to ppShowTypeSpeaker does not seem to change the way the rest of the show functions.
Once the PowerPoint has started, using VBA code to change the value of AdvanceMode to ppSlideShowManualAdvance does not actually enable me to manually advance slides (I am still only able to advance slides using the ActiveX buttons on the slide).
I have thought about using event handling to capture the SlideShowBegin event, but, apparently events can only be trapped once code has established the link to the Application object, and, making that link has to happen in code that runs by clicking an ActiveX control (or similar user action) in an already-running slideshow so I am baffled how the SlideShowBegin event would ever be trapped without an AddIn with an Auto_Open macro.
Bottom line: Is there a way for PowerPoint VBA code to switch a slideshow from kiosk to speaker mode so that slides can be manually advanced? (Or, some other way to enable me to manually advance slides while preventing all other users from manually advancing slides?)
Thanks to #SteveRindsberg, the fix is to (a) determine whether or not to switch presentation modes, then, (b) if a switch is needed, run the code to change the settings, then, (c) programmatically end the slideshow, then, (d) programmatically run the code to re-start the slideshow.
It is assumed that the PowerPoint has been saved to run in Kiosk mode by default so that the standard user cannot use PageDown or other navigation techniques to move through slides; that is, slides can only be navigated by the programmer's ActiveX controls that use VBA code to move through the slideshow. (This is handy for quiz-type slideshows, etc.)
Specifically, I have Slide 1 which includes an ActiveX [OK] button on it which the user is directed to click in order to continue; basically, Slide 1 is a title slide that gives the name of the PowerPoint. When the OK button is clicked, the code behind the [OK] button checks to see whether the user should be allowed to change the presentation mode from the default Kiosk mode to Speaker mode. Here's the code behind the [OK] button in Slide 1:
Private Sub cmdFeedbackOK_Click()
'handle the click of the OK button on the feedback which will move to the next slide or exit if the wrong OS or Office Version (based on text associated with the [OK] button
'check for superuser
If LCase(Environ("UserName")) = "{Windows username who is a superuser}" And ActivePresentation.SlideShowSettings.ShowType <> ppShowTypeSpeaker Then 'this will check to be sure that we have not already changed the ShowType (which will have changed if the user opts to switch modes and the PPTX has re-started)
'superuser, so, change to Speaker mode
If MsgBox("Do you want to switch to Speaker view instead of Kiosk view so you can use PageDown?", vbYesNo + vbDefaultButton1, "Use PageDown?") = vbYes Then
ActivePresentation.SlideShowSettings.ShowType = ppShowTypeSpeaker 'switch from Kiosk to Speaker mode so that PageDown key will work
ActivePresentation.SlideShowSettings.AdvanceMode = ppSlideShowManualAdvance 'switch to allow PageDown to manually advance the slides
ActivePresentation.SlideShowWindow.View.Exit 'exit the show because the change in play mode and advance mode will not take effect until the show is started again
ActivePresentation.SlideShowSettings.Run 'restart the show; code in the OnSlideShowPageChange will get triggered to skip this first slide if the user has restarted the show
Exit Sub
End If
End If
ActivePresentation.SlideShowWindow.View.Next 'move to next slide
End Sub
Then, to prevent the superuser from having to view the first slide twice when the slideshow re-starts, I have added the following code to the OnSlideShowPageChange event:
SlideName = ActivePresentation.SlideShowWindow.View.Slide.Name
If SlideName = "sldTitle" Then 'we're on the first slide
If ActivePresentation.SlideShowSettings.ShowType = ppShowTypeSpeaker Then 'this will be true if the Windows user is me (see code in Slide1), and, since I've already seen that slide, just go to the next slide
ActivePresentation.SlideShowWindow.View.Next 'skip the first slide for superuser
'execute other code as desired
'use Exit Sub here if the code below does not need to run for the superuser
End If
End If
'execute other code as desired here, e.g., code for standard users
For me, Slide 1 gives a lengthy delay (maybe 10 seconds) after clicking the [OK] button before the slideshow re-starts, but, the standard user does not experience the delay so I don't mind the wait--it probably has something to do with the VBA code and large number of slides in the presentation that have numerous ActiveX controls--at least, that's my guess.
Hope this helps someone out!

PowerPoint VBA code not running unless VB editor opened first

I have a PowerPoint presentation which consists of a single slide and some VBA code. The code displays a dialog box (not inside the presentation) which configures the slide.
I need the code to be started when the presentation is started.
I found various suggestions and ended up going with
this one however I am getting inconsistent results!
If I do the following, in sequence, it works:
Open presentation in PowerPoint
Select Developer tab
Select Visual Basic (to open VBA editor)
Close VBA editor
Select Slide Show tab
Select From Beginning
However, if I skip steps 2-4, it does not! I.E.:
1. Open presentation in PowerPoint
2. Select Slide Show tab
3. Select From Beginning
It is almost as though Visual Basic support isn't even loading until the editor is opened.
I also tried adding a slide before my main one with an auto-transition immediately and again, no-go.
This is driving me insane as I need to get this deployed to the rest of my department.
Anyone have any ideas?
It's kind of a known problem.
OnSlideShowPageChange sometimes doesn't fire. To get around it, add any of the Active-X controls from the Developer tab to the first slide. Scoot it off the slide if you don't want it visible.
Somehow the control forces VBA to initialize, so events fire.
After I did this with your presentation, it fired off right away.

How to provide VBA access for a modify password protected read only PowerPoint file?

I’m trying to create a free non-editable version of a PowerPoint slide that demonstrates how VBA can be used to make a slide very dynamic. The slide is an interactive stopwatch and there is a video of it here:
http://i-present.co.uk/free-stuff/free-powerpoint-stopwatch/
VBA is used to modify various shapes on the slide based on the Windows API timer.
In the free version, I want the VBA functionality to run but set the presentation up so that the slide objects cannot be edited.
This is what I’ve tried so far:
1 - Setting a modify password on a ppsm version of the file. Problem : VBA cannot modify the properties of objects on the slide when the presentation is opened in read only mode.
2 - Using VBA to save a temporary write version of the file. Problem : once the presentation is opened as read only, it doesn’t appear to be possible to use VBA to provide the password and then save as a modifiable file.
3 - Creating a separate ppsm file which has a single shape on it, with an Action to run a macro to open the password protected stopwatch deck. Problem : the VBA code to open a password protected presentation (available since PowerPoint 2010) causes PowerPoint 2013 to crash:
Dim oPVW As ProtectedViewWindow
Dim oPres As Presentation
Set oPVW = ProtectedViewWindows.Open(FileName, ReadPassword)
Set oPres = PVW.Edit(ModifyPassword)
4 - Embedded the stopwatch ppsm file within another presentation as a slide object so that the user can click on it but not save and edit it. Problem : spawning a slide show from an embedded object causes the VBA code to not run.
Doe anyone have any ideas how the need can be addressed?
Well howdy, Mr.ChromeBumpers
One approach:
Let them edit the shape to their heart's content. But warn them that if they do, your code will decline to run.
Your code can test any combination of the shape's properties you like: Height, width, top, left, color, text and so on. And refuse to run if even one of those properties has been altered from the shape as supplied by you.
Here is code in Excel that opens a password protected PowerPoint file.
Replace the password with your actual password. This has worked in 2010, 2016 and 365 office.
Dim PPTObj As Object
Set PPTObj = CreateObject("PowerPoint.application")
PPTObj.Presentations.Open ("C:\PowerPoint\PW_prot_file.pptm:password::")

maintaining image object visibility with vba

i am developing a large non-linear powerpoint which has many sub sections to it. This has necessitated a table of contents slide (TOC). in this slide i am representing each section with its own picture. also on the slide are 2 buttons which let the user switch between images. The buttons do this by setting the appropriate section image to visible and all the others to invisible, so that only one sections image is visible at a time. my goal is to make sure that whenever the user goes back to the table of contents slide that the slide displays the same section image each time, regardless of which section what entered the previous time, i.e. the image for section 1 should be visible whenever the user goes back to the table of contents. how do i go about doing this?
also, if i can find new sources to learn more about syntax and other vba coding, i would be most appreciative.
i already consult:
pptalchemy.co.uk
skp.mvps.org
msdn.microsoft.com
i just cannot find more good sites that will help.
I don't quite understand the situation, but one possibility:
Add another slide before the TOC. You could make it a duplicate of the TOC slide (with the image you want in place).
Instead of linking back to the "real" TOC slide, link to this one instead.
On this slide, add a rectangle that covers the entire slide, make it 99% transparent and give it a Run Macro mouse over action setting.
Have the macro do nothing more than set the image you want on slide 2 to be visible, then jump to slide 2 (the real TOC slide), eg
SlideShowWindows(1).View.GoToSlide(2)
The mouse over macro will trigger as soon as the user moves the mouse, and since that will trigger a jump from one slide to an identical one, it will be invisible to the user.
most of the solution came from [pptalchemy] (http://www.pptalchemy.co.uk/PowerPoint_Auto_Open_Code.html):
I downloaded the custom ui editor for microsoft office
I added the code from ppt alchemy to the custom ui editor for the slide show.
In vba i added the code:
Sub onloadcode()
Debug.Print "Running"
End Sub
Sub OnSlideShowPageChange(ByVal SSW As SlideShowWindow)
If SSW.View.CurrentShowPosition = SSW.Presentation.Slides("TOC").SlideIndex Then
'code here'
end if
end sub
the code executes perfectly now, and i have condensed my table of contents from 9 slides down to 1. Just, don't add features to the code until you have everything in place to accept them. In my case i added the code for text boxes which did not exist yet and that messed up my code a lot. Once i made all of the objects for the code and then added the code it worked perfectly.