エクセルVBAで行削除を自動化!空白行や重複行も完全解説
歩君エクセルVBAで行削除のループ処理ができるはずなのに、思ったとおりに削除できない!
ライクさんVBAで行削除する場合は、知っておくといいコツがあるよ!
エクセルVBAを使って行削除をすると、行ズレや一部の空白行が消えないなどのトラブルが起こりがちです。
この記事ではVBAで行削除をする基本と、最終行まで繰り返し処理で行削除をする際に、初心者が失敗しやすいポイントを解説しています。
- 行を指定する際は
Rows・Range・Cellsを使い分ける - 行を削除して上に詰めるのは
Delete、行の中身だけ削除するのはClear - 繰り返し処理は「下から上」の順で、変数を使った
Forループ推奨 - 結合セルは初めに解除しておくことが大事
一見、難しそうな行削除ですが、ポイントさえ押さえておけば大量処理を簡単に自動で行えます。
行削除以外のマクロの基本とポイントについて知りたい方は、以下の記事で学ぶことができますのでご参照ください。
エクセルVBAで行を削除する基本と仕組み
エクセルVBAで行を削除する際にまず重要なのは、コードを覚えるよりも仕組みを理解することです。
行削除のVBAコードを分解すると、主に次の2つに分けられます。
- 指定方法:どの行を削除するか
- 削除方法:どうやって削除するか
この章では、この2つの基本と、初心者が陥りやすい失敗ケースと対処法について解説します。

作例として県庁所在地一覧を使用しますが、ご自身の業務に当てはめてご参照ください。
行を指定する3つのVBAコード
行をVBAで指定する方法は主に3つあります。
- Rows
- Range
- Cells
以下のコードはいずれも「5行目を削除するコード」ですが、役割が異なります。
Rows(5).Delete
Range("5:5").Delete
Cells(5, 1).EntireRow.Delete- Rows
-
- カッコ内に行番号を指定する一番シンプルな方法
- 最初に覚えるのはこれでOK
- Range
-
連続した行をまとめて削除したい場合に使います。
例えば5行目~7行目をまとめて削除する場合は、以下のようにコードを書きます。
Range("5:7").Delete - Cells
-
- 行番号を変数で扱うときに使用
- ループ処理や条件付き削除で必須
まずはこの3つの違いを理解し、目的に応じて使い分けるようにしましょう。
削除する2つのVBAコードとその違い
行削除の方法は次の2つのコードを使います。
Rows(5).Delete
Rows(5).Clear- Delete
-
行そのものを削除し、下の行が上に詰まる
- Clear
-
行の中身を削除し、行そのものは残る
実際にVBAを作成して違いを見てみましょう。
マクロで削除したデータは元に戻せません。
行削除したいファイルのバックアップを取った上で作業しましょう。

- 「開発」タブを押す
- 「Visual Basic」をクリック

- 「挿入」タブを押す
- 「標準モジュール」を選択

- 「挿入」タブを押す
- 「プロシージャ」をクリック

- マクロの名前を付ける
- 「OK」ボタンを押す

まずはDeleteの結果を確認します。
Public Sub()~End Subの間に以下のコードをコピペしましょう。
ActiveSheet.Rows(5).Delete
ライクさんActiveSheetとは現在操作しているシートのことだよ!
状況に応じてシート名を指定してね!

- エクセルで5行目の内容を確認
- VBAエディターの「▶」実行をクリック

- 「マクロ名」から実行するマクロを選ぶ
- 「実行」ボタンを押す

5行目が行削除され、下の行が上に詰まったことを確認しましょう。

- VBAエディターの
Delete部分をClearに書き換える - VBAエディターの「▶」実行をクリック

5行目の中身だけ削除され、空白行が残ったことを確認しましょう。
行を詰めたいのにClearを使うと、空白行が残り、行ズレの原因となります。
行そのものを消したいのか、行の中身を消したいのか、マクロでやりたいことを事前に整理したうえで使い分けましょう。
行削除マクロでよくある失敗ケースと対策法
行そのものを削除するマクロで最も多い失敗が、複数行を上から順番に削除しようとすることです。
例えば「2行目から6行目」を繰り返し処理で削除する場合を考えてみましょう。

このリストの場合、2行目から6行目に該当するのは北海道・青森・岩手・宮城・秋田です。
まずは以下のコードを見てみてください。
Public Sub 行削除失敗例()
For i = 2 To 6
ActiveSheet.Rows(i).Delete
Next i
End SubFor~Nextで繰り返し処理をし、変数iに2~6を順に格納することで、2行目から6行目までを順番に行削除しています。
一見、正しそうに見えますが、このマクロを実行した結果は次の図のようになります。

