VBA Dictionary (SUMIFのように集計)

項目ごとに集計

セル直接版(初心者向け)

Sub SumScoresByName()

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet2")
    
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare '大小区別なし
    
    Dim lastRow As Long
    With ws
        lastRow = .Cells(.Rows.Count, 1).End(xlUp).row
        .Range("D:E").ClearContents
        .Range("D1").Value = "名前"
        .Range("E1").Value = "合計点"
    End With

    Dim i As Long
    Dim name As String
    Dim score As Double

    ' --- 集計処理(SUMIF相当) ---
    For i = 2 To lastRow
        name = Trim(ws.Cells(i, 1).Value)
        score = Val(ws.Cells(i, 2).Value)
        
        If Len(name) > 0 Then
            If dict.Exists(name) Then
                dict(name) = dict(name) + score
            Else
                dict.Add name, score
            End If
        End If
    Next i

    ' --- 出力(名前・合計点) ---
    Dim key As Variant
    Dim r As Long
    r = 2
    
    With ws
        For Each key In dict.Keys
            .Cells(r, 4).Value = key
            .Cells(r, 5).Value = dict(key)
            r = r + 1
        Next key
    End With
    
    MsgBox "名前ごとの点数集計が完了しました!", vbInformation

End Sub

配列&Dictionary高速版

Sub SumScoresByName2()

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet2")
    
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare '名前の大小区別なし
    
    Dim lastRow As Long
    Dim data As Variant  ' A,B列の2次元配列用
    
    With ws
        lastRow = .Cells(.Rows.Count, 1).End(xlUp).row
        
        ' 見出しと出力列クリア
        .Range("D:E").ClearContents
        .Range("D1").Value = "名前"
        .Range("E1").Value = "合計点"
        
        ' データが1行もない場合は終了
        If lastRow < 2 Then
            MsgBox "集計対象データがありません。", vbInformation
            Exit Sub
        End If
        
        ' A2:B最終行 を2次元配列で取得
        data = .Range("A2:B" & lastRow).Value
    End With

    Dim i As Long
    Dim name As String
    Dim score As Double

    ' --- 集計処理(SUMIF相当) ---
    For i = 1 To UBound(data, 1)
        name = Trim(data(i, 1))
        score = Val(data(i, 2))
        
        If Len(name) > 0 Then
            If dict.Exists(name) Then
                dict(name) = dict(name) + score
            Else
                dict.Add name, score
            End If
        End If
    Next i

    ' --- 結果を配列にまとめる(D,E列用) ---
    Dim result As Variant
    Dim key As Variant
    Dim r As Long
    r = 1
    
    If dict.Count = 0 Then
        MsgBox "有効なデータがありませんでした。", vbInformation
        Exit Sub
    End If
    
    ReDim result(1 To dict.Count, 1 To 2)
    
    For Each key In dict.Keys
        result(r, 1) = key
        result(r, 2) = dict(key)
        r = r + 1
    Next key
    
    ' D2:E に一括書き戻し
    ws.Range("D2").Resize(dict.Count, 2).Value = result
    
    MsgBox "名前ごとの点数集計が完了しました!", vbInformation

End Sub

※ 実行結果は、上記と同じ

SUMIF vs Dictionary集計(高速版)

比較項目SUMIFDictionary+配列
基本用途単一条件の合計高機能 SUMIF
実行速度遅い(繰返し処理が多い)高速(1回走査)
出力形式結果は1セル全結果一覧を作れる
重複データの整理別途 UNIQUE関数等が必要自動で重複統合
計算負荷件数×対象行数行数のみ(スケールしやすい)
容易さ関数1つで簡単コードが必要
空白処理ユーザー依存Trim等を組込み可
大文字小文字区別なしCompareModeで制御可
データ件数が1万以上滅茶苦茶遅くなる抜群に強い
  • SUMIFは簡単で手軽
  • Dictionary集計は 高速で拡張性が高い「SUMIF強化版」
  • 大量データや一覧化が必要な場合はDictionaryが圧倒的に有利

コメント