PR
アフィリエイト広告を利用しています
アフィリエイト広告を利用しています

【コピペOK】VBAで文字列を検索する方法|InStr・InStrRev・Like・Range.Findの使い分けと「含む」の判定、全角半角を区別しない書き方(全コード実機確認)

VBAで文字列を検索する方法。含むか調べるならInStrが0より大きいか、形で判定するならLike、セルを探すならRange.FindでNothingを確認 EXCEL VBA講座
スポンサーリンク

【この記事について】本記事に載せた VBA のコードは、2026年11月5日に Microsoft 365 の Excel(Windows デスクトップ版)ですべて実際に実行し、結果を確かめたものです。構文の説明は Microsoft Learn の公式リファレンス(記事末尾に出典)に沿っています。マクロは元に戻せない変更をすることがあります。会社のファイルで試す前に、必ずコピーを取ってから実行してください。マクロの利用が会社のルールで制限されている場合は、そちらに従ってください。本記事の内容の利用は、ご自身の判断と責任でお願いします。

対象環境:Windows 11 / Microsoft 365 の Excel(デスクトップ版・バージョン 16.0 ビルド 20527)。2026年11月5日に全コードの動作を確認。難易度:VBA 入門(マクロを1回でも貼り付けて動かしたことがある人向け)。

VBA で文字列を検索するなら、まずは InStr 関数です。InStr(調べる文字列, 探す文字) が0より大きければ「含む」、0なら「含まない」。後ろから探すなら InStrRev、「〇〇で始まる」「数字3桁」のような形で判定するなら Like 演算子、シートの中から探すセルを見つけるなら Range.Find を使います。この記事では、4つの使い分けを、実機の Excel で動かして確かめたコードで整理します。

VBAの文字列検索をやりたいことで選ぶ図。含むか何文字目かはInStr、大文字小文字や全角半角を区別しないならvbTextCompare、後ろから探すならInStrRev、形で判定するならLike、シートのセルを探すならRange.FindとFindNext。Findの引数はCtrl+Fの設定と共有されるので毎回すべて書く

この記事は「VBA のコードで探す」話です。Excel の画面で Ctrl+F を押しても見つからない、というときは、こちらで原因別に直し方をまとめています。

エクセルで検索できない原因8つと直し方|Ctrl+Fで見つからない・検索対象・完全一致・書式の設定を確認
エクセルで Ctrl + F を押しても見つからないときは、検索のオプションに前回の設定が残っていることがほとんどです。検索対象(数式・値)、完全一致、全角と半角、書式の条件、フィルターで隠れた行、ワイルドカード、検索場所の8つを、Excel で実際に試した結果つきで確認します。

スポンサーリンク

まず結論|VBA の文字列検索4つの早見表

やりたいこと 使うもの 返ってくるもの
文字列に「〇〇」が含まれるか・何文字目にあるか InStr 見つかった位置(数値)。無ければ 0
最後に出てくる位置(パスからファイル名を取り出す等) InStrRev 後ろから探して最初に見つかった位置(数え方は先頭から)
「〇〇を含む」「英字1文字+数字3桁」のような形で判定 Like 演算子 True/False
シートの中で探す文字が入ったセルを見つける Range.Find(続きは FindNext) 見つかったセル。無ければ Nothing

この記事のコードを試すための準備

  1. Excel で新しいブックを開き、Alt+F11 で VBE(マクロを書く画面)を開く
  2. メニューの[挿入]→[標準モジュール]を選ぶ
  3. コードを貼り付け、Ctrl+G でイミディエイト ウィンドウを表示しておく(Debug.Print の結果がここに出ます)
  4. カーソルを Sub の中に置いて F5 で実行する

InStr|「含む」かどうかと、その位置を調べる

InStr は、文字列の中から探す文字を見つけて、それが何文字目から始まるかを返します。見つからなければ 0 です。日本語も1文字ずつ数えます。

Sub InStrBasic()
    Dim s As String
    s = "東京都千代田区丸の内1-1"
    Debug.Print InStr(s, "千代田")   ' → 4(4文字目から見つかった)
    Debug.Print InStr(s, "大阪")     ' → 0(見つからない)
End Sub

実行すると、イミディエイト ウィンドウに 4 と 0 が表示されました。

「含む」の判定は「0より大きいか」で書く

実務でいちばん使うのはこの形です。位置そのものは使わず、0かどうかだけを見るのがコツです。

Sub InStrContains()
    Dim s As String
    s = "株式会社サンプル 御中"
    If InStr(s, "御中") > 0 Then
        Debug.Print "「御中」が含まれています"
    Else
        Debug.Print "含まれていません"
    End If