もともと3行目・5行目だった青森・宮城が残り、8・10行目だった福島と栃木が削除されています。
この理由は、行を削除するたびに行番号が詰まり変わってしまうためです。

この対策は簡単で、行削除を下から行うことで解決します。
Public Sub 行削除下から()
For i = 6 To 2 Step -1
ActiveSheet.Rows(i).Delete
Next i
End SubFor~Nextで繰り返し処理をすることは変わりませんが、以下の2点を変更しています。
- 変数
iを2 To 6ではなく6 To 2にする Step -1を追加
これにより、6から2まで逆順で作業を繰り返すこととなり、行の繰り上がりの影響を受けなくなります。
この考え方はすべての行削除処理の基本になりますので、「行削除は必ず下から」と覚えておきましょう。
条件を指定して行を削除するVBA
実際の現場で行削除をVBAで行う場合、条件付きで行削除を行うケースがほとんどです。
ここでは、IF文と繰り返し処理を使った安全な行削除の方法を解説します。
前章に引き続き、作例として県庁所在地一覧を使用します。
条件付きで行削除するマクロの基本
エクセルVBAで条件付きで行削除する基本の流れは以下の3ステップです。
- 行を1行ずつチェック
- 条件に合えば削除
- 下から上へ
For~Nextを使って繰り返し処理
歩君でも、どうやって最終行を調べるの?
ライクさん安心して!
最終行を調べる方法があるよ!
マクロのサンプルは以下のとおりです。
エクセルのVBAで最終行まで繰り返し処理を行い、左から7列目に「送付対象」と入力されている行「以外」を削除します。
Public Sub 最終行まで条件付き行削除()
Dim lastRow As Long
Dim i As Long
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
For i = lastRow To 2 Step -1
If ActiveSheet.Cells(i, 7).Value <> "送付対象" Then
ActiveSheet.Rows(i).Delete
End If
Next i
End SublastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Rowで最終行の行番号を取得した上で、iに変数として格納しています。
If ActiveSheet.Cells(i, 7).Value <> "送付対象"で条件を設定しています。

Cells(i, 7)は(行,列)の順番で書かれています。
参照する列を変えたい場合は「7」を変更してください。
行削除の条件を変えたい場合は、.Value <> "送付対象"を変更します。
変更例は次のとおりです。
- <>”送付対象”:送付対象「以外」を削除
- =”送付対象”:送付対象を削除する
- <10:10未満を削除
- >=10:10以上を削除
このマクロを実行すると、送付対象「以外」の行が削除されます。

