C# Can';如果宏为';工作表中有什么?

C# Can';如果宏为';工作表中有什么?,c#,vba,excel,office-interop,C#,Vba,Excel,Office Interop,我使用以下代码通过C#Excel interop运行VBA宏: public void macroTest() { Excel.Application xlApp = new Excel.Application(); xlApp.Visible = true; string bkPath = @"C:\somePath\someBk.xlsm"; Excel.Workbook bk = xlApp.Workbooks.Ope

我使用以下代码通过C#Excel interop运行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\u m
位于模块
testMacro
中,并且该模块运行成功。当我将其替换为:

string macroName = "testThisMacro_s";
testThisMacro\u 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.
我检查了宏安全设置,它们确实设置为“禁用通知”,但能够从模块而不是从工作表运行宏似乎表明这与应用程序级宏安全不同

在工作表中对宏进行互操作调用时,我必须执行哪些不同的操作

更新:我可以通过将调用更改为:

string macroName = "Sheet1.testThisMacro_s"
string macroName = "Sheet1.testThisMacro_s"

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

a
工作表
对象是一个对象,并且对象是用类模块定义的。工作表、工作簿、用户表格;它们都是物体。如果没有对象的实例,就不能对对象调用方法

宏使用标准模块,这些模块不是对象,不需要实例化


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

我可以通过将调用更改为:

string macroName = "Sheet1.testThisMacro_s"
string macroName = "Sheet1.testThisMacro_s"

助手子系统不能解决您的两个问题吗,re:Mat的Mug关于实例化的回答

在某些标准模块中:

Sub testHelperSubToBeCalledFromInterop
    Call Sheet1.testThisMacro_s
End Sub
编辑:


我可以通过调用
Sheet1来运行它。testThisMacro\u s
,但现在我需要弄清楚如何检测宏何时完成(请参见更新我的OP)。好吧,您不能。如果你明白了这一点,我很想知道,我的项目的单元测试特性肯定可以使用它!有趣的是,您可以给它命名为工作表名称,我认为它是有效的,因为
Sheet1
是工作表的代码名,因此引用的是实际的对象实例。@Mat'sMug哦,但您似乎可以,但只适用于文档类型模块!调用
Application.Run“Sheet1.Foo”
Application.Run“ThisWorkbook.Foo”
或(在Word中)
Application.Run“ThisDocument.Foo”
所有工作。不幸的是,它不适用于预先声明的类模块,不管该类是否是PublicNotCreatable。是的,在更新中有不同的问题。将您的发现写为“答案”,标记它以关闭线程,然后写一个新问题。这是针对许多具有相同模板的工作簿运行的,因此它们都需要相应地更新代码。最好找到只涉及修改C代码的解决方案。
Sheet1
像这样使用是一个对象实例:工作表和用户表单是类模块,它们的
VB\u predeclarede
属性设置为
True
,这使得VBA创建一个以类型命名的全局对象实例(如上所述)@Mat'sMug:我以为问题只限于找到入口点。您说过
Application.Run
不能调用对象的方法,我对此没有异议,但我将其解释为
Application.Run
可以在标准模块中运行方法。因此,如果您有一个带有指向工作表的宏的标准模块。。。这难道不能解决问题吗?在我的帖子里放一个截图。它似乎在Excel中“本地”工作,它是否也可以与interop一起工作?@Vegard Yes。这正是单元测试的工作原理=)@Mat'smugh噢,那样的话,我的错。我觉得你在反驳我的解决方案。很高兴我们同意!