基于CallByName的自定义CReliability类集合去重计数技术问询
刚好之前处理过类似的自定义类集合去重计数需求,结合CallByName的话可以很灵活地实现,我给你梳理下具体的实现步骤和代码:
实现思路
首先我们需要借助字典来跟踪唯一的属性值(或属性组合),同时用CallByName动态操作自定义类的属性,避免硬编码每个属性名。核心步骤是:
- 遍历原始集合中的每个CReliability对象
- 提取指定属性的值,生成唯一标识键
- 用字典判断该键是否已存在,不存在则创建新对象并添加到目标集合,存在则更新计数
- 全程用CallByName来读写属性,保持代码的通用性
代码实现
首先假设你的CReliability类模块定义如下(如果已有属性,只需要添加一个Count属性用于计数即可):
' 类模块:CReliability Public Category As String ' 示例属性1 Public Status As String ' 示例属性2 Public Metric As Double ' 示例属性3 Public Count As Integer ' 用于存储该属性组合的出现次数
然后是核心处理函数:
Sub ProcessReliabilityCollection(rawCol As Collection, newCol As Collection, ParamArray propertyNames() As Variant) Dim rawRel As CReliability Dim newRel As CReliability Dim propValue As Variant Dim dict As Object Dim propName As Variant Dim uniqueKey As String ' 初始化字典用于跟踪唯一属性组合 Set dict = CreateObject("Scripting.Dictionary") ' 遍历原始集合中的每个CReliability对象 For Each rawRel In rawCol ' 生成唯一键:拼接所有指定属性的值(用于多属性组合去重) uniqueKey = "" For Each propName In propertyNames ' 用CallByName动态获取属性值 propValue = CallByName(rawRel, propName, VbGet) uniqueKey = uniqueKey & "|" & CStr(propValue) Next propName uniqueKey = Mid(uniqueKey, 2) ' 移除开头的分隔符 ' 检查该属性组合是否已存在 If Not dict.Exists(uniqueKey) Then ' 创建新的CReliability对象 Set newRel = New CReliability ' 用CallByName动态设置新对象的属性 For Each propName In propertyNames CallByName newRel, propName, VbLet, CallByName(rawRel, propName, VbGet) Next propName newRel.Count = 1 ' 初始化计数为1 newCol.Add newRel ' 记录新对象在目标集合中的索引,方便后续更新计数 dict.Add uniqueKey, newCol.Count Else ' 找到已存在的对象,增加计数 Set newRel = newCol(dict(uniqueKey)) newRel.Count = newRel.Count + 1 End If Next rawRel End Sub
使用示例
比如你有两个集合:rawCollection(存放原始CReliability对象)和newCollection(空集合,用于存放去重后的结果),如果要按Category属性去重并计数,调用方式如下:
Dim rawCollection As New Collection Dim newCollection As New Collection ' 先往rawCollection添加原始CReliability对象(这里省略添加逻辑) ' 调用处理函数,指定按Category属性去重 ProcessReliabilityCollection rawCollection, newCollection, "Category"
如果需要按Category和Status的组合去重,只需要多传一个属性名:
ProcessReliabilityCollection rawCollection, newCollection, "Category", "Status"
关键说明
- CallByName的作用:它让我们可以通过字符串形式的属性名来读写对象属性,不用硬编码每个属性,比如如果后续CReliability类新增了属性,只需要在调用函数时传入新属性名即可,不用修改函数内部逻辑。
- 字典的作用:快速判断属性组合是否已存在,同时记录目标集合中对应对象的位置,避免每次都遍历目标集合查找,提升效率。
- 分隔符选择:示例中用
|作为属性值的分隔符,要确保你的属性值中不会出现这个字符,如果有冲突可以换成其他符号比如~。 - 属性访问权限:确保CReliability类的属性是
Public的,否则CallByName无法访问。
内容的提问来源于stack exchange,提问作者Nick Thalken
相关产品推荐
相关产品推荐

