दिलचस्प पोस्ट
लिनक "अभिव्यक्ति का … एसक्यूएल में अनुवाद नहीं कर सका और इसे स्थानीय अभिव्यक्ति के रूप में नहीं माना जा सका।" नेविगेशन नियंत्रक पुश व्यू नियंत्रक दृश्य में प्रयुक्त PostgreSQL कॉलम बदलें कॉलम में अल्पविराम से अलग प्रवेश को परिवर्तित करें एंड्रॉइड कॉलम '_id' मौजूद नहीं है? परियोजनाओं के लिए App.Config परिवर्तन जो Visual Studio 2010 में वेब प्रोजेक्ट्स नहीं हैं? बंद करने की चेतावनी में अग्रविकल्प चर तक पहुंच जावास्क्रिप्ट में एक स्ट्रिंग के अग्रणी शून्य को छोटा करें पीएचपी में महीना का नाम बदलने के लिए रनटाइम.एक्सएसी (): एंड्रॉइड में रिबूट करें? Node.js में process.env.port का मूल्य कैसे बदल सकता है? एक मतदान प्रणाली में अद्वितीय आईपी थोड़ा सा सेट है या नहीं, यह जांचता है एक तत्व में पाठ का चयन करना (आपके माउस के साथ हाइलाइटिंग के समान) सीएसएस शब्द-रैपिंग में डिव

vba: सरणी से अद्वितीय मान प्राप्त करें

क्या एक-आयामी सरणी से अद्वितीय मूल्य प्राप्त करने के लिए Vba में कार्यक्षमता में बनाया गया है? केवल डुप्लिकेट से छुटकारा पाने के बारे में क्या?

यदि नहीं, तो मैं कैसे एक सरणी से अद्वितीय मूल्य मिल जाएगा?

Solutions Collecting From Web of "vba: सरणी से अद्वितीय मान प्राप्त करें"

इस पोस्ट में 2 उदाहरण हैं मुझे दूसरा एक पसंद है:

Sub unique() Dim arr As New Collection, a Dim aFirstArray() As Variant Dim i As Long aFirstArray() = Array("Banana", "Apple", "Orange", "Tomato", "Apple", _ "Lemon", "Lime", "Lime", "Apple") On Error Resume Next For Each a In aFirstArray arr.Add a, a Next For i = 1 To arr.Count Cells(i, 1) = arr(i) Next End Sub 

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

 Dim d As Object Set d = CreateObject("Scripting.Dictionary") 'Set d = New Scripting.Dictionary Dim i As Long For i = LBound(myArray) To UBound(myArray) d(myArray(i)) = 1 Next i Dim v As Variant For Each v In d.Keys() 'd.Keys() is a Variant array of the unique values in myArray. 'v will iterate through each of them. Next v 

संपादित करें: मैंने टॉमलिक के सुझाव के उत्तर के अनुसार लबैंड और UBound का उपयोग करने के लिए लूप को बदल दिया। संपादित करें: d.Keys() एक वेरिएंट सरणी है, संग्रह नहीं।

अपडेट (6/15/16)

मैंने बहुत अधिक संपूर्ण मानक बनाए हैं सबसे पहले, के रूप में @ सीएचएमजी ने बताया, प्रारंभिक बाध्यकारी एक बड़ा फर्क पड़ता है (मैं मूल रूप से ebbsorto के ऊपर वर्बेटीम कोड का उपयोग करता है जो देर से बंधन का उपयोग करता है) दूसरे, मेरे मूल मानक में केवल अद्वितीय वस्तु बनाने के लिए समय शामिल था, हालांकि, यह वस्तु का उपयोग करने की दक्षता का परीक्षण नहीं करता। ऐसा करने में मेरी बात यह है कि वास्तव में कोई चीज नहीं है अगर मैं एक ऑब्जेक्ट वास्तव में तेजी से बना सकता हूं, यदि मैं जो ऑब्जेक्ट बनाऊँ तो वह घर्षण है और आगे बढ़ने में मुझे धीमा कर देती है

पुरानी टिप्पणी: यह पता चला है कि संग्रह ऑब्जेक्ट पर लूपिंग अत्यधिक अक्षम है

