2010-01-08 18 views
6

का उपयोग कर vba से C# तक एक सरणी पास करें com-interop का उपयोग कर vba से .net (विशेष रूप से C#) से उपयोगकर्ता परिभाषित कक्षाओं की सरणी पास करने का उचित तरीका क्या है?कॉम-इंटरऑप

यहां मेरा सी # कोड है। अगर मैं vba से Method1 को कॉल करता हूं तो यह "ऐरे या उपयोगकर्ता परिभाषित प्रकार अपेक्षित" या "फ़ंक्शन एक स्वचालन प्रकार का उपयोग करता है जो दृश्य मूलभूत में समर्थित नहीं है" के साथ विफल रहा है।

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

मैंने मार्शलएएसएट्रिब्यूट क्लास के बारे में कुछ पढ़ा है। क्या यह सी # कोड में गायब टुकड़ा हो सकता है?

यहाँ VBA कोड मैं का उपयोग कर रहा है:

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

हम यहाँ में थोड़ा और अधिक जानकारी की आवश्यकता होगी। क्या आप टाइप की वीबीए परिभाषा और कुछ कोड जोड़ सकते हैं जो आपको COM इंटरफ़ेस को कॉल कर रहा है? – JaredPar

+0

जोड़ा गया वीबीए कोड। – Freddie

+0

आपकी सरणी घोषणा भिन्नताओं की एक सरणी घोषित कर रही है - इसे आपके उपयोगकर्ता परिभाषित क्लास की सरणी घोषित करनी चाहिए, उदा। "Dim MyArray (0 से 3) UserDefinedClass के रूप में" – Joe

उत्तर

4

IIRC आप संदर्भ द्वारा सरणियों पारित करने के लिए।

आप नेट ग्राहकों के लिए रेफरी मानकों के साथ अपने वर्ग को प्रदूषित करने के लिए नहीं करना चाहते हैं के रूप में

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

अपने विधि घोषित करने का प्रयास करें, तो आप एक 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

मैंने कोशिश की है, लेकिन मैंने स्पष्ट रूप से 'इन' खंड जोड़ने की कोशिश नहीं की है। मैं उसे एक शॉट भी दूंगा। 'ref UserDefinedClass [] foo' का उपयोग करके उसी त्रुटि में मुझे डर लगता है। – Freddie

+0

तो, आप कह रहे हैं कि मुझे 'पैरामीटर्स' पैरामीटर पर कोई अतिरिक्त विशेषताओं को शामिल करने की आवश्यकता नहीं है। मैंने अन्य कोड देखा है जो यहां मार्शलए का उपयोग करता है, लेकिन जैसा कि मैंने उल्लेख किया है कि मेरे परिदृश्य में काम नहीं कर रहा था। – Freddie

+0

"तो, आप यह कह रहे हैं ..." - मुझे पता है कि आपको आदिम प्रकारों के सरणी तर्कों के लिए रेफरी की आवश्यकता है। [इन] विशेषता आईडीएल की पीढ़ी को प्रभावित करती है और आवश्यक नहीं है। मैं आमतौर पर उपयोगकर्ता द्वारा परिभाषित कक्षाओं को वीबीए (पब्लिक क्लास माईयूसर डिफिनेड क्लासकोलेक्शन: संग्रह <उपयोगकर्ता परिभाषित क्लास>) में पास करने के लिए संग्रह प्रकार का उपयोग करता हूं, इसलिए मैंने वास्तव में यह कोशिश नहीं की है। – Joe