2012-09-12 13 views
14

मैं स्थानीय रूप से और मेरे सर्वर पर मेरी स्क्रिप्ट को निष्पादित करने के बीच मतभेदों को मापने के लिए कोड निष्पादन समय मापने के आसपास खेल रहा हूं। एक बिंदु पर मैं screen updating निष्क्रिय करने के लिए भूल गया और आभारी मैं और अधिक विस्तार में इस बारे में सोच से पहले रोशनी चमकती के प्रति संवेदनशील नहीं कर रहा हूँ था:स्क्रीन अपडेट करने का प्रभाव

जब मैं पहली बार VBA का उपयोग शुरू किया मैं हमेशा मान लिया कि यह सिर्फ इतना है कि यह नहीं था इस्तेमाल किया गया था अपने पीसी को सोचने में डरते अंत उपयोगकर्ताओं को दुर्घटनाग्रस्त होने वाला था। जब मैंने आपके कोड की दक्षता में सुधार करने के लिए और अधिक पढ़ना शुरू किया, तो मुझे समझ में आया कि यह क्या था लेकिन screen updating पर वास्तव में कितने प्रभाव हैं आपके कोड निष्पादन समय पर हैं?

+4

आपका कोड क्या कर रहा है, इस पर निर्भर करते हुए, "मैनुअल" में 'एप्लिकेशन। गणना' सेट करने से आपको अक्सर एक बड़ी गति वृद्धि भी मिलती है। आप आम तौर पर लंबे समय से चलने वाले मैक्रो के लिए दोनों करते हैं। यद्यपि गणना को रीसेट करना न भूलें - यह एक सतत सेटिंग है। –

+1

असलो, 'स्क्रीनअपडेटिंग' चालू होने के साथ आप उपयोगकर्ता को 'Application.Statusbar =' के माध्यम से प्रगति को जान सकते हैं। फिर इसे सामान्य पर वापस करने के लिए 'गलत' पर सेट करें। कुछ लोगों को प्रगति देखने की ज़रूरत है अन्यथा उन्हें लगता है कि उनका कंप्यूटर जमे हुए है और सबकुछ बंद कर देता है। – Rory

+0

मैंने यह भी पढ़ा है कि एक्सेल में डिफ़ॉल्ट डेटा प्रारूप वास्तव में मुद्रा है, इसलिए डेटा रूपांतरण से बचने के लिए संभव होने पर डबल के बजाय डेटा मान के रूप में मुद्रा का उपयोग करना सबसे अच्छा है। –

उत्तर

23

स्क्रीन अपडेटिंग को बंद करने से केवल निष्पादन समय में अंतर आएगा यदि कोड एक्सेल के साथ इस तरह से इंटरैक्ट करता है जिससे स्क्रीन सामग्री में परिवर्तन होता है। स्क्रीन की मात्रा जितनी बड़ी होगी, उतना ही बड़ा प्रभाव होगा। अन्य पोस्ट उत्तर सही ढंग से इसका प्रदर्शन करते हैं।

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

Sub YourSub() 
    On Error GoTo EH 

    Application.ScreenUpdating = False 
    Application.Calculation = xlCalculationManual 
    Application.EnableEvents = False 

    ' Code here 

CleanUp: 
    On Error Resume Next 
    Application.ScreenUpdating = True 
    Application.Calculation = xlCalculationAutomatic 
    Application.EnableEvents = True 
Exit Sub 
EH: 
    ' Do error handling 
    GoTo CleanUp 
End Sub 

अन्य तकनीकों मौजूद है कि निष्पादन में और भी अधिक सुधार प्रदान कर सकते हैं गति।

सबसे अधिक उपयोगी शामिल

  1. Select, Activate और ActiveCell/Sheet/Workbook के रूप में संभव के रूप में ज्यादा से बचें। इसके बजाय चर घोषित करें और असाइन करें और उनको संदर्भ दें।
  2. बड़ी श्रेणियों का संदर्भ देते समय, रेंज डेटा को प्रोसेसिंग के लिए एक संस्करण सरणी में कॉपी करें और परिणाम को बाद में श्रेणी में कॉपी करें।
  3. संदर्भित कक्षों की संख्या को सीमित करने के लिए Range.SpecialCells, Range.Find और Range.AutoFilter का उपयोग करें।

SO पर इन तकनीकों के कई उदाहरण हैं।

+1

आप अपने 'क्लीनअप:' को इसके विपरीत करने के लिए चाहते हैं सही? ;) – enderland

+0

@ वेंडरलैंड ओप्स ... –

2

सबसे पहले मैं स्क्रिप्ट के द्वारा रिची (यूके) पोस्ट # लिखा उपयोग कर रहे हैं 7 Here

यह बस एक पाश एक सेल में मैं का मान बदलने के माध्यम से दोहराता। मैंने इसे थोड़ा बदल दिया है, इसलिए यह 10,000 गुना कम हो जाता है और मैं इसे नमूना आकार के लिए 10 बार निष्पादित करता हूं।

मेरे कोड निष्पादन की गति पर स्क्रीन अपडेट करने का क्या प्रभाव है?

ये निष्पादन की लंबाई जब Screen Updating विकलांग था और सक्षम हैं:

Disabled Enabled 
0.61909653 2.105066913 
0.619555829 2.106865363 
0.620805767 2.106866315 
0.625528325 2.102403315 
0.625319976 2.0991179 
0.621287448 2.105103142 
0.621540236 2.101392665 
0.624537531 2.106866716 
0.620401789 2.109004449 

