दिलचस्प पोस्ट
आर में एक ही साजिश में दो रेखांकन प्लोट करें सूची दृश्य खाली होने पर खाली दृश्य दिखा रहा है NSDefaultRunLoopMode बनाम NSRunLoopCommonModes एक ही कक्षा में किसी अन्य ऑब्जेक्ट के निजी क्षेत्र में प्रवेश करें सेवा उपलब्ध नहीं है – जियोओकोडर एंड्रॉइड Node.js में बड़ी लॉगफाइल पार्सिंग – लाइन-बाय-लाइन में पढ़ें NSDate मेरे स्थानीय समय क्षेत्र / उपकरण का डिफ़ॉल्ट समय क्षेत्र नहीं लौटा रहा है अनुक्रमितों का सी ++ सॉर्टिंग और रखे जाने का तरीका सरणी php के माध्यम से लूप PHP समय की तुलना करें MySQL के साथ यादृच्छिक पंक्तियों का चयन करना कैसे रुबी में बाहरी चक्र को तोड़ने के लिए? पायथन में `string.split ()` का कोई जनरेटर संस्करण है? एंड्रॉइड ऐप में फायरबेज (बाएएस) का इस्तेमाल करते हुए ई-मेल और पासवर्ड को संचित करते समय उपयोगकर्ता नाम कैसे शामिल है? जावा में गणित अभिव्यक्ति के मूल्यांकन के लिए विधि

Excel VBA में चयन का उपयोग करने से कैसे बचें

मैंने उपयोग करने की समझी घृणा के बारे में बहुत कुछ सुना है .Select Excel VBA में चयन करें, लेकिन इसका उपयोग करने से कैसे बचें यह अनिश्चित है I मुझे लगता है कि मेरा कोड अधिक पुन: उपयोग योग्य होगा यदि मैं फ़ंक्शन का Select करने के बजाय चर का उपयोग करने में सक्षम था। हालांकि, मुझे यकीन नहीं है कि कैसे चीजों को संदर्भित करना है (जैसे कि ActiveCell आदि) यदि Select का उपयोग न Select

मैंने इस लेख को श्रेणियों और इस उदाहरण को चयन का उपयोग न किए जाने के लाभों पर पाया है लेकिन कैसे कुछ भी नहीं मिल सकता है?

वेब के समाधान से एकत्रित समाधान "Excel VBA में चयन का उपयोग करने से कैसे बचें"

चुनने से बचने के कुछ उदाहरण

Dim 'डी चर का उपयोग करें

 Dim rng as Range 

आवश्यक सीमा में चर Set एकल-कक्ष श्रेणी को संदर्भित करने के कई तरीके हैं

 Set rng = Range("A1") Set rng = Cells(1,1) Set rng = [A1] Set rng = Range("NamedRange") 

या एक मल्टी सेल रेंज

 Set rng = Range("A1:B10") Set rng = Range(Cells(1,1), Cells(2,10)) Set rng = [A1:B10] Set rng = Range("AnotherNamedRange") 

उपर्युक्त सभी उदाहरण सक्रिय पत्रक पर कक्षों को दर्शाते हैं। जब तक आप विशेष रूप से केवल सक्रिय पत्रक के साथ काम करना नहीं चाहते हैं, तब भी Worksheet चर को मंद करना बेहतर है

 Dim ws As Worksheet Set ws = Worksheets("Sheet1") Set rng = ws.Cells(1,1) 

फिर, यह सक्रिय कार्यपुस्तिका को संदर्भित करता है, इसलिए आप यहां भी स्पष्ट होना चाह सकते हैं।

 Dim wb As Workbook Set wb = Application.Workbooks("Book1") Set rng = wb.Worksheets("Sheet1").Range("A1") 

रेंज चर के रूप में अपने Sub और Function के पास रेंज है

 Sub ClearRange(r as Range) r.ClearContents '.... End Sub Sub MyMacro() Dim rng as Range Set rng = [A1:B10] ClearRange rng End Sub 

