VBA 中统计重复项使用 Dictionary 非常方便 —— 在无需引用设置的情况下安全地进行汇总

VBA・Officeカテゴリを表すパンダのイラスト VBA・Office

关于本文
本文是通过利用生成式 AI 的自动化生成流程创建的。我们查阅了 Microsoft Learn 的 Dictionary object 规范,重新审查了现有示例,并修正为不删除输入工作表列的结构。

验证状态:📘 已确认官方规范・已完成示例安全性审查・尚未在 Excel 实机上进行验证

VBA 中统计重复项使用 Dictionary 非常方便 —— 在无需引用设置的情况下安全地进行汇总

如果想在 Excel VBA 中通过单次遍历统计“某个相同值有多少条记录”,使用 Scripting.Dictionary 非常方便。通过使用 CreateObject("Scripting.Dictionary"),即使在不添加 VBE 引用设置的 Late Binding 情况下也可以使用它。

这次还有一点很重要,那就是结果的输出方式。我们不应该把输入工作表中看起来空着的整列删掉来写入结果,而是应该输出到专用的结果工作表中。

Dictionary 的思路

Dictionary 拥有“键”和“值”的组合。在这里,我们将单元格的字符串作为键,将出现次数作为值。

东京 -> 3
大阪 -> 2
福岡 -> 1

如果遇到相同的键,则将次数加 1;如果是第一次出现,则以 1 添加。

Set dict = CreateObject("Scripting.Dictionary")

' 将大小写视为相同的键。
' 在添加键之前设置 CompareMode。
dict.CompareMode = vbTextCompare

For row = 2 To lastRow
    key = Trim$(CStr(sourceWs.Cells(row, "A").Value2))

    If Len(key) > 0 Then
        If dict.Exists(key) Then
            dict(key) = CLng(dict(key)) + 1
        Else
            dict.Add key, 1
        End If
    End If
Next row

采用 Late Binding 的理由

如果是 Early Binding,虽然可以直接声明 Scripting.Dictionary 类型,但通常需要对“Microsoft Scripting Runtime”进行引用设置。由于 Late Binding 使用了 ObjectCreateObject,因此可以减少在分发目标环境中因引用设置丢失而无法运行的问题。

另一方面,VBE 的代码补全和类型检查会变弱。在制作教材或内部发布时,可以根据“是希望不需要引用设置”还是“优先考虑开发时的类型辅助”来进行选择。

将输出目标设为专用工作表

在最初的版本中,输入工作表的 C:D 列被 ClearContents 了。但是,如果使用者在那里放了其他数据,就会被删掉。

因此,当前版本创建了 重複集計結果 工作表,并且只重复使用该工作表。

flowchart LR
    A[入力シート A列] --> B[Scripting.Dictionary]
    B --> C[キーごとに件数を加算]
    C --> D[重複集計結果シート]
    D --> E[値 / 件数]

即使是“能运行的代码”,如果不考虑如何处理现有数据,也无法适应实际业务。在这次夜间生成中,我们在写成文章之前也对示例本身进行了修正。

此示例的判定规则

  • 以 A2 及之后的行为对象

  • 使用 Trim$ 去除前后空白

  • 不统计空字符串

  • 因为是 vbTextCompare,所以不区分英文字母的大小写

  • 使用 CStr 将值转换为字符串作为键

例如,对于想要严格区分数字 123 和字符串 "123" 并将它们视为不同事物的用途,这样直接使用并不合适。如果需要连数据类型一起区分,则需要更改键的创建方式。

GitHub 示例

官方信息・一手资料

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
标题和URL已复制