यह पता चला है कि संग्रह पर लूपिंग काफी कुशल हो सकता है यदि आप जानते हैं कि यह कैसे करना है (मैं नहीं)। @ कैमिमजी (फिर से) के रूप में, टिप्पणियों में बताया गया है, For Each का उपयोग करने के For Each हास्यास्पद रूप से एक लूप का उपयोग करने के लिए हास्यास्पद बेहतर है। लूप निर्माण को बदलने से पहले आपको एक विचार देने के लिए, Test Case Size = 10^6 लिए Collection2 Test Case Size = 10^6 का समय 1400 से अधिक (यानी ~ 23 मिनट) था। यह अब एक मामूली 0.195 s (7000x से अधिक तेज) है।

Collection विधि के लिए दो बार हैं पहला (मेरा मूल बेंचमार्क Collection1 ) अद्वितीय ऑब्जेक्ट बनाने के लिए समय दिखाता है। दूसरे भाग ( Collection2 ) ऑब्जेक्ट पर लूप का समय दिखाता है (जो बहुत ही स्वाभाविक है) अन्य फ़ंक्शन के रूप में वापसी योग्य सरणी बनाने के लिए।

नीचे दिए गए चार्ट में, एक पीले रंग की पृष्ठभूमि इंगित करती है कि यह परीक्षण मामले के लिए सबसे तेज़ था, और लाल बहुत धीमी ("परीक्षण नहीं किया गया" एल्गोरिदम को बाहर रखा गया है) दर्शाता है। Collection विधि के लिए कुल समय Collection1 और Collection2 का योग है। फ़िरोज़ा इंगित करता है कि मूल क्रम की परवाह किए बिना सबसे तेज़ था।

Benchmarks5

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

इस एल्गोरिथम के पीछे मुख्य विचार हैं:

  1. इंडेक्स सरणी
  2. मूल्यों के आधार पर क्रमबद्ध करें
  3. सरणी के अंत में समान मान रखें और बाद में उन्हें "काट" करें
  4. अंत में, सूचकांक क्रमबद्ध करें

नीचे एक उदाहरण है:

 Let myArray = (86, 100, 33, 19, 33, 703, 19, 100, 703, 19) 1. (86, 100, 33, 19, 33, 703, 19, 100, 703, 19) (1 , 2, 3, 4, 5, 6, 7, 8, 9, 10) <<-- Indexing 2. (19, 19, 19, 33, 33, 86, 100, 100, 703, 703) <<-- sort by values (4, 7, 10, 3, 5, 1, 2, 8, 6, 9) 3. (19, 33, 86, 100, 703) <<-- remove duplicates (4, 3, 1, 2, 6) 4. (86, 100, 33, 19, 703) ( 1, 2, 3, 4, 6) <<-- sort by index 

यहां कोड है:

 Function SortingUniqueTest(ByRef myArray() As Long, bOrigIndex As Boolean) As Variant Dim MyUniqueArr() As Long, i As Long, intInd As Integer Dim StrtTime As Double, Endtime As Double, HighB As Long, LowB As Long LowB = LBound(myArray): HighB = UBound(myArray) ReDim MyUniqueArr(1 To 2, LowB To HighB) intInd = 1 - LowB 'Guarantees the indices span 1 to Lim For i = LowB To HighB MyUniqueArr(1, i) = myArray(i) MyUniqueArr(2, i) = i + intInd Next i QSLong2D MyUniqueArr, 1, LBound(MyUniqueArr, 2), UBound(MyUniqueArr, 2), 2 Call UniqueArray2D(MyUniqueArr) If bOrigIndex Then QSLong2D MyUniqueArr, 2, LBound(MyUniqueArr, 2), UBound(MyUniqueArr, 2), 2 SortingUniqueTest = MyUniqueArr() End Function Public Sub UniqueArray2D(ByRef myArray() As Long) Dim i As Long, j As Long, Count As Long, Count1 As Long, DuplicateArr() As Long Dim lngTemp As Long, HighB As Long, LowB As Long LowB = LBound(myArray, 2): Count = LowB: i = LowB: HighB = UBound(myArray, 2) Do While i < HighB j = i + 1 If myArray(1, i) = myArray(1, j) Then Do While myArray(1, i) = myArray(1, j) ReDim Preserve DuplicateArr(1 To Count) DuplicateArr(Count) = j Count = Count + 1 j = j + 1 If j > HighB Then Exit Do Loop QSLong2D myArray, 2, i, j - 1, 2 End If i = j Loop Count1 = HighB If Count > 1 Then For i = UBound(DuplicateArr) To LBound(DuplicateArr) Step -1 myArray(1, DuplicateArr(i)) = myArray(1, Count1) myArray(2, DuplicateArr(i)) = myArray(2, Count1) Count1 = Count1 - 1 ReDim Preserve myArray(1 To 2, LowB To Count1) Next i End If End Sub 

