How do I get function prototypes for PowerPoint add-in macros when using actxserver('PowerPoint.Application')?
5 views (last 30 days)
Show older comments
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
Accepted Answer
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
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
More Answers (0)
See Also
Categories
Find more on Live Scripts and Functions in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!