VBAで「文字列の一部を別の文字に置き換えたい」と思ったとき、最初に候補に挙がるのがReplace関数です。住所の全角スペースを半角に直したい、商品コードの記号を統一したい、ファイル名から不要な文字を取り除きたい、といった処理は、Replace関数1行でほぼ完結します。
ただし実際に使ってみると、「start引数を指定したら前半が消えた」「大文字と小文字が区別されて置換できない」など、引数の挙動でつまずく方も少なくありません。Replace関数は6つの引数を持つため、それぞれの役割を理解しないと意図しない結果になりがちです。
この記事では、VBA Replace関数の基本構文から、Count・Compare引数を活用した一括置換のテクニック、そして実務でコピペして使えるコードパターンまでをまとめて解説します。WorksheetFunction.Substituteとの使い分けも比較表で整理しているので、文字列加工の判断軸として活用してください。
VBAのReplace関数とは
VBA Replace関数は、指定した文字列の中から検索対象の部分文字列を見つけて、別の文字列に置き換える組み込み関数です。Excel関数のSUBSTITUTEに近い動きをしますが、VBAコード内ではこちらが標準となります。
最大の特徴は、引数によって挙動を細かく制御できる点です。「最初の1件だけ置換する」「N文字目から検索を開始する」「大文字と小文字を区別しない」といった処理が、追加のIf文なしに引数指定だけで実現できます。
事務処理では、フォーム入力データの正規化、CSVの整形、ファイル名の一括変更など、文字列加工が発生する場面で頻繁に登場します。一度引数の意味を押さえておけば、関連する自動化処理の幅が大きく広がる関数です。
なお、VBAには同名のメソッドがStringクラスやRangeオブジェクトにも存在しますが、本記事では純粋な関数としてのReplace(VBA.Strings.Replace)を扱います。
基本構文と引数一覧
Replace関数の構文は以下のとおりです。
Replace(expression, find, replace[, start[, count[, compare]]])
引数は6つあり、最初の3つが必須、後ろの3つは省略可能です。
| 引数 | 必須 | デフォルト | 説明 |
|---|---|---|---|
| expression | 必須 | — | 置換対象の文字列式 |
| find | 必須 | — | 検索する部分文字列 |
| replace | 必須 | — | 置換後の文字列 |
| start | 省略可 | 1 | 検索を開始する位置 |
| count | 省略可 | -1(全置換) | 置換を実行する回数 |
| compare | 省略可 | vbBinaryCompare(0) | 比較の種類 |
最もシンプルな使い方は、必須の3引数だけを指定するパターンです。
Sub BasicReplace()
Dim result As String
result = Replace("2026/05/19", "/", "-")
Debug.Print result ' → 2026-05-19
End Sub
このように、expressionの中に出てくるfindをすべてreplaceに置き換えた文字列が返ります。デフォルトでは全件置換となるため、Countを指定しない限り該当箇所はすべて置換されると覚えておきましょう。
【引数別】戻り値の変化と注意点
ここからは、省略可能な3つの引数の挙動を順番に見ていきます。とくにstart引数には「前半部分が消える」という有名な落とし穴があるため、最初に押さえておきましょう。
戻り値の特殊ケースも整理しておきます。
expressionが空文字列のとき →""を返すexpressionがNullのとき → エラー(IsNullでの事前チェック必須)findが空文字列のとき →expressionのコピーをそのまま返すreplaceが空文字列のとき →findの出現箇所をすべて削除した文字列を返すstartがLen(expression)より大きいとき →""を返すcountが0のとき →expressionのコピーを返す(置換なし)
Null値が混入しそうな処理では、必ずIf IsNull(value) Then ...で分岐を入れておきます。
start引数を使うときの落とし穴
startは検索開始位置を指定する引数ですが、戻り値が「start位置から末尾までの文字列のみ」になります。先頭部分は戻り値に含まれません。
Sub StartPitfall()
Dim str As String
str = "ABCDEFG-ABCDEFG"
' 6文字目以降のAをXに置換したい
Debug.Print Replace(str, "A", "X", 6)
' → "FG-XBCDEFG"
' 先頭の "ABCDE" が消える!
End Sub
「6文字目以降のAをXに置換したい」と意図して書いたコードですが、先頭5文字が消えた結果が返ってきます。これは仕様であり、バグではありません。
先頭部分を保持したい場合は、Left関数で前半を取り出して連結する必要があります。
Sub StartFixed()
Dim str As String
Dim head As String
Dim tail As String
Dim result As String
str = "ABCDEFG-ABCDEFG"
'--- 先頭5文字を保持 ---
head = Left(str, 5)
'--- 6文字目以降のAを置換 ---
tail = Replace(str, "A", "X", 6)
result = head & tail
Debug.Print result ' → "ABCDEFG-XBCDEFG"
End Sub
この挙動を知らずにstartを使うと、データが意図せず削れる事故につながります。startは「途中から検索したい」というより「途中以降の文字列を加工して返したい」ときに使う引数だと理解しておくのが安全です。
count引数で置換回数を制限する
count引数は、置換を実行する回数の上限を指定します。デフォルトは-1で、これは「すべての出現箇所を置換する」という意味です。
Sub CountLimit()
Dim str As String
str = "AAA-AAA-AAA"
' 全置換(デフォルト)
Debug.Print Replace(str, "A", "X")
' → "XXX-XXX-XXX"
' 最初の1件だけ置換
Debug.Print Replace(str, "AAA", "BBB", 1, 1)
' → "BBB-AAA-AAA"
' 最初の2件だけ置換
Debug.Print Replace(str, "AAA", "BBB", 1, 2)
' → "BBB-BBB-AAA"
End Sub
countを使うときは、startも同時に指定する必要があります(countは4番目、startは5番目という順序のため)。先頭から数えたい場合はstartに1を渡しておきましょう。
ログの先頭1件目だけタイムスタンプを差し替えたい、テンプレートの最初のプレースホルダだけ置き換えたい、といった用途で役立ちます。
compare引数で大文字小文字を無視する
compare引数は文字列の比較方法を切り替えます。デフォルトは大文字と小文字を区別するvbBinaryCompareです。
| 定数 | 値 | 動作 |
|---|---|---|
| vbBinaryCompare | 0 | 大文字・小文字を区別する(既定値) |
| vbTextCompare | 1 | 大文字・小文字を区別しない |
| vbDatabaseCompare | 2 | Access専用 |
vbTextCompareを指定すれば、「vba」「VBA」「Vba」「vBa」のような表記ゆれをまとめて拾えます。
Sub CompareDemo()
Dim str As String
str = "vbaとVBAとVbaは同じ言語です"
' 既定値(大文字小文字を区別)
Debug.Print Replace(str, "vba", "Excel")
' → "ExcelとVBAとVbaは同じ言語です"
' vbTextCompare(大文字小文字を無視)
Debug.Print Replace(str, "vba", "Excel", 1, -1, vbTextCompare)
' → "ExcelとExcelとExcelは同じ言語です"
End Sub
ユーザー入力データやWebから取得した文字列は、大文字小文字が揺れていることが珍しくありません。表記ゆれをまとめて正規化したいときは、vbTextCompareを積極的に使いましょう。
実務でよく使うコードパターン3選
ここからは、事務処理の現場で頻出する3つのパターンを紹介します。いずれもコピペしてそのまま使えるコードです。
パターン1: スペース・特殊文字を全削除する
データの正規化で最も多いのが、不要な空白や記号の削除です。replaceに空文字列""を渡せば、findに該当する箇所がすべて消えます。
Sub RemoveSpaces()
Dim str As String
str = "山田 太郎 さん" ' 全角+半角スペース混在
'--- 半角スペースを全削除 ---
str = Replace(str, " ", "")
'--- 全角スペースを全削除(Chr(12288)) ---
str = Replace(str, Chr(12288), "")
Debug.Print str ' → "山田太郎さん"
End Sub
タブ・改行を含めて一気に除去したい場合は、Replace関数をネストするのが定番です。
Sub RemoveWhitespace()
Dim str As String
str = "ABC" & vbTab & "DEF" & vbCrLf & "GHI"
'--- タブ・LF・CRをまとめて除去 ---
str = Replace(Replace(Replace(str, Chr(9), ""), Chr(10), ""), Chr(13), "")
Debug.Print str ' → "ABCDEFGHI"
End Sub
スペース削除専用の手段としては、Trim関数やLTrim / RTrim関数もあります。前後の空白だけを削りたい場合はTrim系のほうがシンプルです。詳しくはVBA Trim関数の使い方やVBAでスペースを削除する方法もあわせて参考にしてください。
パターン2: 大文字小文字を統一する
入力データの「VBA/vba/Vba」のような表記ゆれを統一するパターンです。compare引数にvbTextCompareを渡せば、大文字小文字を無視して置換できます。
Sub NormalizeCase()
Dim str As String
str = "vbaのコード例とVBA講座、Vba入門書"
'--- 大文字小文字を区別せず "VBA" に統一 ---
str = Replace(str, "vba", "VBA", 1, -1, vbTextCompare)
Debug.Print str
' → "VBAのコード例とVBA講座、VBA入門書"
End Sub
ポイントは、startに1、countに-1を必ず渡すことです。compareは6番目の引数なので、前の引数を省略できません。「先頭から全件置換」を意味する1, -1はセットで覚えておくと迷いません。
商品コード・型番・タグなど、半角英字が混じるデータの正規化で重宝するパターンです。
パターン3: 複数の文字列を一括置換する
複数の検索パターンを順番に置換するときは、配列とループを組み合わせると保守性が上がります。置換ルールが10件、20件と増えても、配列の中身を変えるだけで済むのが利点です。
Sub MultiReplace(ByRef str As String)
Dim findList As Variant
Dim repList As Variant
Dim i As Long
'--- 検索文字と置換文字をペアで定義 ---
findList = Array("(", ")", " ", "・")
repList = Array("(", ")", " ", "-")
'--- 順番に置換していく ---
For i = 0 To UBound(findList)
str = Replace(str, findList(i), repList(i))
Next i
End Sub
Sub TestMultiReplace()
Dim s As String
s = "(株)山田 商事・東京"
Call MultiReplace(s)
Debug.Print s ' → "(株)山田 商事-東京"
End Sub
findListとrepListを同じインデックスで対応させるのがコツです。要素数が一致しないと配列の境界エラーになるため、追加時は両方の配列を必ずセットで更新してください。
社内システムから出力されたCSVを集計用に整形する、住所データの記号を統一する、といった処理にそのまま流用できます。
VBA Replace関数 vs WorksheetFunction.Substitute
VBAから文字列を置換する手段は、Replace関数だけではありません。WorksheetFunction.Substituteを経由して、Excel関数のSUBSTITUTEを呼び出す方法もあります。両者には明確な使い分けの基準があります。
| 比較軸 | VBA Replace関数 | WorksheetFunction.Substitute |
|---|---|---|
| コード量 | 短い | 長い |
| 大文字小文字の無視 | 可能(compare引数) | 不可 |
| 検索開始位置の指定 | 可能(start引数) | 不可 |
| 置換回数の上限 | 可能(count引数) | 不可 |
| N番目のみ置換 | 不可 | 可能(第4引数) |
| 主な用途 | VBAコード内の文字列加工全般 | N番目のみ置換したい特殊ケース |
基本的にはVBA Replace関数のほうがコードが短く、引数も柔軟です。日常的な置換処理は、まずReplace関数で書くことを推奨します。
一方、「3番目に出現した文字だけを置換したい」のような限定的なケースでは、WorksheetFunction.Substituteの第4引数(インスタンス番号)が役立ちます。
Sub SubstituteByPosition()
Dim str As String
Dim result As String
str = "A-A-A-A-A"
'--- 3番目の "A" だけ "X" に置換 ---
result = WorksheetFunction.Substitute(str, "A", "X", 3)
Debug.Print result ' → "A-A-X-A-A"
End Sub
Replace関数ではN番目だけの置換ができないため、この用途に限ってはSubstituteの出番です。Excel関数の挙動についてはExcelのSUBSTITUTE関数の使い方も参考になります。
まとめ
VBA Replace関数のポイントを振り返ります。
- 基本構文は
Replace(expression, find, replace, start, count, compare)の6引数 startを指定すると先頭部分が戻り値から消える。Left関数との連結で対処countで置換回数を制限できる。最初の1件だけ、最初の2件だけといった指定が可能compareにvbTextCompareを渡すと、大文字小文字を区別せず置換できる- 実務では「スペース全削除」「大文字小文字統一」「複数文字列の一括置換」の3パターンが頻出
- N番目のみ置換したい特殊ケースは
WorksheetFunction.Substituteを使う
パターンに一致する文字列をまとめて置換したい場合はVBA正規表現(RegExp)の使い方が便利です。
引数の挙動さえ押さえれば、Replace関数は文字列加工の最強の味方になります。とくにcompare引数の存在を知っているかどうかで、表記ゆれデータの処理スピードは大きく変わります。まずは基本の3引数からスタートし、慣れてきたらcount・compareを組み合わせて、データ正規化の自動化に役立ててください。