यहाँ मैं सॉर्टिंग एल्गोरिथ्म का उपयोग करता हूँ (इस एल्ग के बारे में अधिक)

 Sub QSLong2D(ByRef saArray() As Long, bytDim As Byte, lLow1 As Long, lHigh1 As Long, bytNum As Byte) Dim lLow2 As Long, lHigh2 As Long Dim sKey As Long, sSwap As Long, i As Byte On Error GoTo ErrorExit If IsMissing(lLow1) Then lLow1 = LBound(saArray, bytDim) If IsMissing(lHigh1) Then lHigh1 = UBound(saArray, bytDim) lLow2 = lLow1 lHigh2 = lHigh1 sKey = saArray(bytDim, (lLow1 + lHigh1) \ 2) Do While lLow2 < lHigh2 Do While saArray(bytDim, lLow2) < sKey And lLow2 < lHigh1: lLow2 = lLow2 + 1: Loop Do While saArray(bytDim, lHigh2) > sKey And lHigh2 > lLow1: lHigh2 = lHigh2 - 1: Loop If lLow2 < lHigh2 Then For i = 1 To bytNum sSwap = saArray(i, lLow2) saArray(i, lLow2) = saArray(i, lHigh2) saArray(i, lHigh2) = sSwap Next i End If If lLow2 <= lHigh2 Then lLow2 = lLow2 + 1 lHigh2 = lHigh2 - 1 End If Loop If lHigh2 > lLow1 Then QSLong2D saArray(), bytDim, lLow1, lHigh2, bytNum If lLow2 < lHigh1 Then QSLong2D saArray(), bytDim, lLow2, lHigh1, bytNum ErrorExit: End Sub 

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

 Function IndexSort(ByRef myArray() As Long, bOrigIndex As Boolean) As Variant '' Modified to take both positive and negative integers Dim arrVals() As Long, arrSort() As Long, arrBool() As Boolean Dim i As Long, HighB As Long, myMax As Long, myMin As Long, OffSet As Long Dim LowB As Long, myIndex As Long, count As Long, myRange As Long HighB = UBound(myArray) LowB = LBound(myArray) For i = LowB To HighB If myArray(i) > myMax Then myMax = myArray(i) If myArray(i) < myMin Then myMin = myArray(i) Next i OffSet = Abs(myMin) '' Number that will be added to every element '' to guarantee every index is non-negative If myMax > 0 Then myRange = myMax + OffSet '' Eg if myMax = 10 & myMin = -2, then myRange = 12 Else myRange = OffSet End If If bOrigIndex Then ReDim arrSort(1 To 2, 1 To HighB) ReDim arrVals(1 To 2, 0 To myRange) ReDim arrBool(0 To myRange) For i = LowB To HighB myIndex = myArray(i) + OffSet arrBool(myIndex) = True arrVals(1, myIndex) = myArray(i) If arrVals(2, myIndex) = 0 Then arrVals(2, myIndex) = i Next i For i = 0 To myRange If arrBool(i) Then count = count + 1 arrSort(1, count) = arrVals(1, i) arrSort(2, count) = arrVals(2, i) End If Next i QSLong2D arrSort, 2, 1, count, 2 ReDim Preserve arrSort(1 To 2, 1 To count) Else ReDim arrSort(1 To HighB) ReDim arrVals(0 To myRange) ReDim arrBool(0 To myRange) For i = LowB To HighB myIndex = myArray(i) + OffSet arrBool(myIndex) = True arrVals(myIndex) = myArray(i) Next i For i = 0 To myRange If arrBool(i) Then count = count + 1 arrSort(count) = arrVals(i) End If Next i ReDim Preserve arrSort(1 To count) End If ReDim arrVals(0) ReDim arrBool(0) IndexSort = arrSort End Function 

