Excel VBAのFind関数の使い方をお探しですね。
広告
Excel VBAで「特定の文字列を含むセル」を検索する方法【初心者向け】
Excelで一覧表を扱っていると、「特定の文字列を含むセル」を探したい場面がよくありますよね。
たとえば、商品名に「りんご」が入っている行だけをチェックしたい、備考欄に「要対応」と書かれたセルを見つけたい、顧客名の一部から該当データを探したい、といった場面です。
こういった検索処理には、VBAの**Findメソッド**が便利です。
Excelの検索機能をVBAで操作するイメージで、セルを効率よく見つけられます。
この記事では、Findメソッドを使って特定の文字列を含むセルを検索・抽出する方法を、初心者の方にも分かりやすく解説していきます。
Findメソッドの基本的な使い方
Findメソッドは、指定した範囲の中から条件に合うセルを探して、見つかったセルを教えてくれる機能です。
たとえば、A列の商品名から「りんご」を含むセルを探したいときは、検索範囲と検索文字列を指定するだけで使えます。
ここで重要なのが、**「含む」セルを探したいときの設定**です。
`LookAt`という引数に`xlPart`を指定すると、部分一致で検索できます。
つまり、「青りんご」「りんごジュース」「国産りんご」のように、セルの中に「りんご」という文字が入っていればヒットします。
逆に、セルの内容が完全に「りんご」だけのものを探したい場合は、`LookAt:=xlWhole`を指定します。
「りんご」を含む商品名を広く探したいなら部分一致、ピッタリ「りんご」だけを探したいなら完全一致、という使い分けですね。
Findメソッドは、条件に合うセルが見つかるとそのセルを返してくれますが、見つからないときは`Nothing`という値を返します。
なので、検索結果を使う前には必ず「見つかったかどうか」を確認する必要があります。
これを忘れるとエラーになってしまうので注意しましょう。
基本的なコードはこんな感じです。
“`vb
Sub FindBasic()
Dim ws As Worksheet
Dim rng As Range
Dim keyword As String
Set ws = ThisWorkbook.Worksheets(“Sheet1”)
keyword = “りんご”
Set rng = ws.Range(“A2:A100”).Find( _
What:=keyword, _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
MatchByte:=False)
If rng Is Nothing Then
MsgBox “検索文字列を含むセルは見つかりませんでした。
”
Else
MsgBox “見つかったセル:” & rng.Address(False, False) & vbCrLf & _
“値:” & rng.Value
End If
End Sub
“`
このコードでは、A2からA100の範囲で「りんご」を含むセルを探しています。
`LookIn:=xlValues`は「セルに表示されている値」を対象にする設定で、数式そのものを検索したいときは`xlFormulas`を使います。
検索処理では、「どこを探すのか」「値を探すのか数式を探すのか」「完全一致か部分一致か」をはっきり指定することが大切です。
これを省略すると、Excelの検索ダイアログで前に使った条件の影響を受けてしまい、思わぬ結果になることがあります。
Findメソッドの引数を理解しよう
Findメソッドは便利ですが、引数がたくさんあるので、最初はどれを指定すればいいか迷うかもしれません。
特定の文字列を含むセルを検索する場合、最低限押さえておきたいのは次の引数です。
– **What**:検索したい文字列や値を指定します(必須)
– **LookIn**:値を検索するなら`xlValues`、数式を検索するなら`xlFormulas`
– **LookAt**:部分一致なら`xlPart`、完全一致なら`xlWhole`
– **SearchOrder**:行方向に探すなら`xlByRows`、列方向なら`xlByColumns`
– **MatchCase**:大文字と小文字を区別するかどうか
– **MatchByte**:全角と半角を区別するかどうか
特に`LookAt`は検索結果を大きく左右します。
「含むセル」を探したい今回の目的では、必ず`LookAt:=xlPart`を指定しましょう。
また、日本語データでは`MatchByte`も重要です。
半角カタカナと全角カタカナ、半角英数字と全角英数字が混在している場合があるからです。
たとえば「ABC」と「ABC」を同じものとして扱いたいなら`MatchByte:=False`、厳密に区別したいなら`True`を指定します。
引数を省略すると何が起こる?
実は、Findメソッドの一部の検索条件は、Excelの検索設定と連動しています。
手作業で「検索と置換」を使った後にVBAを実行すると、省略した引数が前回の検索条件に引きずられることがあるんです。
たとえば、前回の検索で「完全一致」を使っていた場合、VBAで`LookAt`を省略すると、部分一致で探したつもりなのに見つからない…なんてことも。
安定したマクロにするには、面倒でも主要な引数をきちんと書いておくのがおすすめです。
書式検索を使ったことがある環境では、`SearchFormat`にも注意が必要です。
書式条件が残っていると、文字列は一致しているのに書式が違うから見つからない、という分かりにくい状況が起こることがあります。
通常の文字列検索では、事前に`Application.FindFormat.Clear`を実行し、`SearchFormat:=False`を指定しておくと安全です。
複数のセルを検索して抽出する方法
Findメソッドだけだと、最初に見つかった1件しか取得できません。
検索範囲の中に「りんご」を含むセルが複数ある場合、2件目以降を取得するには**FindNext**メソッドを使います。
FindNextは、直前に見つかったセルの次から同じ条件で検索を続けるメソッドです。
ただし注意点があって、検索は範囲の最後まで行くと先頭に戻ってきます。
なので、終了条件を正しく書かないと無限ループになってしまいます。
これを防ぐには、最初に見つかったセルのアドレスを保存しておいて、再び同じアドレスに戻ったら処理を終える、という書き方をします。
これが定番のやり方です。
次のコードは、A列から「りんご」を含むセルをすべて探して、該当する行全体を別シートに抽出する例です。
“`vb
Sub FindAndExtractRows()
Dim wsData As Worksheet
Dim wsResult As Worksheet
Dim searchRange As Range
Dim foundCell As Range
Dim firstAddress As String
Dim keyword As String
Dim outputRow As Long
Set wsData = ThisWorkbook.Worksheets(“データ”)
Set wsResult = ThisWorkbook.Worksheets(“抽出結果”)
Set searchRange = wsData.Range(“A2:A100”)
keyword = “りんご”
outputRow = 2
Application.FindFormat.Clear
wsResult.Rows(“2:” & wsResult.Rows.Count).ClearContents
Set foundCell = searchRange.Find( _
What:=keyword, _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
MatchByte:=False, _
SearchFormat:=False)
If foundCell Is Nothing Then
MsgBox “該当データはありませんでした。
”
Exit Sub
End If
firstAddress = foundCell.Address
Do
wsData.Rows(foundCell.Row).Copy Destination:=wsResult.Rows(outputRow)
outputRow = outputRow + 1
Set foundCell = searchRange.FindNext(foundCell)
Loop While Not foundCell Is Nothing And foundCell.Address <> firstAddress
MsgBox “抽出が完了しました。
”
End Sub
“`
このコードでは、検索対象をA列に限定して、見つかったセルの行全体を「抽出結果」シートへコピーしています。
商品名列で検索して、同じ行にある価格や在庫数、担当者などの情報も一緒に抽出できるわけです。
ポイントは、**最初のセルを覚えておくこと**です。
`firstAddress = foundCell.Address`で最初に見つかった場所を保存して、ループの中で再び同じアドレスに戻ったら終了します。
これを入れないと、同じセルを何度も見つけ続けてしまいます。
検索結果の抽出方法は、行コピーだけじゃありません。
該当セルに色を付ける、セルのアドレスだけを一覧にする、必要な列だけを転記するなど、目的に合わせて処理を変えられます。
大量データを扱う場合は、行全体をコピーするより必要な列だけ代入で転記したほうが軽くなることもあります。
Findメソッドの注意点と他の方法との使い分け
Findメソッドは便利ですが、万能ではありません。
いくつか注意点があります。
よくあるエラーと対処法
**1. 見つからなかったときのエラー**
Findメソッドで見つからなかった場合は`Nothing`が返るので、すぐに`foundCell.Value`や`foundCell.Row`を参照するとエラーになります。
これは初心者がつまずきやすいポイントです。
検索後は必ず`If foundCell Is Nothing Then`で判定して、見つからなかった場合の処理を用意しましょう。
**2. 引数を省略したときの不安定さ**
検索対象を値にするのか数式にするのか、部分一致にするのか完全一致にするのか、大文字小文字や全角半角を区別するのか…これらを省略すると、環境や直前の操作によって結果が変わる可能性があります。
業務で使うなら、検索条件をきちんと明示しておくのがベストです。
**3. 結合セルや数式がある表での注意**
結合セルや空白セルが多い表、数式の表示結果と数式そのものが異なる表では、検索対象を`xlValues`にするか`xlFormulas`にするかで結果が変わります。
期待したセルが見つからないときは、まず引数の指定を確認してみましょう。
InStr関数との使い分け
「特定の文字列を含むかどうか」を1セルずつ判定したいだけなら、**InStr関数**を使う方法もあります。
InStrは文字列の中に指定した文字列が何文字目にあるかを返す関数で、見つからない場合は0を返します。
検索範囲をFor Eachで回して、`If InStr(cell.Value, keyword) > 0 Then`のように判定すれば、FindNextの終了条件を考えずに書けます。
コードの分かりやすさを重視する場合や、複数条件を組み合わせたい場合には、FindよりInStrのほうが扱いやすいこともあります。
オートフィルターとの使い分け
A列に「要対応」を含む行だけを表示したいなら、VBAでオートフィルターを設定するほうが自然な場合もあります。
Findメソッドは「セルを探す」処理に向いていますが、「条件に合う行だけを表として絞り込む」処理では、Excelのフィルター機能を使ったほうが見た目にも分かりやすく、ユーザーがそのまま確認しやすいことがあります。
使い分けの目安
– **最初の1件を素早く探したい** → Findメソッド
– **複数件を検索して抽出したい** → Find + FindNext
– **複雑な条件判定や読みやすさ重視** → For Each + InStr
– **表として条件抽出したい** → オートフィルター
検索結果を別シートに転記するのか、元の表で絞り込むのか、セルを装飾するのかによって、最適な方法は変わってきます。
まとめ
Excel VBAのFindメソッドで特定の文字列を含むセルを検索・抽出するには、次のポイントを押さえましょう。
– 部分一致で検索するには`LookAt:=xlPart`を指定する
– 見つからなかった場合の`Nothing`判定を必ず入れる
– 複数件を扱うときは`FindNext`と最初のアドレスによる終了条件を組み合わせる
– 検索条件を省略せず明示することで、環境に左右されにくいコードになる
Find、InStr、オートフィルターの特徴を理解して使い分ければ、一覧表から必要な情報を取り出す作業を効率よく自動化できます。
ぜひ実際のデータで試してみてください!
広告
