Tracks
VBAマクロをいくつか書いたことがあるなら、セル内に特定のテキストが存在するかを確認したくなる場面に必ず出会います。VBAでは、InStrは至る所で使う関数のひとつです。あるテキストの中に別のテキストが現れる位置を教えてくれます。セル内にテキストが存在するかの確認、文字列から値を抽出する処理、テキストのパターンに依存するマクロの条件分岐などに使えます。
このガイドでは、InStrの構文、いくつかの例、比較モードの仕組み(多くの人がここでつまずきます)、そして実際に再利用できるパターンを解説します。
VBAに進む前にしっかり基礎を固めたい方は、まずは当社のExcel Fundamentalsスキルトラックから始めることをおすすめします。経験がある方はAdvanced Excel Functionsコースで、関数がデータ分析の効率化にどう役立つかをさらに学んでください。
VBA InStr関数とは?
InStrは、ある文字列の中に別の文字列が最初に現れる位置を返すVBA関数です。
結果は次のように振る舞います。
- 見つかった場合は数値(マッチが始まる位置)を返す
- 見つからない場合は0を返す
例えば、文字列の5文字目に「cat」が現れるなら、5が返ります。存在しないなら0です。
VBA InStrの構文
以下がInStrの完全な構文です。
InStr([start], string1, string2, [compare])
各引数の意味は次のとおりです。
-
start(省略可):検索を開始する位置。省略時は位置1から始まります。 -
string1(必須):検索対象となる全文字列。 -
string2(必須):見つけたい文字列。 -
compare(省略可):比較方法(大文字小文字を区別するかどうか)を指定。省略時は既定の比較モードで、通常は大文字小文字を区別します。
簡易版としてstartとcompareを省略し(InStr(string1, string2))、使うこともできます。ただし、compareを指定する場合は、startも同時に指定する必要があります。
VBA InStrの動作
InStrは、文を左から右へ1文字ずつ読んでいくイメージです。
関数はstring1を走査し、string2が最初に一致する位置を探します。見つけた瞬間に停止し、一致が始まった位置を返します。
「一致」した位置は重要です。VBAは0ではなく1から数えるため、先頭の文字は位置1、次が2…となります。
VBA InStrの戻り値
InStrの結果の解釈は単純です。次のいずれかになります。
-
正の数値:一致が見つかった場合で、その開始位置を示します。
-
0:文字列内のどこにも一致がない場合
ただし、入力文字列がNullの場合、関数はNullを返します。基本的なマクロでは無視しがちですが、この違いが条件を静かに壊すことがあるので注意してください。
VBA InStrの基本例
ここから、VBAのInStr関数の使い方をいくつか例で示します。
文中の単語を見つける
メモ「Deliver before noon」に単語「before」が含まれるかを確認します。
Sub Before()
Dim result As Integer
result = InStr("Deliver before noon", "before")
MsgBox result
End Sub
上記のVBAの結果は9です。「before」は9文字目から始まるためです。
文字が存在するかを確認する
与えられた文字列に「0」という文字が存在するかを確認するには、次のVBAを使います。
Sub ChExist()
Dim result As Integer
result = InStr(“A1023”, “0”)
MsgBox result
End Sub
この場合、0より大きい結果は、その文字が見つかったことを意味します。
文字列の先頭から検索する
文字列の先頭から検索する場合、開始位置を指定する必要はありません。何も指定しなければ1から始まります。特に指示しない限り、これが毎回の既定です。
Sub ChExist()
Dim result As Integer
result = InStr("Report_2026_Final", "2026")
MsgBox result
End Sub
If文でのVBA InStrの使い方
実際のスプレッドシートでは、単に数値を求めるだけではなく、意思決定が目的です。InStrの最も一般的な使い方は、If文の中でデータを絞り込むことです。
このチュートリアル全体を通して、ID、CustomerName、Email、City、OrderNotesの列を持つサンプルデータセットOrdersを使用します。
If InStr(...) > 0 Then
InStrは何も見つからないと0を返すため、0より大きい数が返ったときに結果が存在すると判断します。
次の例では、OrderNotes列(5列目)を確認し、「Fragile」という語を見つけたら、6列目に「Handle Carefully」と書き込みます。
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
' Check if the order notes mention "Fragile"
If InStr(Cells(i, 5).Value, "Fragile") > 0 Then
Cells(i, 6).Value = "Handle Carefully"
End If
Next i
End Sub
キーワードの条件チェックとテキストのフィルタリング
InStrは、フレーズに多少の揺れがあっても、文字列内のキーワードを確認する用途にも使えます。例えば、以下のコードはメモに「Call」(「Call on arrival」や「Call before delivery」など)が含まれるかを確認します。見つけた場合は、6列目に「Cal Customer」というタグを付けてフラグを立てます。
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
' Check if the order notes mention “Call”
If InStr(Cells(i, 5).Value, “Call”) > 0 Then
Cells(i, 6).Value = “Call Customer”
End If
Next i
End Sub
VBA InStrの大文字小文字と比較モード
既定では、InStrは大文字小文字を区別します(vbBinaryCompare)。たとえば「chicago」を検索しても、データが「Chicago」なら、InStrは0を返します。
この問題を解決するには、compare引数を使います。指定内容は次のとおりです。
-
vbBinaryCompare(既定):大文字小文字を区別(「A」と「a」は別物) -
vbTextCompare:大文字小文字を区別しない(「A」と「a」は同じ)
次の例では、「Fragile items」の中から小文字の「fragile」を探すため、InStrは0を返します。
Sub CheckFragile()
Dim result As Integer
result = InStr(1, "Fragile items", "fragile", vbBinaryCompare)
MsgBox result
End Sub
一方、vbTextCompareを使えば、同じ検索でも大文字小文字を無視して1が返ります。
Sub CheckFragile()
Dim result As Integer
result = InStr(1, "Fragile items", "fragile", vbTextCompare)
MsgBox result
End Sub
開始位置を指定したVBA InStr
文字列の先頭から検索したくない場合もあります。start引数で検索開始位置を指定します。
次の例では、startを10に設定しているため、VBAは先頭ではなく10文字目から検索を開始します。その後、文字列の後半で"delivery"を見つけます。
Sub CheckUrgent()
Dim result As Integer
result = InStr(10, “Deliver before noon - urgent delivery”, “delivery”)
MsgBox result
End Sub
上記の結果は31で、"delivery"が始まる位置です。
この方法は、2回目の出現位置を取りたいときや、繰り返しパターンで既知の接頭辞を無視したいときに有用です。
VBA InStrとInStrRevの違い
すでに見たように、InStrは左から右へ検索します。対して、InStrRevは右から左へ検索します。
例えば、InStrRevを使ってメール内の最後のドットを見つけます。結果は18で、「com」の前のドットの位置です。
Sub CheckChr()
Dim result As Integer
result = InStrRev("john.jacobs@email.com", ".")
MsgBox result
End Sub
InStrRevは、最後の出現位置が必要なときや、ファイル名・メール・パスを扱うときに特に役立ちます。
VBA InStrの一般的なユースケース
VBAのInStr関数の動作例を見たところで、よくあるユースケースを確認しましょう。
セルにキーワードが含まれているかの確認
顧客注文のデータセットがあり、特別な対応が必要な注文にフラグを付けたいとします。次のコードはOrderNotes列を見て、「noon」を含むものにフラグを付けます。
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
If InStr(1, "Deliver before noon", "noon", vbTextCompare) > 0 Then
' Logic to mark as "Morning Delivery"
End If
Next i
End Sub
メール形式の簡易チェック
InStrで簡易的にメール形式をチェックすることも可能です。例えば、以下のコードはメールに@が含まれているかを確認し、6列目に「Valid Email Format」と書き込みます。
Sub ValidateEmail()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
If InStr(Cells(i, 3).Value, "@") > 0 Then
Cells(i, 6).Value = "Valid Email Format"
End If
Next i
End Sub
カンマやハイフンなどの区切り記号の検出
InStrを使って、ハイフン、カンマ、スラッシュがテキストに存在するかを確認できます。次の例では、OrderNotes(E列)をループし、テキストにカンマがあるかを確認して、結果をF列に書き込みます。
Sub ValidateEmail()
Dim i As Integer
Dim commaPos As Integer
Dim OrderNotes As String
For i = 2 To 51
OrderNotes = Cells(i, 5).Value
commaPos = InStr(1, OrderNotes, ",")
' If a comma exists, mark it
If commaPos > 0 Then
Cells(i, 6).Value = "Has comma"
Else
Cells(i, 6).Value = "No comma"
End If
Next i
End Sub
VBA InStrでよくあるミス
経験豊富な開発者でも、InStrにまつわる問題でコードが想定外の挙動をすることがあります。ここでは、私が遭遇した一般的な問題とその対処法を挙げます。
-
InStrが1始まりであることを忘れる:位置は0ではなく1から始まることを常に意識してください。PythonやJavaScriptの経験があると最初は違和感があります。
-
InStrをTrue/Falseのように扱う:
InStrはTrue/Falseを返しません。見つけたい場合は、結果が> 0かどうかをチェックする必要があります。 -
大文字小文字の区別を無視する:既定では
InStrは大文字小文字を区別します。大小を区別したくない場合は、compare引数にvbTextCompareを指定しましょう。 -
string1とstring2を取り違える:最初の引数が「検索対象」、2番目が「探す文字列」です。
InStr(SearchTerm, FullText)のように書くと、常に0になります。
VBAの他の文字列関数との比較
InStrはテキスト内での位置を示すのが主用途なので、他の文字列関数と比較してみましょう。
InStr vs. Like
Like演算子はパターンマッチに使います。例えば、以下のコードは「Fragile」をチェックしますが、パターン*(前後に任意の文字列)を用いています。
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
If Cells(i, 5).Value Like "*Fragile*" Then
Cells(i, 6).Value = "Handle Carefully"
End If
Next i
End Sub
InStrはテキストの存在確認に、Likeは複雑なパターンでの確認に使い分けましょう。
InStr vs. Replace
InStrでセル全体の値を置き換えることもできますが、Replace関数はセル内の特定のテキストだけを置き換えます。
以下の例では、Replace関数がテキスト内の「Fragile」を「Handle Carefully」に直接置換します。
Sub ReplaceOrder()
Dim i As Integer
For i = 2 To 51
Cells(i, 5).Value = Replace(Cells(i, 5).Value, "Fragile", "Handle Carefully")
Next i
End Sub
InStr vs. Mid
Mid関数は文字列からテキストを抽出するために使います。そのため、位置を取得した後に抽出する目的でInStrとMidを組み合わせて使うことがよくあります。
以下のコードは、データセットのメールからドメインを抽出します。InStr関数でメール内の「@」の位置を見つけ、Midでその直後から抽出します。最後に抽出したドメインをH列に書き込みます。
Sub ExtractDomain()
Dim i As Integer
Dim pos As Integer
Dim domain As String
For i = 2 To 51
pos = InStr(1, Cells(i, 3).Value, "@")
If pos > 0 Then
domain = Mid(Cells(i, 3).Value, pos + 1)
Cells(i, 8).Value = domain
End If
Next i
End Sub
InStr vs.Split
Split関数は、区切り文字を指定してテキストを分割するために使います。
以下の例では、A列の各行を読み込み、カンマがあるかを確認してからテキストを2つに分割します。Name → B列、City → C列に書き込みます。
Sub SplitTextColumn()
Dim i As Integer
Dim lastRow As Integer
Dim parts As Variant
Dim text As String
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
text = Cells(i, 1).Value
' Only split if a comma exists
If InStr(1, text, ",") > 0 Then
parts = Split(text, ",")
Cells(i, 2).Value = parts(0) ' Name
Cells(i, 3).Value = parts(1) ' City
End If
Next i
End Sub
VBA InStr活用のベストプラクティス
VBAでのエラーを避けるために、私が時間短縮に役立てている次のベストプラクティスをおすすめします。
-
大文字小文字が重要でないならvbTextCompareを使う:実データでは大文字小文字が揺れるのが普通なので、既定の
compare引数に頼るとマッチを見逃すことがあります。 -
「If」と組み合わせて明確なロジックにする:
InStr単体は数値を返すだけなので、常に何らかの処理に結びつけるようにしましょう。 -
厳密な位置ではなく> 0で判定する(位置が本当に必要な場合を除く)。
-
パース処理は読みやすく保つ。1行に関数を詰め込みすぎない。
まとめ
InStrはシンプルですが、至る所で使うことになります。ある文字列中で別の文字列が現れる位置を返し、その一つの数値が、存在確認、抽出開始位置、次にマクロが取るべき行動といった多くの判断を支えます。単体では検索にすぎませんが、Mid、Replace、Splitのような関数と組み合わせると、実務的なワークフローの一部として機能します。
高度な分析スキルを身につけるにはData Analysis in Excelコースをご受講ください。また、データ変換やM言語を学ぶにはIntermediate Power Query in Excelコースもおすすめです。
FAQs
InStrは実際に何を返しますか?
一致が始まる位置を返します。何も見つからない場合は0を返します。
InStrは大文字小文字を区別しますか?
はい。InStrは既定で大文字小文字を区別します。”Fragile”と”fragile”は別物として扱われます。大文字小文字を区別したくない場合はvbTextCompareを使用してください。
InStrが1始まりとはどういう意味ですか?
文字列の最初の文字は位置1であり、0ではありません。他の関数に結果を渡すときに重要です。
いずれかの値がNullの場合はどうなりますか?
結果も0ではなくNullになります。
InStrとInStrRevの違いは何ですか?
InStrは左から右へ検索し、InStrRevは右から左へ検索します。最後の出現位置が重要な場合は後者を使います。