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

时间秒杀一切 提交于 2019-11-30 03:51:17

问题


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.


回答1:


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")



回答2:


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)


来源:https://stackoverflow.com/questions/35579974/passing-a-variant-through-com-object-via-powershell-to-run-a-macro-in-powerpoint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!