Передать массив из VBA в C # с помощью Com-Interop - PullRequest
6 голосов
/ 08 января 2010

Как правильно передать массив пользовательских классов из vba в .net (в частности, c #), используя com-interop?

Вот мой код на C #. Если я вызываю Method1 из vba, происходит сбой с «Ожидается массив или определенный пользователем тип» или «Функция использует тип автоматизации, не поддерживаемый в 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)

1 Ответ

4 голосов
/ 08 января 2010

IIRC вы должны передавать массивы по ссылке.

Попробуйте объявить ваш метод как

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

Если вы не хотите загрязнять свой класс параметрами ref для клиентов .NET, вы можете определить интерфейс 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 мог вызывать (например, Add, Remove, Insert, Clear, ...) , Например.

[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
...