【问题标题】:PowerShell: Remove VBA module from excel filePowerShell:从 excel 文件中删除 VBA 模块
【发布时间】: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


【解决方案1】:

最近不得不做类似的事情,我就是这样做的。

$Code = @'
your code here
Make sure this guy is public
@'

$Excel = new-object -com Excel.Application
#Need to change security settings

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

$Workbook = $Excel.Workbooks.open("Insert Path to file here",$true)
$xlModule = $Workbook.VBProject.VBComponents.Add(1)
$Module = $xlmodule.CodeModule.AddFromString($Code)
$Excel.Run("Name of Module here, make sure that the sub is public")
$Workbook.VBProject.VBComponents.Remove($xlmodule)
$Workbook.Close($True)

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多