前章の注意点のとおり、「下から上」に繰り返し処理をすることが失敗しないコツです。
「最終行まで繰り返し処理」と聞くとDo~Loopのループ処理を思い浮かべる方もいるかもしれません。
ですが、Do~Loopは条件を書き間違えると止まらないマクロになります。
今回のように事前に最終行が分かる場合は、For~Nextループを使うほうが安心です。
空白行をマクロで安全に削除するコツ
空白行をVBAで削除するときに注意すべき点は、「空白」の種類がいくつかあるということです。
- セルに情報が何も入っていない
- 見た目は空白でもスペースが入っている
- =IF(A1="", "", A1)など、セルに数式が入っていても表示が空白
上記が混在している状態で、以下のコードで行削除すると、結果も混在してしまいます。
Public Sub 空白行削除スペースは残る()
Dim lastRow As Long
Dim i As Long
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
For i = lastRow To 2 Step -1
If ActiveSheet.Cells(i, 7).Value = "" Then
Rows(i).Delete
End If
Next i
End Sub| ①セルに情報が何も入っていない | 削除 |
|---|---|
| ②スペースが入っている | 削除されない |
| ③セルに数式が入っていても表示が空白 | 削除 |
スペースが入っている場合も含めて、見た目が空白ならすべて削除するには、コードにTrimを追加します。
Public Sub 空白行削除スペースも削除()
Dim lastRow As Long
Dim i As Long
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
For i = lastRow To 2 Step -1
If Trim(ActiveSheet.Cells(i, 7).Value) = "" Then
ActiveSheet.Rows(i).Delete
End If
Next i
End SubTrimは文字列の前後のスペースを削除します。
これにより、スペースしか入っていないセルを本当の空白セルとして扱えるようになります。
また、VBAのValueは、数式そのものではなく数式の計算結果を返すため、同じ数式が入っていても計算結果によって行削除の有無が変わります。
計算結果に関わらずすべての数式セルを残したい場合は、以下のようにIf文を重ねてください。
Public Sub 空白行削除数式は残す()
Dim lastRow As Long
Dim i As Long
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
For i = lastRow To 2 Step -1
If Not ActiveSheet.Cells(i, 7).HasFormula Then
If Trim(ActiveSheet.Cells(i, 7).Value) = "" Then
ActiveSheet.Rows(i).Delete
End If
End If
Next i
End SubIf Not Cells(i, 7).HasFormula Thenに書かれている.HasFormulaとは、そのセルに数式が入っているかどうかを調べるためのものです。
If Not Cells(i, 7).HasFormula Thenと書くことで、数式が入っていないセルだけを対象にすることができます。
重複行を削除するポイントと考え方
重複行を削除するVBAを作るポイントは、判定基準を先に明確にすることです。
例えば、A列のみ重複している場合や、A列・B列・C列すべてが重複している場合などです。
ここでは、実務でよく使われる「複数列で重複判定するコード」をご紹介します。
Sub 複数列で重複行を削除()
Dim i As Long
Dim lastRow As Long
Dim dict As Object
Dim key As String
Set dict = CreateObject("Scripting.Dictionary")
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
For i = lastRow To 2 Step -1
key = ActiveSheet.Cells(i, 1).Value & "|" & ActiveSheet.Cells(i, 2).Value & "|" & ActiveSheet.Cells(i, 3).Value
If dict.Exists(key) Then
ActiveSheet.Rows(i).Delete
Else
dict.Add key, True
End If
Next i
End Sub最終行の行数を取得して変数lastRowに格納することと、For~Nextループで下から上に向かって繰り返し処理をすることは前章と変わりません。
ここでのポイントは以下のとおりです。
- Set dict = CreateObject("Scripting.Dictionary")
-
変数
dictを重複チェック用の箱として設定しています。 - key = ActiveSheet.Cells(i, 1).Value & "|" & ActiveSheet.Cells(i, 2).Value & "|" & ActiveSheet.Cells(i, 3).Value
-
変数
keyに1~3列目であるA・B・C列の値を1つにまとめて格納しています。間に「|」を追加して「A|B|C」という1つの判定キーを作成することがポイントです。
重複チェックの列を増やしたい場合は
& "|" & ActiveSheet.Cells(i, 3).Valueを増やしてください。 - If dict.Exists(key) Then
ActiveSheet.Rows(i).Delete
Else
dict.Add key, True
End If -
If dict.Exists(key) Thenで、判定キーkeyの値がすでに重複チェックの箱dictに登録されているかを確認しています。すでに登録されている場合は
ActiveSheet.Rows(i).Deleteで行削除します。まだ登録されていない場合は
dict.Add key, Trueでkeyの内容がdictに追加登録される流れです。
ライクさんIf条件式Then該当する場合の処理Else該当しない場合の処理
の順番だよ!
なお、繰り返し処理が下から上に向かって行われるため、重複削除する場合は上にある行が削除されることに注意が必要です。
例を見てみましょう。

上のように「020001|02|青森県」「040002|04|宮城県」が重複している場合、重複削除をすると以下の結果となります。