आपको वैरिएबल के लिए तरीकों (जैसे कि Find और Copy ) लागू करना चाहिए

 Dim rng1 As Range Dim rng2 As Range Set rng1 = [A1:A10] Set rng2 = [B1:B10] rng1.Copy rng2 

यदि आप किसी श्रेणी की कोशिकाओं पर पाशन कर रहे हैं, तो यह पहले से एक वैरिएंट सरणी में रेंज मानों की प्रतिलिपि बनाने के लिए अक्सर बेहतर होता है (पहले) और उस पर लूप

 Dim dat As Variant Dim rng As Range Dim i As Long Set rng = [A1:A10000] dat = rng.Value ' dat is now array (1 to 10000, 1 to 1) for i = LBound(dat, 1) to UBound(dat, 1) dat(i,1) = dat(i,1) * 10 'or whatever operation you need to perform next rng.Value = dat ' put new values back on sheet 

यह संभव है कि क्या संभव है के लिए एक छोटा टेस्टर है।

दो मुख्य कारण क्यों .Select Selection / .Activate / Selection / Activecell / Activesheet / Activeworkbook आदि … से बचा जाना चाहिए

  1. यह आपका कोड धीमा करता है
  2. यह आमतौर पर रनटाइम त्रुटियों का मुख्य कारण है

हम इसे कैसे से बचें?

1) सीधे संबंधित वस्तुओं के साथ काम करते हैं

इस कोड पर विचार करें

 Sheets("Sheet1").Activate Range("A1").Select Selection.Value = "Blah" Selection.NumberFormat = "@" 

यह कोड भी लिखा जा सकता है

 With Sheets("Sheet1").Range("A1") .Value = "Blah" .NumberFormat = "@" End With 

2) यदि आवश्यक है तो आपके चर को घोषित करें उपरोक्त एक ही कोड के रूप में लिखा जा सकता है

 Dim ws as worksheet Set ws = Sheets("Sheet1") With ws.Range("A1") .Value = "Blah" .NumberFormat = "@" End With 

जोर देने का एक छोटा सा बिंदु मैं उपरोक्त सभी उत्कृष्ट उत्तरों में जोड़ूंगा:

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

यहां नामित श्रेणियों का उदार उपयोग करने के लिए कुछ अतिरिक्त कारण दिए गए हैं, हालांकि मुझे यकीन है कि मैं और अधिक सोच सकता हूं।

नामांकित श्रेणियां आपके कोड को पढ़ने और समझने में आसान बनाती हैं।

उदाहरण:

 Dim Months As Range Dim MonthlySales As Range Set Months = Range("Months") 'eg, "Months" might be a named range referring to A1:A12 Set MonthlySales = Range("MonthlySales") 'eg, "Monthly Sales" might be a named range referring to B1:B12 Dim Month As Range For Each Month in Months Debug.Print MonthlySales(Month.Row) Next Month 

यह बहुत स्पष्ट है कि नामित श्रेणियों में Months और MonthlySales होते हैं, और प्रक्रिया क्या कर रही है।

यह महत्वपूर्ण क्यों है? आंशिक रूप से क्योंकि यह अन्य लोगों के लिए यह समझना आसान है, लेकिन भले ही आप केवल एक ही व्यक्ति हैं जो कभी भी आपके कोड को देखेंगे या उपयोग करेगा, तो आपको नामित श्रेणियों और अच्छे चर नामों का उपयोग करना चाहिए क्योंकि आप यह भूलेंगे कि आप इसके साथ क्या करना चाहते हैं एक साल बाद, और आप 30 मिनट बर्बाद कर देंगे बस पता लगाना कि आपका कोड क्या कर रहा है

नामांकित सीमाएं यह सुनिश्चित करती हैं कि आपके मैक्रोज़ को तब नहीं तोड़ना होगा जब (यदि नहीं!) स्प्रेडशीट परिवर्तनों का कॉन्फ़िगरेशन

