【问题标题】:Pass an array from vba to c# using com-interop使用 com-interop 将数组从 vba 传递到 c#
【发布时间】:2011-01-02 22:06:14
【问题描述】:

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

这是我的 C# 代码。如果我从 vba 调用 Method1,它会因“预期的数组或用户定义类型”或“函数使用 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)

【问题讨论】:

  • 我们需要更多信息。您能否添加类型的 VBA 定义和一些显示您调用 COM 接口的代码?
  • 您的数组声明正在声明一个变体数组 - 它应该声明您的 UserDefinedClass 数组,例如"Dim myArray(0 To 3) As UserDefinedClass"
  • 我应该提到这一点。我也尝试过,结果相同'函数使用 vb 不支持的自动化类型'。我真的认为问题出在 c# 中方法的定义,但完全有可能问题出在 vba 代码中。我是 VB 的新手。

标签: c# vba com-interop


【解决方案1】:

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

尝试将您的方法声明为

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

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

[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

【讨论】:

  • 我试过了,但我没有明确尝试添加“in”子句。我也会试一试。恐怕使用 'ref UserDefinedClass[] foo' 会导致同样的错误。
  • 所以,您是说我不需要在“参数”参数中包含任何其他属性。我在这里看到了使用 MarshallAs 的其他代码,但正如我所提到的,这在我的场景中似乎不起作用。
  • “所以,你是说......” - 我知道对于原始类型的数组参数,你需要 ref。 [In] 属性会影响 IDL 的生成并且不是必需的。我通常会使用集合类型将用户定义的类传递给 VBA(公共类 MyUserDefinedClassCollection : Collection),所以我实际上没有尝试过。
  • 集合类也可以。将集合传递给 c# 的 vba 代码是什么样的?
  • 您不需要将其作为参考传递。例如。 “无效方法 1(MyUserDefinedClassCollection 集合);”。当然集合类以及 MyUserDefinedClass 需要是 ComVisible。
猜你喜欢
  • 1970-01-01
  • 2011-06-28
  • 2015-11-22
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
相关资源
最近更新 更多