End Sub

実行結果は「「御中」が含まれています」でした。逆に「含まない」を判定したいときは If InStr(s, "御中") = 0 Then と書きます。

大文字・小文字、全角・半角を区別しないで探す

InStr は、そのままだと大文字と小文字を区別します。区別したくないときは、1つ目に開始位置、4つ目に vbTextCompare を指定します。4つ目を書くときは、1つ目の開始位置を省略できません。

Sub InStrIgnoreCase()
    Dim s As String
    s = "Excel VBA 研修"
    Debug.Print InStr(1, s, "vba")                 ' → 0(大文字小文字を区別)
    Debug.Print InStr(1, s, "vba", vbTextCompare)  ' → 7(区別しない)
End Sub

実機では、vbTextCompare を付けると、全角の「VBA研修」から半角の “vba” を探しても 1(見つかった)が返りました。付けない場合は 0 でした。社内の表に全角と半角が混ざっているときは、vbTextCompare を付けておくと取りこぼしが減ります。

2つ目以降を探す|開始位置をずらす

InStr の1つ目の引数に探し始める位置を渡せます。1つ目に見つかった位置の「次の文字」から探し直せば、2つ目が見つかります。

Sub InStrSecond()
    Dim s As String, p1 As Long, p2 As Long
    s = "2026-11-05"
    p1 = InStr(s, "-")            ' 1つ目の「-」
    p2 = InStr(p1 + 1, s, "-")    ' 1つ目の次の文字から探す
    Debug.Print p1, p2            ' → 5  8
    Debug.Print Mid(s, p1 + 1, p2 - p1 - 1)   ' → 11(月)
End Sub

実行結果は 5 8 と 11 でした。日付の文字列から「月」の部分だけを取り出す、といった使い方ができます。

InStrRev|後ろから探して、ファイル名や拡張子を取り出す

InStrRev は、文字列の後ろから探します。返ってくる位置は、InStr と同じく先頭から数えた位置です。フォルダーの区切り「\」は何個あるか分かりませんが、最後の「\」の後ろがファイル名なので、InStrRev がぴったりです。

