【ExcelVBA】Findメソッドの使い方とは?エラーの対策も解説!

仕事効率化
スポンサーリンク

あなたは、VBAでFindメソッドを使ったことがありますか?

  • VBAで任意のキーワードを使って検索したい
  • 同じ列から同条件で繰り返し検索をしたい
  • Findメソッドを使う方法が知りたい!
という方もいるのではないでしょうか。

そこで今回は、任意のキーワードで検索ができるFindメソッドについて、エラー回避方法や実例も含めて紹介します。

スポンサーリンク

VBAでのFindメソッドの使い方

Findメソッドの基本的な使い方

  1. 基本構文
対象オブジェクトFind(検索値, [検索開始位置], [検索対象形式], [検索方法], [検索方向], [検索順], [比較形式1(大文字・小文字)], [比較形式2(全角・半角)], [書式検索])
  • Findメソッドが返すのは「Rangeオブジェクト」
  • 「LookAt」が「xlWhole」なら完全一致、「xlPart」なら部分一致
  • 「LookAt」を一度も指定していない場合は「部分一致」となる
  1. コード例
ActiveSheet.Rangge("A1:A10").Find("ABC", LookAt:=xlWhole)
アクティブシート上「A1:A10」の範囲から、文字列「ABC」で完全一致した値を持つ「Rangeオブジェクト」を返します。
01_VBAFindイメージ 例では、検索開始位置(=After)を省略しているので、検索開始位置は一つ目のセル「A1」の次のセルからとなります。よってコード例は、Rangeオブジェクト「A10」を返します。

Findメソッドの引数について

Findメソッドの引数一覧

引数省略既定値詳細
検索値(What)省略不可検索する値を設定
検索開始位置(After)省略可検索を開始するセルを指定(指定したセルの次のセルから検索開始)
検索対象形式(LookIn)省略可最後に指定した値
(一度も指定していない場合は「xlFormulas」)
「xlFormulas」:セルを数式で検索
「xlValues」:セルを値で検索
「xlComments」:セルをコメントで検索
検索方法(LookAt)省略可最後に指定した値
(一度も指定していない場合は「xlPart」)
「xlPart」:部分一致で検索
「xlWhole」:完全一致で検索
検索方向(SearchOrder)省略可最後に指定した値
(一度も指定していない場合は「xlRows」)
「xlRows」:対象範囲を行方向に検索
「xlColumns」:対象範囲を列方向に検索
検索順(SearchDirection)省略可xlNext「xlNext」:上から下・左から右に検索
「xlPrevious」:下から上・右から左に検索
比較形式1(MatchCase)省略可False「True」:大文字と小文字を区別して検索
「False」:大文字と小文字を区別しないで検索
比較形式2(MatchByte)省略可最後に指定した値
(一度も指定していない場合は「False」)
「True」:全角と半角を区別して検索
「False」:全角と半角を区別しないで検索
書式検索(SearchFormat)省略可最後に指定した値
(一度も指定していない場合は「False」)
「True」:セルに設定された書式で検索する
「False」:セルの値で検索
Findメソッドは「検索値(= What)」以外の全ての引数が省略可能ですが、以前の指定やシート上での手動操作の設定を引き継ぐ引数も多いです。Findメソッドより処理も早く、予期せぬ操作で条件が変わらない「Match関数」もあわせて覚えておきましょう。

Findメソッドの検索開始位置について

Findメソッドでは、第二引数「検索開始位置(After)」を使って、検索開始位置を指定できます。引数には「Rangeオブジェクト」を指定します。

この時、指定した「Rangeオブジェクト」はFindメソッドで検索される対象範囲内に含まれている必要があります。また「検索開始位置(After)」に指定した「Rangeオブジェクト」の次のセルから検索が開始されるので、注意が必要です。
  • コード例
