如何按对象属性vbscript对字典进行排序

时间:2018-01-05 13:39:24

标签: sorting dictionary vbscript

我正在尝试使用我在网上通过对象属性找到的函数对字典进行排序,这是一个Id,但在For Each i In dict行上我收到此错误消息Microsoft VBScript运行时错误:对象没有' t支持此属性或方法。我尝试了For Each i In dict.Items但是我收到了与“dict.Items”相同的错误消息。我使用的是较旧版本的VBScript,因此它没有dict.Count

等功能

VBScript类:

Class TestClass
    Public ID
    Public TestText
    Private Sub Class_Initialize
            TestText  = ""
    End Sub
End Class

Set gDic = CreateObject("Scripting.Dictionary")


For i = 1 to 5
    Set temp = new TestClass
    temp.ID = i
    temp.TestText = "Test" & i

    gDic.Add i,temp
Next


Set NewDic = SortDict(gDic)
msgbox NewDic.Items()(1).TestText

排序功能:

Function SortDict(ByVal dict)
    Dim i, j, temp
    For Each i In dict
        For Each j In dict
            If(dict.Item(i) <= dict.Item(j)) Then
                temp = dict.Item(i)
                dict.Item(i) = dict.Item(j)
                dict.Item(j) = temp
            End If
        Next
    Next
    Set SortDict = dict
End Function

3 个答案:

答案 0 :(得分:4)

尝试将您的功能修改为:

Function SortDict(dict)
    Dim i, j, arrKeys, arrItems
    arrKeys = dict.keys                                               'Array containing the keys
    arrItems = dict.Items                                             'Array containing the Items(which are nothing but objects of class TestClass)
    Set tempObj = New TestClass
    For i=0 To UBound(arrItems)-1                                     'From 1st element to the penultimate element
        For j=i+1 To UBound(arrItems)                                 'From i+1th element to last element
            If arrItems(i).id < arrItems(j).id Then                  'Sorting in DESCENDING ORDER by the Property "ID"
                tempObj.ID = arrItems(i).ID
                tempObj.TestText = arrItems(i).testText
                dict.item(arrKeys(i)).ID = arrItems(j).ID
                dict.item(arrKeys(i)).TestText = arrItems(j).TestText
                dict.item(arrKeys(j)).ID = tempObj.ID
                dict.item(arrKeys(j)).TestText = tempObj.TestText
            End If
        Next
    Next
    Set SortDict = dict
End Function

排序前:

|Key             |Value                |
|----------------|---------------------|
|1               |1,Test1              |
|2               |2,Test2              |
|3               |3,Test3              |
|4               |4,Test4              |
|5               |5,Test5              |

排序后:

|Key             |Value                |
|----------------|---------------------|
|1               |5,Test5              |
|2               |4,Test4              |
|3               |3,Test3              |
|4               |2,Test2              |
|5               |1,Test1              |

我找不到更好的交换价值的方法。我相信有更好的方法可以做到这一点。我得到的东西会更新它。

答案 1 :(得分:0)

要添加到@Potato提供的答案中,我需要对字典中的两个值进行降序排序,然后将这些值与数据库进行比较。幸运的是,UI允许我先按降序排序,然后使用@Potato提供的Sorting方法将值与数据库进行比较。如果需要对数据库中的多个值进行排序,我将不得不使用更多的字典。

此函数将字典按照相似的值(例如ID)分组。然后根据ReverseSortDescDict(descDict)

中的第二个值对该字典进行排序
Function OrderCompareDictionary(UICompareDict, MIPdict)
arrItems = UICompareDict.Items
arrKeys = UICompareDict.Keys
limitkeys = cint(UBound(arrKeys))
numOfCols = Ubound(arrItems(0))    
Set descDict = CreateObject("Scripting.Dictionary")

For k = 0 To limitkeys    
If Ubound(arrItems(k)) = numOfCols Then
    If not (k < 0 or k > UBound(arrKeys))  Then
        If not (k = UBound(arrKeys)) Then
            If arrItems(k)(0) = arrItems(k + 1)(0) Then 
                descDict.Add arrKeys(k) , arrItems(k)
            Else 
                descDict.Add arrKeys(k) , arrItems(k)  'Does not match next value
                Call ReverseSortDescDict(descDict)
                Call CompareAndResetDescDict(descDict, k, MIPdict)
            End If
        Else
            If arrItems(k)(0) = arrItems(k - 1)(0) Then 'Last row matches previous row
                descDict.Add arrKeys(k) , arrItems(k)
                Call ReverseSortDescDict(descDict)
                Call CompareAndResetDescDict(descDict, k, MIPdict)                    
            Else
                descDict.Add arrKeys(k) , arrItems(k)
                Call ReverseSortDescDict(descDict)
                Call CompareAndResetDescDict(descDict, k, MIPdict)                    
            End If
        End If
    Else
        MsgBox "Out of bounds for dictionary array values"
    End If
Else
    MsgBox "Error in comparison"
End If
Next      
End Function

此功能在比较之前按降序排序。包含打印语句以查看字典对象。

Function ReverseSortDescDict(descDict)

Dim i, j, temp
For Each i In descDict
    For Each j In descDict
        If(descDict.Item(i)(1) >= descDict.Item(j)(1)) Then
            temp = descDict.Item(i)
            descDict.Item(i) = descDict.Item(j)
            descDict.Item(j) = temp
        End If
    Next
Next

displayDescDictCount = 0
descDictKeys = descDict.Keys
descDictItems = descDict.Items
For each item in descDictItems 
    print descDictKeys (displayDescDictCount) & " " & item(0) & " " & item(1) & " " & item(2)
    displayDescDictCount = displayDescDictCount + 1
Next

End Function 

答案 2 :(得分:0)

如果您需要沿字典进行一次遍历,则可以使用断开连接的记录集对键进行排序,然后按顺序从字典中检索值,以便从记录集中获取键。

dim rs 'the recordset used to sort keys  must be global
Set D = CreateObject("Scripting.Dictionary") 
for i=1 to 10
d.add right("0000"&Cint(rnd*10000),4), i
next

'
for each j in d.keys
   wscript.echo j & " " & d(j) 
next    
wscript.echo ""

i=0
do
  b= DicNextItem(d,i)
  wscript.echo b(0)&" "&b(1)
loop until i=-1 

'---------------------------------------------

Function DicNextItem(dic,i) 
'returns succesive items from dictionnary ordered by keys
'arguments  dic: the dictionnary
'         i: 0 must be passed at fist call, 
'                 returns 1 if there are more items 
'                 returns-1 if no more items   
'returnas array with the key in index 0 and the value and value in index 1
'requires rs as global variable (no static in vbs)  
'it supposes the key is a string
      const advarchar=200
      const adopenstatic=3
      dim a(2)
      if i=0 then
        Set rs = CreateObject("ADODB.RECORDSET")
        with rs 
        .fields.append "Key", adVarChar, 100
        .CursorType = adOpenStatic
        .open
        'add all keys to the disconnected recordset  
        for each i in Dic.keys
          .AddNew
          rs("Key").Value = i
          .Update
        next
        .Sort= " Key ASC"
        .MoveFirst
        end with
        i=1
       end if
       if rs.EOF then 
         a=array(nul,nul)
       else
         a(0)=rs(0)
     a(1)=dic(a(0))
         rs.movenext
       end if
       if rs.EOF then i=-1:set rs=nothing
       DicNextItem=a
end function