() VBA

2013-07-05 9 views
7

हाय में और Evaluate() रहस्य
() VBA


MSDN कार्यालय डेवलपर संदर्भ (2013) प्रलेखन कहते हैं करने के लिए स्वागत का मूल्यांकन:

वर्ग कोष्ठक का उपयोग करना (उदाहरण के लिए, "[A1: सी 5]") को एक स्ट्रिंग तर्क के साथ मूल्यांकन विधि को कॉल करने के समान है।


तो, मैं यह देखने के लिए कैसे सही Microsoft's Documentation of the Evaluate() विधि है एक बहुत ही सरल कोड भाग गया है।
आश्चर्य की बात नहीं है, मैं लगातार परिणाम के बावजूद अजीब हो रहा हूं।
ध्यान दें:Immediate WindowCTRL + जी में 4 आदेशों में से प्रत्येक पर अमल। प्रत्येक कॉल में अंतर देखें। अंतर्निहित बगप्रत्येक MsgBox को दो बार दिखाता है। बस रखें कि मन में और उलझन में नहीं मिलता है ...
स्टिक इस कोड को एक मॉड्यूल में

Private Sub SleepESub() 
    Application.Wait Now + TimeValue("0:00:20") 
    MsgBox "w8'd " 
End Sub 

तो (एक समय में 1) इन 4 आदेश पर अमल तत्काल खिड़की

? Evaluate ("SleepESub()")
में ? [SleepESub()]
? [SleepESub]
? SleepESub

पहले 2 कोड को तुरंत निष्पादित करें; मेरे लिए मतलब है कि उन्होंने कोड का मूल्यांकन किया है। तीसरा एक (दस्तावेज़ीकरण के अनुसार)Evaluating होना चाहिए, लेकिन यह उसी तरह से कार्य नहीं करता है जैसे जैसा कि यह मॉड्यूल के शरीर में करता है। तत्काल विंडो Error 2023 दे रही है, हालांकि मॉड्यूल के शरीर के भीतर से एक ही कॉल निष्पादित करता है जैसे कि आप उप-कॉल कर रहे थे। यह 20 seconds की तरह प्रतीक्षा करता है जैसे कि यह सामान्य Call SleepESub() था जो नंबर 4 कॉल है।

क्या कोई यह समझा सकता है कि मैं यहां क्या खो रहा हूं? क्या लाइन नंबर 3 उचित Evaluation कॉल नहीं है? या यह उप खुद को कॉल का मूल्यांकन करता है (है कि अगर समझ में आता है)


अद्यतन:
मुझे लगता है कि कुछ लोगों को गलत समझ रहे हैं मैं यहाँ क्या मूल्यांकन कर रहा हूँ - चिंता मत करो यह एक उन्नत विषय है और मैं नहीं कर रहा हूँ एक पुस्तक लेखक और आप दिमागी पाठक नहीं हैं। (मुझे माफ़ कर दो ...)
बेहतर विचार पाने के लिए आप तत्काल विंडो बनाम मॉड्यूल के शरीर से परिणामों की तुलना कर सकते हैं।

' Run each of the calls separately 
' in a module's body and compare it with 
' the previous calls from the Immediate Window 
    Sub ModuleBody() 
     Evaluate ("SleepESub()") 
     '[SleepESub()] 
     '[SleepESub] 
     'SleepESub 
    End Sub 
+0

दिलचस्प। मुझे पिछले दो के लिए '?' को हटाने की जरूरत है। 'रन ("स्लीपसब")' और 'रन ("स्लीपसब()") समान हैं लेकिन 'मूल्यांकन (" स्लीपसब ") काम नहीं करता है। क्या चल रहा है?! –

+0

एक्सेल 2010 के साथ (_Evaluate_ दस्तावेज़ 2013 के समान है), '? मूल्यांकन करें ("स्लीपसब") 'रिटर्न' त्रुटि 2029'; 'के लिए वही? [SleepESub] '। मैं निष्कर्ष निकालूंगा कि 2010 "साफ" है (दस्तावेज़ीकरण से मेल खाता है) –

+1

@ डी-स्ट्रायर '? [स्लीपसब] '(* तत्काल विंडो से बुलाया गया *) एक 'त्रुटि 2029' वापस करता है, हालांकि यदि आप मॉड्यूल के शरीर में एक ही कॉल करते हैं तो यह काम करता है, हालांकि इसका मूल्यांकन नहीं कर रहा है जैसे कि आप उप-कॉल कर रहे थे । मैं आश्चर्यचकित हो रहा हूं कि इस मामले में स्क्वायर ब्रैकेट को अनदेखा किया जा रहा है क्योंकि संकलक * सोचता है * '[स्लीपसब] = स्लीपिसब '। दूसरी तरफ, यदि तत्काल विंडो एक त्रुटि दे रही है तो मॉड्यूल बॉडी से एक ही कॉल कैसे काम करता है? –

