hiko-blog

VBA業務改善

MENU

KEYを作って最新のもの抽出

Sub KEYを作って最新のもの抽出()
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim lastRow As Long, i As Long, j As Long
    Dim dict As Object
    Dim dictKey As Variant ' ディクショナリのキーを格納する変数
    
    ' シート1とシート2を設定
    Set ws1 = ThisWorkbook.Sheets("Sheet1")
    Set ws2 = ThisWorkbook.Sheets("Sheet2")
    
    ' シート2を初期化
    ws2.Cells.Clear
    
    ' シート1の最終行を取得
    lastRow = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
    
    ' ディクショナリを作成
    Set dict = CreateObject("Scripting.Dictionary")
    
    ' シート1からデータを読み込み
    For i = 2 To lastRow
        Dim 項目1 As String
        項目1 = Trim(ws1.Cells(i, 1).Value) ' 項目1を文字列として取得
        
        Dim 項目2 As String
        項目2 = Format(ws1.Cells(i, 2).Value, "000") ' 3桁のゼロ埋め形式で項目2を取得
        
        Dim 項目3 As String
        項目3 = Trim(ws1.Cells(i, 3).Value) ' 項目3を文字列として取得
        
        dictKey = 項目1 & "_" & 項目2 & "_" & 項目3 ' 項目1_項目2_項目3
        
        If Not dict.exists(dictKey) Then
            Set dict(dictKey) = CreateObject("Scripting.Dictionary")
        End If
        
        ' 内部のディクショナリを取得
        Dim innerDict As Object
        Set innerDict = dict(dictKey)
        
        Dim 項目4 As String
        項目4 = Format(ws1.Cells(i, 4).Value, "000") ' 3桁のゼロ埋め形式で項目4を取得
        
        Dim innerKey As Variant
        innerKey = 項目4 & "_" & Trim(ws1.Cells(i, 6).Value) ' 項目4と日付を組み合わせてキーを作成
        
        If Not innerDict.exists(innerKey) Then
            innerDict(innerKey) = Array(項目1, 項目2, 項目3, 項目4, ws1.Cells(i, 5).Value, ws1.Cells(i, 6).Value)
        End If
    Next i
    
    ' シート2にヘッダーを設定
    ws2.Cells(1, 1).Value = "項目1"
    ws2.Cells(1, 2).Value = "項目2"
    ws2.Cells(1, 3).Value = "項目3"
    ws2.Cells(1, 4).Value = "項目4"
    ws2.Cells(1, 5).Value = "単価"
    ws2.Cells(1, 6).Value = "適用日"
    
    ' ディクショナリからデータを抽出し、シート2に書き込み
    j = 2
    For Each dictKey In dict.Keys
        Dim maxKey As String
        Dim max項目4 As Long
        Dim max適用日 As Date
        
        max項目4 = -1
        max適用日 = DateSerial(1900, 1, 1) ' Excelで扱える最小の日付
        
        ' グループ内の最大項目4と最新適用日を見つける
        For Each innerKey In dict(dictKey).Keys
            Dim values As Variant
            values = Split(innerKey, "_")
            
            Dim項4 As Long
            Dim 適用日 As Date
            
           項4 = CLng(values(0))
            適用日 = CDate(values(1))
            
            If項4 > max項目4 Or (職 = max項目4 And 適用日 > max適用日) Then
                max項目4 =項4
                max適用日 = 適用日
                maxKey = innerKey
            End If
        Next innerKey
        
        ' シート2に書き込み
        Dim outputData As Variant
        outputData = dict(dictKey)(maxKey)
        ws2.Cells(j, 1).Resize(1, 6).Value = outputData
        j = j + 1
    Next dictKey
    Call 表示3桁
    
    MsgBox "データ抽出が完了しました。", vbInformation
End Sub