Excel VBA 逆引き集 | FINDALL(全件検索)

Excel VBA
スポンサーリンク

FINDALL(全件検索)

複数の一致を一気に拾い上げて処理するなら、Range.Find + FindNext が定番です。最初のヒットのアドレスを覚えて一周したら終了、という型を覚えれば初心者でも安全に「全件検索」を扱えます。


基本:Find → FindNext の全件列挙テンプレ

Sub FindAll_Basic()
    Dim rng As Range, hit As Range, first As String
    Set rng = Range("A2:A10000")

    Set hit = rng.Find(What:="ERROR", LookAt:=xlPart, LookIn:=xlValues) '部分一致で値を検索
    If hit Is Nothing Then Exit Sub

    first = hit.Address
    Do
        Debug.Print "ヒット: " & hit.Address & " 値=" & hit.Value
        Set hit = rng.FindNext(hit)
    Loop While Not hit Is Nothing And hit.Address <> first
End Sub
VB
  • ポイント:
    • first を記録し一周で終了: 最初のヒット住所に戻ったらループを終えるのが定石。
    • LookAt/LookIn を毎回明示: Find は設定を保持するため、意図しない検索を防げます。

応用:全ヒットをまとめて処理(Unionで集合化)

Sub FindAll_UnionAndProcess()
    Dim rng As Range, hit As Range, first As String, allHits As Range
    Set rng = Range("A2:A50000")

    Set hit = rng.Find(What:="WARN", LookAt:=xlPart, LookIn:=xlValues)
    If hit Is Nothing Then Exit Sub

    first = hit.Address
    Set allHits = hit

    Do
        Set hit = rng.FindNext(hit)
        If hit Is Nothing Then Exit Do
        If hit.Address = first Then Exit Do
        Set allHits = Union(allHits, hit)
    Loop

    '一括処理:色付けや別シートへコピーなど
    allHits.Interior.Color = RGB(255, 235, 156)
    Worksheets("抽出").Range("A2").Resize(allHits.Count, 1).Value = Application.Transpose(allHits.Value)
End Sub
VB
  • ポイント:
    • Unionで一括対象を作る: 集合化してから書式やコピーを一度に適用できる。
    • FindNextは自動終了しない: 自分で「一周確認」する必要がある。

見出し検索と行・列への展開

'列見出しを探して列番号を取得 → その列だけ処理
Sub FindAll_HeaderColumn()
    Dim headRow As Range, hit As Range
    Set headRow = Range("A1:Z1")
    Set hit = headRow.Find(What:="単価", LookAt:=xlWhole, LookIn:=xlValues)
    If Not hit Is Nothing Then
        Dim colNo As Long: colNo = hit.Column
        Range(Cells(2, colNo), Cells(10000, colNo)).Value = _
            Range(Cells(2, colNo), Cells(10000, colNo)).Value
    End If
End Sub

'1件ヒットした行で横展開の計算
Sub FindAll_RowProcess()
    Dim hit As Range
    Set hit = Range("A2:A10000").Find(What:="顧客1001", LookAt:=xlWhole, LookIn:=xlValues)
    If Not hit Is Nothing Then
        Dim r As Long: r = hit.Row
        Cells(r, "H").Value = Val(Cells(r, "C").Value) * Val(Cells(r, "D").Value)
    End If
End Sub
VB
  • ポイント:
    • 見出し検索に向く: 完全一致で見出しを特定して安全に列番号を取る。
    • 行番号利用: hit.Row で同じ行の別列へアクセスが簡単。

複数キーワードの全件検索(誤ヒット抑制付き)

Sub FindAll_MultiKeywords()
    Dim kw As Variant: kw = Array("ERROR", "WARN", "CRITICAL")
    Dim src As Range: Set src = Range("A2:A80000")
    Dim i As Long, first As String, hit As Range

    For i = LBound(kw) To UBound(kw)
        Set hit = src.Find(What:=kw(i), LookAt:=xlPart, LookIn:=xlValues, MatchCase:=False, SearchOrder:=xlByRows)
        If hit Is Nothing Then GoTo NextKw

        first = hit.Address
        Do
            '誤ヒットを減らすなら前後を検査(例:区切り記号など)
            If InStr(1, hit.Value, kw(i), vbTextCompare) > 0 Then
                hit.Font.Color = vbRed
            End If
            Set hit = src.FindNext(hit)
        Loop While Not hit Is Nothing And hit.Address <> first
NextKw:
    Next i
End Sub
VB
  • ポイント:
    • LookAt/LookIn/MatchCase を都度指定: 設定保持に影響されないように。
    • FindNextの巡回はキーワードごとに完結: 状態混線を防げます。

安全・高速ラップ(業務テンプレ)

Sub FindAll_SafeWrap()
    Dim scr As Boolean: scr = Application.ScreenUpdating
    Dim ev As Boolean: ev = Application.EnableEvents
    Dim calc As XlCalculation: calc = Application.Calculation
    On Error GoTo Cleanup

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual

    '=== ここにFind/FindNextの本処理を記述 ===

Cleanup:
    Application.Calculation = calc
    Application.EnableEvents = ev
    Application.ScreenUpdating = scr
End Sub
VB
  • ポイント:
    • 設定退避→復帰: エラー時でも環境を元に戻す。大量検索の体感速度も向上します。

よくある落とし穴と対策

  • 設定が保持されて意図と違う検索になる:
    • 対策: 毎回 LookAt・LookIn・MatchCase を明示する。
  • FindNextが終わらず無限ループ:
    • 対策: 最初のヒットの Address を記録し、戻ってきたら終了。
  • 完全一致のつもりが部分一致で拾ってしまう:
    • 対策: LookAt:=xlWhole を使い、必要なら前後条件や区切りで確認。
  • 数式が対象なのに見つからない:
    • 対策: LookIn:=xlFormulas を使う。値なら xlValues。
  • 大量件数で遅い:
    • 対策: ヒットを Union で集合化し一括処理。書式やコピーを最小回数にする。
タイトルとURLをコピーしました