MATLAB Answers

How do I get function prototypes for PowerPoint add-in macros when using actxserver​('PowerPoi​nt.Applica​tion')?

16 views (last 30 days)
Michael
Michael on 25 Jul 2017
Commented: Michael on 27 Jul 2017
I am using the activex capability to control PowerPoint from MATLAB. I have written a couple VBA macros and saved them as a PowerPoint add-in. I can successfully call some of those macros, but not others. It appears that I don't have the right functional form, but I'm not sure how to discover it when it's not obvious. Any suggestions?
Here are the details in case someone wants to try to reproduce it...
In a .potm file I wrote the following macros, then saved it as a .ppam file and activated that add-in:
Function triggerBoxFcn()
Dim testStr As String
testStr = "Yay, it worked!"
showBoxFcn (testStr)
End Function
Function showBoxFcn(textStr As String)
MsgBox (textStr)
End Function
Function getItemAdjustments(slideNum As Integer, shapeNum As Integer) As Variant
Dim points() As Double
Dim numPoints As Integer
Dim N As Integer
numPoints = ActivePresentation.Slides.Item(slideNum).Shapes.Item(shapeNum).Adjustments.Count
ReDim points(1 To numPoints)
For N = 1 To numPoints
points(N) = ActivePresentation.Slides.Item(slideNum).Shapes.Item(shapeNum).Adjustments.Item(N)
Next N
If numPoints > 0 Then
getItemAdjustments = points
Else
getItemAdjustments = -1
End If
End Function
Function setItemAdjustments(slideNum As Integer, shapeNum As Integer, points() As Double) As Integer
Dim numPoints As Integer
Dim N As Integer
numPoints = ActivePresentation.Slides.Item(slideNum).Shapes.Item(shapeNum).Adjustments.Count
If numPoints = UBound(points) Then
For N = 1 To numPoints
ActivePresentation.Slides.Item(slideNum).Shapes.Item(shapeNum).Adjustments.Item(N) = points(N)
Next N
setItemAdjsutments = 1
Else
setItemAdjustments = -1
End If
End Function
Then from MATLAB I can run the following commands to initialize PowerPoint and get a slide:
ppt = actxserver('PowerPoint.Application');
ppt.Visible = 1; % opens ppt on screen (error when hiding window)
Presentation = ppt.Presentation.Add;
Slide1 = Presentation.Slides.AddSlide(1,Presentation.SlideMaster.CustomLayouts.Item(7)); % Item(7) is a completely blank slide
At this point I try to run my simplest macro which should pop up a message box in PowerPoint with the prepopulated text:
>> ppt.Run('triggerBoxFcn');
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
This didn't work. However, adding a dummy argument makes it work just fine:
>> ppt.Run('triggerBoxFcn',[]); % pop-up worked as expected
Then I try the slightly more elaborate function assuming that it too needs the dummy argument:
>> ppt.Run('showBoxFcn','Too bad :(',[]);
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
That didn't work. But if I omit that extra dummy argument it works just fine:
>> ppt.Run('showBoxFcn','This worked though :)'); % pop-up worked as expected
So now onto the functions I actually want to use. Though I could programmatically create and connect blocks, I do it by mouse in PowerPoint for now on slide 1. The elbow connector is the item of interest and it's number 3 as confirmed this crude way:
>> Slide1.Shapes.Count
ans =
3
>> Slide1.Shapes.Item(3).Name
ans =
Elbow Connector 4
So I try all kinds of approaches and they all fail:
>> ppt.Run('getItemAdjustments',1,3)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',1,3,[])
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',[],1,3)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',[],1,3,[])
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',1,3,[],[])
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> a=int32(1);b=int32(3); % thinking maybe it doesn't like doubles
>> ppt.Run('getItemAdjustments',a,b)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',a,b,[])
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',[],a,b)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',[],a,b,[])
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',a,b,[],[])
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> c=[]; % thinking maybe it wants me to pass in a container that it'll use to return
>> c=ppt.Run('getItemAdjustments',a,b,c)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
How do I know what form a macro function is expecting when it's called externally (i.e. from MATLAB)? I can't seem to guess and test this one to success but I'm not sure how to get function prototype information on the macro functions themselves. Using something like libfunctions(ppt,'-full') only tells me the form for the Run function (which is Variant Run(handle, string, SafeArray(Variant)) by the way) but that doesn't help me know how to call an individual macro function.

  0 Comments

