2012-11-17 9 views
7

के बीच संचार मेरे मालिक के अनुरोध पर मैंने स्क्रिप्ट का एक छोटा सा सेट बनाया जिसका उपयोग समय-समय पर कुछ उपकरणों और प्रक्रियाओं की स्थिति की निगरानी करने के लिए किया जाता है। यह जानकारी बाद में एक अपेक्षाकृत विस्तृत VBA मॉड्यूल है कि सभी की जानकारी एकत्र करता है, सूत्रों लागू होता है का उपयोग कर संसाधित किया जाता है, पर्वतमाला सेट और रेखांकन उत्पन्न करता है, आदिसी # और वीबीए

वहाँ दो समस्याओं तथापि हैं: मैं एक शौकिया प्रोग्रामर हूँ, इसलिए मेरी VBA दिनचर्या काफी अक्षम है। यह मेरे लिए एक बड़ी समस्या नहीं है (मैं बस उठता हूं और कॉफी चलाता हूं), लेकिन अन्य उपयोगकर्ताओं के लिए यह परेशानी हो सकती है, क्योंकि तब नहीं पता कि यह इतना समय क्यों ले रहा है। मैं प्रगति का एक ग्राफिकल प्रतिनिधित्व चाहता हूँ। एप्लिकेशन की कॉन्फ़िगरेशन टेक्स्ट फ़ाइल के माध्यम से की जाती है। मैं विन्यास स्थापित करने के लिए एक सभ्य जीयूआई प्रदान करना चाहता हूं।

इसे प्राप्त करने के लिए, मैं अपने सी # WinForms एप्लिकेशन को मेरे वीबीए एप्लिकेशन के साथ संवाद करने का एक तरीका ढूंढ रहा हूं। मुझे पता है कि मेरे सी # ऐप से वीबीए रूटीन कैसे चलाया जाए, लेकिन मुझे नहीं पता कि मैं उन्हें रीयल-टाइम में कैसे कम कर सकता हूं।

यहाँ दो बातें मैं विशेष रूप से हासिल करना चाहते हैं:

  • मैं पहले से ही है कि VBA दिनचर्या के अंत में सहेजा जाता है, एक लॉग फ़ाइल है। कि हालांकि मैं (बस नहीं आवेदन के अंत में) वास्तविक समय में मेरी सी # आवेदन करने के लिए लॉग/डिबगिंग-संदेश भेजने के लिए चाहते हैं, ताकि संदेशों के बजाय मेरी जीयूआई अनुप्रयोग में प्रदर्शित किया जा सकता के रूप में वे वीबीए ऐप द्वारा उत्पन्न होते हैं।
  • मैं भी को VBA एप्लिकेशन मेरी जीयूआई अनुप्रयोग के लिए वास्तविक समय प्रगति के बारे में जानकारी भेजें ताकि मैं अपने जीयूआई अनुप्रयोग में एक ग्राफिकल प्रगति-बार बना सकते हैं चाहता हूँ।

मैंने पहले ही मानक आउटपुट के माध्यम से संचार करने के बारे में सोचा है। मुझे पता है कि मानक आउटपुट से सी #/नेट का उपयोग करके कैसे पढ़ा जाए, लेकिन मुझे यकीन नहीं है कि मैं वीबीए का उपयोग करके स्टडऑट स्ट्रीम में कैसे लिखूंगा।

मुझे यकीन है कि कई लोग यह इंगित करेंगे कि मैं जो हासिल करने की कोशिश कर रहा हूं वह बेवकूफ और पुरानी शैली (या पूरी तरह से अनावश्यक) है, लेकिन शौकिया प्रोग्रामर के रूप में यह मेरे लिए वास्तव में चुनौतीपूर्ण और मजेदार प्रोजेक्ट जैसा प्रतीत होता है मुझे एक या दो सिखाओ।

+2

