タイトルが分かりにくいですかね。つまり、こういうことです。
こうなっていたとき、じゃ「n番目の"-"は何文字目」にあるのか調べようってことです。文字列の中で、任意の文字の位置を調べるにはInStr関数が便利です。InStr関数は、一般的に次のように使われます。
でも実は、ほかにも引数があって、先頭には次のような引数を指定できます。
引数「開始位置」を指定すると「どこ(何文字目)から探すか」を指定できます。引数「開始位置」は省略できます。普通は省略しますよね。省略すると「1」を指定したと見なされます。一般的に探すときは文字列の先頭(1文字目)から探すことが多いので、省略することが多いわけで。でも上図のような状態で、3文字目から探せば、2つめの"-"の位置が分かるわけです。
まとめてみましょう。
ちなみに、最初の「先頭から探す」ときは「InStr("…", "・")」のように引数「開始位置」を省略してもいいですし、「InStr(1, "…", "・")」でもいいです。
なので、次のようにしてn番目の位置を調べることができます。
Sub Sample1() Dim i As Long, P As Long For i = 1 To 3 '' ← 3番目の位置 P = InStr(P + 1, "A-B-C-D-E", "-") Next i MsgBox P & "文字目" End Sub
変数名のPは「Position」のつもりです。関係ないですけど、最近はできるだけ短い変数名を使うのがマイブームですw どうでもいい変数にはどうでもいい名前をつけた方が、逆に重要な変数名が際立ちます。何でもかんでも長いしっかりした名前をつければいいってのも、どうかと思います。個人的な感覚ですけど。
これ、もちろん次のようなケースでも対応できます。
Sub Sample3() Dim i As Long, P As Long For i = 1 To 4 ''←4番目の位置 P = InStr(P + 1, "西野-佐々木-桜井-東-松本", "-") Next i MsgBox P & "文字目" End Sub
せっかくですから、Functionにしちゃいましょうか。
Sub Sample4() Dim buf As String, N As Long buf = "西野-佐々木-桜井-東-松本" N = InStr2(buf, "-", 3) MsgBox Left(buf, N - 1) & vbCrLf & Mid(buf, N + 1) End Sub Function InStr2(str1 As String, str2 As String, pos As Long) Dim i As Long, P As Long For i = 1 To pos P = InStr(P + 1, str1, str2) Next i InStr2 = P End Function
なお、今回の"西野-佐々木-桜井-東-松本"に"-"は4つしかありません。このときあり得ない5番目のように指定すると、For Nextの最後で見つかりませんから、最後のInStr関数は0を返します。なので、次のようにできます。
まぁ、Functionの方で確認してもいいですけど。
Function InStr2(str1 As String, str2 As String, pos As Long) Dim i As Long, P As Long If pos > UBound(Split(str1, str2)) Then InStr2 = -1 Exit Function End If For i = 1 To pos P = InStr(P + 1, str1, str2) Next i InStr2 = P End Function
でも、本来であれば呼び出し元のマクロ側で、ちゃんと確認すべきでしょうね。