ExcelVBAにおいて文字列を置換する処理に使う、
Replace関数とReplaceメソッドの違いを解説します。
と、ここで先に注意点ですが、Replace関数には、
「シート関数のREPLACE」と、「VBA関数のReplace」の2つがあります。
このページでは、3つのReplaceの違いについて解説します。
同じところ
3つとも「文字列を別の文字列に置き換える」、
いわゆる「置換」を行うための関数・機能です。
例えばA1セルにある「みかん(和歌山産)」を「みかん(愛媛産)」に置換する場合は、
' Replaceメソッド Range("A1").Replace "和歌山", "愛媛", LookAt:=xlPart
' Replace関数(VBA) Range("A1") = Replace(Range("A1"), "和歌山", "愛媛")
' シート関数REPLACE Range("A1") = WorksheetFunction.Replace(Range("A1"), 5, 3, "愛媛")
と、どれを使っても処理できます。
VBAのReplace関数とReplaceメソッドの違い
↑の通りシート関数のReplaceは引数が全然違うので後回しにして、
VBAにおけるReplace関数とReplaceメソッドの違いを説明します。
まずReplaceメソッドは、
正確には「RangeオブジェクトのReplaceメソッド」と呼び、
Range("A1").Replace "和歌山","愛媛", LookAt:=xlPart
と、Rangeオブジェクト(セルやセル範囲).Replaceで呼び出します。
実行すると、セルの値がそのまま書き換わりますので、
置換した結果を別のセルに出力するなど、元のデータを残すことはできません。
Rangeオブジェクトであればセル範囲でもいいので、
Range("A1:A100").Replace "和歌山","愛媛", LookAt:=xlPart Range(Cells(1,1),Cells(100,1)).Replace "和歌山","愛媛", LookAt:=xlPart
など、複数のセルに一気に実行できるのが便利です。
このメソッドはRangeオブジェクトさんの持ち物ですので、
変数などを置換することはできません。
対して、Replace関数は「関数」ですので、
なんにでも使えますし、結果を別の場所に出力もできます。
' セルから別のセルに Range("B1") = Replace(Range("A1"), "和歌山", "愛媛") ' 変数からセルに Range("A1") = Replace(String変数, "和歌山", "愛媛") ' セルからシート名に ws処理シート.Name = Replace(Range("A1"), "和歌山", "愛媛")
その代わり、セル範囲に実行する場合は、
Dim R As Long For R = 1 To 100 Cells(R, 1) = Replace(Cells(R, 1), "和歌山", "愛媛") Next
と、For文などのループを使用する必要があります。
また重要な違いとして、置換する文字列を検索する際に、
Replaceメソッドはワイルドカード「*」が使用できます。
つまり、A1セルの「みかん(和歌山産)」を「みかん(愛媛産)」に置換する場合、
Range("A1").Replace "和歌山","愛媛", LookAt:=xlPart
と和歌山を狙い撃ちする以外に、
Range("A1").Replace "(*)","(愛媛産)", LookAt:=xlPart
と、「"("から")"まで(中身は任意)」を指定することで、
どの県産でも、さらには国産でなくても、すべてを愛媛産にすることもできます。
これはReplace関数にはできないことなので、
Replaceメソッドを使う大事なポイントになります。
使い分け
↑のようにどうしてもReplaceメソッドが便利という場面を除いて、
なるべくReplace関数を使うようにします。
というのも、Replaceメソッドには結構危ない罠があるからです。
RangeオブジェクトのReplaceメソッドとは、
ワークシート上で「Ctrl+h」で呼び出す「置換」機能のことです。
この「検索と置換」ダイアログですが、注意しなければいけないのが、
「各種設定は前に実行したときの設定を引き継ぐ」という点です。
一番危険なのが「セルの内容が完全に同一であるものを検索する」のチェックで、
これがもしついていると、
Range("A1").Replace "和歌山","愛媛"
このコードは「みかん(和歌山産)⇒みかん(愛媛産)」を置換してくれず、
A1セルが完全に「和歌山」だったときだけ「愛媛」に置換するようになります。
この「前回設定の引継ぎ」は、手作業だろうとマクロだろうと引き継ぐ上に、
置換と検索ダイアログで設定を共有していますので、検索の影響もうけます。
- マクロを実行する前にユーザーがCtrl+F検索で「完全一致」検索をした。
- Findメソッドで完全一致(LookAt:=xlWhole)検索するマクロを実行した。
などがあると、「今まで動いてたのに急に動かなくなった!」になりかねません。
なので、本当はすべてのオプションを指定した方がいいのですが、
面倒でもLookAt:=xlPartだけはきっちり書いておきましょう。
また、もう一つ注意しなければいけないのが、
Replaceメソッドはオートフィルターで非表示になっているセルを検知できません。
これもユーザーの操作に影響を受ける部分なので、
ユーザーがフィルターをかけたままマクロを実行したとき用に、
処理の開始前にフィルターをクリアするなど対策を取っておく必要があります。
ということでなるべくならReplaceメソッドは使わない方が安全なのですが、
しかしReplaceメソッドは便利ですし、
特に「ワイルドカードの検索」だけは替えが効きません。
よって、Replace関数とReplaceメソッドの使い分けとしては、
① ワイルドカードを使うときは、細心の注意を払ってReplaceメソッドを使う。
② オートフィルターの範囲内ではReplace関数を使う。
③ セル範囲に一気に実行するときは、
Dim R As Long For R = 1 To 100 Cells(R, 1) = Replace(Cells(R, 1), "和歌山", "愛媛") Next
この「For文を書くめんどくささ」と、
「マクロが急に動かなった場合の被害」を比較して決める。
あたりが落としどころな気がします。
例えば③について私は、自分で使うマクロではじゃんじゃんReplaceメソッドを使いますが、人に配布するマクロではめったにReplaceメソッドを使いません。
VBAのReplace関数とExcelのREPLACE関数の違い
最後にこの違いを解説します。
Range("A1") = Replace(Range("A1"), "和歌山", "愛媛") Range("A1") = WorksheetFunction.Replace(Range("A1"), 5, 3, "愛媛")
わかりやすい違いとして、シート関数のReplaceは引数の指定が「文字列:和歌山」ではなく「文字位置:5,3」です。
「検索して置換する」関数ではなく、
「位置を指定して置換する」関数ということですね。
なので、イメージとしては「シート関数のREPLACEはMid関数の親戚」とした方が近いかもしれません。
Mid(Range("A1"), 5, 3) WorksheetFunction.Replace(Range("A1"), 5, 3, "愛媛") ' ↑5文字目から3文字分を○○するご親戚
逆にいえば、VBAのReplace関数の兄弟はシート関数の「SUBSTITUTE」です。
Range("A1") = Replace(Range("A1"), "和歌山", "愛媛") Range("A1") = WorksheetFunction.Substitute(Range("A1"), "和歌山", "愛媛")
このように同じ引数を渡せ、その時はまったく同じ動きをしますので、
ワークシート関数の「SUBSTITUTE」= VBA関数の「Replace」
と覚えてしまって構いません。
以上が3つのReplaceの違いになります。
それぞれ長所・短所がありますので、
そのマクロに一番活かせそうなものをお使いください。