You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA中按嵌套类对象属性排序字典后如何保留并输出对应ID键

VBA中按嵌套类对象属性排序字典后如何保留并输出对应ID键

哎,这个问题我太懂了!你现在的情况是只把字典里的类对象单独抽出来排序,结果和对应的ID键断了联系对吧?别着急,咱们有两种简单的办法解决这个问题,既能按属性排序,又能保留ID和对象的对应关系。

方法一:打包Key和对象一起排序(无需修改类)

这个思路是把字典的ID键和对应的类对象绑定到同一个数组元素里,排序的时候同时交换两者,这样排序后每个位置都能同时拿到ID和对象的属性。

修改后的完整代码示例

首先调整你的Tester过程,把Key和对象一起存入数组:

Sub Tester()
    Dim dict As Object, i As Long, e As Variant
    Dim arr() As Variant, idx As Long
    
    Set dict = CreateObject("scripting.dictionary")
    
    ' 生成测试数据
    For i = 1 To 10
        dict.Add "ID" & i, GetTestObject(i, -i, "Job_" & i)
    Next i
    
    ' 创建一个二维数组:第一列存ID键,第二列存类对象
    ReDim arr(1 To dict.Count, 1 To 2)
    idx = 1
    For Each e In dict.Keys
        arr(idx, 1) = e
        Set arr(idx, 2) = dict(e)
        idx = idx + 1
    Next e
    
    ' 调用带Key的排序方法,按Salary降序排列
    SortObjectsWithKeys arr, "Salary"
    
    ' 输出排序后的结果(包含ID)
    Debug.Print "---------By Salary (Highest to Lowest)-------"
    Debug.Print "ID", "Salary", "Revenue", "Position"
    For i = LBound(arr, 1) To UBound(arr, 1)
        Debug.Print arr(i, 1), arr(i, 2).Salary, arr(i, 2).Revenue, arr(i, 2).Position
    Next i
End Sub

然后新增一个支持Key+对象排序的子过程:

' 排序包含ID键和类对象的二维数组,按指定属性排序
Sub SortObjectsWithKeys(arr As Variant, propName As String)
    Dim First As Long, Last As Long, i As Long, j As Long
    Dim tempKey As String, tempObj As Object
    Dim valI As Variant, valJ As Variant
    
    First = LBound(arr, 1)
    Last = UBound(arr, 1)
    
    ' 冒泡排序逻辑,同时交换Key和对象
    For i = First To Last - 1
        For j = i + 1 To Last
            ' 获取两个对象的指定属性值
            valI = CallByName(arr(i, 2), propName, VbGet)
            valJ = CallByName(arr(j, 2), propName, VbGet)
            
            ' 降序排序(如果要升序,改成valI > valJ即可)
            If valI < valJ Then
                ' 交换ID键
                tempKey = arr(i, 1)
                arr(i, 1) = arr(j, 1)
                arr(j, 1) = tempKey
                
                ' 交换对应的类对象
                Set tempObj = arr(i, 2)
                Set arr(i, 2) = arr(j, 2)
                Set arr(j, 2) = tempObj
            End If
        Next j
    Next i
End Sub

原来的GetTestObject函数和Class1可以完全不用修改,直接用就行。

方法二:给类添加ID属性(需修改类定义)

如果你允许修改Class1的结构,可以直接给类加一个ID属性,在把对象存入字典时,同步把ID赋值给对象自身。这样排序后,直接从对象里就能拿到ID,不用管字典的Key了。

步骤1:修改Class1

打开你的Class1模块,新增一个公共属性:

Public Salary As Double
Public Revenue As Double
Public Position As String
Public ID As String ' 新增ID属性

步骤2:调整Tester过程的赋值逻辑

Sub Tester()
    Dim dict As Object, i As Long, itms, e As Variant
    Dim obj As Class1
    
    Set dict = CreateObject("scripting.dictionary")
    
    ' 生成测试数据时,给对象绑定ID
    For i = 1 To 10
        Set obj = GetTestObject(i, -i, "Job_" & i)
        obj.ID = "ID" & i ' 把ID赋值给对象自身
        dict.Add "ID" & i, obj
    Next i
    
    itms = dict.Items
    
    ' 调用原来的SortObjects方法即可
    SortObjects itms, "Salary"
    
    ' 输出时直接从对象取ID
    Debug.Print "---------By Salary (Highest to Lowest)-------"
    Debug.Print "ID", "Salary", "Revenue", "Position"
    For Each e In itms
        Debug.Print e.ID, e.Salary, e.Revenue, e.Position
    Next e
End Sub

这个方法更简洁,但需要修改类的定义,适合你有权限修改类的场景。

两种方法的对比

  • 方法一:无需修改原有类结构,对现有代码侵入性小,适合不能修改类的情况。
  • 方法二:代码更简洁,后续使用对象时随时能拿到ID,适合可以调整类定义的场景。

你可以根据自己的实际需求选其中一种,两种方法都能完美解决你“排序后丢失ID对应关系”的问题~

备注:内容来源于stack exchange,提问作者Erba Aitbayev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 09:03:03