मैं आपको वीबीए ऐप को बेहतर बनाने में अपना समय बिताने की सलाह देता हूं। इसके अलावा, कोई कारण नहीं है कि आप प्रगति पट्टी और वीबीए में लॉगिंग भी नहीं कर सके। यदि आपको आवश्यकता नहीं है तो अतिरिक्त जटिलता क्यों पेश करें? –

+0

ठीक है, सबसे पहले, मुझे नहीं लगता कि मैं एक तेज़ या अधिक कुशल अनुप्रयोग बनाने में सक्षम होने जा रहा हूं, क्योंकि मैंने पहले से ही वीबीए के अपने सभी ज्ञान का उपयोग किया है। जैसा कि मैंने कहा, मैं एक पूर्ण शौकिया हूँ। दूसरा: जब तक कार्यपुस्तिका वास्तव में पूरी तरह उत्पन्न नहीं होती है तब तक मैं "एक्सेल-लेयर" को अदृश्य होने के लिए चाहूंगा। तीसरा: मुझे वीबीए में फॉर्म बनाने के साथ बिल्कुल शून्य अनुभव भी है, जबकि मुझे सी # में इसके साथ कुछ अनुभव है। और चौथा: जैसा कि मैंने कहा, यह वास्तव में, वास्तव में दिलचस्प/मजेदार चीज की तरह लग रहा था। –

+0

मुझे समझ में नहीं आता कि आप ऐसी स्थिति में कैसे पहुंचे हैं जहां आपने सी # में प्रोग्रामिंग सीखा है लेकिन वीबीए में 'अन्य' प्रोग्रामिंग? क्या यह सब एक मंच या दूसरे में चलने के लिए और अधिक समझ में नहीं आता है? मैं इसे सी # में चलने की सलाह दूंगा क्योंकि यह नई तकनीक है। हालांकि, अगर यह सिर्फ एक पूर्ण वीबीए परियोजना बनाने के लिए आपको बनाने की आवश्यकता है, तो वास्तव में वीबीए में फॉर्म काफी सरल हैं। जब आप अटक जाते हैं तो बस कोशिश करें और प्रश्न पूछें। यह वीबीए के बीच घटनाओं को बढ़ाने की कोशिश करने से बहुत आसान होगा और उन्हें डुबोएगा। नेट –

उत्तर

7

सी # COM-visible क्लास बनाना बहुत आसान है, और (जैसा कि आपने अपनी टिप्पणियों में कहा है) यह मजेदार है। यहां एक छोटा सा नमूना है।

एक नया सी # पुस्तकालय परियोजना में, जोड़ें:

using System; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace CSharpCom 
{ 
    [ComVisible(true)] 
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    //The 3 GUIDs in this file need to be unique for your COM object. 
    //Generate new ones using Tools->Create GUID in VS2010 
    [Guid("18C66A75-5CA4-4555-991D-7115DB857F7A")] 
    public interface ICSharpCom 
    { 
     string Format(string FormatString, [Optional]object arg0, [Optional]object arg1, [Optional]object arg2, [Optional]object arg3); 
     void ShowMessageBox(string SomeText); 
    } 

    //TODO: Change me! 
    [Guid("5D338F6F-A028-41CA-9054-18752D14B1BB")] //Change this 
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    interface ICSharpComEvents 
    { 
     //Add event definitions here. Add [DispId(1..n)] attributes 
     //before each event declaration. 
    } 

    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.None)] 
    [ComSourceInterfaces(typeof(ICSharpComEvents))] 
    //TODO: Change me! 
    [Guid("C17C5EAD-AA14-464E-AD32-E9521AC17134")] 
    public sealed class CSharpCom : ICSharpCom 
    { 
     public string Format(string FormatString, [Optional]object arg0, [Optional]object arg1, [Optional]object arg2, [Optional]object arg3) 
     { 
      return string.Format(FormatString, arg0, arg1, arg2, arg3); 
     } 

     public void ShowMessageBox(string SomeText) 
     { 
      MessageBox.Show(SomeText); 
     } 
    } 
} 

