PowerShell:从excel文件中删除VBA模块

Tho*_*sMX 6 macros excel powershell automation vba

我想做的事:

  • 打开Excel文件
  • 动态导入VBA模块并从模块运行功能
  • 卸下模块

所以这是我的powershell代码:

$excel = New-Object -ComObject Excel.Application
$excel.Workbooks.Open($filepath) | Out-Null
$macro = $excel.ActiveWorkbook.VBProject.VBComponents.Import($MacroFilepath)
$Excel.ActiveWorkbook.Application.Run("HoursSumCounter.main") | Out-Null
$excel.ActiveWorkbook.VBProject.VBComponents.Remove($macro)
Run Code Online (Sandbox Code Playgroud)

(当然我启用了在Excel的信任中心设置中访问VBA项目,以便能够动态导入模块)

现在我得到的错误如下:

Cannot find an overload for "Remove" and the argument count: "1".
At line:1 char:1
+ $excel.ActiveWorkbook.VBProject.VBComponents.Remove($macro)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
Run Code Online (Sandbox Code Playgroud)

如果我在Excel(没有powershell)中这样做,这整件事实际上是有效的.

但这是我发现的......

我检查了Remove函数的重载:

[DBG]: PS C:\Users\MUT2BP\Desktop\recefice>> $excel.ActiveWorkbook.VBProject.VBComponents.Remove

OverloadDefinitions                                                                                                                                                                           
-------------------                                                                                                                                                                           
void Remove(Microsoft.Vbe.Interop.VBComponent VBComponent)                                                                                                                                    
void _VBComponents.Remove(Microsoft.Vbe.Interop.VBComponent VBComponent)                                                                                                                      
void _VBComponents_Old.Remove(Microsoft.Vbe.Interop.VBComponent VBComponent) 
Run Code Online (Sandbox Code Playgroud)

事实证明,我实际上应该传递一个类型的对象,Microsoft.Vbe.Interop.VBComponent VBComponent但我的$macro对象是类型System.__ComObject#{eee00921-e393-11d1-bb03-00c04fb6c4a6}

[DBG]: PS C:\Users\MUT2BP\Desktop\recefice>> $macro | Get-Member


   TypeName: System.__ComObject#{eee00921-e393-11d1-bb03-00c04fb6c4a6}

Name            MemberType Definition                        
----            ---------- ----------                        
Activate        Method     void Activate ()                  
DesignerWindow  Method     Window DesignerWindow ()          
Export          Method     void Export (string)         
...
Run Code Online (Sandbox Code Playgroud)

...即使该Remove函数实际返回一种类型VBComponent,在此OLE自动化过程中它将转换为COM对象.

我只是怀疑我必须以某种方式将此COM对象转换为实际的VBComponent对象,我怎么能不明确地转换它.

小智 0

有没有理由不能简单地引用适当的模块?excel 不需要附加模块。加载项和个人工作簿中的模块可以在任何工作表上运行。

如果您创建一个加载项(另存为 _ 加载项,然后在开发人员工具下单击该框将其打开),您可以使用您想要的任何模块即时更新它。

如果您无权访问开发人员工具选项卡,您可以将该模块添加到您的个人工作簿(这是一个隐藏的工作簿,可以在您第一次使用记录宏按钮时自动生成)

通过执行上述任何操作,您可以打开一个 Excel 文件,在其上运行代码,然后关闭该文件,而无需尝试以编程方式将模块添加到不支持模块的 fike 中。

如果您绝对必须附加和删除模块,请尝试以下操作:打开文件,转换为 xlsb 格式,关闭文件,将文件重命名为 .zip,添加模块并更新 .zip 内的 xml 路径,重命名为 .xlsb,在 Excel 中打开,运行模块,另存为不支持模块的文件。