【问题标题】:Passing a variant through COM object via PowerShell to run a macro in PowerPoint通过 PowerShell 通过 COM 对象传递变体以在 PowerPoint 中运行宏
【发布时间】:2017-04-04 21:12:05
【问题描述】:

尝试将标题串在一起已经是一项挑战......

我正在尝试从 PowerShell 运行一些 PowerPoint 宏。我非常擅长从 Powershell for Excel 运行宏。当我在 Excel 上运行宏时,COM 对象的 Run() 方法将采用各种参数,具体取决于宏是否有任何参数。但是另一方面,PowerPoint Run() 方法需要参数,我不知道如何传递它们。

我的宏期望通过一个字符串,我在谷歌上大肆搜索,结果很短。我总是收到这个错误:

错误:

type must not be ByRef

我在 PowerShell 中为 PowerPoint 编写了一个非常基本的 PoC:

代码:

# 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

宏本身只是跨框移动一些文本,从 PowerPoint 运行时效果很好。

要求:

我现在想跨多个文件和幻灯片自动执行此操作。

Documentation on the PowerPoint COM object Run method,表示需要两个参数。

【问题讨论】:

  • 能不能把宏贴在pptm里(至少是sub的声明)?您能告诉我们其中包含哪些参考资料(工具 > 参考资料)吗?你能测试一下 (1) 你能在宏的开头显示一个消息框吗 (2) 可以从同一个文件中运行另一个具有相同类型参数的宏 (3) 可以从同一个文件中运行另一个不带参数的宏跑? (4) pptm 文件中的任何宏都可以在您计算机上的 PowerShell 中运行吗?
  • 我之所以问这些,是因为我的假设是,当参数交给宏时不会发生错误,但稍后会抛出异常并最终被 PowerShell 捕获。

标签: vba powershell powerpoint


【解决方案1】:

很好的问题,不像你说的那样网上有很多例子。我设法进一步简化了您的示例,并成功地将一些文本传递给 PowerPoint 宏中的 MsgBox,而没有真正改变您所拥有的内容。

保存在 C:\Temp 文件 PowerShellTest.pptm 中的宏

Sub DisplayMessage(myText As String)
  MsgBox myText
End Sub

PowerShell 脚本:

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

您提供的 Run 方法文档链接提到可能包含模块名称,因此这对我也有用:

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

【讨论】:

  • 感谢您尝试更简单的示例,我已经尝试逐字运行您的代码,并且得到完全相同的输出,所以我的结果肯定还有其他东西在起作用。
  • 嗯。也许一些信任中心设置?我不会唱我的宏项目(就像我通常做的那样),所以我不会绕过一些更冗长的 MSFT 问题。
  • 这与 Excel 中的信任中心会有所不同吗?因为我能够通过 PowerShell 到 Excel 很好地运行宏。只是想找出问题所在。
  • 是的。信任中心设置取决于应用程序,例如每个 Office 应用程序都不同。当然不确定这是否是问题。
【解决方案2】:

也许尝试删除下面代码行中的 [ref] 或尝试将其更改为 [val]

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

所以要么:

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

或:

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

然后还要确保 PowerPoint 宏期望通过 ByVal 传递变量。例如这样的:

Sub IAM(ByVal sMonthName As String)

【讨论】:

  • 感谢您的建议!因此,选项 1(删除 [ref])给出了错误:“类型不能是 ByRef”,选项 2([val])给出:“无法找到类型 [val]。确保包含此类型的程序集是已加载。”
  • 也许 PowerPoint 宏期望参数由 Ref 传递?您是否检查了宏签名以确保它不期望参数通过 Ref 传递?
  • 我按照您的建议将 ByVal 添加到宏中。它所做的只是将一个字符串放入 MsgBox 中,就像 Jamie 在第一个答案中的建议一样。
猜你喜欢
  • 2015-12-18
  • 2016-06-06
  • 2020-04-23
  • 2019-01-19
  • 1970-01-01
  • 2021-05-13
  • 2020-12-24
  • 2023-03-31
  • 1970-01-01
相关资源
最近更新 更多