【VBA入門】InStrで文字列検索する方法を6つのステップでマスター

VBAのInStr関数で文字列を検索する方法が知りたい
大文字と小文字を区別して検索したい
正規表現を使用して文字列を検索したい

こんにちは!フリーランスの長野です。

VBAである文字列の中に指定の文字列が含まれているか検索したい場合、InStr関数を使用します。この記事ではそんなInStr関数について、使い方の基礎から応用的な使い方まで6つのステップでわかりやすく解説していきます。

今回はInStr関数について、基礎から応用までをわかりやすく解説していきますのでぜひ参考にしてください。

目次

VBAのInStr関数とは

InStr関数は、特定の文字列が別の文字列内で最初に見つかった位置を返します。なお、戻り値の型はVariant型です。

InStr関数は以下のように記述して使用します。

InStr([start, ]string1, string2[, compare])

引数の中で「[ ]」で囲まれた部分は省略することができます。引数の指定について表にまとめました。

引数定数(値)説明
start各検索の開始位置を設定する数式を指定
省略すると、先頭の文字から検索
Null が含まれている場合はエラーが発生
引数 compareが指定されている場合は必須
string1検索先の文字列
string2検索する文字列
comparevbUseCompareOption(-1)Option Compare ステートメントの設定を使用して比較
vbBinaryCompare(0)バイナリで比較
vbTextCompare(1)テキストで比較
大文字、小文字の区別なし
全角、半角の区別なし

戻り値は引数の指定によって変わってくるので、これも表にまとめます。

条件戻り値
string1の長さが00
string1がNullNull
string2の長さが0start
string2がNullNull
string2がみつからない0
string2がstring1内でみつかった最初にみつかった位置
startの値がstring2の文字数より大きいとき0

引数のstring1の中にstring2が複数存在するときは、最初にみつかった位置を返します。

なお、バイト型のデータが格納された文字列の場合はInStrB関数を使用します。InStrB関数は最初にみつかったバイト位置を返します。

VBAのInStr関数の使い方

ここではVBAのInStr関数について、基本的な使い方から応用的な使い方まで6つのパターンを解説していきます。

InStr関数の基本的な使い方

それでは基本的な使い方についてみていきましょう。以下のサンプルコードをご覧ください。

Sub macro1()
    Dim string1 As String, string2 As String
    string1 = "侍エンジニア"
    string2 = "塾"
    
    MsgBox "「" & string2 & "」の位置は" & InStr(string1, string2) & "番目"
End Sub

InStr01

実行結果

このサンプルコードでは、InStr関数を使って文字列string1からstring2の位置を取得しています。

InStrRev関数の使い方

InStr関数を使う場合、文字列の前方から検索して位置を取得することができます。それでは文字列の後方から検索して位置を取得したい場合はどうすればいいのでしょうか?

そんな場合はInStrRev関数を使います。

後方からの検索ですので検索先の文字列の中に指定の文字列が複数含まれている場合などに、一番後ろの文字列の位置を前方からの順番で取得することができます。

InStrRev関数は以下のように記述します。

InstrRev(string1, string2 [, start[, compare]])

引数の中で「[ ]」で囲まれた部分は省略することができます。InStrRev関数の引数の指定順はInStr関数とは違うので、注意しましょう!

引数、戻り値の説明についてはInStr関数と同じですので、さきほどの章の表を参考にしてくださいね。

それではサンプルコードで確認していきましょう。

Sub macro2()
    Dim string1 As String, string2 As String
    string1 = "侍エンジニア侍エンジニア"
    string2 = "塾"
    
    MsgBox "後方からの検索では「" & string2 & "」の位置は" & InStrRev(string1, string2) & "番目"
End Sub

InStr02

実行結果

このサンプルコードでは、InStrRev関数を使って文字列string1から文字列string2を後方から検索しています。後方からの検索ですので、一番後ろの文字列の位置が前方からの順番で返ってきています。

Left関数、Mid関数との組み合わせ

InStr関数を使うと含まれる文字列の位置が取得できるので、その位置情報を元に文字列を分割することができます。文字列を分割する関数にはSplit関数がありますが、Split関数の場合は指定の区切り文字1文字での分割になります。

これに対してInStr関数を使うと指定の文字列で分割することができます。InStr関数を使って文字列を分割する場合、Left関数やMid関数などを使って分割後の文字列を取得することになります。

Left関数は文字列の先頭から、指定した文字数文の文字列を抜き出して返します。

Left関数は以下のように記述します。

Left(string, length)

  • 引数のstringには、抜き出す元の文字列を指定します。
  • 引数のlengthには、抜き出す文字数を指定します。
  • Mid関数は文字列から抜き出す先頭位置を指定し、指定文字数文を抜き出して返します。


Mid関数は以下のように記述します。

Mid(string, start[, length])

  • 引数のstringには、抜き出す元の文字列を指定します。
  • 引数のstartには、抜き出す先頭位置を指定します。
  • 引数のlengthには、抜き出す文字数を指定します。
  • 引数のlengthは記述を省略することができます。


それではサンプルコードで確認していきましょう。

Sub macro3()
    Dim string1 As String, string2 As String
    string1 = "侍エンジニア"
    string2 = "エンジニア"
    
    'string2の位置を取得
    Dim num As Variant
    num = InStr(string1, string2)
    
    '分割後の文字列を取得
    Dim msg1 As String, msg2 As String
    msg1 = Left(string1, num - 1)
    msg2 = Mid(string1, num + Len(string2))
    
    MsgBox msg1 & ", " & msg2
End Sub

InStr03

実行結果

このサンプルコードでは、InStr関数を使って文字列string1から文字列string2の位置を取得しています。

またLeft関数を使って、string1からstring2より前の文字列を抜き出しています。さらにMid関数を使って、string2より後の文字列を抜き出しています。

Mid関数を使って抜き出す際には、string2の文字列数をLen関数を使って算出し、抜き出す先頭位置を指定しています。Mid関数や、Left関数、Right関数とInStr関数を組み合わせて使う方法については、こちらのサイトで詳しく解説しています。

文字列中に複数含まれる場合

これまでは、検索する対象の文字列中に検索したい文字列が1つ含まれる場合についてお伝えしてきました。もし、検索したい文字列が2つ以上含まれている場合はどうしたらいいのでしょうか?

検索したい文字列が2つ以上含まれている場合について、サンプルコードで確認していきましょう。

Sub macro7()
    Dim string1 As String, string2 As String
    string1 = "侍エンジニア侍エンジニア侍エンジニア"
    string2 = "塾"
    
    Dim i As Integer, msg As String
    i = InStr(i + 1, string1, string2)
    Do While i > 0
        msg = msg & i & ", "
        i = InStr(i + 1, string1, string2)
    Loop
    
    MsgBox "「" & string2 & "」の位置は" & msg & "番目"
End Sub

実行結果:
InStr07

InStr関数は第1引数で検索のスタート位置を指定することができます。検索対象となる文字列に検索したい文字列が複数含まれる場合は、見つかった位置の1つ後ろの位置から検索を再び行えば次の位置を検索することができます。

これを見つからなくなるまでループで繰り返します。InStr関数は見つからなくなると0(ゼロ)を返しますので、戻り値が0(ゼロ)になるまで繰り返すことで、すべての位置を取得することができます

複数の文字列で検索する方法

InStr関数は複数の文字列で検索することはできません。複数の文字列で検索する場合は論理演算子のOrやAndを使う必要があります。

サンプルコードで確認しましょう。