यहां संग्रह (@ डॉकब्रौन द्वारा) और डिक्शनरी (@ एक्सहोर्सो द्वारा) फ़ंक्शन हैं।

 Function CollectionTest(ByRef arrIn() As Long, Lim As Long) As Variant Dim arr As New Collection, a, i As Long, arrOut() As Variant, aFirstArray As Variant Dim StrtTime As Double, EndTime1 As Double, EndTime2 As Double, count As Long On Error Resume Next ReDim arrOut(1 To UBound(arrIn)) ReDim aFirstArray(1 To UBound(arrIn)) StrtTime = Timer For i = 1 To UBound(arrIn): aFirstArray(i) = CStr(arrIn(i)): Next i '' Convert to string For Each a In aFirstArray ''' This part is actually creating the unique set arr.Add a, a Next EndTime1 = Timer - StrtTime StrtTime = Timer ''' This part is writing back to an array for return For Each a In arr: count = count + 1: arrOut(count) = a: Next a EndTime2 = Timer - StrtTime CollectionTest = Array(arrOut, EndTime1, EndTime2) End Function Function DictionaryTest(ByRef myArray() As Long, Lim As Long) As Variant Dim StrtTime As Double, Endtime As Double Dim d As Scripting.Dictionary, i As Long '' Early Binding Set d = New Scripting.Dictionary For i = LBound(myArray) To UBound(myArray): d(myArray(i)) = 1: Next i DictionaryTest = d.Keys() End Function 

इज़राइल हॉटेज़ द्वारा प्रदान किया गया प्रत्यक्ष दृष्टिकोण यहाँ है

 Function ArrayUnique(ByRef aArrayIn() As Long) As Variant Dim aArrayOut() As Variant, bFlag As Boolean, vIn As Variant, vOut As Variant Dim i As Long, j As Long, k As Long ReDim aArrayOut(LBound(aArrayIn) To UBound(aArrayIn)) i = LBound(aArrayIn) j = i For Each vIn In aArrayIn For k = j To i - 1 If vIn = aArrayOut(k) Then bFlag = True: Exit For Next If Not bFlag Then aArrayOut(i) = vIn: i = i + 1 bFlag = False Next If i <> UBound(aArrayIn) Then ReDim Preserve aArrayOut(LBound(aArrayIn) To i - 1) ArrayUnique = aArrayOut End Function Function DirectTest(ByRef aArray() As Long, Lim As Long) As Variant Dim aReturn() As Variant Dim StrtTime As Long, Endtime As Long, i As Long aReturn = ArrayUnique(aArray) DirectTest = aReturn End Function 

