在字典中sorting键

我有一组数字键,我想从最小到最大sorting。

Dim result Set result = CreateObject("Scripting.Dictionary") For i = 1 To N weeksThisIteration = 0 Do While conditiaonTrue //... weeksThisIteration = weeksThisIteration + 1 Loop 'If Not result.Item(weeksThisIteration) Then ' result.Add weeksThisIteration, 0//apparently I don't have to initiailize 'End If result.Item(weeksThisIteration) = result.Item(weeksThisIteration) + 1 

我想sortingresult ,最好在一个子/function。 我试过了:

  • 创build一个子MySort(list As Scripting.Dictionary)

我有问题通过价值。 我添加了对“Microsoft脚本运行时”的引用。 当我调用方法时,仍然收到有关传递ByRef的错误,另外我不确定实现。

  • 调用一个本地函数SortDictionary 。 VBA说func不存在。

我怎样才能在一个方法中实现一个数字键sorting,并调用它的这种数据types?

看看这个页面 。

具体来说,他有一个名为SortDictionary的部分

 Public Sub SortDictionary(Dict As Scripting.Dictionary, _ SortByKey As Boolean, _ Optional Descending As Boolean = False, _ Optional CompareMode As VbCompareMethod = vbTextCompare) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' SortDictionary ' This sorts a Dictionary object. If SortByKey is False, the ' the sort is done based on the Items of the Dictionary, and ' these items must be simple data types. They may not be ' Object, Arrays, or User-Defined Types. If SortByKey is True, ' the Dictionary is sorted by Key value, and the Items in the ' Dictionary may be Object as well as simple variables. ' ' If sort by key is True, all element of the Dictionary ' must have a non-blank Key value. If Key is vbNullString ' the procedure will terminate. ' ' By defualt, sorting is done in Ascending order. You can ' sort by Descending order by setting the Descending parameter ' to True. ' ' By default, text comparisons are done case-INSENSITIVE (eg, ' "a" = "A"). To use case-SENSITIVE comparisons (eg, "a" <> "A") ' set CompareMode to vbBinaryCompare. ' ' Note: This procedure requires the ' QSortInPlace function, which is described and available for ' download at www.cpearson.com/excel/qsort.htm . ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim Ndx As Long Dim KeyValue As String Dim ItemValue As Variant Dim Arr() As Variant Dim KeyArr() As String Dim VTypes() As VbVarType Dim V As Variant Dim SplitArr As Variant Dim TempDict As Scripting.Dictionary ''''''''''''''''''''''''''''' ' Ensure Dict is not Nothing. ''''''''''''''''''''''''''''' If Dict Is Nothing Then Exit Sub End If '''''''''''''''''''''''''''' ' If the number of elements ' in Dict is 0 or 1, no ' sorting is required. '''''''''''''''''''''''''''' If (Dict.Count = 0) Or (Dict.Count = 1) Then Exit Sub End If '''''''''''''''''''''''''''' ' Create a new TempDict. '''''''''''''''''''''''''''' Set TempDict = New Scripting.Dictionary If SortByKey = True Then '''''''''''''''''''''''''''''''''''''''' ' We're sorting by key. Redim the Arr ' to the number of elements in the ' Dict object, and load that array ' with the key names. '''''''''''''''''''''''''''''''''''''''' ReDim Arr(0 To Dict.Count - 1) For Ndx = 0 To Dict.Count - 1 Arr(Ndx) = Dict.Keys(Ndx) Next Ndx '''''''''''''''''''''''''''''''''''''' ' Sort the key names. '''''''''''''''''''''''''''''''''''''' QSortInPlace InputArray:=Arr, LB:=-1, UB:=-1, Descending:=Descending, CompareMode:=CompareMode '''''''''''''''''''''''''''''''''''''''''''' ' Load TempDict. The key value come from ' our sorted array of keys Arr, and the ' Item comes from the original Dict object. '''''''''''''''''''''''''''''''''''''''''''' For Ndx = 0 To Dict.Count - 1 KeyValue = Arr(Ndx) TempDict.Add Key:=KeyValue, Item:=Dict.Item(KeyValue) Next Ndx ''''''''''''''''''''''''''''''''' ' Set the passed in Dict object ' to our TempDict object. ''''''''''''''''''''''''''''''''' Set Dict = TempDict '''''''''''''''''''''''''''''''' ' This is the end of processing. '''''''''''''''''''''''''''''''' Else ''''''''''''''''''''''''''''''''''''''''''''''' ' Here, we're sorting by items. The Items must ' be simple data types. They may NOT be Objects, ' arrays, or UserDefineTypes. ' First, ReDim Arr and VTypes to the number ' of elements in the Dict object. Arr will ' hold a string containing ' Item & vbNullChar & Key ' This keeps the association between the ' item and its key. ''''''''''''''''''''''''''''''''''''''''''''''' ReDim Arr(0 To Dict.Count - 1) ReDim VTypes(0 To Dict.Count - 1) For Ndx = 0 To Dict.Count - 1 If (IsObject(Dict.Items(Ndx)) = True) Or _ (IsArray(Dict.Items(Ndx)) = True) Or _ VarType(Dict.Items(Ndx)) = vbUserDefinedType Then Debug.Print "***** ITEM IN DICTIONARY WAS OBJECT OR ARRAY OR UDT" Exit Sub End If '''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Here, we create a string containing ' Item & vbNullChar & Key ' This preserves the associate between an item and its ' key. Store the VarType of the Item in the VTypes ' array. We'll use these values later to convert ' back to the proper data type for Item. '''''''''''''''''''''''''''''''''''''''''''''''''''''''' Arr(Ndx) = Dict.Items(Ndx) & vbNullChar & Dict.Keys(Ndx) VTypes(Ndx) = VarType(Dict.Items(Ndx)) Next Ndx '''''''''''''''''''''''''''''''''' ' Sort the array that contains the ' items of the Dictionary along ' with their associated keys '''''''''''''''''''''''''''''''''' QSortInPlace InputArray:=Arr, LB:=-1, UB:=-1, Descending:=Descending, CompareMode:=vbTextCompare For Ndx = LBound(Arr) To UBound(Arr) ''''''''''''''''''''''''''''''''''''' ' Loop trhogh the array of sorted ' Items, Split based on vbNullChar ' to get the Key from the element ' of the array Arr. SplitArr = Split(Arr(Ndx), vbNullChar) '''''''''''''''''''''''''''''''''''''''''' ' It may have been possible that item in ' the dictionary contains a vbNullChar. ' Therefore, use UBound to get the ' key value, which will necessarily ' be the last item of SplitArr. ' Then Redim Preserve SplitArr ' to UBound - 1 to get rid of the ' Key element, and use Join ' to reassemble to original value ' of the Item. ''''''''''''''''''''''''''''''''''''''''' KeyValue = SplitArr(UBound(SplitArr)) ReDim Preserve SplitArr(LBound(SplitArr) To UBound(SplitArr) - 1) ItemValue = Join(SplitArr, vbNullChar) ''''''''''''''''''''''''''''''''''''''' ' Join will set ItemValue to a string ' regardless of what the original ' data type was. Test the VTypes(Ndx) ' value to convert ItemValue back to ' the proper data type. ''''''''''''''''''''''''''''''''''''''' Select Case VTypes(Ndx) Case vbBoolean ItemValue = CBool(ItemValue) Case vbByte ItemValue = CByte(ItemValue) Case vbCurrency ItemValue = CCur(ItemValue) Case vbDate ItemValue = CDate(ItemValue) Case vbDecimal ItemValue = CDec(ItemValue) Case vbDouble ItemValue = CDbl(ItemValue) Case vbInteger ItemValue = CInt(ItemValue) Case vbLong ItemValue = CLng(ItemValue) Case vbSingle ItemValue = CSng(ItemValue) Case vbString ItemValue = CStr(ItemValue) Case Else ItemValue = ItemValue End Select '''''''''''''''''''''''''''''''''''''' ' Finally, add the Item and Key to ' our TempDict dictionary. TempDict.Add Key:=KeyValue, Item:=ItemValue Next Ndx End If ''''''''''''''''''''''''''''''''' ' Set the passed in Dict object ' to our TempDict object. ''''''''''''''''''''''''''''''''' Set Dict = TempDict End Sub 

约翰·布斯托斯的回答是一个很好的答案。 这种sorting使得你的dictionary.keys都是string。 在我的情况下,键是整数。 我在SortDictionary的加载部分中进行了转换更改:

  ' Load TempDict. The key value come from ' our sorted array of keys Arr, and the ' Item comes from the original Dict object. '''''''''''''''''''''''''''''''''''''''''''' For Ndx = 0 To Dict.Count - 1 KeyValue = Arr(Ndx) 'MsgBox "key: " & KeyValue & "Item Value: " & Dict.Item(CInt(KeyValue)) TempDict.Add Key:=KeyValue, Item:=Dict.Item(CInt(KeyValue))'Convert here Next Ndx 

你也需要QSortInPlace来使这个代码工作。 链接在jsfiddle的情况下作者的链接死一天。 代码太长,无法直接发布到SO中。