今回は「Find、FindNext」で指定した文字列を、検索する方法をご説明します。
「Find」メソッドは引数が多かったり、完全一致や部分一致、すべて検索、エラー処理と処理が多岐にわたります。
長くなりますが、それぞれ順に説明したいと思います。
より高速な検索をしたい場合は「Findの高速化 膨大なデータを超高速で検索する方法と速度検証」をご覧下さい。
1.Findメソッドとは
「Find」メソッドはシート上のデータから指定した文字列を検索するのに使用します。
完全一致や部分一致など、引数の指定で検索方法を指定する事ができます。
Findメソッドの構文
Findメソッドの構文は次の様に記述します。
Find (What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
引数が非常に多くいですが、Excelの検索メニューと同じと考えてください。
Findメソッドの引数
引数の一覧は次の通りです。
全ての引数を指定する必要もなく、「What」のデータ範囲のみ必須です。
名前 | 必須/省略 | 定数 | 説明 |
What | 必須 | – | 検索するデータです。 |
After | 省略可能 | – | 指定したセルの後ろから検索します。 |
LookIn | 省略可能 | xlFormulas xlValues xlComents | 検索する対象を、数式、文字列、コメント に指定します。 |
LookAt | 省略可能 | xlPart xlWhole | 部分一致と完全一致を指定します。 |
SearchOrder | 省略可能 | xlByRows xlByColumns | 検索方向を列と行で指定します。 |
SearchDirection | 省略可能 | xlNext xlPrevious | 検索方向を順方向、逆方向で指定します。 |
MatchCase | 省略可能 | True False | 大文字/小文字を区別するか指定します。 |
MatchByte | 省略可能 | True False | 半角/全角を区別するか指定します。 |
SearchFormat | 省略可能 | True False | 検索の書式を指定します。 |
2.エラー処理
まず最初にエラーについて説明します。
以下のサンプルコードにはすべてエラー処理が組み込まれるからです。
Findメソッドは検索結果がなかった時にエラーとなります。
そのため、検索結果がなかった時の処理を組み込みます。
エラー処理は次のように記述します。
If 検索結果 Is Nothing Then
MsgBox "検索文字列はありませんでした"
Exit Sub
End If
3.完全一致で検索
完全一致で検索する方法です。
部分一致の検索には引数に「xlWhole」を指定します。
サンプルデータは次の図で、サンプル1~100まであります。
エラー処理もない、最もシンプルなコードです。
Set SearchRange = Range(“A1:A100”)で検索したいデータ範囲を指定します。
KeyItem = “サンプル10″で検索したい文字列を指定します。
「Set ResultRange = SearchRange.Find(KeyItem, LookAt:=xlWhole)」で検索結果を格納しています。
「If ResultRange Is Nothing」 Thenで検索結果を判定しています。
Sub Sample1()
Dim SearchRange As Range
Dim ResultRange As Range
Dim KeyItem As String
Set SearchRange = Range("A1:A100") '検索したいデータ範囲
KeyItem = "サンプル10"
Set ResultRange = SearchRange.Find(KeyItem, LookAt:=xlWhole)
If ResultRange Is Nothing Then
MsgBox "検索文字列はありませんでした"
Exit Sub
End If
MsgBox ResultRange.Row & "行目"
End Sub
4.部分一致で検索
同じサンプルデータを使用して「10」を含むデータを検索します。
部分一致の検索には引数に「xlPart」を指定します。
結果はSample1と同じです。
Sub Sample2()
Dim SearchRange As Range
Dim ResultRange As Range
Dim KeyItem As String
Set SearchRange = Range("A1:A100") '検索したいデータ範囲
KeyItem = "10"
Set ResultRange = SearchRange.Find(KeyItem, LookAt:=xlPart)
If ResultRange Is Nothing Then
MsgBox "検索文字列はありませんでした"
Exit Sub
End If
MsgBox ResultRange.Row & "行目"
End Sub
5.FindNextですべて検索する
先ほどの検索方法は1つ検索して終了しましたが、データ範囲に複数の該当文字列が存在した場合に、すべて検索する方法を使用します。
すべて検索するには「FindNext」を使用します。
FindNextメソッドは引数で指定したセルの直後のセルから検索を継続します。
つまり、検索で見つかった場合にその行を指定する事で、次の行から検索を再開します。
サンプルデータにはサンプル1~20を5個並べたデータを使用します。
サンプルコードは10を含む文字列をすべて検索します。
Sub Sample3()
Dim SearchRange As Range '検索範囲格納
Dim ResultRange As Range '検索結果格納
Dim StartRange As Range '検索行格納
Dim KeyItem As String
Dim MsgStr As String
Dim i As Long
Set SearchRange = Range("A1:A100") '検索したいデータ範囲
KeyItem = "10"
Set ResultRange = SearchRange.Find(KeyItem, LookAt:=xlPart)
If ResultRange Is Nothing Then
MsgBox "検索文字列はありませんでした"
Exit Sub
Else
Set StartRange = ResultRange '最初に見つかったセルを格納しておく
End If
Do
Set ResultRange = Cells.FindNext(ResultRange) '次の検索セルを指定する
If ResultRange.Address = StartRange.Address Then '見つかったセルが最初のセルか判定
Exit Do '同じ場合はループを離脱
Else
MsgStr = MsgStr & ResultRange.Row & "行目" & vbCrLf
End If
Loop
MsgBox MsgStr
End Sub
Sample1~2 と違う部分の説明です。
「Set StartRange = ResultRange」で最初に見つかったセルを格納しておきます。
「Do~Loop」で最初に見つかったセルから1周するまでループします。
「If ResultRange.Address = StartRange.Address Then」で1周したか判定しています。
「Exit Do」で1周した場合はループを抜けます。(これがないと無限ループします。)
最後は処理方法ですが、ここでは単に文字列にして表示しています。
6.列方向に検索する
先ほどまでは行方向に検索でしたが、引数の使い方を説明するために列方向に、逆方向に検索するコードを紹介します。
次のようなデータを使用して列方向に、かつ逆方向に検索します。
ベースはSample3のコードを使用します。
Sub Sample4()
Dim SearchRange As Range '検索範囲格納
Dim ResultRange As Range '検索結果格納
Dim StartRange As Range '検索行格納
Dim KeyItem As String
Dim MsgStr As String
Dim i As Long
Set SearchRange = Range("A1:CW1") '検索したいデータ範囲
KeyItem = "10"
Set ResultRange = SearchRange.Find(KeyItem, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious)
If ResultRange Is Nothing Then
MsgBox "検索文字列はありませんでした"
Exit Sub
Else
Set StartRange = ResultRange '最初に見つかったセルを格納しておく
End If
Do
Set ResultRange = Cells.FindNext(ResultRange) '次の検索セルを指定する
If ResultRange.Address = StartRange.Address Then '見つかったセルが最初のセルか判定
Exit Do '同じ場合はループを離脱
Else
MsgStr = MsgStr & ResultRange.Column & "列目" & vbCrLf
End If
Loop
MsgBox MsgStr
End Sub
「Set SearchRange = Range(“A1:CW1”)」でデータ範囲を指定していますが列のため、A1~CW1なっています。
「LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious」で部分一致、列方向検索、逆方向検索を指定しています。引数の指定は「 := 」と記述します。
文字列に格納する際は「ResultRange.Column」で列を取得しています。