विचार करें, अगर उपरोक्त उदाहरण इस तरह लिखा गया था:

 Dim rng1 As Range Dim rng2 As Range Set rng1 = Range("A1:A12") Set rng2 = Range("B1:B12") Dim rng3 As Range For Each rng3 in rng1 Debug.Print rng2(rng3.Row) Next rng3 

यह कोड पहले ही ठीक काम करेगा – जब तक कि आप या भविष्य के उपयोगकर्ता "जीआईआईजीज़" का फैसला नहीं करते हैं, मुझे लगता है कि मैं कॉलम A में वर्ष के साथ एक नया कॉलम जोड़ूंगा !, या महीनों के बीच एक व्यय स्तंभ डालें और बिक्री कॉलम, या प्रत्येक कॉलम में एक हेडर जोड़ें। अब, आपका कोड टूट गया है। और क्योंकि आपने भयानक चर नामों का इस्तेमाल किया है, आपको यह तय करने के लिए बहुत अधिक समय लगेगा कि इसे कैसे तय करना चाहिए, इसकी तुलना में करना चाहिए।

यदि आपने नामित श्रेणियों का उपयोग शुरू किया था, तो Months और Sales कॉलम आपके आस-पास के सभी स्थानांतरित किए जा सकते थे, और आपका कोड केवल ठीक काम करना जारी रखेगा।

मैं छोटा जवाब देने जा रहा हूं क्योंकि हर किसी ने लंबे समय तक एक दिया।

आपको मिल जाएगा। चयन करें और। जब भी आप मैक्रोज़ रिकॉर्ड करते हैं और उन्हें पुन: उपयोग करते हैं सक्रिय करें। जब आप किसी सेल या शीट को चुनते हैं तो यह केवल सक्रिय बना देता है। उस बिंदु पर जब भी आप अयोग्य संदर्भों जैसे Range.Value उपयोग करते हैं। वे वे सक्रिय कक्ष और शीट का उपयोग करते हैं। यह समस्याग्रस्त भी हो सकता है यदि आप नहीं देखते हैं कि आपका कोड कहां रखा गया है या उपयोगकर्ता कार्यपुस्तिका पर क्लिक करता है

इसलिए, आप सीधे अपने कक्षों को संदर्भित करके इन मुद्दों को बढ़ा सकते हैं। कौन सा जाता है:

 'create and set a range Dim Rng As Excel.Range Set Rng = Workbooks("Book1").Worksheets("Sheet1").Range("A1") 'OR Set Rng = Workbooks(1).Worksheets(1).Cells(1, 1) 

या आप कर सकते हैं

 'Just deal with the cell directly rather than creating a range 'I want to put the string "Hello" in Range A1 of sheet 1 Workbooks("Book1").Worksheets("Sheet1").Range("A1").value = "Hello" 'OR Workbooks(1).Worksheets(1).Cells(1, 1).value = "Hello" 

इन विधियों के विभिन्न संयोजन हैं, लेकिन यह मेरे जैसे अधीर लोगों के लिए जितनी जल्दी संभव हो उतना ही सामान्य विचार व्यक्त होगा।

"… और मुझे लगता है कि मेरा कोड अधिक पुन: उपयोग योग्य होगा यदि मैं फ़ंक्शन का चयन करने के बजाय चर का उपयोग करने में सक्षम था।"

हालांकि मैं अलग-थलग मुट्ठी भर स्थितियों की तुलना में किसी भी बारे में सोच भी नहीं सकता हूं .Select चयन में प्रत्यक्ष सेल संदर्भ देने से बेहतर विकल्प होगा, मैं Selection की रक्षा में वृद्धि करूँगा और .Select हूं कि इसे उसी कारणों से नहीं निकाला जाना चाहिए जो .Select से बचा जाना चाहिए।

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