Sign in to comment.

Accepted Answer

Philip Borghesani
Philip Borghesani on 26 Jul 2017
Edited: Philip Borghesani on 26 Jul 2017
I have never actually done this but I am going to give you an educated guess based on normal MATLAB use and error message interpretation.
Variant Run(handle, string, SafeArray(Variant))
Says to me that the run command must take 3 inputs but that the third input can be a SafeArray of variant type which I expect translates into a cell array. Given that you would run a script with the syntax:
ppt.Run('myfun',{ arg1, arg2, ...})
% or with no arguments
ppt.Run('myfun',{})
% so
ppt.Run('getItemAdjustments',{1,3})
FYI: libfunctions is not the correct function to retrieve the function signatures. You should use the methods command. (libfunctions happens to work because it calls methods internally)

  3 Comments

Michael
Michael on 26 Jul 2017
Thanks for taking a shot at it. It was a good guess, but unfortunately it didn't work. I get a different error when I pass all arguments as a cell array which seems to suggest there are not enough function arguments based on the "function not defined" type error. I get the same error if I only pass the first integer and not the second. Oddly, passing what should be the right amount of arguments and way too many arguments give the same error. See various input/error combinations below.
>> ppt.Run('getItemAdjustments',1,3)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> ppt.Run('getItemAdjustments',{1,3})
Error using COM.PowerPoint_Application/Run
Invoke Error, Dispatch Exception:
Source: Microsoft PowerPoint 2010
Description: Application.Run : Invalid request. Sub or function not defined.
Help File:
Help Context ID: 0
>> ppt.Run('getItemAdjustments',1)
Error using COM.PowerPoint_Application/Run
Invoke Error, Dispatch Exception:
Source: Microsoft PowerPoint 2010
Description: Application.Run : Invalid request. Sub or function not defined.
Help File:
Help Context ID: 0
>> ppt.Run('getItemAdjustments',1,3,5,7,9,11,13)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
Philip Borghesani
Philip Borghesani on 26 Jul 2017
You might try using invoke instead of run. I found this code:
function runPowerPointMacro(fileName,macroName,varargin)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Run a powerpoint macro within a specified powerpoint
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initiate active X component
powerPoint=actxserver('PowerPoint.Application');
% Visible
powerPoint.Visible=1;
% Minimize powerpoint
powerPoint.WindowState=2;
% Load presentations object
presentations=powerPoint.presentations;
% Open file
presentation=invoke(presentations,'open',fileName);
% Load VBA project
k=presentation.VBProject.Collection.get();
% Run Macro
k=invoke(presentation.application,'run',macroName,varargin{:});
% Close all
presentation.Save;
presentation.Close;
powerPoint.Quit;
powerPoint.delete;
end
In a CSSM posting and referenced in an Undocumented Matlab article.
Michael
Michael on 27 Jul 2017
Thank you very much for that latest suggestion - it worked! I have no idea what the difference is between invoking run on a macro and just running the macro, but it definitely makes a difference I guess:
>> ppt.Run('getItemAdjustments',1,3)
No method 'Run' with matching signature found for class 'COM.PowerPoint_Application'.
>> invoke(Presentation.application,'run','getItemAdjustments',1,3)
ans =
0.222220003604889 2 1.33333003520966
It is worth mentioning that the
k=presentation.VBProject.Collection.get();
line from the code you found was not necessary for me at all. I could just use the invoke command to run my macro right away. In fact, unless I adjusted the PowerPoint macro trust center options (check the "Trust access to the VBA project object model" option), that line errored out:
>> k=Presentation.VBProject.Collection.get();
Invoke Error, Dispatch Exception:
Source: Microsoft PowerPoint 2010
Description: Programmatic access to Visual Basic Project is not trusted.
Help File: ppmain10.chm
Help Context ID: 1e

Sign in to comment.

More Answers (0)


Translated by