使用com-interop将数组从vba传递给c#

Fre*_*die 6 c# vba com-interop

使用com-interop将用户定义的类数组从vba传递到.net(特别是c#)的正确方法是什么?

这是我的c#代码.如果我从vba调用Method1,它会因"期望的数组或用户定义类型"或"函数使用visual basic中不支持的自动化类型"而失败.

public class MyClass 
{
    public Method1(UserDefinedClass[] Parameters) { ... }
    public Method2(Object Parameters) { ... }
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了一些关于MarshallAsAttribute类的内容.这可能是c#代码中缺少的部分吗?

这是我正在使用的vba代码:

Dim udt As New UserDefinedClass
Dim myArray()
myArray(1) = udt
myClass.Method1(myArray)
myClass.Method2(myArray)
Run Code Online (Sandbox Code Playgroud)

Joe*_*Joe 5

IIRC 你必须通过引用传递数组。

尝试将您的方法声明为

public class MyClass  
{ 
    public void Method1([In] ref UserDefinedClass[] Parameters) { ... } 
    ...
} 
Run Code Online (Sandbox Code Playgroud)

如果您不想使用 .NET 客户端的 ref 参数污染您的类,您可以定义一个 ComVisible 接口以供 COM 客户端使用,并显式实现它:

[ComVisible(true)]
public interface IMyClass  
{ 
    void Method1([In] ref UserDefinedClass[] Parameters) { ... } 
    ...
} 

public class MyClass : IMyClass
{
    void IMyClass.Method1(ref UserDefinedClass[] Parameters)
    {
        this.Method1(Parameters);
    }

    public Method1(UserDefinedClass[] Parameters)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

** 回应评论 ** 如果您想向 VBA 公开一个集合而不是一个数组,您只需要公开一个枚举器,以及您希望 VBA 代码能够调用的任何其他方法(例如添加、删除、插入,清除,...)。例如

[ComVisible]
public interface IUserDefinedClassCollection
{
    IEnumerator GetEnumerator();

    int Count { get; };

    IUserDefinedClass this[int index] { get; }

    int Add(IUserDefinedClass item);

    // etc, other methods like Remove, Clear, ...
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像往常一样在 VBA 中使用它:

Dim objUserDefinedClasses As UserDefinedClassCollection
...
objUserDefinedClasses.Add objUserDefinedClass 
...
For nIndex = 0 To objUserDefinedClasses.Count

Next nIndex
Run Code Online (Sandbox Code Playgroud)