VBAでデータを検索する方法は、大きく「Findメソッド」「ループ検索」「InStr関数」の3つがあります。完全一致で1件だけ素早く探すなら Find、複数条件や全件チェックならループ、文字列の中に含まれているかどうかの部分一致なら InStr という使い分けが基本です。
この記事では、次の内容を順番に解説します。
- 3つの検索方法の使い分けの基準
- Findメソッドの基本コードと注意点
- Findで複数件を順番に見つける方法(FindNext)
- ループ検索で複数条件に対応する方法
- InStr関数で部分一致を検索する方法
- よくある質問(大文字小文字の区別・見つからない場合の処理等)
3つの検索方法の使い分けを理解するには?
まず全体像を一覧で確認しましょう。
| 方法 | 得意なこと | 苦手なこと |
|---|---|---|
| Find | 完全一致で高速に1件を取得 | 複雑な条件には向かない |
| ループ | 複数条件・全件処理・柔軟な判定 | データ量が多いと遅くなる |
| InStr | 文字列の部分一致(含む)の検索 | 単独では行番号の取得ができない |
迷ったときの判断基準はシンプルです。「1件だけ完全一致で探す → Find」「条件が複雑または全件をチェックしたい → ループ」「〇〇という文字が含まれているかどうか → InStr」と覚えておくだけで、大半の場面に対応できます。
Findメソッドの基本コードと注意点を理解するには?
次のコードは、A列から「佐藤」を検索して、見つかった場合にそのセルのアドレスをメッセージで表示します。
Sub FindData()
Dim result As Range
Set result = Range("A2:A100").Find(What:="佐藤", LookAt:=xlWhole)
If Not result Is Nothing Then
MsgBox result.Address & " に見つかりました"
Else
MsgBox "見つかりませんでした"
End If
End Sub
Findメソッドの主な引数は次の通りです。
| 引数 | 説明 | よく使う値 |
|---|---|---|
What | 検索する値 | 文字列・数値 |
LookAt | 一致の方法 | xlWhole(完全一致)/xlPart(部分一致) |
MatchCase | 大文字小文字を区別するか | True(区別する)/False(しない・デフォルト) |
SearchOrder | 検索方向 | xlByRows(行方向)/xlByColumns(列方向) |
重要な注意点: Findで見つからなかった場合、戻り値は Nothing になります。If Not result Is Nothing Then のチェックを必ず入れないと、見つからなかったときにエラーで止まります。
Findで複数件を順番に見つけるには?(FindNext)
同じ値が複数行にある場合は、FindNext を使って順番に取得できます。
Sub FindAllData()
Dim result As Range
Dim firstAddress As String
Set result = Range("A2:A100").Find(What:="佐藤", LookAt:=xlWhole)
If result Is Nothing Then
MsgBox "見つかりませんでした"
Exit Sub
End If
' 最初に見つかったアドレスを記録(無限ループ防止)
firstAddress = result.Address
Do
MsgBox result.Address & " に見つかりました"
Set result = Range("A2:A100").FindNext(result)
Loop While Not result Is Nothing And result.Address <> firstAddress
MsgBox "検索完了"
End Sub
firstAddress を記録して最初の場所に戻ってきたらループを止める、という処理が無限ループを防ぐポイントです。
ループ検索で複数条件に対応するには?
「部署がA部門かつ担当者が佐藤」のように複数の条件を組み合わせたい場合は、ループの中で条件を書く方が柔軟に対応できます。
Sub LoopSearch()
Dim i As Long
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
' A列が「営業部」かつB列が「佐藤」の行を探す
If Cells(i, 1).Value = "営業部" And Cells(i, 2).Value = "佐藤" Then
MsgBox i & "行目に見つかりました"
End If
Next i
End Sub
Find では書きにくい「AかつB」「AまたはB」「数値が〇以上」といった複合条件も、And・Or・比較演算子を使うだけで自由に表現できます。また、見つかった行に対してそのまま処理(色をつける、値を書き換えるなど)を続けることも簡単です。
InStr関数で部分一致を検索するには?
「佐藤商事」「株式会社佐藤」など、「佐藤」という文字が含まれているセルをすべて探したい場合は InStr を使います。
Sub InStrSearch()
Dim i As Long
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
If InStr(Cells(i, 1).Value, "佐藤") > 0 Then
MsgBox i & "行目:" & Cells(i, 1).Value
End If
Next i
End Sub
InStr(文字列, 検索語) は、文字列の中に検索語が含まれている場合にその開始位置(1以上の数値)を返します。含まれていない場合は 0 を返すため、> 0 で「含まれているかどうか」を判定できます。
大文字・小文字を区別しない部分一致にしたい場合は、LCase で両方を小文字に変換してから比較するのが確実です。
If InStr(LCase(Cells(i, 1).Value), LCase("Sato")) > 0 Then
まとめ
- 完全一致で1件を素早く取得 → Find(必ず
Nothingチェックを入れる) - 複数件を順番に取得 → FindNext(最初のアドレスを記録して無限ループを防ぐ)
- 複数条件・全件処理 → ループ+If(
And・Orで自由に条件を組み合わせる) - 文字列に含まれているかどうか → InStr(戻り値が
0より大きければ含まれている)
よくある質問
Findで大文字・小文字を区別して検索するには?
MatchCase:=True を引数に追加します。デフォルトは False(区別しない)です。
Set result = Range("A2:A100").Find(What:="ABC", LookAt:=xlWhole, MatchCase:=True)
Findで数値を検索するときの注意点は?
数値を検索する場合、セルの書式が「文字列」になっていると一致しないことがあります。また、LookIn の引数を xlValues(セルの値)に指定しておくと意図しないマッチを防げます。
Set result = Range("A2:A100").Find(What:=100, LookIn:=xlValues, LookAt:=xlWhole)
ループ検索で最初に見つかった行だけを処理したい場合は?
条件に一致した時点で Exit For を使ってループを抜けます。
For i = 2 To lastRow
If Cells(i, 1).Value = "佐藤" Then
MsgBox i & "行目に見つかりました"
Exit For ' 最初の1件だけ処理して終了
End If
Next i
InStrで検索語の位置(何文字目にあるか)を知りたい場合は?
InStr の戻り値がそのまま開始位置(何文字目か)を表します。たとえば「株式会社佐藤」の中に「佐藤」があれば 5 が返ります。この位置情報を使って Mid 関数で前後を切り取るなど、文字列の加工にも応用できます。
FindとInStrはどちらを使うべき?
検索対象がセルの値全体なら Find、セルの値の中に特定の文字が含まれているかを調べるならInStrが向いています。また、Findは単独で動作しますが、InStrはループと組み合わせて使うのが基本です。複数列・複数条件を同時にチェックするならループ+InStrの組み合わせが最も柔軟です。


