Excel VBA | 超初心者(Excel操作+マクロ体験):Excelオブジェクト基礎 - Find

Excel VBA VBA
スポンサーリンク

Find は「表の中から“条件に合うセル”を一発で探しに行くためのメソッド」

まずイメージから。
Find は「この範囲の中から“〇〇”という値(文字)を持つセルを探してきて」と頼むためのメソッドです。

手作業だと Ctrl+F で「検索」しますよね。
その「検索」を VBA でやるのが Range.Find です。

ポイントは次の3つです。

どの範囲の中を探すか(検索対象の Range)
何を探すか(What)
見つかったら、そのセル(Range オブジェクト)が返ってくる

この3つをセットでイメージできるようになると、一気に扱いやすくなります。


一番基本:範囲の中から「最初に見つかった1件」を探す

A列の中から「山田」を探す

Sub SampleFindBasic()

    Dim ws As Worksheet
    Dim rngSearch As Range
    Dim c As Range

    Set ws = ThisWorkbook.Worksheets("顧客一覧")
    Set rngSearch = ws.Range("A:A")   ' A列全体を検索対象にする

    Set c = rngSearch.Find(What:="山田", LookAt:=xlWhole)

    If Not c Is Nothing Then
        MsgBox "山田さんは " & c.Address & " にいます。"
    Else
        MsgBox "山田さんは見つかりませんでした。"
    End If

End Sub
VB

ここでやっていることを分解します。

検索対象の範囲を rngSearch に入れる(ここでは A列全体)
rngSearch.Find(...) で「山田」を探す
見つかったら、そのセルを表す Range オブジェクトが c に入る
見つからなかったら c は Nothing のまま

超重要なのは、「Find は“セルのアドレス”ではなく“セルそのもの(Range)”を返す」ということです。
だから c.Address で住所を聞いたり、c.Offset で隣のセルを触ったりできます。


Find の主な引数を、必要な分だけ押さえる

What(何を探すか)

Set c = rngSearch.Find(What:="山田")
VB

探したい文字列や数値を指定します。
文字列なら "山田", "ABC", "2024-01" など。

LookAt(完全一致か、部分一致か)

LookAt:=xlWhole    ' 完全一致(セルの中身が「山田」ちょうど)
LookAt:=xlPart     ' 部分一致(「山田太郎」「山田さん」もヒット)
VB

例えば、セルに「山田太郎」と入っている場合、

LookAt:=xlWhole → ヒットしない
LookAt:=xlPart → ヒットする

という違いになります。

まずは「完全一致なら xlWhole、あいまいなら xlPart」と覚えておけば十分です。

LookIn(どこを見るか:値/数式など)

超初心者のうちは、正直ここは一旦固定で構いません。

LookIn:=xlValues   ' 表示されている値を対象に検索
VB

と書いておけば、「見えている値」で検索してくれます。


見つかったセルを起点に「周りの情報」を取る

見つかった行の、別の列の値を読む

例えば、「A列で“山田”を探して、その行の C列(電話番号)を取りたい」場合。

Sub SampleFindGetOtherColumn()

    Dim ws As Worksheet
    Dim rngSearch As Range
    Dim c As Range

    Set ws = ThisWorkbook.Worksheets("顧客一覧")
    Set rngSearch = ws.Range("A:A")

    Set c = rngSearch.Find(What:="山田", LookAt:=xlWhole)

    If Not c Is Nothing Then
        MsgBox "山田さんの電話番号は " & c.Offset(0, 2).Value & " です。"
    Else
        MsgBox "山田さんは見つかりませんでした。"
    End If

End Sub
VB

ここでのポイントは、

c は「山田」が見つかったセル(A列のどこか)
c.Offset(0, 2) は「同じ行の2列右」、つまり C列

という関係です。

Find で「起点のセル」をつかまえてしまえば、
Offset や EntireRow などで、その行全体を自由に扱えるようになります。


同じ値が複数ある場合に「全部」見つけたいとき

Find と FindNext を使って、全ヒットを回る

Find は「最初の1件」を返しますが、
FindNext と組み合わせることで「次のヒット」「次のヒット」と順番に回れます。

典型パターンはこれです。

Sub SampleFindAll()

    Dim ws As Worksheet
    Dim rngSearch As Range
    Dim c As Range
    Dim firstAddress As String

    Set ws = ThisWorkbook.Worksheets("顧客一覧")
    Set rngSearch = ws.Range("A:A")

    Set c = rngSearch.Find(What:="山田", LookAt:=xlWhole)

    If Not c Is Nothing Then

        firstAddress = c.Address   ' 最初に見つかったセルの住所を覚えておく

        Do
            ' 見つかったセルごとに処理を書く(例:メッセージ表示)
            Debug.Print "見つかった場所: " & c.Address

            ' 次の「山田」を探す
            Set c = rngSearch.FindNext(After:=c)

        Loop While Not c Is Nothing And c.Address <> firstAddress

    End If

End Sub
VB

流れを言葉で説明すると、

まず最初の1件を Find で見つける
そのセルの Address を firstAddress に保存しておく
Do ~ Loop の中で、見つかったセルに対する処理を書く
FindNext で「次のヒット」を探す
ぐるっと一周して最初のセルに戻ってきたら終了

という感じです。

ここでの超重要ポイントは、「firstAddress を覚えておいて、一周したら止める」ことです。
これを忘れると、無限ループになります。


Find を使うときに意識してほしい重要ポイント

「検索対象の範囲」を必ず Range で握る

避けたい書き方の例です。

Cells.Find What:="山田"
VB

これは「シート全体」を対象にしてしまうので、
どこにヒットするかが読みにくくなります。

超初心者のうちは、必ずこういう形にしてください。

Set rngSearch = ws.Range("A:A")          ' A列だけ
Set rngSearch = ws.Range("A1:C1000")     ' 表の範囲だけ
Set rngSearch = ws.UsedRange             ' 使われている範囲だけ
VB

「どこを探すか」を自分で決めて、その Range に対して Find を呼ぶ、というスタイルです。

「見つからなかったとき」の分岐を必ず書く

Find は、見つからなかったときにエラーにはなりません。
その代わり、戻り値が Nothing になります。

だからこそ、毎回この形をセットで書いてください。

Set c = rngSearch.Find(What:="山田", LookAt:=xlWhole)

If Not c Is Nothing Then
    ' 見つかったときの処理
Else
    ' 見つからなかったときの処理
End If
VB

これをサボると、「見つからなかったのに c を使おうとしてエラー」が起きます。
「Find を使うなら If Not c Is Nothing Then までがワンセット」と覚えてしまいましょう。


まとめ:Find は「範囲の中から“条件に合うセル”を見つけ、そのセルを起点に処理するためのメソッド」

Find の本質は、

「指定した Range の中から、指定した条件(What, LookAt など)に合うセルを探し、そのセルを表す Range を返す」

ことです。

押さえておきたいポイントをコンパクトにまとめると、

検索対象の Range を決めてから、その Range に対して Find を呼ぶ
戻り値は「セルそのもの(Range)」なので、Address や Offset で周りも扱える
見つからなかったときは Nothing になるので、If Not c Is Nothing Then を必ず書く
複数ヒットを全部回したいときは、Find+FindNext+firstAddress で一周する

タイトルとURLをコピーしました