我继承了一个 VB6 应用程序,它可以启动 Excel、打开工作簿并按一定间隔运行宏。该宏通过其参数返回值。在我尝试使用互操作将其转换为 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
最佳答案
据我所知,不,您不能以这种方式通过参数从 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())。
关于c# - Excel 互操作宏输出/引用参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43001923/