【问题标题】:Automate running vba code on excel file via Powershell通过 Powershell 在 excel 文件上自动运行 vba 代码
【发布时间】:2021-05-18 21:45:11
【问题描述】:

操作系统:Windows 10、1903
办公室:Office 2016
Powershell:5.1

我有一个 Excel 文件,我们称之为 records.xlsm,它每天都会自动下载。我需要对该文件进行处理,然后将其发送到其他地方。我已经创建了必要的 VBA 代码来自动执行此操作,并且该代码位于一个 .bas 文件中,我们将调用 cleanup.bas

我正在尝试找到一种方法来使用 Powershell 或其他一些罐装 Microsoft 工具来自动针对文件运行 vba 代码。我还没有找到一种(我喜欢的)使用 Powershell 来做到这一点的方法。

我的目标是使用任务调度程序运行 Powershell 脚本,以使用 cleanup.bas 中的代码在 records.xlsm 中进行更改。

我不介意是否必须将 cleanup.bas 导入 records.xlsm,但该过程也必须自动化。

我认为这是可能的。我要求确认/否认是否是。如果可能,请告诉我我需要从哪里开始查找文档。

我从here 找到了代码。我不介意走那条路,但它似乎不那么优雅。实用性胜过漂亮,所以如果没有其他效果,我会使用它。

$xl = New-Object -ComObject Excel.Application
$xl.Visible = $true
$xl.DisplayAlerts = $false

$workbook = $xl.Workbooks.Open("c:\temp\test.xls")
$xlmodule = $workbook.VBProject.VBComponents.Add(1)

$code = @"
sub cleanup()
'your code goes here
end sub
"@

$xlmodule.CodeModule.AddFromString($code)

感谢您的时间。

【问题讨论】:

  • 最简单的方法是将您的 VBA 放在一个独立的 Excel xlsm 文件中,您可以在打开源文件后打开该文件 - 然后使用 Application.Run 运行宏,传入名称源工作簿作为代码的“目标”。
  • 感谢您抽出宝贵的时间,但我们在这里并不容易。
  • 我不确定您在该评论中所说的内容 - 您想按照您发布的方式进行操作吗?如果是这样,那为什么不试试呢?
  • 至于这个......“我正在尝试找到一种方法来使用 Powershell 或其他一些罐装 Microsoft 工具来自动针对文件运行 VBA 代码。我还没有找到方法(我喜欢)使用 Powershell 来做到这一点。”......这是一件非常自以为是的事情。从而为您进行意见辩论做好准备。只有你知道你会喜欢什么,不喜欢什么。因此,您实际上是在向人们征求一堆想法,因此当 SO 和整个网络上已经存在一堆想法时,您就可以做出决定。
  • PowerShell 在您使用时通过 COM 与 MSOffice 应用程序对话。为什么要将独立的 VBA 加入其中。只需使用 VBA 用例并将其转换为 PowerShell 以直接通过 COM 对文件运行?为什么要使这个用例过于复杂,仅仅因为?不要不必要地增加你的核心工作量,然后把它转嫁给那些跟随你的人。

标签: excel vba powershell


【解决方案1】:

继续我的评论...

但是,如果您要通过上面的搜索框搜索(永远不要停留在找到的第一个)SO 帖子;您会看到关于您想要的用例的类似问答。

How to use VBA Code inside a Powershell Script

或者只是网络搜索:

https://www.excell-en.com/blog/2018/8/20/powershell-run-macros-copy-files-do-cool-stuff-with-power

https://powershelladministrator.com/2017/12/20/open-excel-file-and-run-macro/

解决方案的想法和受欢迎程度(如果有的话)来自个人研究。

更新:

继续我的评论,直到你对我的最后评论。

您可以将任何基于文本的文件读入 PowerShell,但这并不意味着 PowerShell 可以运行它。外部代码必须使用所需的解析引擎运行。同样,在您的用例中是 MSOffie VBA 引擎。

我可以重构您的代码,以这种方式调用序列化的 .bas 文件。

$xl               = New-Object -ComObject Excel.Application
$xl.Visible       = $true
$xl.DisplayAlerts = $false

$workbook = $xl.Workbooks.Open("c:\temp\test.xls")
$xlmodule = $workbook.VBProject.VBComponents.Add(1)

$VbaCode = (Get-Content -Path '$PWD\SomeCode.bas' -Raw)

$xlmodule.CodeModule.AddFromString($VbaCode)

更新

还有一点是,如果你没有这两个键...

New-ItemProperty -Path "HKCU:\Software\Microsoft\Office\$($excel.Version)\excel\Security" -Name AccessVBOM -Value 1 -Force | 
Out-Null

New-ItemProperty -Path "HKCU:\Software\Microsoft\Office\$($excel.Version)\excel\Security" -Name VBAWarnings -Value 1 -Force | 
Out-Null

...在您尝试执行此操作的主机上设置,这个...

$xlmodule = $workbook.VBProject.VBComponents.Add(1)

...无论如何都会失败,因为 VBComponent 在您设置它们之前不存在。

【讨论】:

  • 谢谢。我会尝试提高我的搜索技能....我已经访问过这些链接。它不会按我想要的方式工作。我将回顾一下我如何提问和如何搜索,以免在这里浪费任何人的时间。
  • 我想你也应该认为我在搜索和思考方面很糟糕(根据你的回复和帖子)。我将把它归咎于我无法有效地表达我想要的东西。长话短说,通过 powershell 直接从 COM 调用可能是最好的方法,但是将 vba 代码直接放入 powershell 脚本可以节省更多时间,并且仍然是最实用的方法 - 在这个时候,对于我。
【解决方案2】:

我不太熟悉在 Office 应用程序中设置宏。但我经常针对 Outlook COM 对象运行 VBS,结果与 VBA 代码非常相似。也就是说,PowerShell 可以实例化 COM 对象!我见过很多人纯粹在 PowerShell 中做同样的事情,包括 Excel。在这个范例中,它实际上并不是一个宏,而是一个破解打开 XLSX 文件的外部脚本进行修改并将其保存回来。

我的建议是查看ImportExcel PowerShell module,您可以在图库中找到它。它非常强大,不需要安装 Excel,它比 COM 更像是一等公民。我意识到这可能需要对您进行重大改写,但我敢打赌,您会对最终产品更满意。

【讨论】:

  • 我会调查的。感谢您的建议。
  • 不用担心,但我的观点是 Steven 重申的,根本不需要调用 .bas 文件。只需将.bas 转换为从 PowerShell 到 Excel 的 COM 调用。这就是 COM 存在的原因,既然您必须使用 COM 与 MSOffice 相关的任何东西进行互操作,那么为什么不直接使用它。 PowerShell 仅运行 .ps* 文件,任何外部内容都必须由该事物的所有者调用/处理。在您的情况下,Excel VBA 引擎。
猜你喜欢
  • 2018-12-19
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 2020-04-18
相关资源
最近更新 更多