Excel互操作宏输出/参考参数

时间:2017-03-24 14:21:15

标签: c# excel vba vb6

我继承了一个VB6应用程序,它启动Excel,打开工作簿,并在一段时间内运行一个宏。此宏通过其参数返回值。在我尝试使用interop将其转换为C#时,我可以成功运行宏,但不会返回这些参数值。

下面的代码中是否有丢失/不正确的内容,或者这根本不受支持?

VBA宏:

Sub Foo(bar As Long)
    bar = 5
End Sub

C#代码:

void CallFoo()
{
    // Declared as an object to avoid losing the value in auto-boxing
    // The result is the same if declared as int
    Object bar = 0;

    m_application.Run(m_fooCommand, a);

    Console.WriteLine(a); // a is always 0
}

这个(大致)等效的VB6代码可以很好地获得返回值。

Dim bar as Long
bar = 0
xlApp.Run "Test.xlsm!Foo", bar
MsgBox bar // prints 5

1 个答案:

答案 0 :(得分:0)

所以尽我所知,不,你不能以这种方式通过VBA到C#的参数返回值。接下来最好的事情是简单地在.NET中创建一个类型,使其可见COM,重新调整它然后在VBA脚本中引用它。

所以,为了完整......

返回类型:

[ComVisible(true)]
[Guid("097B5B52-C73B-4BD0-A540-802D0BC7C49F")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IFooResult
{
    int Value { get; set; }
}

[ComVisible(true)]
[Guid("76B6BCBD-6F4D-4457-8A85-CDC48F4A7613")]
[ClassInterface(ClassInterfaceType.None)]
public class FooResult : IFooResult
{
    [DispId(1)]
    public byte[] Buffer { get; set; }
}

生成强名称(由regasm要求)

sn -k FooLib.snk

注册程序集

regasm FooLib.dll /tlb:FooLib.tlb /codebase

然后简单地引用VBA项目中的库。它现在可以作为参数传递并填充在宏中,或者在宏中创建并从宏返回(我相信这需要在.NET端进行清理,Marshal.ReleaseComObject())。