Excel VBA Max 10值从字典

我需要从字典中获得10个最大值。 鉴于我有以下forms的一些数据:

ID Value 1 23 2 342 5 -23 ... 

什么是最快的方法来做到这一点?

为了使事情更清晰,以下是我将如何在C#中执行此操作的代码清单:

 class Custom { int ID {get; set;} double Val {get; set;} double Val2 {get; set;} } List<Custom> GetMaxValues(List<Custom> myList){ return myList.SortByDescending(c => c.Val).Take(10); } 

我在C#自定义类中包含了第二个值,因为实际上在字典中需要几个值。 一个multidimensional array是一个很好的解决scheme来保存三联数据。 然后,我可以简单地运行一些sortingalgorithm,并从数组中select最后10个项目。

编辑:我只是注意到,我不能使用一个数组,因为数据有不同的types。 ID的实际上是string,而不是整数。

我已经生成了一些VBA,应该将字典中的前N个值返回给数组。 我试着把它分解成辅助函数,使它更清晰易读,并把可重用的职责分开。 当然,它可以进一步开发错误检查,但我嘲笑它相对较快(例如,它忽略重复)。

让我们知道,如果它做你需要做什么,如果你需要任何帮助收养你自己的代码。

 Sub PerformTheActions() Dim oDictionary As Object Set oDictionary = CreateObject("Scripting.Dictionary") AddToDictionary oDictionary, Sheet1.Range("A1:A33") va = ReturnTopNValuesFromDict(oDictionary, 10) For i = LBound(va) To UBound(va) MsgBox "Key: " & va(i, 1) & " Value: " & va(i, 2) Next i End Sub ' Below is just a helper function to add a bunch of numbers into a dictionary ' You won't need to use it because you likely have other business logic to create your dict Private Sub AddToDictionary(odict As Object, rng As Range) Dim cel As Range Dim nID As Integer nID = 1 For Each cel In rng If Not odict.exists(cel.Value) Then odict.Add nID, cel.Value nID = nID + 1 End If Next cel End Sub Private Function ReturnTopNValuesFromDict(odict As Object, nTop As Integer) As Variant() Dim topN() As Variant Dim nCounter As Integer Dim vCutoff As Variant Dim nCutoffIndex As Long ReDim topN(1 To nTop, 1 To 2) nCounter = 1 For Each oitem In odict If nCounter <= nTop Then topN(nCounter, 1) = oitem topN(nCounter, 2) = odict(oitem) nCounter = nCounter + 1 Else vCutoff = topN(LBound(topN), 2) nCutoffIndex = LBound(topN) For i = LBound(topN) + 1 To UBound(topN) If topN(i, 2) < vCutoff Then vCutoff = topN(i, 2) nCutoffIndex = i End If Next i If vCutoff > odict(oitem) Then 'Do nothing because lowest value in array is greater than this item Else topN(nCutoffIndex, 1) = oitem topN(nCutoffIndex, 2) = odict(oitem) End If End If Next oitem BubbleSortArray topN ReturnTopNValuesFromDict = topN End Function Private Function BubbleSortArray(vArray As Variant) As Variant() Dim vPlaceHolder As Variant Dim nFirst As Long Dim nSecond As Long For nFirst = LBound(vArray) To UBound(vArray) For nSecond = nFirst + 1 To UBound(vArray) If vArray(nFirst, 2) < vArray(nSecond, 2) Then vPlaceHolder = vArray(nFirst, 1) vArray(nFirst, 1) = vArray(nSecond, 1) vArray(nSecond, 1) = vPlaceHolder vPlaceHolder = vArray(nFirst, 2) vArray(nFirst, 2) = vArray(nSecond, 2) vArray(nSecond, 2) = vPlaceHolder End If Next nSecond Next nFirst End Function 

不要使用字典 – 而是使用ArrayList:

 Sub foo() Dim myList As Object Dim resultArray As Variant '// create the arraylist and populate it Set myList = CreateObject("System.Collections.ArrayList") For i = 100 To 1 Step -1 myList.Add i Next '// sort the values numerically myList.Sort '// remove the last 90 elements (we're only interested in the first 10) myList.RemoveRange 10, myList.Count - 10 '// pass the values to a single dimension array resultArray = myList.ToArray() '// print the results Debug.Print Join$(resultArray, ",") End Sub 

MSDN ArrayList类