यहां बेंचमार्क फ़ंक्शन है जो सभी कार्यों की तुलना करता है। आपको ध्यान रखना चाहिए कि पिछले दो मामलों को स्मृति समस्याओं के कारण थोड़ा अलग किया जाता है। यह भी ध्यान दें, मैंने Test Case Size = 10,000,000 लिए Collection विधि का परीक्षण नहीं किया। किसी कारण के कारण, यह गलत परिणाम लौट रहा था और असामान्य व्यवहार कर रहा था (मैं संग्रह ऑब्जेक्ट का अनुमान लगा रहा हूं कि आप इसमें कितनी चीजें रख सकते हैं।) मैंने खोजा और इस पर कोई साहित्य नहीं पाया।

 Function UltimateTest(Lim As Long, bTestDirect As Boolean, bTestDictionary, bytCase As Byte) As Variant Dim dictionTest, collectTest, sortingTest1, indexTest1, directT '' all variants Dim arrTest() As Long, i As Long, bEquality As Boolean, SizeUnique As Long Dim myArray() As Long, StrtTime As Double, EndTime1 As Variant Dim EndTime2 As Double, EndTime3 As Variant, EndTime4 As Double Dim EndTime5 As Double, EndTime6 As Double, sortingTest2, indexTest2 ReDim myArray(1 To Lim): Rnd (-2) '' If you want to test negative numbers, '' insert this to the left of CLng(Int(Lim... : (-1) ^ (Int(2 * Rnd())) * For i = LBound(myArray) To UBound(myArray): myArray(i) = CLng(Int(Lim * Rnd() + 1)): Next i arrTest = myArray If bytCase = 1 Then If bTestDictionary Then StrtTime = Timer: dictionTest = DictionaryTest(arrTest, Lim): EndTime1 = Timer - StrtTime Else EndTime1 = "Not Tested" End If arrTest = myArray collectTest = CollectionTest(arrTest, Lim) arrTest = myArray StrtTime = Timer: sortingTest1 = SortingUniqueTest(arrTest, True): EndTime2 = Timer - StrtTime SizeUnique = UBound(sortingTest1, 2) If bTestDirect Then arrTest = myArray: StrtTime = Timer: directT = DirectTest(arrTest, Lim): EndTime3 = Timer - StrtTime Else EndTime3 = "Not Tested" End If arrTest = myArray StrtTime = Timer: indexTest1 = IndexSort(arrTest, True): EndTime4 = Timer - StrtTime arrTest = myArray StrtTime = Timer: sortingTest2 = SortingUniqueTest(arrTest, False): EndTime5 = Timer - StrtTime arrTest = myArray StrtTime = Timer: indexTest2 = IndexSort(arrTest, False): EndTime6 = Timer - StrtTime bEquality = True For i = LBound(sortingTest1, 2) To UBound(sortingTest1, 2) If Not CLng(collectTest(0)(i)) = sortingTest1(1, i) Then bEquality = False Exit For End If Next i For i = LBound(dictionTest) To UBound(dictionTest) If Not dictionTest(i) = sortingTest1(1, i + 1) Then bEquality = False Exit For End If Next i For i = LBound(dictionTest) To UBound(dictionTest) If Not dictionTest(i) = indexTest1(1, i + 1) Then bEquality = False Exit For End If Next i If bTestDirect Then For i = LBound(dictionTest) To UBound(dictionTest) If Not dictionTest(i) = directT(i + 1) Then bEquality = False Exit For End If Next i End If UltimateTest = Array(bEquality, EndTime1, EndTime2, EndTime3, EndTime4, _ EndTime5, EndTime6, collectTest(1), collectTest(2), SizeUnique) ElseIf bytCase = 2 Then arrTest = myArray collectTest = CollectionTest(arrTest, Lim) UltimateTest = Array(collectTest(1), collectTest(2)) ElseIf bytCase = 3 Then arrTest = myArray StrtTime = Timer: sortingTest1 = SortingUniqueTest(arrTest, True): EndTime2 = Timer - StrtTime SizeUnique = UBound(sortingTest1, 2) UltimateTest = Array(EndTime2, SizeUnique) ElseIf bytCase = 4 Then arrTest = myArray StrtTime = Timer: indexTest1 = IndexSort(arrTest, True): EndTime4 = Timer - StrtTime UltimateTest = EndTime4 ElseIf bytCase = 5 Then arrTest = myArray StrtTime = Timer: sortingTest2 = SortingUniqueTest(arrTest, False): EndTime5 = Timer - StrtTime UltimateTest = EndTime5 ElseIf bytCase = 6 Then arrTest = myArray StrtTime = Timer: indexTest2 = IndexSort(arrTest, False): EndTime6 = Timer - StrtTime UltimateTest = EndTime6 End If End Function 

और अंत में, यह सब उपरोक्त तालिका का उत्पादन करता है।

 Sub GetBenchmarks() Dim myVar, i As Long, TestCases As Variant, j As Long, temp TestCases = Array(1000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000) For j = 0 To 11 If j < 6 Then myVar = UltimateTest(CLng(TestCases(j)), True, True, 1) ElseIf j < 10 Then myVar = UltimateTest(CLng(TestCases(j)), False, True, 1) ElseIf j < 11 Then myVar = Array("Not Tested", "Not Tested", 0.1, "Not Tested", 0.1, 0.1, 0.1, 0, 0, 0) temp = UltimateTest(CLng(TestCases(j)), False, False, 2) myVar(7) = temp(0): myVar(8) = temp(1) temp = UltimateTest(CLng(TestCases(j)), False, False, 3) myVar(2) = temp(0): myVar(9) = temp(1) myVar(4) = UltimateTest(CLng(TestCases(j)), False, False, 4) myVar(5) = UltimateTest(CLng(TestCases(j)), False, False, 5) myVar(6) = UltimateTest(CLng(TestCases(j)), False, False, 6) Else myVar = Array("Not Tested", "Not Tested", 0.1, "Not Tested", 0.1, 0.1, 0.1, "Not Tested", "Not Tested", 0) temp = UltimateTest(CLng(TestCases(j)), False, False, 3) myVar(2) = temp(0): myVar(9) = temp(1) myVar(4) = UltimateTest(CLng(TestCases(j)), False, False, 4) myVar(5) = UltimateTest(CLng(TestCases(j)), False, False, 5) myVar(6) = UltimateTest(CLng(TestCases(j)), False, False, 6) End If Cells(4 + j, 6) = TestCases(j) For i = 1 To 9: Cells(4 + j, 6 + i) = myVar(i - 1): Next i Cells(4 + j, 17) = myVar(9) Next j End Sub 

सारांश
परिणामों की तालिका से, हम देख सकते हैं कि 500,000 से भी कम मामलों के लिए Dictionary पद्धति वास्तव में अच्छी तरह से काम करती है, फिर भी, इसके बाद, IndexMethod वास्तव में हावी हो जाती है। आप देखेंगे कि जब आदेश कोई फर्क नहीं पड़ता है और आपका डेटा सकारात्मक पूर्णांक से बना होता है, तो IndexMethod विधि एल्गोरिथ्म से कोई तुलना नहीं IndexMethod है (यह एक सरणी से अद्वितीय मान देता है जिसमें 1 सेकंड से कम 1 करोड़ तत्व होते हैं !!! !)। नीचे मेरे पास एक ब्रेकडाउन है जो विभिन्न मामलों में एल्गोरिदम को पसंद किया जाता है।

मामला एक
आपके डेटा में पूर्णांक होते हैं (अर्थात् पूर्ण संख्याएं, दोनों सकारात्मक और नकारात्मक): IndexMethod

केस 2
आपके डेटा में 200000 से भी कम तत्वों के साथ गैर-पूर्णांक (यानी भिन्न, डबल, स्ट्रिंग, आदि) शामिल हैं: Dictionary Method

केस 3
आपके डेटा में 200000 से अधिक तत्वों के साथ गैर-पूर्णांक (यानी भिन्न, डबल, स्ट्रिंग, आदि) शामिल हैं: Collection Method

यदि आपको एक एल्गोरिदम का चयन करना है, तो मेरी राय में, Collection विधि अभी भी सबसे अच्छा है क्योंकि इसे केवल कोड की कुछ पंक्तियों की आवश्यकता है, यह सुपर सामान्य है, और यह तेज़ है

नहीं, कुछ भी नहीं बनाया यह स्वयं करो:

  • एक Scripting.Dictionary ऑब्जेक्ट Instantiate
  • अपनी सरणी पर लूप के For एक लिखें (0 से एक्स के लूपिंग के बजाय LBound() और UBound() का उपयोग करना सुनिश्चित करें!)
  • प्रत्येक पुनरावृत्ति पर, शब्दकोष पर Exists() चेक करें प्रत्येक सरणी मान (जो पहले से मौजूद नहीं है) को शब्दकोश के लिए कुंजी के रूप में CStr() उपयोग करें क्योंकि चाबियाँ स्ट्रिंग होने चाहिए क्योंकि मैंने अभी सीखा है, कुंजियों को किसी भी प्रकार की Scripting.Dictionary सरणी का मान ही शब्दकोश में है
  • जब किया जाए, तो शब्दकोशों के सभी मानों को एक नया, अब अनूठे सरणी के रूप में वापस करने के लिए Keys() (या Items() ) का उपयोग करें
  • मेरे परीक्षणों में, शब्दकोश सभी मूलभूत मूल्यों का मूल क्रम रखता है, इसलिए इनपुट का आदेश दिया जाएगा जैसे इनपुट था मुझे यकीन नहीं है कि यह दस्तावेज और विश्वसनीय व्यवहार है, यद्यपि।

मैं VBA में किसी भी अंतर्निहित कार्यक्षमता के बारे में नहीं जानता सबसे अच्छा मूल्य के रूप में मूल्य का उपयोग कर एक संग्रह का उपयोग करना होगा और यदि मूल्य मौजूद नहीं है, तो उसे केवल तभी जोड़ना होगा।

नहीं, VBA में यह कार्यक्षमता नहीं है आप कुंजी के रूप में आइटम का उपयोग करके प्रत्येक आइटम को संग्रह में जोड़ने की तकनीक का उपयोग कर सकते हैं। चूंकि कोई संग्रह डुप्लिकेट की अनुमति नहीं देता है, परिणामस्वरूप अलग-अलग मान हैं, जिन्हें आप की आवश्यकता होती है, तो किसी ऐरे को कॉपी कर सकते हैं।

आप कुछ और अधिक मजबूत चाहते हैं http://www.cpearson.com/excel/distinctvalues.aspx पर विशिष्ट मान फ़ंक्शन देखें

विशिष्ट मान फंक्शन

एक VBA फ़ंक्शन जो किसी इनपुट मानों की श्रेणी या सरणी में अलग-अलग मानों की एक सरणी वापस करेगा।

एक इनपुट श्रेणी से विशिष्ट आइटमों की सूची प्राप्त करने के लिए Excel में कुछ मैन्युअल विधियां हैं, जैसे कि उन्नत फ़िल्टर। ऐसी विधियों का उपयोग करने की कमी यह है कि जब इनपुट डेटा में परिवर्तन होता है, तो आपको मैन्युअल रूप से परिणाम रीफ़्रेश करना चाहिए। इसके अलावा, ये पद्धति केवल श्रेणियों के साथ काम करती है, मूल्यों का सरणियां नहीं, और फ़ंक्शन नहीं होती है, कार्यपत्रक कोशिकाओं से नहीं बुलाया जा सकता है या सरणी सूत्रों में शामिल किया जा सकता है। यह पृष्ठ विशिष्ट वीबीए फंक्शन का वर्णन करता है जिसे डिस्टिक्टवल्यूज़ नामक एक रेंज या एक सरणी डेटा के रूप में स्वीकार करता है और इसके परिणामस्वरूप इनपुट सूची से विशिष्ट आइटम वाले सरणी के रूप में इसका लाभ मिलता है। यही है, सभी डुप्लिकेट वाले तत्व हटा दिए गए हैं। इनपुट तत्वों का क्रम संरक्षित है। आउटपुट सरणी में तत्वों का क्रम इनपुट मूल्यों के क्रम के समान है। फ़ंक्शन को किसी कार्यपत्रक पर सरणी में दर्ज किया गया श्रेणी (सरणी फ़ार्मुलों के बारे में जानकारी के लिए यह पृष्ठ देखें) से, या एक वर्कशीट सेल में या किसी अन्य VB फ़ंक्शन से एक सरणी सूत्र में से कहा जा सकता है।

संग्रह और डिक्शनरी समाधान सभी अच्छे हैं और एक छोटे दृष्टिकोण के लिए चमकते हैं, लेकिन यदि आप गति चाहते हैं तो एक अधिक प्रत्यक्ष दृष्टिकोण का उपयोग करने की कोशिश करें:

 Function ArrayUnique(ByVal aArrayIn As Variant) As Variant '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' ArrayUnique ' This function removes duplicated values from a single dimension array '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim aArrayOut() As Variant Dim bFlag As Boolean Dim vIn As Variant Dim vOut As Variant Dim i%, j%, k% ReDim aArrayOut(LBound(aArrayIn) To UBound(aArrayIn)) i = LBound(aArrayIn) j = i For Each vIn In aArrayIn For k = j To i - 1 If vIn = aArrayOut(k) Then bFlag = True: Exit For Next If Not bFlag Then aArrayOut(i) = vIn: i = i + 1 bFlag = False Next If i <> UBound(aArrayIn) Then ReDim Preserve aArrayOut(LBound(aArrayIn) To i - 1) ArrayUnique = aArrayOut End Function 

इसे कॉल करना:

 Sub Test() Dim aReturn As Variant Dim aArray As Variant aArray = Array(1, 2, 3, 1, 2, 3, "Test", "Test") aReturn = ArrayUnique(aArray) End Sub 

स्पीड तुलनीयता के लिए, यह डिक्शनरी समाधान से 100x से 130x तेज हो जाएगा, और संग्रह के मुकाबले 8000x से 13000x तेज हो जाएगा।

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

शीर्षक मेरे कोड में 1-डी सरणी है

 For i = UBound(titles) To LBound(titles) + 1 Step -1 'Looping backwards through the array If titles(i) = titles(i - 1) Then 'If the last element is the same as the one before it ReDim Preserve titles(i - 1) 'Then trim it down by one. Essentially, delete it from the array End If Next i