あなたは、VBAでFindメソッドを使ったことがありますか?
- VBAで任意のキーワードを使って検索したい
- 同じ列から同条件で繰り返し検索をしたい
- Findメソッドを使う方法が知りたい!
そこで今回は、任意のキーワードで検索ができるFindメソッドについて、エラー回避方法や実例も含めて紹介します。
VBAでのFindメソッドの使い方
Findメソッドの基本的な使い方
- 基本構文
対象オブジェクトFind(検索値, [検索開始位置], [検索対象形式], [検索方法], [検索方向], [検索順], [比較形式1(大文字・小文字)], [比較形式2(全角・半角)], [書式検索])
- Findメソッドが返すのは「Rangeオブジェクト」
- 「LookAt」が「xlWhole」なら完全一致、「xlPart」なら部分一致
- 「LookAt」を一度も指定していない場合は「部分一致」となる
- コード例
ActiveSheet.Rangge("A1:A10").Find("ABC", LookAt:=xlWhole)
アクティブシート上「A1:A10」の範囲から、文字列「ABC」で完全一致した値を持つ「Rangeオブジェクト」を返します。例では、検索開始位置(=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メソッドの検索開始位置について
Findメソッドでは、第二引数「検索開始位置(After)」を使って、検索開始位置を指定できます。引数には「Rangeオブジェクト」を指定します。この時、指定した「Rangeオブジェクト」はFindメソッドで検索される対象範囲内に含まれている必要があります。また「検索開始位置(After)」に指定した「Rangeオブジェクト」の次のセルから検索が開始されるので、注意が必要です。
- コード例
ActiveSheet.Rangge("A1:A10").Find("ABC", After:=ActiveSheet.Rangge("A3")
アクティブシート上「A1:A10」の範囲から、文字列「ABC」と一致する値を持つ「Rangeオブジェクト」を検索します。引数「After」には「A3」セルを指定しているので、その次のセル「A4」セルから検索が開始されます。画像のように「A4」セルから下に向かって検索されるので、最初に検索値「ABC」と一致するRangeオブジェクト「A10」が返り値となります。
Findメソッドと組み合わせて使うFindNextメソッド
FindNextメソッドの使い方
「FindNext」メソッドは、Findメソッドと組み合わせて、同条件で上から下・左から右に向かって繰り返し検索ができます。同じ対象範囲で複数の検索結果があるか調べる時に便利です。- コード例
'検索対象範囲を定義
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で表示しています。
よって、処理結果は次のようになります。
FindPreviousメソッドで逆順検索
「FindPrevious」メソッドは「FindNext」メソッドと同様、Findメソッドと組み合わせて、同条件で下から上・右から左へと逆順に繰り返し検索できます。同じ対象範囲で複数の検索結果があるか調べる時に便利です。- コード例
'検索対象範囲を定義
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で表示しています。
よって、処理結果は次のようになります。
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
「サンプル」シート「A1:A10」が上の画像のようになっている場合、サンプルコードを実行すると次のエラーがでます。サンプルコードでは「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条件」を満たすセルがあった場合は、次の結果となります。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条件」を満たすセルがあった場合は、次の結果となります。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で始まる」セルがあった場合は、次の結果となります。If文については、下記でも詳しく解説しているので、読んでみてください。
VBAでのFindメソッドまとめ
今回はVBAでのFindメソッドの使い方をご紹介いたしました。VBAでのFindメソッドの使い方
エラー回避方法はもちろん、あわせて紹介した「FindNext」メソッドや応用として解説したAnd検索、Or検索なども理解しておくと、応用が効くのでおすすめです。- Findメソッドと組み合わせて使うFindNextメソッド
- Findメソッド使用時によく起こるエラーと回避方法
- Findメソッドで使えるその他の検索方法
ぜひ、使ってみてください。