चयन-आधारित उप ढांचे के उदाहरण:

 Public Sub Run_on_Selected() Dim rng As Range, rSEL As Range Set rSEL = Selection 'store the current selection in case it changes For Each rng In rSEL Debug.Print rng.Address(0, 0) 'cell-by-cell operational code here Next rng Set rSEL = Nothing End Sub Public Sub Run_on_Selected_Visible() 'this is better for selected ranges on filtered data or containing hidden rows/columns Dim rng As Range, rSEL As Range Set rSEL = Selection 'store the current selection in case it changes For Each rng In rSEL.SpecialCells(xlCellTypeVisible) Debug.Print rng.Address(0, 0) 'cell-by-cell operational code here Next rng Set rSEL = Nothing End Sub Public Sub Run_on_Discontiguous_Area() 'this is better for selected ranges of discontiguous areas Dim ara As Range, rng As Range, rSEL As Range Set rSEL = Selection 'store the current selection in case it changes For Each ara In rSEL.Areas Debug.Print ara.Address(0, 0) 'cell group operational code here For Each rng In ara.Areas Debug.Print rng.Address(0, 0) 'cell-by-cell operational code here Next rng Next ara Set rSEL = Nothing End Sub 

संसाधित करने के लिए वास्तविक कोड एकल पंक्ति से कई मॉड्यूल तक हो सकता है। मैंने बाहरी कार्यपुस्तिकाओं के फाइल नाम युक्त कक्षों के बड़े चयन पर लंबे चलने वाले दिनचर्या आरंभ करने के लिए इस पद्धति का उपयोग किया है

संक्षेप में, इसके निकट सहयोग के कारण Selection मत छोड़ें। Selection और ActiveCell कार्यपत्रक संपत्ति के रूप में इसके पास कई अन्य उद्देश्य हैं

(हां, मुझे पता है कि यह सवाल था .Select Selection नहीं, Selection नहीं, लेकिन मैं किसी भी गलत धारणा को हटाना चाहता था, जो कि नौसिखिए VBA coders अनुमान लगा सकते हैं।)

कृपया ध्यान दें कि निम्नलिखित में मैं रेंज दृष्टिकोण (और यह सवाल का जवाब है) के साथ, चयन दृष्टिकोण (जो कि ओ.पी. से बचाना चाहता है) की तुलना कर रहा हूं। तो जब आप पहली बार को देखते हैं तब पढ़ना बंद न करें।

यह वास्तव में आप पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं। वैसे भी एक सरल उदाहरण उपयोगी हो सकता है। मान लीजिए कि आप सक्रिय कक्ष के मूल्य को "फू" में सेट करना चाहते हैं। ActiveCell का उपयोग आप इस तरह से कुछ लिखेंगे:

 Sub Macro1() ActiveCell.Value = "foo" End Sub 

यदि आप इसे एक सेल के लिए उपयोग करना चाहते हैं जो सक्रिय नहीं है, उदाहरण के लिए "B2" के लिए, आपको इसे पहले, पहले से चुनें:

 Sub Macro2() Range("B2").Select Macro1 End Sub 

श्रेणियों का उपयोग करके आप एक अधिक सामान्य मैक्रो लिख सकते हैं जिसे आप चाहते हैं जो भी चाहते हैं, उस सेल के मूल्य को सेट करने के लिए उपयोग किया जा सकता है:

 Sub SetValue(cellAddress As String, aVal As Variant) Range(cellAddress).Value = aVal End Sub 

तो आप मैक्रो 2 को फिर से लिख सकते हैं:

 Sub Macro2() SetCellValue "B2", "foo" End Sub 

और मैक्रो 1 के रूप में:

 Sub Macro1() SetValue ActiveCell.Address, "foo" End Sub 

उम्मीद है कि इससे चीजों को थोड़ी सी छोटी मात्रा में साफ करने में मदद मिलेगी।

कार्यपुस्तिका, वर्कशीट और सेल / रेंज को हमेशा बताएं

उदाहरण के लिए:

 Thisworkbook.Worksheets("fred").cells(1,1) Workbooks("bob").Worksheets("fred").cells(1,1) 