आप "हस्ताक्षर" टैब पर, अपनी परियोजना के गुण में जाने अपने विधानसभा हस्ताक्षर करने के लिए बॉक्स की जांच करना चाहते हैं, और एक नया "बनाने मजबूत नाम कुंजी फ़ाइल "। यह आपके पंजीकृत DLL के साथ संस्करण समस्याओं को रोकने में मदद करेगा।

इसे संकलित करें, और विजुअल स्टूडियो कमांड प्रॉम्प्ट में regasm का उपयोग करके DLL को पंजीकृत करें। आप Office का कौन सा संस्करण उपयोग कर रहे हैं पर निर्भर करता है या तो 32 या 64-बिट regasm का उपयोग करेगा ... आप (क्रमश: 32 और 64-बिट) C:\windows\Microsoft.NET\Framework या C:\windows\Microsoft.NET\Framework64 में RegAsm मिलेगा:

C:\windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase /tlb CSharpCom.dll

यह विंडोज के साथ अपने डीएलएल को पंजीकृत करेगा, इसलिए अब वीबीए संपादक में, आपको टूल्स-> संदर्भों पर जाकर अपने COM का नामस्थान "CSharpCom" ढूंढने में सक्षम होना चाहिए। कि बॉक्स को चेक करें, और अब आप VBA में अपने COM ऑब्जेक्ट बनाने के लिए सक्षम होना चाहिए:

Sub TestCom() 
    Dim c As CSharpCom.CSharpCom 
    Set c = New CSharpCom.CSharpCom 
    c.ShowMessageBox c.Format("{0} {1}!", "Hello", "World") 
End Sub 

आप अपने COM ऑब्जेक्ट के लिए विधियां जोड़ कर उन्हें खोल सकते हैं जब VBA एक विशेष प्रणाली को बुलाती है; आप प्रगति पट्टी के साथ एक फॉर्म बनाने के लिए इसका उपयोग करने में सक्षम होना चाहिए। हालांकि, विचार करने की एक बात यह है कि वीबीए एकल-थ्रेडेड है। इसका मतलब है कि आपका कोड चल रहा है, जबकि सबकुछ जमे हुए हो जाता है, इसलिए चीजें थोड़ा मुश्किल हो सकती हैं।

मेरे सिर के शीर्ष पर, आप अपने COM-visible क्लास में 3 विधियां बना सकते हैं: एक फॉर्म खोलने के लिए, प्रगति को अपडेट करने के लिए एक (VBA के DoEvents() को कॉल करें, आपके वीबीए अपडेट() विधि को कॉल करने के ठीक बाद आपके COM ऑब्जेक्ट पर, Office को स्क्रीन अपडेट को संसाधित करने की अनुमति देने के लिए), और इसे बंद करने के लिए। आपको फॉर्म पर निपटान() को कॉल करना चाहिए; जो "करीबी" विधि में किया जा सकता है, लेकिन मुझे लगता है कि यदि आपका वीबीए दुर्घटनाग्रस्त हो जाता है तो यह संभावित रूप से मेमोरी लीक/समस्याएं पैदा कर सकता है, और आपकी करीबी विधि कभी नहीं कहा जाता है - बस कुछ और विचार करने के लिए।

+0

ऐसा प्रतीत होता है कि वह वीबी में उठाए गए कार्यक्रमों को कैप्चर करने की कोशिश कर रहा है, सी # कार्यक्रम में, दूसरी तरफ नहीं। –

+0

हां, यह वही है जो यह करता है ... COM-visible C# ऑब्जेक्ट्स ** ** सी ** में ** ** ** ** ** ** ** VBA में (** कहीं भी, वास्तव में - यही वह है) के लिए ** लिखा गया है। यह दूसरी तरफ काम नहीं करता है। – transistor1

+0

