Contents
この記事でできること
- VBAでセル内に改行を追加できる
- セル内の改行を一括削除して1行に整理できる
- セル内の改行で分割して個別セルに展開できる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手作業):
- 住所データにセル内改行が混在している
- 改行を手動で削除して1行にしている
- または改行位置で列を分けたいが、手作業でコピペしている
- 100件あると1時間以上かかる
After(マクロ実行):
- 「住所一覧」シートに改行入り住所データを用意
- マクロを実行する
- モードを選ぶ(1:改行削除, 2:改行分割)
- 全件一括で処理される
- 100件が数秒で完了
住所一覧シート(処理前):
| A | B | C | D | |
|---|---|---|---|---|
| 1 | 住所(改行入り) | 住所(1行) | 都道府県 | 市区町村以下 |
| 2 | 東京都(改行)千代田区1-1-1 | |||
| 3 | 大阪府(改行)大阪市北区2-2-2 | |||
| 4 | 北海道(改行)札幌市中央区(改行)3-3-3 |
住所一覧シート(処理後 — 改行削除モード):
| A | B | |
|---|---|---|
| 1 | 住所(改行入り) | 住所(1行) |
| 2 | 東京都(改行)千代田区1-1-1 | 東京都千代田区1-1-1 |
| 3 | 大阪府(改行)大阪市北区2-2-2 | 大阪府大阪市北区2-2-2 |
| 4 | 北海道(改行)札幌市中央区(改行)3-3-3 | 北海道札幌市中央区3-3-3 |
住所一覧シート(処理後 — 改行分割モード):
| A | B | C | D | |
|---|---|---|---|---|
| 1 | 住所(改行入り) | 分割1 | 分割2 | 分割3 |
| 2 | 東京都(改行)千代田区1-1-1 | 東京都 | 千代田区1-1-1 | |
| 3 | 大阪府(改行)大阪市北区2-2-2 | 大阪府 | 大阪市北区2-2-2 | |
| 4 | 北海道(改行)札幌市中央区(改行)3-3-3 | 北海道 | 札幌市中央区 | 3-3-3 |
住所録のデータをVBAでセルに書き込むとき、vbCrLf で改行を入れたのにセル内で改行されなかった。見た目は1行に詰まったまま。ネットで調べたら「vbLf を使え」と書いてあったが、なぜ vbCrLf ではダメなのかが分からなかった。
原因はExcelのセル内改行が vbLf(= Chr(10))だということ。vbCrLf はCR+LFの2文字で、これはテキストファイルやMsgBoxの改行コード。セル内改行は vbLf 一択。
vbLf に統一してからは迷わなくなった。改行の追加も削除も分割も、すべて vbLf を基準にすればいい。住所データの整理が10分から数秒に変わった。
vbCrLf と vbLf の違いは、知らないと確実にハマる。しかもエラーが出ないので原因に気づきにくい。「改行したつもりなのにされていない」という無駄な時間をなくしたい。文字列の置換処理はセルの文字列を一括置換する方法、分割処理は文字列を区切り文字で分割して取り出す方法と組み合わせると応用の幅が広がる。
セル内改行は vbLf(Chr(10))。vbCrLf では改行されないが、エラーも出ないので気づきにくい。
事前準備
シート構成を用意する
実務版コードでは以下の構成を使う。最小版はシート構成不要(アクティブシートのA1セルで動作確認する)。
「住所一覧」シート — 改行入り住所データを入力する場所
| 列 | 内容 | 例 |
|---|---|---|
| A列 | 住所(改行入り) | 東京都(改行)千代田区1-1-1 |
| B列 | 処理結果1 | (マクロで出力) |
| C列 | 処理結果2 | (マクロで出力・分割モード時) |
| D列 | 処理結果3 | (マクロで出力・分割モード時) |
- 1行目はヘッダー。データは2行目から入力する
- A列のセルに
Alt + Enterで改行を入れたデータを用意する - B列以降に既存データがある場合は上書きされるので注意。実行前にB列以降が空であることを確認するか、バックアップを取ること
バックアップを取る
改行の削除は元に戻せない。実行前にファイルのコピーを取っておくこと。テスト用のダミーデータで動作確認してから本番データで実行することを強く推奨する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロは保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
Alt + F8→ マクロ名を選んで「実行」
コード(最小版)– セル内の改行を追加・削除・分割する
まずセル1つで改行の追加・削除・分割の動作を確認する。空のシートで実行するか、A1~E1が上書きされても問題ないことを確認してから実行すること。
Sub セル内改行の基本操作()
Dim ws As Worksheet
Set ws = ActiveSheet
' ========================================
' ★ 1. 改行の追加(セルA1に改行入りテキストを設定)
' ========================================
ws.Range("A1").Value = "東京都" & vbLf & "千代田区" & vbLf & "1-1-1"
ws.Range("A1").WrapText = True ' 折り返し表示をONにする
' ========================================
' ★ 2. 改行の削除(A1の改行を削除してB1に出力)
' ========================================
Dim txt As String
txt = ws.Range("A1").Value
txt = Replace(txt, vbLf, "") ' 改行を削除
ws.Range("B1").Value = txt
' → B1: "東京都千代田区1-1-1"
' ========================================
' ★ 3. 改行で分割(A1を改行で分割してC1以降に出力)
' ========================================
Dim parts() As String
parts = Split(ws.Range("A1").Value, vbLf)
Dim j As Long
For j = 0 To UBound(parts)
ws.Cells(1, 3 + j).Value = parts(j)
Next j
' → C1: "東京都", D1: "千代田区", E1: "1-1-1"
MsgBox "完了しました。" & vbCrLf & _
"A1: 改行入りテキスト" & vbCrLf & _
"B1: 改行削除" & vbCrLf & _
"C1~: 改行で分割"
End Sub
動作確認
- マクロを実行する
- A1セルに改行入りテキストが入る(3行に折り返し表示される)
- B1セルに改行を削除した1行テキストが入る
- C1・D1・E1にそれぞれ分割された値が入る
ポイント:
- 改行の追加: 文字列の間に
vbLfを挟む。WrapText = Trueで折り返し表示をONにする - 改行の削除:
Replace(txt, vbLf, "")で改行を空文字に置換。詳しくはセルの文字列を一括置換する方法を参照 - 改行で分割:
Split(txt, vbLf)で改行を区切り文字にして配列に格納。詳しくは文字列を区切り文字で分割して取り出す方法を参照
最小版で動作が確認できたら、次の実務版に進む。
コード(実務版)– 住所データの改行を一括削除・分割
自分はこの方法で取引先の住所録を整理している。改行入りの住所を1行にまとめたり、都道府県と市区町村に分割したりする作業が数秒で終わるようになった。
住所一覧のA列にある改行入りデータを、モード選択で一括処理する。最終行の取得方法はデータの最終行・最終列を正確に取得する方法を参照。
Sub 住所の改行を一括処理()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim mode As String
Dim cnt As Long
' ★ シート名を指定
Set ws = Worksheets("住所一覧")
' ★ 最終行を取得(A列で判定)
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
' 処理モードを選択
mode = InputBox( _
"処理モードを番号で入力してください。" & vbCrLf & vbCrLf & _
"1: 改行を削除して1行にまとめる(B列に出力)" & vbCrLf & _
"2: 改行で分割して個別セルに展開(B列以降に出力)", _
"改行処理の選択", "1")
If mode = "" Then
Exit Sub ' キャンセル時
End If
If mode <> "1" And mode <> "2" Then
MsgBox "1 または 2 を入力してください。", vbExclamation
Exit Sub
End If
' 確認ダイアログ
Dim modeName As String
If mode = "1" Then
modeName = "改行削除(1行にまとめる)"
Else
modeName = "改行分割(個別セルに展開)"
End If
If MsgBox((lastRow - 1) & " 件の住所データを処理します。" & vbCrLf & _
"モード: " & modeName & vbCrLf & vbCrLf & _
"B列以降のデータは上書きされます。" & vbCrLf & _
"実行しますか?", vbYesNo + vbQuestion) = vbNo Then
Exit Sub
End If
On Error GoTo ErrHandler
Application.ScreenUpdating = False
If mode = "1" Then
' ========================================
' モード1: 改行を削除して1行にまとめる
' ========================================
For i = 2 To lastRow
If ws.Cells(i, 1).Value <> "" Then
ws.Cells(i, 2).Value = Replace(ws.Cells(i, 1).Value, vbLf, "")
cnt = cnt + 1
End If
Next i
Else
' ========================================
' モード2: 改行で分割して個別セルに展開
' ========================================
Dim parts() As String
Dim j As Long
Dim maxCol As Long
For i = 2 To lastRow
If ws.Cells(i, 1).Value <> "" Then
parts = Split(ws.Cells(i, 1).Value, vbLf)
For j = 0 To UBound(parts)
If parts(j) <> "" Then
ws.Cells(i, 2 + j).Value = parts(j)
End If
Next j
' 最大列数を記録(ヘッダー設定用)
If UBound(parts) + 1 > maxCol Then
maxCol = UBound(parts) + 1
End If
cnt = cnt + 1
End If
Next i
' ★ 分割先のヘッダーを自動設定
For j = 1 To maxCol
ws.Cells(1, 1 + j).Value = "分割" & j
Next j
End If
Application.ScreenUpdating = True
MsgBox cnt & " 件の住所データを処理しました。" & vbCrLf & _
"モード: " & modeName, vbInformation
Exit Sub
ErrHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました。" & vbCrLf & _
"行番号: " & i & vbCrLf & _
Err.Description, vbCritical
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | Worksheets("住所一覧") |
住所一覧 | データのシート名 |
| 2 | ws.Cells(i, 1) |
列1(A列) | 改行入りデータの列番号 |
| 3 | ws.Cells(i, 2) |
列2(B列) | 処理結果の出力先列 |
| 4 | Replace(..., vbLf, "") |
“” | 改行の置換先(スペースに変えたい場合は ” ” に変更) |
実務版で追加した機能
| 機能 | 説明 | 参考記事 |
|---|---|---|
| モード選択 | InputBoxで改行削除/改行分割を選択 | — |
| 確認ダイアログ | 件数+モード+上書き警告を表示してYes/No確認 | — |
| ヘッダー自動設定 | 分割モードで「分割1」「分割2」…を自動設定 | — |
| 空セルスキップ | A列が空の行はスキップ | — |
| 高速化 | ScreenUpdating = Falseで画面更新を停止 | — |
| エラー復帰 | On Error GoTo ErrHandlerでScreenUpdating復帰 | — |
vbLf / vbCrLf / vbCr の違い
改行コード一覧
| 定数 | 値 | 正体 | 用途 |
|---|---|---|---|
| vbLf | Chr(10) | LF(Line Feed) | Excelセル内改行。セルに改行を入れるときはこれ |
| vbCrLf | Chr(13) & Chr(10) | CR + LF | テキストファイル(Windows)の改行。MsgBoxの改行 |
| vbCr | Chr(13) | CR(Carriage Return) | 古いMac用の改行コード。通常は使わない |
なぜセル内改行は vbLf なのか
Excelの内部仕様として、セル内の改行は LF(Chr(10))で管理されている。キーボードで Alt + Enter を押したときに入る改行コードも Chr(10)。
vbCrLf(CR+LF)をセルに書き込むと、Excelが自動的にCR(Chr(13))を除去してLF(Chr(10))だけを残す場合と、CR+LFの2文字がそのまま入る場合がある。動作が不安定になるため、セル内改行には vbLf を使うのが確実。
' セル内改行は vbLf(Chr(10))を使う
Range("A1").Value = "1行目" & vbLf & "2行目" ' OK: 正しく改行される
Range("A2").Value = "1行目" & vbCrLf & "2行目" ' NG: 改行されないことがある
' MsgBox の改行は vbCrLf でも vbLf でもOK
MsgBox "1行目" & vbCrLf & "2行目" ' OK
MsgBox "1行目" & vbLf & "2行目" ' OK
外部データの改行コードを統一する
CSVやテキストファイルから取り込んだデータには vbCrLf が含まれている場合がある。処理前に vbLf に統一しておくと安全。
' 改行コードを vbLf に統一する
Dim txt As String
txt = Range("A1").Value
txt = Replace(txt, vbCrLf, vbLf) ' CR+LF → LF(先にCR+LFを変換)
txt = Replace(txt, vbCr, vbLf) ' CR → LF(念のため)
文字列置換の詳しい使い方はセルの文字列を一括置換する方法を参照。
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | vbCrLf でセルに改行を入れたが改行されない |
Excelのセル内改行は vbLf(Chr(10))。vbCrLf はCR+LFの2文字で、セル内改行には不適切 |
セル内改行には vbLf を使う。MsgBoxの改行は vbCrLf でOK |
| 2 | 改行を追加したが表示上は1行のまま | WrapText(折り返し表示)が False のため、改行コードがあっても画面上は1行に見える |
改行追加と同時に WrapText = True を設定する |
| 3 | Replace(txt, vbCrLf, "") で改行を削除したのに改行が残る |
セル内の改行は vbLf なのに vbCrLf で置換しようとした。置換対象が一致しない |
Replace(txt, vbLf, "") を使う |
| 4 | Split で改行分割したら空要素が入る |
末尾に改行がある場合や連続改行がある場合、Split結果に空文字列の要素が含まれる | If parts(j) <> "" Then で空文字列をスキップする |
| 5 | 改行を削除したら文字がくっついて読めない | 「東京都」「千代田区」が「東京都千代田区」になる。区切りがない | Replace(txt, vbLf, " ") でスペースに置換する。用途に応じて区切り文字を変更 |
改行を追加したのに表示上は1行のまま、という経験がある。WrapText = True を設定し忘れていた。折り返し表示をONにしないと、改行があってもセル上では見えない。数式バーで確認すれば改行が入っていることは分かるが、シート上では分からないので見落としやすい。
FAQ
Q1. vbLf と vbCrLf はどう使い分ける?
セル内改行は vbLf。MsgBoxやテキストファイルの改行は vbCrLf。迷ったら「セルは vbLf、それ以外は vbCrLf」と覚えておけばOK。
' セル内改行: vbLf
Range("A1").Value = "1行目" & vbLf & "2行目"
Range("A1").WrapText = True
' MsgBox: vbCrLf
MsgBox "1行目" & vbCrLf & "2行目"
Q2. Alt+Enter で入れた改行もVBAで削除できる?
できる。Alt + Enter で入る改行は Chr(10) = vbLf なので、Replace で削除可能。
Dim txt As String
txt = Range("A1").Value
txt = Replace(txt, vbLf, "") ' Alt+Enter の改行を削除
Range("A1").Value = txt
Q3. セル内の改行の数をカウントしたい
Split で分割して要素数を数える。UBound(Split(txt, vbLf)) が改行の数になる(行数は改行数+1)。
Dim txt As String
txt = Range("A1").Value
Dim lineCount As Long
lineCount = UBound(Split(txt, vbLf)) + 1
MsgBox "行数: " & lineCount
Split関数の詳しい使い方は文字列を区切り文字で分割して取り出す方法を参照。
Q4. CSVから取り込んだデータの改行を処理したい
CSVの改行コードは vbCrLf(Windows)の場合がある。処理前に vbLf に統一してから操作する。
Dim txt As String
txt = Range("A1").Value
' まず改行コードを統一
txt = Replace(txt, vbCrLf, vbLf)
txt = Replace(txt, vbCr, vbLf)
' その後で分割や削除を行う
txt = Replace(txt, vbLf, "")
Range("A1").Value = txt
Q5. 改行の代わりにスペースや区切り文字に置換したい
Replace の第3引数を変更するだけ。置換先の文字を用途に合わせて指定する。
Dim txt As String
txt = Range("A1").Value
' 半角スペースに置換
txt = Replace(txt, vbLf, " ")
' カンマに置換
txt = Replace(txt, vbLf, ",")
' 全角スペースに置換
txt = Replace(txt, vbLf, " ")
Range("A1").Value = txt
全角・半角の変換については全角・半角を一括変換する方法も参照。セルの書式設定はセルの書式を一括変更する方法を参照。
まとめ
この記事では、VBAでセル内の改行を追加・削除・分割する方法を解説した。
- 最小版: セル1つで改行の追加・削除・分割の動作を確認
- 実務版: 住所データの改行を一括削除・分割(モード選択式)
最も重要なポイントは セル内改行は vbLf(Chr(10))を使う こと。vbCrLf ではセル内の改行にならない。
テスト用のダミーデータで動作確認してから、本番データで実行すること。
関連記事
- セルの文字列を一括置換する方法 — Replace関数による文字列置換の詳細。改行削除もReplaceの応用
- 文字列を区切り文字で分割して取り出す方法 — Split関数による文字列分割の詳細。改行分割もSplitの応用
- 全角・半角を一括変換する方法 — 改行処理と組み合わせて住所データを整形
- セルの書式を一括変更する方法 — WrapText(折り返し表示)やNumberFormatなどの書式設定
- データの最終行・最終列を正確に取得する方法 — ループ処理で使う最終行の取得方法
次にやりたくなること
- 文字列の置換をもっと柔軟にやりたい → セルの文字列を一括置換する方法で、改行以外の文字列もまとめて置換できる
- 文字列の分割をもっと詳しく知りたい → 文字列を区切り文字で分割して取り出す方法で、カンマ・タブ・スペースなど任意の区切り文字で分割できる

コメント