和風スパゲティのレシピ

日本語でコーディングするExcelVBA

指定の文字列より右側(後方)を削除する

テキストからある文字列を検索し、それより右側を削除するコードを解説します。

捉え方が違うだけで、左からある文字列までを取得するとも言えますね。

基本の書き方

' 文字列を右側から検索する場合
文字列より右側を削除 = Left(元の文字列, InStrRev(元の文字列, 検索文字列) - 1)

' 文字列を左側から検索する場合
文字列より右側を削除 = Left(元の文字列, InStr(元の文字列, 検索文字列) - 1)

実行サンプル

ファイルパス = "C:\Users\ユーザー名\Desktop\テストフォルダ\Book1.xlsx"

' ファイル名(最後の\より右側)を削除してフォルダパスを取得
フォルダパス = Left(ファイルパス, InStrRev(ファイルパス, "\") - 1)

解説

削除する基準の文字列をInstr関数/InstrRev関数で検索し、
見つかった位置の1文字手前までをLeft関数で取得しています。


検索文字列が複数登場する場合は、
前から探す場合はInstr関数、後ろから探す場合はInstrRev関数を使います。


「右側を削除」と言った場合は、後ろから探すInstrRevを使う方が多いですかね。
前から探すInstrを使う場合は「左側を持ってくる」と表現することが多そうです。


InstrRev関数は後ろから検索していく関数ですが、
見つかった位置はInstr関数と同じく「前から」何文字目かを返してくれます。

よって関数名以外はコードを書き換える必要はありません。


なお、検索文字列がない場合はLeft関数に「-1」が渡ってエラーになってしまうため、
Instr関数の結果が0でないかをIf文で分岐してこれを回避してください。

If InStrRev(ファイルパス, "\") > 0 Then 
    フォルダパス = Left(ファイルパス, InStrRev(ファイルパス, "\") - 1)
End If

検索する文字列も結果に含めたい場合

先ほどのフォルダパスに最後の「\」を含めたいときなど、
検索文字列は消さずに残したい場合は、まずそれが1文字の場合は

文字より右側を削除 = Left(元の文字列, InStrRev(元の文字列, 検索文字))

と、Left関数の文字数指定にあった-1を消すだけでOKです。


検索文字列が2文字以上の場合は、

文字より右側を削除 = Left(元の文字列 _
    , InStrRev(元の文字列, 検索文字列) - 1 +Len(検索文字列))

と、Left関数で取ってくる文字数に「検索文字列の長さ」を足します。


ただ、こういった計算はわかりにくく計算間違いが怖いので、

文字より右側を削除 = Left(元の文字列 _
    , InStrRev(元の文字列, 検索文字列) - 1) & 検索文字列

と、削除が終わった後で検索文字列をもう一度くっつけた方が楽かもしれません。

お好きな方をお使いください。

別解:Split関数を使う方法

ここまでは「ある文字列を検索して、その位置をもとに文字列を加工する」という、
文字列操作の基本に忠実なコードを解説しました。

Left(他にはRight/Mid) + Instrの書き方は必修項目ですので、
まずはこれをマスターしましょう。


さてマスターしたうえで、実はこの処理はもっと簡単なコードで書けます。

それがこちら↓

文字より右側を削除 = Split(元の文字列, 検索文字列)(0)

MsgBox Split("愛媛産みかん","産")(0) ' ← 「愛媛」が表示されます。

Split関数で元の文字列を検索する文字で分割し、その初項をとってくることでも、
目的の処理は果たせます。


Split関数は配列を返す関数ですので、丁寧にコードを書いた場合は

商品名 = "愛媛産みかん"

Dim 配列
配列 = Split(商品名, "産")

' この時点で「配列」は、第0項に「愛媛」、第1項に「みかん」が入っている

産地 = 配列(0)

こうなるのですが、Splitが返す配列を変数に入れずに直接参照すれば、

産地 = Split(商品名,"産")(0)

と、Split(~~)(0)のように書いてしまえるということです。


Split関数を「カンマとかコロンとかの区切り記号に使うもの」と考えていた人は、
「普通の文字列の検索にも使えるもの」と視野を広げてみましょう。

Split関数は「包丁でぶつ切り」するイメージが強いかもしれませんが、
「刀で真っ二つ」にするのにも非常に便利な関数です。


ただし、検索文字列がなかったときには元の文字列が全部返ってきてしまうことや、
前方の検索文字列しか使えない(InstrRevの代わりはできない)など、
この方法は万能ではありません。


文字列操作の基本はやっぱりInstr関数だと思いますので、
基本の型としてInstrをマスターし、実践技としてSplitを身につけ、
どちらもしっかり扱えるようになっておきましょう。

おまけ:文字列処理は関数化しておくと便利

文字列を操作するコード全般に言えることなのですが、
式中に「元の文字列」が何度も登場するため、コードが汚くなりやすいです。


例えば「Cells(R + i, C)」セルの"("より右を消したいときは、

Cells(R + i, C) = Left(Cells(R + i, C), InStr(Cells(R + i, C), "(") - 1)

みたいになって、ぱっと見なにやってるか分からないコードになりますし、
さらには"("がなかったとき用のIf文まで書くとなると面倒ですよね。


ということで、文字列処理を多くやる人は、↓のように汎用関数を作ってみましょう。

' 目的:汎用関数を作って↑のコードをこう書けるようにしたい
Cells(R + i, C) = 右から文字列までを削除(Cells(R + i, C), "(")

' 用意する汎用関数
Function 右から文字列までを削除(ByVal 元の文字列 As String, 検索文字列 As String) As String

    Dim instr位置 As Long
    instr位置 = InStrRev(元の文字列, 検索文字列)
    
    If instr位置 > 0 Then
        右から文字列までを削除 = Left(元の文字列, instr位置 - 1)
    Else
        右から文字列までを削除 = 元の文字列
    End If

End Function

' 使用例
フォルダパス = 右から文字列までを削除(ファイルパス, "\")

使用例だけを見ると、劇的に読みやすくなっていますよね?


関数は一度作ってしまえばあとは使いまわすことができますし、
何なら自分で作らなくても、これをコピペしても動きます。

私と共同開発したつもりになって、持って帰って使ってみてください。


関数と聞くと難しく感じるかもしれませんが、コードを見ればわかる通り、
中身は上で紹介したコードそのままです。

文字列操作は関数化が楽ちんで、その割に関数化の効果が大きいので、
関数づくりの練習にぴったりだと思います。


Functionプロシージャ勉強してみたいけど難しそうだな~って思っている方は、
ちょうどいいのでこの機会に始めて見るといいかもしれません。



今回の「指定文字列より左側を取り出す」や、
他には「文字から文字までを取ってくる(例えばカッコの中身)」など、
私が作成した文字列操作の汎用関数集が下記のページにあります。

関数作成の参考にするなり、中身を見ないでコピーして使うなり、
ご自由にお持ち帰りください。

www.limecode.jp