【发布时间】:2017-02-11 06:01:24
【问题描述】:
我想做什么:
- 打开一个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)
(当然我在 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
如果我在 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)
事实证明,我实际上应该传递一个 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)
...
...尽管Remove 函数实际上返回了VBComponent 的类型,但在此OLE 自动化过程中它被转换为COM 对象。
我只是怀疑我必须以某种方式将此 COM 对象转换为实际的 VBComponent 对象,但我无法显式转换它。
【问题讨论】:
-
我无法复制这个 - 您的代码与示例工作簿和模块一起工作得很好。
-
您是否安装了 MS Office 开发工具?
-
@Comintern 嗯,我不知道。在添加/删除程序和功能(ctrl 面板)中,我没有看到类似的东西。还有其他地方可以验证吗?
-
导入宏文件后$macro对象的类型是什么?
-
IIR,我将它作为 Visual Studio 的一部分安装,但也可以下载 here。
标签: excel vba powershell automation