ActiveSheet.Rangge("A1:A10").Find("ABC", After:=ActiveSheet.Rangge("A3")
アクティブシート上「A1:A10」の範囲から、文字列「ABC」と一致する値を持つ「Rangeオブジェクト」を検索します。引数「After」には「A3」セルを指定しているので、その次のセル「A4」セルから検索が開始されます。
02_VBAFind検索開始位置 画像のように「A4」セルから下に向かって検索されるので、最初に検索値「ABC」と一致するRangeオブジェクト「A10」が返り値となります。

Findメソッドと組み合わせて使うFindNextメソッド

FindNextメソッドの使い方

「FindNext」メソッドは、Findメソッドと組み合わせて、同条件で上から下・左から右に向かって繰り返し検索ができます。同じ対象範囲で複数の検索結果があるか調べる時に便利です。
  1. コード例
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'一つ目の結果を定義
Dim findRng As Range
Set findRng = trgtRng.Find("ABC", LookAt:=xlWhole)

'一つ目の結果がない場合、FindNextメソッドがエラーとなるので、条件分岐
If Not findRng Is Nothing Then
    MsgBox findRng.Address & vbCrLf & trgtRng.FindNext(findRng).Address
End If
はじめに、「サンプル」シートの「A1:A10」を検索対象範囲「trgtRng」に定義しています。次に「Find」メソッドを使って、セルの値が「ABC」と完全一致するRangeオブジェクトを「findRng」に定義しています。

続く「If文」で「Not findRng Is Nothing」つまり、「findRng」がRangeオブジェクトであるかどうかを判定しています。はじめの「Find」メソッドで検索値と一致するセルがなかった場合に、次の「FindNext」メソッドでエラーが出てしまうため、判定を行っています。

最後に、はじめに「Find」メソッドで求めたRangeオブジェクトと「FindNext」でその次に見つかるRangeオブジェクトのセル番地をMsgBoxで表示しています。
03_VBAFindNextイメージ よって、処理結果は次のようになります。
04_VBAFindNextMsgBox

FindPreviousメソッドで逆順検索

「FindPrevious」メソッドは「FindNext」メソッドと同様、Findメソッドと組み合わせて、同条件で下から上・右から左へと逆順に繰り返し検索できます。同じ対象範囲で複数の検索結果があるか調べる時に便利です。
  1. コード例
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'一つ目の結果を定義
Dim findRng As Range
Set findRng = trgtRng.Find("ABC", LookAt:=xlWhole)

'一つ目の結果がない場合、FindPreviousメソッドがエラーとなるので、条件分岐
If Not findRng Is Nothing Then
    MsgBox findRng.Address & vbCrLf & trgtRng.FindPrevious(findRng).Address
End If
はじめに、「サンプル」シートの「A1:A10」を検索対象範囲「trgtRng」に定義しています。次に「Find」メソッドを使って、セルの値が「ABC」と完全一致するRangeオブジェクトを「findRng」に定義しています。

続く「If文」で「Not findRng Is Nothing」つまり、「findRng」がRangeオブジェクトであるかどうかを判定しています。はじめの「Find」メソッドで検索値と一致するセルがなかった場合に、次の「FindPrevious」メソッドでエラーが出てしまうため、判定を行っています。

最後に、はじめに「Find」メソッドで求めたRangeオブジェクトと「FindPrevious」でその次に見つかるRangeオブジェクトのセル番地をMsgBoxで表示しています。
05_VBAFindPreviousイメージ よって、処理結果は次のようになります。
06_VBAFindPreviousMsgBox

Findメソッド使用時によく起こるエラーと回避方法

Findメソッド使用時によく起こるエラー

便利なFindメソッドですが、エラーによってマクロ処理が中断されてしまうこともあります。よくあるエラーをサンプルコードで紹介します。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'検索結果を定義
Dim findRng As Range
Set findRng = trgtRng.Find("あいう", LookAt:=xlWhole)

'検索結果のセル番地をMsgBoxに表示
MsgBox findRng.Address
07_VBAFindエラーシートイメージ 「サンプル」シート「A1:A10」が上の画像のようになっている場合、サンプルコードを実行すると次のエラーがでます。
08_VBAFindエラー サンプルコードでは「trgtRng.Find(“あいう”, LookAt:=xlWhole)」の検索結果が見つからず「findRng」にRangeオブジェクトが定義されていません。その後、最終行のMsgBox内で「findRng」にRangeオブジェクトのセル番地を取得する「Address」を使用しているためエラーとなります。

このように「Find」メソッドは、検索結果が見つからない場合に「Nothing」を返すので、「Find」メソッドで定義した変数をオブジェクトとして扱う場合にエラーが起きる可能性があります。

エラー回避方法

「Find」メソッド使用時によくあるエラーは、「Nothing」を返したにも関わらず、Rangeオブジェクトとして処理を行ってしまうことです。

このエラーは、次の点に気を付けておけば回避することができます。
  • 「Rangeオブジェクト」かどうかの判定を入れる
このエラー回避を先ほどのサンプルコードに追加すると次のようになります。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'検索結果を定義
Dim findRng As Range
Set findRng = trgtRng.Find("あいう", LookAt:=xlWhole)

'「findRng」がNothingでないか判定
If Not findRng Is Nothing Then
    '検索結果のセル番地をMsgBoxに表示
    MsgBox findRng.Address
End If
MsgBoxを実行する前に、If文「If Not findRng Is Nothing Then」を使って「findRng」が「Nothing」でないかどうか、つまり「findRng」が「Rangeオブジェクト」かどうかを判定しています。
この処理を入れることで、検索結果が見つかった場合のみ処理を実行することができ、エラーを防ぐことができます。

「Find」メソッドを使う際は、必ず入れるようにしっかり覚えておきましょう。
If文については、下記でも詳しく解説しているので、読んでみてください。

Findメソッドで使えるその他の検索方法

And検索

Findメソッドで見つかったセルが、別の条件も満たしているかを判定して処理を実行すればAnd検索を行うことができます。

サンプルコードを使って「C」が含まれ、かつ「A」で始まるセルの番地をMsgBoxで表示する処理を解説します。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'And検索のために文字列を定義
Dim strtStr As String
strtStr = "A"
Dim keyword As String
keyword = "C"

'初めの検索結果を定義
Dim firstRng As Range
Set firstRng = trgtRng.Find(keyword, LookAt:=xlPart)

'検索結果を表示するメッセージを格納する変数
Dim buf As String

'「firstRng」がNothingでないか判定
If Not firstRng Is Nothing Then
    '二つ目以降のセルを格納する変数を定義
    Dim findRng As Range
    Set findRng = firstRng
    '複数条件に一致するまでループ処理
    Do
        If findRng.Value Like strtStr & "*" Then
            '検索結果のセル番地をbufに追加(二つ目以降は改行も追加)
            If buf = "" Then
                buf = findRng.Address
            Else
                buf = buf & vbCrLf & findRng.Address
            End If
        End If
        Set findRng = trgtRng.FindNext(findRng)
    Loop Until findRng.Address = firstRng.Address
End If

'条件に一致する結果がある場合(表示するメッセージがある場合)MsgBox表示
If buf <> "" Then
    MsgBox buf
End If
まず、次の部分で検索対象範囲「trgtRng」、判定に使う文字列「strtStr」「keyword」、初めの検索結果「firstRng」を定義しています。「firstRng」は、検索値に「keyword」、検索条件に「部分一致」を指定して検索を行います。また、MsgBoxに表示する文字列を格納する「buf」も定義しています。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'And検索のために文字列を定義
Dim strtStr As String
strtStr = "A"
Dim keyword As String
keyword = "C"

'初めの検索結果を定義
Dim firstRng As Range
Set firstRng = trgtRng.Find(keyword, LookAt:=xlPart)

'検索結果を表示するメッセージを格納する変数
Dim buf As String
次に、初めの検索結果があったかどうかを判定して、あった場合は2つ目以降の結果を格納する「findRng」を定義します。また、この後の処理で「FindNext」メソッドを使用するため「findRng」に初めの検索結果「firstRng」を代入します。

続いて、複数条件の2つ目の条件である、セルの値が「strtStr(= “A”)」で始まるかどうかを「Do Loop」を使って「keyword(= “C”)」を含む全検索結果について判定しています。この条件に一致した場合は、最後にMsgBoxで表示する文字列「buf」にセル番地を代入します。
'「firstRng」がNothingでないか判定
If Not firstRng Is Nothing Then
    '二つ目以降のセルを格納する変数を定義
    Dim findRng As Range
    Set findRng = firstRng
    '複数条件に一致するまでループ処理
    Do
        If findRng Like strtStr & "*" Then
            '検索結果のセル番地をbufに追加(二つ目以降は改行も追加)
            If buf = "" Then
                buf = findRng.Address
            Else
                buf = buf & vbCrLf & findRng.Address
            End If
        End If
        Set findRng = trgtRng.FindNext(findRng)
    Loop Until findRng.Address = firstRng.Address
End If

'条件に一致する結果がある場合(表示するメッセージがある場合)MsgBox表示
If buf <> "" Then
    MsgBox buf
End If
「buf」が空白でない場合、つまり「”C”が含まれ、かつ”A”で始まる」という「And条件」を満たすセルがあった場合は、次の結果となります。
09_VBAFindAnd検索If文については、下記でも詳しく解説しているので、読んでみてください。

Or検索

1つ目の条件のFindメソッドで見つかったセルと2つ目の条件のFindメソッドで見つかったセルをどちらも取得すれば、Or検索を行うことができます。

サンプルコードを使って「D」が含まれる、もしくは「G」が含まれるセルの番地をMsgBoxで表示する処理を解説します。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'And検索のために文字列を定義
Dim keyword1 As String
keyword1 = "D"
Dim keyword2 As String
keyword2 = "G"

'検索結果を表示するメッセージを格納する変数
Dim buf As String

'二つの条件で検索するため、ループ処理を2回行う
Dim i As Long
Dim trgtKeyword As String
For i = 1 To 2
    '対象のキーワードを設定
    If i = 1 Then
        trgtKeyword = keyword1
    Else
        trgtKeyword = keyword2
    End If
    '初めの検索結果を定義
    Dim firstRng As Range
    Set firstRng = trgtRng.Find(trgtKeyword, LookAt:=xlPart)

    '「firstRng」がNothingでないか判定
    If Not firstRng Is Nothing Then
        '二つ目以降のセルを格納する変数を定義
        Dim findRng As Range
        Set findRng = firstRng
        '複数条件に一致するまでループ処理
        Do
            '検索結果のセル番地をbufに追加(二つ目以降は改行も追加)
            If buf = "" Then
                buf = findRng.Address & vbCrLf
            Else
                '一つ目の条件で見つかっていないセルの場合はセル番地を追加
                If InStr(buf, findRng.Address & vbCrLf) = 0 Then
                    buf = buf & findRng.Address & vbCrLf
                End If
            End If
            Set findRng = trgtRng.FindNext(findRng)
        Loop Until findRng.Address = firstRng.Address
    End If
    '検索結果を初期化
    Set firstRng = Nothing
    Set findRng = Nothing
Next i

'条件に一致する結果がある場合(表示するメッセージがある場合)MsgBox表示
If buf <> "" Then
    MsgBox buf
End If
まず、次の部分で検索対象範囲「trgtRng」、判定に使う文字列「keyword1」「keyword2」を定義しています。また、MsgBoxに表示する文字列を格納する「buf」も定義しています。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'And検索のために文字列を定義
Dim keyword1 As String
keyword1 = "D"
Dim keyword2 As String
keyword2 = "G"

'検索結果を表示するメッセージを格納する変数
Dim buf As String
次に、検索条件の数だけループ処理「For Next」を行います。ループ処理の初めに、カウンター「i」によって対象となる検索値を「trgtKeyword」に定義します。続いて、初めの検索結果「firstRng」を、検索値「trgtKeyword」、検索条件「部分一致」で定義します。

その後、初めの検索結果があったかどうかを判定し、あった場合は2つ目以降の結果を格納する「findRng」を定義します。また、この後の処理で「FindNext」メソッドを使用するため「findRng」に初めの検索結果「firstRng」を代入し、ループ処理「Do Loop」を実行します。カウンターが「i」が2以降は、それ以前の条件ですでに見つかっている場合があるので、判定処理を入れ、最後にMsgBoxで表示する文字列「buf」にセル番地を代入しています。
'二つの条件で検索するため、ループ処理を2回行う
Dim i As Long
Dim trgtKeyword As String
For i = 1 To 2
    '対象のキーワードを設定
    If i = 1 Then
        trgtKeyword = keyword1
    Else
        trgtKeyword = keyword2
    End If
    '初めの検索結果を定義
    Dim firstRng As Range
    Set firstRng = trgtRng.Find(trgtKeyword, LookAt:=xlPart)

    '「firstRng」がNothingでないか判定
    If Not firstRng Is Nothing Then
        '二つ目以降のセルを格納する変数を定義
        Dim findRng As Range
        Set findRng = firstRng
        '複数条件に一致するまでループ処理
        Do
            '検索結果のセル番地をbufに追加(二つ目以降は改行も追加)
            If buf = "" Then
                buf = findRng.Address & vbCrLf
            Else
                '一つ目の条件で見つかっていないセルの場合はセル番地を追加
                If InStr(buf, findRng.Address & vbCrLf) = 0 Then
                    buf = buf & findRng.Address & vbCrLf
                End If
            End If
            Set findRng = trgtRng.FindNext(findRng)
        Loop Until findRng.Address = firstRng.Address
    End If
    '検索結果を初期化
    Set firstRng = Nothing
    Set findRng = Nothing
Next i

'条件に一致する結果がある場合(表示するメッセージがある場合)MsgBox表示
If buf <> "" Then
    MsgBox buf
End If
「buf」が空白でない場合、つまり「”D”が含まれる、もしくは”G”が含まれる」という「Or条件」を満たすセルがあった場合は、次の結果となります。
10_VBAFindOr検索If文については、下記でも詳しく解説しているので、読んでみてください。

ワイルドカードでの検索

Findメソッドは「検索値」にワイルドカードを使うこともできます。「検索方法」に「xlPart」を指定した場合とは違い「~で始まる」「~で終わる」検索ができます。

サンプルコードを使って「Jで始まる」セル番地をMsgBoxで表示する処理を解説します。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'初めの検索結果を定義
Dim firstRng As Range
Set firstRng = trgtRng.Find("J*", LookAt:=xlWhole)

'検索結果を表示するメッセージを格納する変数
Dim buf As String

'「firstRng」がNothingでないか判定
If Not firstRng Is Nothing Then
    '二つ目以降のセルを格納する変数を定義
    Dim findRng As Range
    Set findRng = firstRng
    '複数条件に一致するまでループ処理
    Do
        '検索結果のセル番地をbufに追加(二つ目以降は改行も追加)
        If buf = "" Then
            buf = findRng.Address
        Else
            buf = buf & vbCrLf & findRng.Address
        End If
        Set findRng = trgtRng.FindNext(findRng)
    Loop Until findRng.Address = firstRng.Address
End If

'条件に一致する結果がある場合(表示するメッセージがある場合)MsgBox表示
If buf <> "" Then
    MsgBox buf
End If
まず、次の部分で検索対象範囲「trgtRng」、初めの検索結果「firstRng」を定義しています。「firstRng」は、検索値にワイルドカードを使って「J*」つまり「Jで始まる」を指定し、検索条件には「完全一致」を指定して検索を行います。また、MsgBoxに表示する文字列を格納する「buf」も定義しています。
'検索対象範囲を定義
Dim trgtRng As Range
Set trgtRng = ThisWorkbook.Worksheets("サンプル").Range("A1:A10")

'初めの検索結果を定義
Dim firstRng As Range
Set firstRng = trgtRng.Find("J*", LookAt:=xlWhole)

'検索結果を表示するメッセージを格納する変数
Dim buf As String
次に、初めの検索結果があったかどうかを判定して、あった場合は2つ目以降の結果を格納する「findRng」を定義します。また、この後の処理で「FindNext」メソッドを使用するため「findRng」に初めの検索結果「firstRng」を代入します。

続いて、「Do Loop」を使って「Jで始まる」全検索結果を取得しています。最後に取得したセル番地をMsgBoxで表示する文字列「buf」に代入します。
'「firstRng」がNothingでないか判定
If Not firstRng Is Nothing Then
    '二つ目以降のセルを格納する変数を定義
    Dim findRng As Range
    Set findRng = firstRng
    '複数条件に一致するまでループ処理
    Do
        '検索結果のセル番地をbufに追加(二つ目以降は改行も追加)
        If buf = "" Then
            buf = findRng.Address
        Else
            buf = buf & vbCrLf & findRng.Address
        End If
        Set findRng = trgtRng.FindNext(findRng)
    Loop Until findRng.Address = firstRng.Address
End If

'条件に一致する結果がある場合(表示するメッセージがある場合)MsgBox表示
If buf <> "" Then
    MsgBox buf
End If
「buf」が空白でない場合、つまり「Jで始まる」セルがあった場合は、次の結果となります。
11_VBAFindワイルドカード検索If文については、下記でも詳しく解説しているので、読んでみてください。

VBAでのFindメソッドまとめ

今回はVBAでのFindメソッドの使い方をご紹介いたしました。
VBAでのFindメソッドの使い方
  • Findメソッドと組み合わせて使うFindNextメソッド
  • Findメソッド使用時によく起こるエラーと回避方法
  • Findメソッドで使えるその他の検索方法
エラー回避方法はもちろん、あわせて紹介した「FindNext」メソッドや応用として解説したAnd検索、Or検索なども理解しておくと、応用が効くのでおすすめです。

ぜひ、使ってみてください。