आप देख सकते हैं यह रूप में जब Screen Updating अक्षम नहीं है कोड निष्पादित करने के लिए लंबे समय से लगभग 3.5 गुना लेता है।

स्प्रेडशीट को 'देखने' के विपरीत, इन दोनों कोडों को वीबी संपादक में रन बटन का उपयोग करके निकाला गया था।

2 शुरू करने और अपने कोड के अंत में सरल रेखाओं:

Application.ScreenUpdating = False 
Application.ScreenUpdating = True 

लेकिन, वे अपने निष्पादन की दक्षता पर एक बड़ा प्रभाव हो सकता है!

नोट: जाहिर Screen Updating के फायदे अच्छी तरह से कई यहाँ करने के लिए जाना जाएगा, लेकिन यह शुरुआती के लिए लाभकारी हो सकता है और मैं इसे नंबर देखना दिलचस्प!

6

यदि आप ScreenUpdating क्यों महत्वपूर्ण हैं, तो काफी कठोर उदाहरण देखना चाहते हैं, निम्न कोड चलाएं। ScreenUpdating = false के बिना इस स्वैप को चलाने के लिए एक्सेल 2011 में लगभग 45 गुना अधिक समय लगता है! यह समय में विशाल अंतर है।

Sub testScreenUpdating() 

    Dim i As Integer 
    Dim numbSwitches As Integer 
    Dim results As String 

    'swap between sheets this number of times 
    numbSwitches = 1000 

    'keep track of time 
    Dim startTime As Double 
    startTime = Time 

    'swap between sheets 1/2 (need both sheets or this will crash) 
    For i = 1 To numbSwitches 
     Sheets(1 + (i Mod 2)).Select 
    Next i 

    'get results 
    results = "Screen Updating not disabled: " & Format(Time - startTime, "hh:mm:ss") & " seconds" 
    startTime = Time 

    'scenario 2 - screenupdating disabled 

    Application.ScreenUpdating = False 

    'swap between sheets 1/2 (need both sheets or this will crash) 
    For i = 1 To numbSwitches 
     Sheets(1 + (i Mod 2)).Select 
    Next i 

    Application.ScreenUpdating = True 

    'get results for part two 
    results = results & vbCrLf & "Screen Updating IS disabled: " & Format(Time - startTime, "hh:mm:ss") & " seconds" 

    'show results 
    MsgBox results 


End Sub 

इसके अलावा, जब तक हम दक्षता को बढ़ाने के तरीके के विषय पर कर रहे हैं, एक और प्रमुख मुद्दा Select, Selection, और Activate कम ही होते हैं कि (कभी अगर) आवश्यक है। जब आप मैक्रोज़ रिकॉर्ड करते हैं तो यह हमेशा इनका उपयोग करेगा लेकिन बहुत कम स्थितियां हैं जब आपको वास्तव में कोड में उनका उपयोग करने की आवश्यकता होती है। इसी तरह, शीर्षक में Active के साथ कुछ भी (जैसे ActiveCell) आमतौर पर एक संकेत है कि आपके पास धीमे कोड होंगे क्योंकि आप संभवतया कोशिकाओं का चयन कर रहे हैं।

आप लगभग हमेशा सेल/वर्कशीट को संदर्भित कर सकते हैं और चयन से बच सकते हैं।उदाहरण के लिए:

msgbox (Worksheets(1).Range("A1").value) 

इस पर ध्यान दिए बिना काम करेगा कि आप वर्तमान में पहली वर्कशीट पर हैं या नहीं। एक आम नई वीबीए गलती कुछ और करना है:

Worksheets(1).Select 
msgbox (Range("A1").value) 

जो एक अनियंत्रित चरण है।

यह कोडटाइम कोड के लिए महत्वपूर्ण समय जोड़ता है।

+0

अच्छी तरह से कहा। एलिस्टेयर, यदि आप चुनने से बचने के कुछ उत्कृष्ट उदाहरण चाहते हैं, तो क्रिस नील्सन का जवाब देखें: http://stackoverflow.com/a/10717999/138938 –

0

स्क्रीन अपडेटिंग के बारे में जानना एक महत्वपूर्ण बात है जिसे मैंने किसी भी पिछले उत्तर में नहीं देखा था। अपने स्वयं के परीक्षण से मुझे पता चला है कि स्क्रीन अपडेट करने और चालू करने में लगभग 15ms (एक्सेल इंटरऑप के माध्यम से सी # में परीक्षण किया जाता है)। इसे ध्यान में रखें यदि आप कुछ भी निष्पादित करेंगे जो कम समय लेगा। और आखिरकार कुछ लूप में कई बार स्क्रीन अपडेट चालू/बंद नहीं करते हैं। वह असली प्रदर्शन हत्यारा होगा।

और एक और नोट (जिसे आप शायद सुनना नहीं चाहते हैं) यदि आप इसे त्वरित रूप से सी ++ का उपयोग करना चाहते हैं। वीबीए की तुलना में यह आम तौर पर 5 से 10 गुना तेज होता है (मुझे यहां पर पकड़ न करें जो आप वास्तव में करते हैं) पर निर्भर करता है।

0

मैं जानता हूँ कि यह एक पुरानी धागा है, लेकिन:

1) सेट मत ScreenUpdating = सच है, लेकिन याद है और इसे वापस सेट यह पुरानी मूल्य है करने के लिए। 2) कार्यपुस्तिका बदलना स्क्रीनअपडेटिंग को भी रीसेट करेगा।

संबंधित मुद्दे