Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a variant through COM object via PowerShell to run a macro in PowerPoint

Trying to string the title together was enough of a challenge...

I am trying to run some PowerPoint macros from PowerShell. I have gotten quite good at running macros from Powershell for Excel. When I run the macros on Excel, the Run() method from the COM object will take a variety of arguments, depending if the macro has any parameters. However on the other hand, the PowerPoint Run() method expects parameters, and I cannot work out how to pass them.

My macro is expecting one string to be passed through, I've googled profusely and come up short. I always get this error:

Error:

type must not be ByRef

I have put together a very basic PoC for PowerPoint in PowerShell:

Code:

# PowerPoint test
Add-type -AssemblyName office
$PowerPoint = New-Object -comobject PowerPoint.Application

$PowerPoint.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue

$presentation2 = $PowerPoint.Presentations.open("C:\macros.pptm")
$presentation = $PowerPoint.Presentations.open("C:\Test For Macros.pptx")

$PowerPoint.run("macros.pptm!IAM",[ref]"Feb")
$presentation.save()
$presentation.close()

$presentation2.close()
$PowerPoint.quit()

# extra clean up omitted

The macro itself just moves some text across boxes, it works fine when run from PowerPoint.

Requirement:

I now want to automate this across multiple files and slides.

Documentation on the PowerPoint COM object Run method, showing the requirement for two parameters.

like image 603
Chris Avatar asked Feb 23 '16 14:02

Chris


2 Answers

Great question and not a lot of examples online as you say. I managed to strip your example down even further and successfully pass some text to a MsgBox in a PowerPoint Macro without really changing what you had.

The Macro in the file PowerShellTest.pptm saved in C:\Temp

Sub DisplayMessage(myText As String)
  MsgBox myText
End Sub

The PowerShell script:

# PowerPoint test
Add-type -AssemblyName office
$PowerPoint = New-Object -comobject PowerPoint.Application

$PowerPoint.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue

$presentation = $PowerPoint.Presentations.open("C:\Temp\PowerShellTest.pptm")

$PowerPoint.run("PowerShellTest.pptm!DisplayMessage",[ref]"Feb")

The Run method documentation link you provided mentions that the module name may be included so this worked for me too:

$PowerPoint.run("PowerShellTest.pptm!Module1.DisplayMessage",[ref]"Feb")
like image 85
Jamie Garroch - MVP Avatar answered Nov 12 '22 19:11

Jamie Garroch - MVP


Maybe try removing the [ref] in the line of code below or try changing it to [val]

$PowerPoint.run("macros.pptm!IAM",[ref]"Feb")

So either:

$PowerPoint.run("macros.pptm!IAM","Feb")

or:

$PowerPoint.run("macros.pptm!IAM",[val]"Feb")

And then also make sure that the PowerPoint macro is expecting the variable to be passed ByVal. For example something like this:

Sub IAM(ByVal sMonthName As String)
like image 28
J. Garth Avatar answered Nov 12 '22 20:11

J. Garth