HOME > 即効テクニック > Excel VBA > その他関連のテクニック > 重複データのチェック2 − For Each...NextとFindメソッドを使った方法

重複データのチェック2 − For Each...NextとFindメソッドを使った方法|Excel VBA

その他関連のテクニック

重複データのチェック2 − For Each...NextとFindメソッドを使った方法

(Excel 2000/2002/2003/2007/2010)

次のサンプルは、A列から重複を取り除いたデータをB列に出力します。
重複データのチェック1 − For...Nextのネストを使った方法」と同じ結果が得られますが、今回は、For Each...NextステートメントとRangeオブジェクトのFindメソッドを使用します。

「重複データのチェック1」ではA列の全データ数を取得し、処理の繰り返し回数を指定していましたが、For Each...Nextステートメントを使うと、対象データの数を意識することなく、指定したセル範囲のすべてのセルに対して処理を繰り返すことができます。

ここでは、A列の値がB列にあるかどうかをFindメソッドで検索し、同じ値が検索されなかった場合に、その値をB列の最後に出力します。この処理を、A列のすべてのデータについて繰り返します。
「重複データのチェック1」でB列の値を上から順に1つ1つチェックしていたのにくらべ、処理速度はずっと高速です。

A列、B列とも1行目は見出し行とします。
A列の2行目以降にデータを入力し、重複データも用意して実行してください。

Sub Sample()
    Dim ALastRow As Long, BLastRow As Long
    Dim FoundCell As Range
    Dim c As Range
 
    '結果を表示するB列を空にする
    Columns("B").ClearContents
    Range("B1").Value = "重複なしデータ"
     
    'A列の最終データの行番号を取得
    ALastRow = Cells(Rows.Count, 1).End(xlUp).Row
     
    'B列の最終行番号を1(見出し行のみ)に設定
    BLastRow = 1
     
     
    'A列のデータの数だけ繰り返す
    For Each c In Range("A2:A" & ALastRow)
     
        Set FoundCell = Nothing
        
        'A列の値をB列より検索
        If BLastRow > 1 Then
             Set FoundCell = Range("B2", Cells(BLastRow, 2)) _
                             .Find(c.Value, LookIn:=xlValues, LookAt:=xlWhole)
        End If
        
        '検索されなかったら、B列の最終行番号を1増やし、最終行にA列の値を出力
        If FoundCell Is Nothing Then
            BLastRow = BLastRow + 1
            Cells(BLastRow, 2).Value = c.Value
        End If
    Next c
End Sub

A列の値がB列にあるかどうかをチェックするには、Findメソッドのほかに、ワークシート関数のCOUNTIF関数を使う方法もあります。

それには、For Each...Nextのループ部分を次のように変更します。
数値型の変数CellCountにCOUNTIF関数の戻り値を受け取り、A列と同じ値をもつセルの個数をチェックします。

'A列のデータの数だけ繰り返す
    For Each c In Range("A2:A" & ALastRow)
        
        CellCount = WorksheetFunction.CountIf( _
                        Range("B2", Cells(BLastRow, 2)), c)
        
        '検索されなかったら、B列の最終行番号を1増やし、最終行にA列の値を出力
        If CellCount = 0 Then
            BLastRow = BLastRow + 1
            Cells(BLastRow, 2).Value = c.Value
        End If
    Next c