Excel互操作macros输出/参数
我已经inheritance了启动Excel的VB6应用程序,打开一个工作簿,并间隔运行一个macros。 该macros通过其参数返回值。 在我尝试使用interop将其转换为C#,我可以成功运行macros,但是这些参数值不会返回。
在下面的代码中是否存在缺失/不正确的内容,或者仅仅是不支持?
VBAmacros:
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
所以尽我所知,不,你不能通过这种方式从VBA到C#的参数返回值。 下一个最好的事情就是简单地在.NET中创build一个types,使其可见,然后重新引用它,然后在VBA脚本中引用它。
所以,为了完整性…
返回types:
[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项目中引用该库。 它现在可以作为parameter passing并填充到macros中,或者从macros中创build并返回(我相信这将需要在.NET端Marshal.ReleaseComObject())进行清理。