【VBA】セル内の改行を追加・削除・分割する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

  • VBAでセル内に改行を追加できる
  • セル内の改行を一括削除して1行に整理できる
  • セル内の改行で分割して個別セルに展開できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11


完成イメージ(Before / After)

Before(手作業):

  1. 住所データにセル内改行が混在している
  2. 改行を手動で削除して1行にしている
  3. または改行位置で列を分けたいが、手作業でコピペしている
  4. 100件あると1時間以上かかる

After(マクロ実行):

  1. 「住所一覧」シートに改行入り住所データを用意
  2. マクロを実行する
  3. モードを選ぶ(1:改行削除, 2:改行分割)
  4. 全件一括で処理される
  5. 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 のままだとマクロは保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
  3. 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

動作確認

  1. マクロを実行する
  2. A1セルに改行入りテキストが入る(3行に折り返し表示される)
  3. B1セルに改行を削除した1行テキストが入る
  4. C1・D1・E1にそれぞれ分割された値が入る

ポイント:

最小版で動作が確認できたら、次の実務版に進む。


コード(実務版)– 住所データの改行を一括削除・分割

自分はこの方法で取引先の住所録を整理している。改行入りの住所を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 ではセル内の改行にならない。

テスト用のダミーデータで動作確認してから、本番データで実行すること。

関連記事


次にやりたくなること

コメント

タイトルとURLをコピーしました