2010-01-08 14 views
6

Kullanıcı tanımlı sınıflar dizisini vba'dan .net'e (özellikle C#) com-interop kullanarak iletmenin uygun yolu nedir?Bir diziyi com-interop kullanarak vba'dan C#'ye geçirme

İşte C# kodum. Yöntem1'i vba'dan çağırırsam, "Array veya userdefined type bekleniyor" veya "Function, görsel temelde desteklenmeyen bir otomasyon türü kullanır" hatası verir.

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

MarshallAsAttribute sınıfı hakkında biraz bilgi okudum. Bu C# kodundaki eksik parça olabilir mi?

İşte kullanıyorum vba kod: Sahip

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

Biz burada biraz daha fazla bilgi ihtiyacı olur. Türün VBA tanımını ve COM arayüzünü çağıran bazı kodları ekleyebilir misiniz? – JaredPar

+0

Eklenen vba kodu. – Freddie

+0

Dizi bildiriminiz bir dizi varyant bildiriyor - UserDefinedClass öğesinin bir dizisini bildiriyor olması gerekir, ör. "DimTrack (0'dan 3'e) UserDefinedClass olarak" – Joe

cevap

4

IIRC referans olarak diziler geçmek.

.NET müşterileri için ref parametreleri ile sınıfınızı kirletmeye istemiyorsanız COM istemcileri tarafından kullanılacak bir ComVisible arayüzü tanımlayabilirsiniz,

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

olarak yöntem bildirerek deneyin ve bunu uygulamaya açıkça böylece: Eğer VBA bir dizinin yerine bir koleksiyon ortaya çıkarmak istiyorsanız cevaben

[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) 
    { 
     ... 
    } 
} 

** ** yorum yapmak

, sadece bir sýralayýcý açığa gerekiyor ve başka yöntemler VBA kodunu istiyorum aramak için (örneğin, Ekle, Yeniden Taşı, Ekle, Temizle, ...). Örneğin.

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

    int Count { get; }; 

    IUserDefinedClass this[int index] { get; } 

    int Add(IUserDefinedClass item); 

    // etc, other methods like Remove, Clear, ... 
} 

Ardından VBA'DA zamanki gibi kullanabilirsiniz:

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

Next nIndex 
+0

Denedim, ancak açık bir şekilde 'in' maddesini eklemeyi denemedim. Ben de bir şans vereceğim. 'ref UserDefinedClass [] foo' kullanarak korkarım aynı hatayla sonuçlandı. – Freddie

+0

Yani, 'Parameters' parametresine herhangi bir ek nitelik eklememem gerektiğini söylüyorsunuz. Burada MarshallA'ları kullanan başka bir kod gördüm, ama belirttiğim gibi senaryoda çalışmış görünmüyordu. – Freddie

+0

"Yani, bunu söylüyorsun ..." - İlkel türlerin dizi argümanlarına karşı ref'e ihtiyacın olduğunu biliyorum. [In] özniteliği IDL'nin üretimini etkiler ve gerekli değildir. Normalde kullanıcı tanımlı sınıfları VBA'ya (public class MyUserDefinedClassCollection: Collection ) geçirmek için bir koleksiyon türü kullanırdım, bu yüzden bunu gerçekten denemedim. – Joe