उत्तर

5

यह मुझे दिखाई देगा कि कोड को निष्पादित करने के विभिन्न तरीकों में जो भिन्नता है वह थ्रेड होगा - यह यूआई थ्रेड या पृष्ठभूमि थ्रेड, और पार्सर। Evaluate निष्पादित कार्यों को स्पष्ट रूप से परिभाषित कार्यों के लिए अलग-अलग संभाला जाएगा, और तत्काल विंडो से बुलाए गए कार्यों को थोड़ा अलग तरीके से संभाला जाएगा।

में:

Sub ModuleBody() 
    Evaluate ("SleepESub()") 
    [SleepESub()] 
    [SleepESub] 
    SleepESub 
End Sub 

Evaluate ("SleepESub()") और [SleepESub()] दिखाई एक सूत्र की उम्मीद है, और Private Sub SleepESub() बिल्कुल निष्पादित नहीं किया जा रहा है।

पर कैसे पार्सर प्रक्रिया संभालती है निर्भर करता है, प्रत्येक आदेश के अनुक्रम में एकल थ्रेड में, Application.Wait से देरी में जिसके परिणामस्वरूप मार डाला जा सकता है, या Application.Wait केवल यूआई धागे पर मान्य होने के लिए विचार किया जा सकता है, और छोड़ दिया जब पृष्ठभूमि धागे पर चलाते हैं।

यह, निम्नलिखित कोड द्वारा की पुष्टि की जा सकती है, तत्काल विंडो में ?[SleepESub()] या ?Evaluate("SleepESub()") द्वारा निष्पादित:

Private Declare PtrSafe Sub sapiSleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long) 
Private Sub SleepESub() 
    'Application.Wait Now + TimeValue("0:00:05") 
    sapiSleep 5000 
    MsgBox "w8'd " 
End Sub 

sapiSleep 5000 API कॉल का उपयोग करते समय इंतजार होता है (! दो बार - कि बग कि उल्लेख किया गया था) , लेकिन Application.Wait Now + TimeValue("0:00:05") का उपयोग करते समय, कोई देरी नहीं होती है।

+0

आप सही हैं! मैं गलत मान रहा था कि पहले दो कॉल का मूल्यांकन किया गया है, वे नहीं थे - उन्हें आंशिक रूप से निष्पादित किया गया था। 'Application.Wait' छोड़ा गया था, भले ही msgstr "msgstr" msgstr "msgstr" msgstr "msgstr" msgstr "msgstr" msgstr "msgstr" msgstr "msgstr" msgstr "msgstr" संदेश को दिखाया गया था, यह ठीक से' स्लीपसब 'निष्पादित नहीं करता था यह मॉड्यूल बनाम तत्काल विंडो से 'मॉड्यूल बॉडी' को कॉल करने में एक फर्क पड़ता है। यह उल्लेखनीय है कि '[स्लीपसब] = स्लीपसब'। –

+1

दरअसल, मूल्यांकन में ("स्लीपसब()") और [स्लीपसब()], प्राइवेट सब स्लीपसब() को निष्पादित नहीं किया जा रहा है - सब मॉड्यूलबॉडी() और प्राइवेट सब स्लीपसब() लाइनों पर ब्रेकपॉइंट्स सेट करने का प्रयास करें, और आप देखेंगे कि जब आप मॉड्यूलबॉडी() में इन दो पंक्तियों पर निजी सब स्लीपसब() को हिट नहीं करते हैं, तो कोड के माध्यम से एकल चरण। –

-1

मुझे लगता है कि यह राज्य के लिए कि 3 कॉल का मूल्यांकन नहीं कर रहा है गलत है: इस कोड का प्रयास करें यह वास्तव में प्रदान की वस्तु का मूल्यांकन, और इसके मूल्य वापस (के रूप में दस्तावेज) करता है।

मैं थोड़ा उप संशोधित किया है वर्णन करने के लिए:

Private Function SleepESub() 
    Debug.Print Application.Wait(Now + TimeValue("0:00:02")) 
    MsgBox "w8'd " 
    SleepESub = 42 
End Function 

4 मूल्यांकन कॉल से प्रत्येक वास्तव में वापस आ जाएगी 42 अपेक्षा के अनुरूप।

क्या अलग है:

  • आवेदन संदर्भ (एक मामले कॉल में Application.Wait को सफल होता है, अन्य में यह विफल रहता है - डिबग आउटपुट नोटिस जो रिटर्न सही या गलत)
  • दिनचर्या (एक या दो कॉल) पर कॉल की संख्या

हालांकि इनमें से किसी भी अंतर के लिए मुझे कोई स्पष्टीकरण नहीं है।