क्योंकि अंतिम उपयोगकर्ता हमेशा बस बटन क्लिक करेंगे और जैसे ही फोकस कार्यपुस्तिका को बंद कर देता है, कोड फिर से पूरी तरह गलत होने के साथ काम करना चाहता है

और कभी भी किसी कार्यपुस्तिका के सूचक का उपयोग न करें

 Workbooks(1).Worksheets("fred").cells(1,1) 

जब आप उपयोगकर्ता अपना कोड चलाते हैं, तो आप नहीं जानते कि अन्य कार्यपुस्तिका क्या खुली होंगी

.select उपयोग। लोगों की ओर से चयन, जो मुझे मैक्रो रिकॉर्डिंग के .select की .select से सीखना शुरू करते हैं और फिर इस बात को महसूस किए बिना कोड को संशोधित करते हैं। selection और बाद का selection सिर्फ एक अनावश्यक मध्यम-पुरुष है।

.select से बचा जा सकता है, जैसा कि पहले से ही पहले से ही पोस्ट किया गया है, पहले से ही मौजूदा ऑब्जेक्ट्स के साथ सीधे काम करके, जो कि कई अप्रत्यक्ष संदर्भों को एक जटिल तरीके से i और j की गणना करने और फिर सेल (i, j), आदि को संपादित करने की अनुमति देता है।

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

ऐसा कैसे हो सकता है कि आप निम्न मामलों में Select :

जब आप कार्यपत्रकों के बीच श्रेणी को कॉपी करना चाहते हैं:

से:

 Sheets("Source").Select Columns("A:D").Select Selection.Copy Sheets("Target").Select Columns("A:D").Select ActiveSheet.Paste 

सेवा मेरे:

 Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").Range("a1") 

फैंसी नामित श्रेणियों का उपयोग करना

आप उन्हें [] साथ एक्सेस कर सकते हैं जो वास्तव में सुंदर है, दूसरे रास्ते की तुलना में। अपने आप को जांचो:

 Dim Months As Range Dim MonthlySales As Range Set Months = Range("Months") Set MonthlySales = Range("MonthlySales") Set Months =[Months] Set MonthlySales = [MonthlySales] 

ऊपर से उदाहरण इस तरह दिखेगा:

 Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").[A1] 

मूल्यों की प्रतिलिपि नहीं, बल्कि उन्हें लेना

आमतौर पर, यदि आप select लिए तैयार हैं, तो शायद आप कुछ कॉपी कर रहे हैं यदि आप केवल मूल्यों में रुचि रखते हैं, तो यह चयन करने से बचने का एक अच्छा विकल्प है:

Range("B1:B6").Value = Range("A1:A6").Value

शीघ्र जवाब:

का उपयोग करने से बचने के लिए .Select विधि चुनें आप चाहते हैं कि संपत्ति के बराबर एक चर सेट कर सकते हैं।

► उदाहरण के लिए, यदि आप Cell A1 में मान चाहते हैं तो आप उस सेल की वैल्यू संपत्ति के बराबर एक वैल्यू सेट कर सकते हैं।

  • उदाहरण valOne = Range("A1").Value

► उदाहरण के लिए, यदि आप 'शीट 3' का कोडनाम चाहते हैं तो आप उस कार्यपत्रक की कोडन्यूम संपत्ति के बराबर एक वैल्यू सेट कर सकते हैं।

  • उदाहरण valTwo = Sheets("Sheet3").Codename

मुझे आशा है कि वह मदद करेंगे। अगर आपका कोई प्रश्न हैं, तो मुझे से पूछें।

यह एक ऐसा उदाहरण है जो कोशिका "A1" की सामग्री को साफ़ कर देगा (या अधिक अगर चयन प्रकार एक्सलस्टसेल, आदि)। सभी कोशिकाओं का चयन करने के बिना किया

 Application.GoTo Reference:=Workbook(WorkbookName).Worksheets(WorksheetName).Range("A1") Range(Selection,selection(selectiontype)).clearcontents 

मुझे उम्मीद है इससे किसी को सहायता मिलेगी।