2010-01-08 91 views
6

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

这是我的c#代码。如果我从vba调用Method1,那么它会失败,并显示“Array or userdefined type expected”或“Function uses an automatic type not visual in visual basic”。

public class MyClass 
{ 
    public Method1(UserDefinedClass[] Parameters) { ... } 
    public Method2(Object Parameters) { ... } 
} 

我读过一些关于MarshallAsAttribute类的内容。这可能是c#代码中缺失的部分吗?

下面是我使用的VBA代码:你有

Dim udt As New UserDefinedClass 
Dim myArray() 
myArray(1) = udt 
myClass.Method1(myArray) 
myClass.Method2(myArray) 
+0

我们会需要更多的信息在这里。你可以添加类型的VBA定义和一些代码来显示调用COM接口吗? – JaredPar 2010-01-08 13:24:56

+0

添加了vba代码。 – Freddie 2010-01-08 21:02:00

+0

你的数组声明声明了一个变体数组 - 它应该声明一个你的UserDefinedClass数组,例如“Dim myArray(0 To 3)As UserDefinedClass” – Joe 2010-01-08 21:28:42

回答

4

IIRC按引用传递数组。

尝试宣告你的方法

public class MyClass 
{ 
    public void Method1([In] ref UserDefinedClass[] Parameters) { ... } 
    ... 
} 

如果你不想污染与.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) 
    { 
     ... 
    } 
} 

**在回应评论** 如果要公开的集合,而不是一个数组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, ... 
} 

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

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

Next nIndex 
+0

我试过了,但我没有明确尝试添加'in'子句。我也会给你一个机会。使用'ref UserDefinedClass [] foo'导致了相同的错误,我很害怕。 – Freddie 2010-01-08 20:58:17

+0

所以,你说我不应该在'Parameters'参数中包含任何附加属性。我见过使用MarshallAs的其他代码,但正如我所提到的那样,似乎在我的场景中不起作用。 – Freddie 2010-01-08 21:03:11

+0

“所以,你说...” - 我知道你需要参考原始类型的数组参数。 [In]属性会影响IDL的生成,因此不是必需的。我通常会使用集合类型将用户定义的类传递给VBA(public class MyUserDefinedClassCollection:Collection ),所以我没有真正尝试过。 – Joe 2010-01-08 21:27:13