本来の並び順で言えば上の行を残したいところですが、下から上に向かって繰り返し処理が行われるため上の行が重複とみなされて削除されてしまいます。
必要に応じて重複削除の後にVBAでソートを追加して並び替えましょう。
重複行を手軽に削除するコードにRemoveDuplicatesがありますが、判定を細かく設定できず、担当者が変わった際に削除の仕組みが見えにくいため実務向きではありません。
本記事では、実務での応用や事故防止を重視し、「判定 → 削除」という考え方に基づいた方法を解説しています。
なお、一刻も早く機械的に重複行を削除したい場合は、以下のコードを使用してください。
Public Sub 機械的に重複行を削除()
Range("A:F").RemoveDuplicates (Array(1, 3, 4))
End SubA列からF列までのリストで、左から1・3・4列目であるA列・C列・D列すべてが重複している行を機械的に削除するマクロです。
リストの範囲が異なる場合はRange("A:F")の範囲を変更、重複している列の判定を変更したい場合はArray(1, 3, 4)の数字を変更してください。
削除を実行する前に必ずバックアップを取っておきましょう。
エクセルVBAの行削除と一緒に覚えておきたい便利技
VBAを使った行の削除は、単体で削除を行うよりも、列の削除や行・列の挿入などと組み合わせることが多いです。
ここでは、行削除と一緒に覚えておきたいコードを簡単にご紹介します。
エクセルVBAで列を削除する基本ポイント
列を削除する基本構文は次のとおりです。
Columns(5).Delete
Range("E:E").Delete
Cells(1, 5).EntireColumn.Delete行ではRowsを使っていた代わりにColumnsを使います。
RangeとCellsは変わりません。
行削除との違いは縦方向か横方向かだけであり、考え方は全く同じです。
エクセルの行や列を挿入するマクロの基本
行や列の削除とセットで使われるのが挿入です。
挿入にはInsertを使います。
Rows(5).Insert
Columns(5).Insert削除と挿入を同時に行う場合は、「削除してから挿入」の順番を意識することをお勧めします。
行や列は削除や挿入をすると位置がずれるからです。
例えば「5行目を削除して新しく作り直したい」場合は、次の順番でコードを書きましょう。
Rows(5).Delete
Rows(5).Insertもしも挿入Insertを先に書いた場合は、以下の順番で処理が行われます。
- 5行目に行を挿入→もともとの5行目は6行目に移動
- 5行目を行削除→挿入した①が削除される
- マクロ実行前と変わらない
削除→挿入の順番を意識することで、行や列のずれが起きにくくなるので覚えておきましょう。
行・列操作を安全に行う実務マクロと注意点
VBAで行や列を削除するとき、対象範囲内に結合セルが含まれていると、以下のような問題が起こります。
- 削除できない
- マクロが途中で止まる
- 意図しない範囲まで削除される
この原因は、結合セルが「複数の行や列にまたがった1つのセル」として扱われるからです。
エクセルVBAを実務に活用する際、シート内に結合セルがある場合は、まずは結合セルの有無をチェックした上で行や列の削除を行いましょう。
サンプルコードは以下のとおりです。
Public Sub 結合セルを解除して行削除()
Dim lastRow As Long
Dim i As Long
lastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
For i = lastRow To 2 Step -1
If ActiveSheet.Cells(i, 7).Value <> "送付対象" Then
If ActiveSheet.Rows(i).MergeCells Then '結合セルの有無を確認
ActiveSheet.Rows(i).UnMerge '結合セルを解除
End If
ActiveSheet.Rows(i).Delete
End If
Next i
End Sub
MergeCellsは、結合セルを含んでいればTrueを返します。
また、UnMergeでは結合を解除しています。
これらをあらかじめ入れておくことで、結合セルが原因のエラーを防ぐことができます。
なお、行と列の操作を一つのマクロ内で行いたい場合は、行を操作した後に列を操作しましょう。
行と列を同時に操作すると、想定していない位置が削除される可能性があるからです。
ライクさん繰り返し処理は「下から上の順」
削除と挿入がある場合は「削除が先」
行と列を操作する場合は「行が先」
と覚えておこう!
結合セルの確認と、操作の順番に気を付けることで、実務でも安全に動くマクロになります。
エクセルVBAの行削除に関するQ&A
- 行削除がうまくいかない原因はなんですか?
-
行削除がうまくいかない原因は、繰り返し処理を上から順番に行っているケースがほとんどです。
行削除の場合は下から上に向かって処理を繰り返しましょう。
くわしくは行削除マクロでよくある失敗ケースと対策法の節をご覧ください。
- エクセルで行を削除して上に詰めるにはどうすればいいですか?
-
行削除で上に詰めるには、
Deleteを使ってください。 - エクセルVBAの
ClearとDeleteの違いはなんですか? -
Clearはセルの中身だけ、Deleteは行ごと削除します。必要に応じて使い分けましょう。
くわしくは削除する2つのVBAコードとその違いの節をご覧ください。
行削除をVBAで自動化してミスをなくそう!
この記事では行削除の基本と、初心者が間違えやすい行削除のポイントと対策方法について解説しました。
行削除の基本の仕組みをしっかりと理解することで、繰り返し処理や条件付き削除など複雑なVBAをつまずかずに処理できるようになります。
解説した内容をおさらいしておきましょう。
- 行を指定する際は
Rows・Range・Cellsを使い分ける - 行を削除して上に詰めるのは
Delete、行の中身だけ削除するのはClear - 繰り返し処理は「下から上」の順で、変数を使った
Forループ推奨 - 結合セルは初めに解除しておくことが大事
リストが大量であるほど行削除は必須の業務となります。
手作業によるミスをなくすためにも、エクセルVBAを使った行削除をマスターしましょう!
行削除のほかにも、実務に役立つマクロの基本を解説しています。
こちらから学ぶことができますので、ぜひご参照ください。