1
votes

I have a PowerPoint Presentation that gets filled with pictures by a VBA script attached to it. I want to automatically open the Presentation and run the macro. Here's what I have tried:

  • turning the script into an add-in as shown here: it ran when I clicked activated it, but never when I simply opened powerpoint.
  • downloaded a pre-built add in, and called my script sub auto_open(). This worked, but because it is a macro enabled file(?), but I have to open powerpoint up and enable the add in before opening the file, so it's not much more automatic than just running the macro
  • Running PowerPoint through MatLab. I used the following commands that I found here, which do open powerpoint, and the file I am interested in.

    • g = actxserver('PowerPoint.Application');
    • Presentation = invoke(g.Presentations,'Open','\\path\Automatic_NEdN_Template2.pptm')
    • a = invoke(Presentation.Application,'Run','Auto_Open',[])

    With small test cases, it even seemed to work--I could call a vba function that read data from a file and it would return the data to matlab, but when I tried to call the one that makes pictures, it returned NaN and the PowerPoint was not filled.

Ideally, I'd like to double click on something, then have PowerPoint open, and run my script.

Here are some code snippets if they'll help:

    Function read_in_data_from_txt_file(strFileName As String) As String()

    Dim dataArray() As String
    Dim i As Integer

    'Const strFileName As String = "C:\H5_Samples\Plots\WeeklyPlots\zz_avgTemp.txt"
    Open strFileName For Input As #1

     ' -------- read from txt file to dataArrayay -------- '

     i = 0
     Do Until EOF(1)
        ReDim Preserve dataArray(i)
        Line Input #1, dataArray(i)
        i = i + 1
     Loop
     Close #1

    read_in_data_from_txt_file = dataArray
    End Function

And here is the code for the pictures:

   Function Auto_Open() As String  

   Dim oSlide As Slide
   Dim oPicture As Shape
   Dim oText As Variant
   Dim heightScaleFactor As Single
   Dim widthScaleFactor As Single
   Dim width As Single
   heightScaleFactor = 2.1
   widthScaleFactor = 2.1
   width = 205
   Height = 360

   ActiveWindow.View.GotoSlide 2

    Set oSlide = ActiveWindow.Presentation.Slides(2)

    Set oPicture = oSlide.Shapes.AddPicture("C:\H5_Samples\Plots\WeeklyPlots\Nominal DS Real spectra.png", _
        msoFalse, msoTrue, 1, 150, Height, width)


    Set oPicture = oSlide.Shapes.AddPicture("C:\H5_Samples\Plots\WeeklyPlots\Nominal DS Imaginary spectra.png", _
        msoFalse, msoTrue, 350, 150, Height, width)

    'Full Resolution
    ActiveWindow.View.GotoSlide 3

    Set oSlide = ActiveWindow.Presentation.Slides(3)

    Set oPicture = oSlide.Shapes.AddPicture("C:\H5_Samples\Plots\WeeklyPlots\Full Resolution DS Real spectra.png", _
        msoFalse, msoTrue, 1, 150, Height, width)


    Set oPicture = oSlide.Shapes.AddPicture("C:\H5_Samples\Plots\WeeklyPlots\Full Resolution DS Imaginary spectra.png", _
        msoFalse, msoTrue, 350, 150, Height, width)
    End Function
1
Try www.pptxbuilder.comBoosted_d16

1 Answers

1
votes

Two ways to do this come to mind:

  1. An Add-in that has an application-level event handler. Then, you could leverage the application class PresentationOpen event, compare the filename against the known file which you want to operate on, and then run the macro only when the right file has been opened. See this MSDN link for some information about creating an application-level event handler class.

  2. Use the Ribbon XML framework to call a procedure from the ribbon's OnLoad event.

The second method would be essentially self-contained whereas the previous method would require at least one additional Add-in file to control the process.

The second method would use VBA that looks something like:

Option Explicit
Public Rib As IRibbonUI

'Callback for customUI.onLoad
Sub RibbonOnLoad(ribbon As IRibbonUI)
    Set Rib = ribbon
    Call Auto_Open()  '### I would recommend changing your procedure name just to avoid confusion...
End Sub
Sub Auto_Open()
    '### This is your procedure/macro that you want to run
    ' etc
    ' etc

End Sub

And you would need the ribbon XML (use the CustomUI editor to insert this, it can be done otherwise but this is probably the simplest):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <customUI onLoad="RibbonOnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui">
   </customUI>

The way this works is that when the file is opened, the RibbonOnLoad procedure is called, and that procedure then calls the procedure which executes your macro code. Note that unhandled run-time errors may cause the loss of the ribbon object variable which can be disastrous in larger applications, but in your specific use-case this shouldn't be a problem as re-opening the file from disk will always reload the ribbon anyways.

This link also has more info about the basics of ribbon customization, but for your purposes, I think the above code is all you should need.