テキストから2つの文字列を検索し、その間にある文字列を置換したり、削除する方法を解説します。
1.RangeオブジェクトのReplaceメソッドを使う
一番簡単な方法は、Rangeオブジェクト(セルやセル範囲)のReplaceメソッドを使う方法です。
例えばA2:A100にあるテキストの「カッコの中身」を一括で消したい場合は、
以下のコードを実行します。
Range("A2:A100").Replace "(*)", "" , Lookat:= xlPart
削除ではなく置換したい場合は、""を置換後の文字列にします。
他の方法と違い、RangeオブジェクトのReplaceメソッドは、
ワイルドカード「*」を使えるのが非常に便利です。
' Replace「メソッド」ならワイルドカード*が使用可能 Range("A1") = "みかん(和歌山産)" Range("A1").Replace "(*)", "" MesgBox Range("A1").Value ' ← みかんが表示されます。 ' Replace「関数」ではできない MsgBox Replace("みかん(和歌山産)","(*)","") ' ←置換はできず、みかん(和歌山産)のまま
↑このように、Replace関数ではワイルドカードは使えません。
Replaceメソッドの注意点
RangeオブジェクトのReplaceメソッドとは、
ワークシート上で「Ctrl+h」で呼び出す「置換」機能のことです。
この「検索と置換」ダイアログですが、注意しなければいけないのが、
「各種設定は前に実行したときの設定を引き継ぐ」という点です。
一番危険なのが「セルの内容が完全に同一であるものを検索する」のチェックで、
これがついているかいないかで、
Range("A2:A100").Replace "(*)", ""
このコードが「みかん(和歌山産)⇒みかん」を置換してくれるかどうかに差が出ます。
この「前回設定の引継ぎ」は、手作業だろうとマクロだろうと引き継ぎますし、
置換と検索が設定を共有していますので、
- マクロを実行する前にユーザーがCtrl+F検索で「完全一致」検索をした。
- Findメソッドで完全一致(LookAt:=xlWhole)検索するマクロを実行した。
などがあると、「今まで動いてたのに急に動かなくなった!」になりかねません。
なので、本当はすべてのオプションを指定した方がいいのですが、
面倒でもLookAt:=xlPartだけはきっちり書いておきましょう。
また、もう一つ注意しなければいけないのが、
Replaceメソッドはオートフィルターによって非表示になっているセルを検知できません。
これもユーザーの操作に影響を受ける部分なので、
ユーザーがフィルターをかけたまま実行したとき用の対策を取っておく必要があります。
ワイルドカードは非常に便利なので、「自分で使うマクロ」ではじゃんじゃんReplaceメソッドを使うといいです。
ですが人に配布するマクロでは、面倒でもReplace関数や↓で説明するInstr関数を使って、強固なマクロを組むことをおすすめします。
元のセル値を残したい場合
Replaceメソッドはセルの値を直接書き換えますので、
元のセルを書き換えたくない場合は、
Range("B2:B100").Value = Range("A2:A100").Value Range("B2:B100").Replace "(*)", ""
と、別セルに丸ごと値を移してから実行すればOKです。
ちなみにこのコードのように、
セル範囲.Value = セル範囲.Value で「値貼り付け」ができます。
Copy ⇒ PasteSpecial でやるより高速・安全でしかも書きやすいので、
知らなかった人はこの機会に覚えてしましましょう。
詳しくはこちらをどうぞ
www.limecode.jp
2.Instr関数で検索して頑張る
- 加工したいのがセル値ではなく変数
- (が2つ出てくるなどワイルドカードで対応できない
- 上記「検索オプションの引継ぎ」の危険を回避したい
などでReplaceメソッドが使えない場合は、Instr関数で検索して頑張ります。
削除開始位置 = InStr(元の文字列, 文字A) 削除終了位置 = InStr(元の文字列, 文字B) 文字Aから文字Bまでを消す = Left(元の文字列, 削除開始位置 - 1) _ & Mid(元の文字列, 削除終了位置 + 1)
「左から文字列まで」 & 「右から文字列まで」 の合わせ技ですね。
削除ではなく置換する場合は、この間に置換後の文字列を入れればOKです。