Sub InStrRevFileName()
    Dim p As String
    p = "C:\Users\sato\Documents\見積書_2026.xlsx"
    Debug.Print InStrRev(p, "\")                 ' → 24(最後の「\」の位置)
    Debug.Print Mid(p, InStrRev(p, "\") + 1)     ' → 見積書_2026.xlsx
    Debug.Print Left(p, InStrRev(p, ".") - 1)    ' 拡張子を除いた部分
End Sub

実行結果は 24、見積書_2026.xlsx、C:\Users\sato\Documents\見積書_2026 でした。Mid 関数は「〇文字目から最後まで」を、Left 関数は「先頭から〇文字」を取り出します。

何回出てくるかを数える|Replace との組み合わせ

VBA には「文字が何回出てくるか」を直接数える関数がありません。探す文字を消した長さとの差を、探す文字の長さで割ると数になります。

Sub CountWord()
    Dim s As String, w As String, n As Long
    s = "請求書、見積書、請求書(再発行)、納品書"
    w = "請求"
    n = (Len(s) - Len(Replace(s, w, ""))) / Len(w)
    Debug.Print n   ' → 2
End Sub

実行結果は 2 でした(「請求書」と「請求書(再発行)」の2回)。

Like|「〇〇を含む」「数字3桁」のような形で判定する

Like 演算子は、ワイルドカードを使って文字列の形を判定し、True か False を返します。

記号 意味 例
* 0文字以上の何か "*株式会社*"=「株式会社」を含む
? 任意の1文字 "第?回"=「第1回」「第A回」など
# 数字1文字 "###"=数字3桁
[A-Z] 括弧内の範囲の1文字 "[A-Z]-###"=英大文字1つ+「-」+数字3桁
Sub LikeSample()
    Debug.Print "見積書_株式会社サンプル" Like "*株式会社*"   ' → True
    Debug.Print "A-123" Like "[A-Z]-###"                       ' → True
    Debug.Print "A-12X" Like "[A-Z]-###"                       ' → False
End Sub

実行結果は True・True・False でした。商品コードや社員番号の書式チェックに便利です。「含むかどうか」だけなら InStr でも Like でも同じことができるので、読みやすいほうを選んでかまいません。

セルを1つずつ調べて、含む行に印を付ける

InStr は、ループと組み合わせると力を発揮します。A列に「請求」を含む行があれば、B列に「対象」と書き込む例です。

Sub MarkRows()
    Dim ws As Worksheet, i As Long, lastRow As Long
    Set ws = ActiveSheet
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    For i = 2 To lastRow
        If InStr(ws.Cells(i, "A").Value, "請求") > 0 Then
            ws.Cells(i, "B").Value = "対象"
        Else
            ws.Cells(i, "B").ClearContents
        End If
    Next i
End Sub

A2:A7 に「請求書_10月分」「見積書_株式会社サンプル」「請求書(再発行)」「納品書」「ご請求のお知らせ」「VBA研修の案内」を入れて実行すると、「請求」を含む3行(2・4・6行目)だけに「対象」が入りました。最終行の取り方とループの書き方は、こちらで詳しく扱っています。

【もう迷わない】VBAで最終行を取得する方法5つと使い分け|End(xlUp)が1を返す・途中の空白・UsedRangeのズレ
VBAで最終行を取るなら、まずは ws.Cells(ws.Rows.Count, 1).End(xlUp).Row の1行です。データ0件でも1が返る・シート指定の漏れ・基準列の空白・Integerのオーバーフローという4つのつまずきと、Find・UsedRange・CurrentRegionとの使い分けを、Microsoft公式ドキュメントをもとにまとめました。

Range.Find|シートの中から探す文字が入ったセルを見つける

行数が多い表で「どのセルにあるか」を知りたいときは、Ctrl+F と同じ働きの Range.Find が速くて確実です。見つからないと Nothing が返るので、必ず先に Nothing かどうかを確かめます。

Sub FindAllCells()
    Dim ws As Worksheet, c As Range, firstAddress As String
    Set ws = ActiveSheet
    Set c = ws.Range("A:A").Find(What:="請求", LookIn:=xlValues, _
        LookAt:=xlPart, MatchCase:=False, MatchByte:=False)
    If c Is Nothing Then
        MsgBox "見つかりませんでした"
        Exit Sub
    End If
    firstAddress = c.Address
    Do
        Debug.Print c.Address, c.Value
        Set c = ws.Range("A:A").FindNext(c)
    Loop While c.Address <> firstAddress
End Sub

上と同じ表で実行すると、$A$2・$A$4・$A$6 の3つが、値と一緒に表示されました。表を空にして実行すると「見つかりませんでした」と表示されました。FindNext は最初のセルに戻ってくるまで探し続けるので、最初に見つかったアドレスを覚えておき、そこに戻ったら止めるのが決まった書き方です。

Find の引数は毎回すべて書く

Microsoft Learn によると、LookIn・LookAt・SearchOrder・MatchByte の設定は、Find を使うたびに保存され、省略すると前回の値が使われます。しかも、この設定はCtrl+F の[検索]ダイアログと共有されています。前に誰かが「完全一致」で検索していると、コードが同じでも結果が変わります。だから上の例では、引数を全部書いています。

引数 指定する値 意味
LookIn xlValues 表示されている値で探す(xlFormulas だと数式で探す)
LookAt xlPart / xlWhole 一部が一致(含む)/セル全体が一致
MatchCase False 大文字・小文字を区別しない
MatchByte False 全角・半角を区別しない(日本語版 Excel 用の引数)

実機では、MatchByte:=False で “VBA” を探すと全角の「VBA研修の案内」($A$7)が見つかり、MatchByte:=True では見つかりませんでした。

セル全体が一致するものだけを探す

Sub FindWhole()
    Dim c As Range
    Set c = ActiveSheet.Range("A:A").Find(What:="納品書", LookIn:=xlValues, LookAt:=xlWhole)
    If c Is Nothing Then
        Debug.Print "見つかりませんでした"
    Else
        Debug.Print c.Address   ' → $A$5
    End If
End Sub

実行結果は $A$5 でした。LookAt:=xlWhole にすると、「納品書」とだけ書かれたセルを探し、「納品書(控え)」のようなセルは対象外になります。

よくあるつまずき

Find の結果をそのまま使うと「実行時エラー91」で止まる

見つからなかったときの Nothing に対して c.Address などを使うと、実行時エラー91(オブジェクト変数または With ブロック変数が設定されていません)で止まります。If c Is Nothing Then の確認を飛ばさないでください。

【止まらない】VBA「実行時エラー91」の原因7つと直し方|オブジェクト変数またはWithブロック変数が設定されていません
VBAで『実行時エラー91:オブジェクト変数またはWithブロック変数が設定されていません』が出て止まる原因を7つに整理。Set忘れ・Find・Withブロックなど、コピペで直せる修正コードつきで解説します。

InStr の引数の順番を逆にしている

InStr は「調べる文字列」が先、「探す文字」が後です。逆に書いてもエラーにならず、0が返るだけなので気付きにくいミスです(実機で InStr("御中", "株式会社サンプル 御中") は 0 でした)。結果がいつも0のときは、まず順番を確かめてください。

探す文字が空のとき

探す文字が空文字("")だと、InStr は開始位置(通常は1)を返しました。セルの値を探す文字に使うときは、空のセルだと「含む」と判定されてしまうので、先に If 探す文字 <> "" Then で除いておくと安全です。

よくある質問

Q. InStr と Like は、どちらを使えばいいですか?

「含むかどうか」だけなら、どちらでも同じ結果になります。位置が必要なら InStr、「数字3桁」のような形を判定したいなら Like と覚えておけば迷いません。

Q. ワークシート関数の SEARCH や FIND は VBA で使えますか?

WorksheetFunction 経由で呼べます。ただ、実機で WorksheetFunction.Search("大阪", "東京都千代田区") を試すと、見つからないときは実行時エラー1004(WorksheetFunction クラスの Search プロパティを取得できません)で止まりました。VBA の中では、見つからないと 0 を返す InStr を使うのが素直です。

Q. 大量の行を InStr で調べると遅いです。

セルを1つずつ読む回数が多いと遅くなります。何万行もあるなら、範囲をまとめて配列に読み込んでから InStr で調べると速くなります。配列の使い方は、こちらで実測つきで説明しています。

【コピペOK】VBAの配列の使い方|Dim・ReDim Preserve・UBoundからセル範囲の一括読み込みまで(2万行が20倍以上速くなった実測つき)
VBAの配列を、Dimでの作り方・Array関数・ReDim Preserve・UBoundから、セル範囲を配列へ一度に読み込んで書き戻す方法まで、実際にExcelで動かしたコードで解説。2万行で20倍以上速くなった実測と、エラー9・13の原因と直し方もまとめました。

まとめ|「含む」は InStr > 0 から始める

  • 含むか・何文字目か → InStr(0なら見つからない)
  • 大文字小文字・全角半角を区別しない → InStr(1, 文字列, 探す文字, vbTextCompare)
  • 後ろから探す・ファイル名を取り出す → InStrRev
  • 形で判定する(コードの書式チェックなど) → Like
  • シートの中のセルを探す → Range.Find。Nothing の確認と、引数を全部書くことを忘れない

文字列の検索ができるようになると、「目で探して印を付ける」作業が、ボタン1つで終わる作業に変わります。まずは今日の表で、InStr の例を1つ動かしてみてください。0以外の数字が返ってきたら、それがあなたの最初の自動化です。

次に読む

【コピペOK】VBAのループ4種類の使い分け|For Next・For Each・Do While/Until・抜け方と無限ループの止め方(全コード実機確認)
VBAのループは、回数が決まっているならFor Next、セル範囲やシートを全部処理するならFor Each、どこで終わるか分からないならDo While/Do Until。While...Wendは覚えなくて大丈夫です。前判定と後判定の違い、Exit For/Exit Doでの抜け方、無限ループをEscキーで止める方法と防ぎ方まで、実機のExcelで全コードを動かして確かめました。
【もう迷わない】VBAで最終行を取得する方法5つと使い分け|End(xlUp)が1を返す・途中の空白・UsedRangeのズレ
VBAで最終行を取るなら、まずは ws.Cells(ws.Rows.Count, 1).End(xlUp).Row の1行です。データ0件でも1が返る・シート指定の漏れ・基準列の空白・Integerのオーバーフローという4つのつまずきと、Find・UsedRange・CurrentRegionとの使い分けを、Microsoft公式ドキュメントをもとにまとめました。

参考にした一次情報(2026年11月5日 確認)

InStr 関数|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/instr-function

InStrRev 関数|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/instrrev-function

Like 演算子|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/like-operator

Range.Find メソッド (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.range.find

Range.FindNext メソッド (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.range.findnext


当ブログは、Excel や VBA で手が止まった事務職のみなさんに、その場で直せる手順を届けたい思いで運営しています。
「記事が役に立った」「続きも読んでみたい」と感じていただけたら、下記リンクからのご利用・ご支援で応援してもらえると嬉しいです。

EXCEL VBA講座
スポンサーリンク
シェアする
メリ爺をフォローする

コメント

タイトルとURLをコピーしました