如果它在工作表中,不能通过互操作 运行 宏吗?

Can't run macro via interop if it's in a worksheet?

我正在使用以下代码通过 C# Excel 互操作 运行 一个 VBA 宏:

public void macroTest()
    {
        Excel.Application xlApp = new Excel.Application();
        xlApp.Visible = true;
        string bkPath = @"C:\somePath\someBk.xlsm";
        Excel.Workbook bk = xlApp.Workbooks.Open(bkPath);
        string bkName = bk.Name;
        string macroName = "testThisMacro_m";
        string runString = "'" + bkName + "'!"+macroName;
        xlApp.Run(runString);
        bk.Close(false);
        xlApp.Quit();
    }

testThisMacro_m 在模块 testMacro 中,这 运行 成功了。当我将其替换为:

string macroName = "testThisMacro_s";

其中 testThisMacro_s 的代码在 Sheet1 中,xlApp.Run() 行给出以下 COM 异常:

Cannot run the macro ''someBk.xlsm'!testThisMacro_s'. 
The macro may not be available in this workbook or all macros may be disabled.

我检查了宏安全设置,它们确实设置为 "Disable with notification",但是能够 运行 来自模块而不是来自工作表的宏似乎表明这是不同的比应用程序级宏安全问题更严重。

在对工作表中的宏进行互操作调用时,我必须做一些不同的事情吗?

更新:通过将调用更改为:

,我能够让宏执行
string macroName = "Sheet1.testThisMacro_s"

但是这似乎在宏完成之前将控制权交还给了 C#,所以现在我需要弄清楚如何检查宏是否完成(可能是另一个问题)。

一个Worksheet对象是一个对象——并且对象是用class模块定义的。工作表、工作簿、用户表单;他们都是对象。如果您没有该对象的 实例 ,则不能只调用该对象的方法。

宏基于 标准模块,它们不是对象,不需要实例化。

Application.Run 不能调用 对象的方法,这就是为什么宏需要在标准模块中的原因。

通过将调用更改为:

,我能够让宏执行
string macroName = "Sheet1.testThisMacro_s"

帮手 sub 不会解决您的两个问题吗,回复:Mat's Mug 关于实例化的回复?

在一些标准模块中:

Sub testHelperSubToBeCalledFromInterop
    Call Sheet1.testThisMacro_s
End Sub

编辑: