「VBA InStr 見つからない」で検索してここに来た方の多くは、
本当は文字が含まれているはずなのに、InStrが0を返す状態に困っているはずです。
まず結論から言うと、InStrは見つからない場合は0を返します。
つまり、コードが間違っているというより「データ側になにか不備がある」ことがほとんどです。
この記事では、よくある原因と解決方法を、コピペOKのコード付きでまとめます。
まず確認:InStrは「何を返す関数」?
InStrは、文字列の中から指定した文字が最初に出てくる位置を返します。見つからなければ0です。
pos = InStr(文字列A, 探す文字)
If pos > 0 Then
' 含まれている
Else
' 見つからない(0)
End If
原因1:大文字/小文字が違う(デフォルトは区別されやすい)
InStrは比較方法を指定できます。
大文字小文字を区別しないで探したいなら、vbTextCompare を付けるのが定番です。
' 大文字小文字を区別しない(おすすめ)
If InStr(1, "ABC", "abc", vbTextCompare) > 0 Then
MsgBox "見つかった"
End If
また、モジュールの先頭に Option Compare Text を書く方法もあります(モジュール全体に影響します)
Option Compare Text
原因2:前後の空白(スペース)が混ざっている
セルの値に、前後の空白が入っていると「見つからない」原因になります。
まずは Trim で前後の空白を落としてから探すのが基本です。
Dim s As String
s = Trim(CStr(Range("A1").Value))
If InStr(1, s, "東京", vbTextCompare) > 0 Then
MsgBox "見つかった"
End If
原因3:改行コードが混ざっている(Alt+Enterなど)
セル内改行(Alt+Enter)などで、文字の間に改行が入っていると、見た目は同じでも一致しないことがあります。
改行には複数種類(CR/LF/CRLF)があるため注意が必要です。
対策:改行をスペースに置換してから探す。
Dim s As String
s = CStr(Range("A1").Value)
s = Replace(s, vbCrLf, " ")
s = Replace(s, vbCr, " ")
s = Replace(s, vbLf, " ")
If InStr(1, s, "東京", vbTextCompare) > 0 Then
MsgBox "見つかった"
End If
原因4:見えない空白(nbsp:ノンブレークスペース)が混ざっている
この空白は見た目では分かりにくく、Trimでも消えないことがあり、InStrが0になる原因になります。
対策:ChrW(160) を通常の半角スペースに置換します。
Dim s As String
s = CStr(Range("A1").Value)
' nbsp(ChrW(160)) を普通のスペースへ
s = Replace(s, ChrW(160), " ")
s = Trim(s)
If InStr(1, s, "東京", vbTextCompare) > 0 Then
MsgBox "見つかった"
End If
原因5:数値/日付/エラー値など「文字列ではない」ものを渡している
セルの値が数値や日付でも、VBA的には「文字列として扱えていない」ケースがあります。
基本は CStr で文字列に変換してからInStrするのが安全です。
Dim s As String
s = CStr(Range("A1").Value)
If InStr(1, s, "123", vbTextCompare) > 0 Then
MsgBox "見つかった"
End If
※セルがエラー値(#N/Aなど)の場合は、先にエラー判定してください。
If IsError(Range("A1").Value) Then Exit Sub
困ったらこれ:InStr用の「正規化(整える)関数」テンプレ
実務では、探す前に文字列を「整える」だけで解決することが多いです。
以下は、空白・改行・nbspをまとめて整えるテンプレです(コピペOK)。
Option Explicit
Private Function NormalizeText(ByVal v As Variant) As String
Dim s As String
If IsError(v) Then
NormalizeText = ""
Exit Function
End If
s = CStr(v)
' nbsp(ChrW(160)) を普通のスペースへ
s = Replace(s, ChrW(160), " ")
' 改行をスペースへ
s = Replace(s, vbCrLf, " ")
s = Replace(s, vbCr, " ")
s = Replace(s, vbLf, " ")
' 前後の空白を削除
s = Trim(s)
NormalizeText = s
End Function
Public Function ContainsText(ByVal v As Variant, ByVal keyword As String) As Boolean
Dim s As String
s = NormalizeText(v)
ContainsText = (InStr(1, s, keyword, vbTextCompare) > 0)
End Function
使い方:
Sub TestContains()
If ContainsText(Range("A1").Value, "東京") Then
MsgBox "含まれています"
Else
MsgBox "見つかりません"
End If
End Sub
それでも見つからないときの最終手段:文字コードを調べる
「見た目は同じなのに一致しない」場合、文字コードが違うことがあります。
次のマクロで、文字ごとのコードをイミディエイトウィンドウに出せます(原因特定に強いです)。
Sub DumpCharCodes()
Dim s As String, i As Long
s = CStr(Range("A1").Value)
For i = 1 To Len(s)
Debug.Print i, Mid$(s, i, 1), AscW(Mid$(s, i, 1))
Next i
End Sub
まとめ:「InStrが0」はデータのクセを疑うのが近道
- InStrは見つからないと0を返す
- 大文字小文字の違いは vbTextCompare / Option Compare Text で対策
- 空白・改行・nbsp(ChrW(160))など「見えない文字」を整えると解決しやすい
- 困ったら正規化関数を作って、探す前に整える
このテンプレを入れておけば、「VBA InStr 見つからない」問題はかなりの確率で解決できます。


コメント