यह वास्तव में करता है जो मैंने पूछा, हालांकि यह एक सुंदर उन्नत तकनीक है। मुझे इन अलग-अलग समाधानों के साथ बहुत मज़ा आया था, लेकिन अंत में मैं (अनुमानतः) इस निष्कर्ष पर पहुंचा कि मेरे "आवेदन" का पूर्ण पुनर्विचार (यदि ऐसा नाम वास्तव में यहां जो मैं देख रहा हूं उस पर लागू किया जा सकता है) आवश्यक है। इनपुट के लिए धन्यवाद, मैंने वास्तव में कुछ चीजों से भी ज्यादा कुछ सीख लिया है! –

5

आप अपने वीबी 6 प्रोजेक्ट के साथ एक .NET DLL का उपयोग कर सकते हैं और अपनी असेंबली में परिभाषित किसी ऑब्जेक्ट का उदाहरण बना सकते हैं। यह एक प्रकार लाइब्रेरी फ़ाइल (.tlb) बनाकर COM इंटरऑप (VB6 में उपयोग) के लिए .NET असेंबली (.dll) को पंजीकृत करके किया जाता है। .tlb फ़ाइल में अतिरिक्त जानकारी होती है ताकि आपकी वीबी 6 प्रोजेक्ट आपके .dll का उपयोग कर सके। नोट, आपका वीबी 6 प्रोजेक्ट .dll लेकिन संबंधित .tlb फ़ाइल का संदर्भ नहीं देगा। आप एक प्रकार पुस्तकालय उत्पन्न करने और पंजीकृत करने और प्रबंधित असेंबली के स्थान को पंजीकृत करने के लिए Regasm.exe उपयोगिता का उपयोग कर सकते हैं। फिर यह सिर्फ आपके .NET ऑब्जेक्ट का उदाहरण बनाने का मामला है, भले ही यह WinForm या कुछ अन्य शांत वर्ग हो। =)।

Dim MyDotNetObject As MyDotNetClass 

Set MyDotNetObject = New MyDotNetClass 
MyDotNetObject.SomeMethod(value1, value2) 

''end of execution 
Set MyDotNetObject = Nothing 

देखें: http://support.microsoft.com/default.aspx?scid=kb;en-us;817248

+0

ऐसा प्रतीत होता है कि वह वीबी में उठाए गए कार्यक्रमों को कैप्चर करने की कोशिश कर रहा है, सी # कार्यक्रम में, दूसरी तरफ नहीं। –

4

मेरा मानना ​​है कि इस लिंक में कोड मोटे तौर पर करता है कि आप क्या चाहते:

  • सी # कोड एक COM वस्तु (उदाहरण यह आईई है में बनाता है, लेकिन से आपका विवरण, आप पहले से ही अपने वीबीए दिनचर्या का एक उदाहरण बनाने में कामयाब रहे हैं)

  • यह एक .NET ईवेंट हैंडलर (+ = का उपयोग करके) द्वारा उठाए गए एक ईवेंट को जोड़ता है COM ऑब्जेक्ट (जब शीर्षक परिवर्तन)

  • यह नमूना ईवेंट प्रबंधन कोड

http://msdn.microsoft.com/en-us/library/66ahbe6y.aspx

मैं इस कोड को समझने के लिए दावे नहीं करते हैं, मेरी उद्देश्य जटिल दिखाने के लिए इस समाधान होता है परिभाषित करता है हो! आपको वास्तव में केवल एक समाधान में इसे बनाना चाहिए। कुल वीबीए समाधान विकसित होगा (आपको केवल वीबीए फॉर्म सीखना होगा जो आसान है), लेकिन पुरानी तकनीक। कुल सी # समाधान विकसित करने के लिए धीमा हो जाएगा लेकिन फिर आपको सी # सीखना होगा।

प्रदर्शन वास्तव में एक मुद्दा है। यदि यह अब अक्षमता से निष्पादित करता है, तो क्या होता है जब आपके पास प्रक्रिया के लिए 5x अधिक रिकॉर्ड होते हैं? से पहले आपको प्रदर्शन समस्या को हल करना चाहिए, आपको कई रिकॉर्ड मिलते हैं।