Sub macro4()
    Dim string1 As String, string2 As String, string3 As String
    string1 = "侍エンジニア"
    string2 = "侍"
    string3 = "塾"
    
    Dim msg As String
    
    'Or検索
    If InStr(string1, string2) <> 0 Or InStr(string1, string3) <> 0 Then
        msg = msg & "「" & string2 & "」もしくは「" & string3 & "」がみつかりました" & vbCrLf
    Else
        msg = msg & "「" & string2 & "」、「" & string3 & "」どちらもみつかりません" & vbCrLf
    End If
    
    'And検索
    If InStr(string1, string2) <> 0 And InStr(string1, string3) <> 0 Then
        msg = msg & "「" & string2 & "」、「" & string3 & "」どちらもみつかりました" & vbCrLf
    Else
        msg = msg & "「" & string2 & "」、「" & string3 & "」どちらかもしくは両方みつかりません" & vbCrLf
    End If
    
    MsgBox msg
End Sub

InStr04

実行結果

大文字と小文字の区別について

InStr関数は引数を設定しなければ、大文字と小文字を区別して位置を返します。大文字と小文字の区別をなしにしたい場合は、引数のcompareをvbTextCompareに指定します。

なお、引数のcompareを指定する場合は引数のstartを指定する必要があります。

サンプルコードで確認しましょう!

Sub macro5()
    Dim string1 As String, string2 As String
    string1 = "Hello VBA!"
    string2 = "vba"
    
    Dim num As Variant, msg As String
    
    'バイナリで比較
    num = InStr(string1, string2)
    If num <> 0 Then
        msg = msg & "「" & string2 & "」の位置は" & num & "番目" & vbCrLf
    Else
        msg = msg & "「" & string2 & "」はみつかりませんでした" & vbCrLf
    End If
    
    'テキストで比較
    num = InStr(1, string1, string2, vbTextCompare)
    If num <> 0 Then
        msg = msg & "「" & string2 & "」の位置は" & num & "番目" & vbCrLf
    Else
        msg = msg & "「" & string2 & "」はみつかりませんでした" & vbCrLf
    End If
    
    MsgBox msg
End Sub

InStr05

実行結果

このサンプルコードでは、InStr関数を使って文字列string1から文字列string2の位置を取得しています。string2は「vba」と小文字の文字列ですが、string1には「VBA」と大文字の文字列であれば含まれています。

InStr関数の引数compareを指定しない場合は、バイナリで比較が行われ大文字と小文字を区別しstring2の位置はみつかっていません。引数のcompareをvbTextCompareで指定した場合は、テキストで比較が行われ大文字と小文字を区別せずにstring2の位置がみつかっています。

ワイルドカードや正規表現の使用について

InStr関数では正規表現を指定して使用することはできません。

代わりにLike演算子とワイルドカードを使う方法についてご紹介します。

ワイルドカードとは、あるパターンにマッチするように表現した文字列のことです。

ワイルドカードで使える文字は、正規表現で使える文字に比べて少ないので、正規表現に比べて表現できるパターンには制限がありますが、正規表現をワイルドカードで代替できることも多いです。

サンプルコードで確認しましょう。

Sub macro6()
    Dim string1 As String, string2 As String
    string1 = "侍エンジニア"
    string2 = "侍*塾*"
    
    'Likeを使用
    If string1 Like string2 Then
        MsgBox "「" & string2 & "」がみつかりました"
    Else
        MsgBox "「" & string2 & "」がみつかりません"
    End If
End Sub

InStr06

実行結果

このサンプルコードでは、文字列string2に「*」(アスタリスク)が含まれています。Like演算子では、「*」(アスタリスク)などのワイルドカードを使った部分的に合致した場合の条件分岐を記述することができます。

string1の「侍エンジニア」はstring2の「侍*塾*」のパターンと一致しますので、Trueが返ってきています。ワイルドカードでは「*」(アスタリスク)の他にも以下の表のような文字を使って、マッチングのパターンを指定することができます。

文字説明
?任意の1文字
*0文字以上の文字
#0~9の半角数字
[charlist]charlistに含まれる全角または半角の1文字
[!charlist]charlistに含まれない全角または半角の1文字

Like演算子とワイルドカードの使い方については、こちらのサイトで詳しく解説しています。

まとめ

ここでは、InStr関数、InStrRev関数の使い方について説明しました。InStr関数を使うと含まれる文字列の位置を取得することができるので、その位置を使って分割などの文字列操作もできるようになります。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次