和風スパゲティのレシピ

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

Replace関数とReplaceメソッドの違い

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の違いになります。

それぞれ長所・短所がありますので、
そのマクロに一番活かせそうなものをお使いください。