2012-07-16 19 views
6

के बीच मनमाने ढंग से प्रकार का डेटा पास करें तो मैं एक एक्सेल प्रोजेक्ट पर काम कर रहा हूं जो वीबीए का उपयोग कर सी ++ डीएल लोड करने जा रहा है। मैं क्या करना चाहता हूं कि किसी विशिष्ट प्रकार के साथ एक्सेल रेंज पारित करने में सक्षम होना (डेटा संख्यात्मक या स्पष्ट हो सकता है) C++ dll (मेरे एक्सेल रेंज का वर्णन करने का सबसे अच्छा तरीका variant प्रकार का है)।वीबीए और डीएल

तो चरणों शायद शामिल:

  1. लोड VBA में dll
  2. एक्सेल रेंज भेजें dll को
  3. (रेंज संख्याओं और/या तार के स्तंभों में से स्तंभों हो सकती है) में हेरफेर डीएलएल फ़ाइल में एक्सेल से डेटा

मैं एक्सेल संस्करण और सी ++ संस्करण का उपयोग करने के बारे में सोच रहा हूं। लेकिन मेरे लिए यह स्पष्ट नहीं है कि सी ++ संस्करण का उपयोग कैसे करें क्योंकि मुझे इस पर कोई अच्छा दस्तावेज नहीं मिला।

मुझे प्राप्त एक और सुझाव COM प्रोग्रामिंग के लिए था।

मेरे सवाल:

  • एक प्रकार आत्मा संभवतः कैसे आगे बढ़ना है पर मेरे लिए संकेत प्रदान कर सकता है? (उदाहरण के लिए सी ++ प्रोटोटाइप प्रदान करना, और संस्करण को संभालने का एक सरल उदाहरण)
  • क्या किसी को सी ++ वेरिएंट (और शायद संयुक्त रूप से वीबीए के साथ) का उपयोग करने पर कोई अच्छा दस्तावेज/ट्यूटोरियल पता है?
  • यदि गति एक मुद्दा है तो VARIANTS का उपयोग करने के लिए COM को बेहतर उपयोग कर रहा है?
  • सी एपीआई एक विकल्प का उपयोग कर रहा है?

अद्यतन:

  • पर्वतमाला मैं हेरफेर करने के लिए की जरूरत का आकार बड़ा (~ 500,000 पंक्तियों) हो सकता है।
  • गति एक कारक है, इस प्रकार, मैं जितना संभव हो अनावश्यक प्रतिलिपि से बचना चाहता हूं।

उत्तर

2

बशर्ते आप केवल, आप दो मूलभूत विकल्प हैं (जैसे Range के रूप में वास्तविक एक्सेल वस्तुओं के लिए और नहीं संकेत) dll को डेटा पास करना चाहते हैं:

  1. आपके पास बहुत बड़ा डेटा सेट और करना चाहते हैं जितना संभव हो कॉपी करने से बचें।
    इस मामले में आप सरणी पारित करना चाहेंगे जो आपको Range.Value पर कॉल करके मिलता है। ऐसा करने के लिए, आपको वीबी से संदर्भित करने के लिए थोड़ा टीएलबी लिखना होगा, जिसमें आप SAFEARRAY(VARIANT)* की अपेक्षा के अनुसार अपने निर्यात किए गए सी ++ फ़ंक्शन का वर्णन करेंगे। ऐसा इसलिए है क्योंकि Declare ऑपरेटर आपको वास्तव में एक सुरक्षित * पास नहीं करने देगा।
    समारोह इस तरह दिखेगा:

    LONG __stdcall ReturnArrLowerBound(SAFEARRAY** ppArr) 
    { 
        if (ppArr == NULL) return -1; 
        SAFEARRAY* pArr = (*ppArr); 
    
        LONG res = 0; 
        SafeArrayGetLBound(pArr, 1, &res); 
    
        return res; 
    } 
    

    और TLB descripion कि तरह दिखेगा:

    [ 
        uuid(A686B138-D8CE-462e-AEF2-75DA4DBF1C75) 
    ] 
    library foo 
    { 
        [ 
         dllname("TestSafearray.dll") 
        ] 
        module vb 
        { 
         [entry("ReturnArrLowerBound")] 
         LONG __stdcall ReturnArrLowerBound(SAFEARRAY(VARIANT)* ppArr); 
        } 
    } 
    

    और अपने सी ++ परियोजना एक डीईएफ़ फ़ाइल को शामिल स्पष्ट रूप से होगा:

    LIBRARY "TestSafearray" 
    
    EXPORTS 
        ReturnArrLowerBound 
    
  2. आपके डेटा सेट उचित रूप से आकार में हैं और आपको कॉपी करने की थोड़ी सी बात नहीं है।
    फिर अपने सी ++ फ़ंक्शन को केवल int[] स्वीकार करने के लिए बनाएं और इसे V12 में arr() as Long स्वीकार करने के रूप में घोषित करें। वीबी पक्ष पर, Long एस पर एक सरणी आवंटित करें और तत्वों को Range.Value सरणी से कॉपी करें।

+0

धन्यवाद! अगर मुझे गलत नहीं लगता है, तो टीएलबी लिखना COM प्रोग्रामिंग शामिल है, है ना? और फिर क्या यह एप्लिकेशन की पोर्टेबिलिटी को सीमित करता है (विशेष रूप से लिनक्स मशीनों पर)? – SMir

+1

@SMir नहीं, इसमें COM प्रोग्रामिंग प्रति से शामिल नहीं है। वीबी के लिए आपके सी ++ फ़ंक्शन हस्ताक्षर को समझने के लिए आप केवल टीएलबी लिखते हैं। इसके अलावा, फ़ंक्शन एक सादा, गैर-COM, क्लासिक शैली निर्यात किया गया फ़ंक्शन है। – GSerg

+0

त्वरित प्रतिक्रिया के लिए धन्यवाद। क्या 'Variant' का उपयोग करके मुझे मिश्रित प्रकारों को डीएलएल में पास करने की अनुमति मिलती है? या यह केवल एक ही प्रकार (इसे तार या संख्या, आदि) होने की अनुमति देता है। – SMir