エクセルVBAで行削除を自動化!空白行や重複行も完全解説

歩君

エクセルVBAで行削除のループ処理ができるはずなのに、思ったとおりに削除できない!

ライクさん

VBAで行削除する場合は、知っておくといいコツがあるよ!

エクセルVBAを使って行削除をすると、行ズレや一部の空白行が消えないなどのトラブルが起こりがちです。

この記事ではVBAで行削除をする基本と、最終行まで繰り返し処理で行削除をする際に、初心者が失敗しやすいポイントを解説しています。

行削除の基本とポイント
  1. 行を指定する際はRowsRangeCellsを使い分ける
  2. 行を削除して上に詰めるのはDelete、行の中身だけ削除するのはClear
  3. 繰り返し処理は「下から上」の順で、変数を使ったForループ推奨
  4. 結合セルは初めに解除しておくことが大事

一見、難しそうな行削除ですが、ポイントさえ押さえておけば大量処理を簡単に自動で行えます。

行削除以外のマクロの基本とポイントについて知りたい方は、以下の記事で学ぶことができますのでご参照ください。

目次

エクセルVBAで行を削除する基本と仕組み

エクセルVBAで行を削除する際にまず重要なのは、コードを覚えるよりも仕組みを理解することです。

行削除のVBAコードを分解すると、主に次の2つに分けられます。

  1. 指定方法:どの行を削除するか
  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を作成して違いを見てみましょう。

マクロで削除したデータは元に戻せません。
行削除したいファイルのバックアップを取った上で作業しましょう。

STEP
VBAエディターを立ち上げる
Alt+F11でも開く
Alt+F11でも開く
  • 「開発」タブを押す
  • 「Visual Basic」をクリック
STEP
標準モジュールを挿入
挿入タブから操作
挿入タブから操作
  • 「挿入」タブを押す
  • 「標準モジュール」を選択
STEP
プロシージャを追加
続けて挿入
続けて挿入
  • 「挿入」タブを押す
  • 「プロシージャ」をクリック
STEP
マクロ名を付ける
マクロ名は日本語でOK
マクロ名は日本語でOK
  • マクロの名前を付ける
  • 「OK」ボタンを押す
STEP
コードを入力
Deleteを確認
Deleteを確認

まずはDeleteの結果を確認します。

Public Sub()End Subの間に以下のコードをコピペしましょう。

ActiveSheet.Rows(5).Delete
ライクさん

ActiveSheetとは現在操作しているシートのことだよ!
状況に応じてシート名を指定してね!

STEP
5行目の内容を確認した上でマクロを実行
5行目は宮城県
5行目は宮城県
  • エクセルで5行目の内容を確認
  • VBAエディターの「▶」実行をクリック
STEP
マクロ名を選んで実行
実行するマクロを選ぶ
実行するマクロを選ぶ
  • 「マクロ名」から実行するマクロを選ぶ
  • 「実行」ボタンを押す
STEP
Deleteの結果を確認
宮城県が行ごと削除
宮城県が行ごと削除

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

STEP
コードを書き換える
コードを上書き修正
コードを上書き修正
  • VBAエディターのDelete部分をClearに書き換える
  • VBAエディターの「▶」実行をクリック
STEP
Clearの結果を確認
秋田県の中身だけ削除
秋田県の中身だけ削除

5行目の中身だけ削除され、空白行が残ったことを確認しましょう。

行を詰めたいのにClearを使うと、空白行が残り、行ズレの原因となります。

行そのものを消したいのか、行の中身を消したいのか、マクロでやりたいことを事前に整理したうえで使い分けましょう。

行削除マクロでよくある失敗ケースと対策法

行そのものを削除するマクロで最も多い失敗が、複数行を上から順番に削除しようとすることです。

例えば「2行目から6行目」を繰り返し処理で削除する場合を考えてみましょう。

北海道から秋田までを削除
北海道から秋田までを削除

このリストの場合、2行目から6行目に該当するのは北海道・青森・岩手・宮城・秋田です。

まずは以下のコードを見てみてください。

Public Sub 行削除失敗例()

For i = 2 To 6

    ActiveSheet.Rows(i).Delete

Next i

End Sub

ForNextで繰り返し処理をし、変数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 Sub

ForNextで繰り返し処理をすることは変わりませんが、以下の2点を変更しています。

  • 変数i2 To 6ではなく6 To 2にする
  • Step -1を追加

これにより、6から2まで逆順で作業を繰り返すこととなり、行の繰り上がりの影響を受けなくなります。

この考え方はすべての行削除処理の基本になりますので、「行削除は必ず下から」と覚えておきましょう。

条件を指定して行を削除するVBA

実際の現場で行削除をVBAで行う場合、条件付きで行削除を行うケースがほとんどです。

ここでは、IF文と繰り返し処理を使った安全な行削除の方法を解説します。

前章に引き続き、作例として県庁所在地一覧を使用します。

条件付きで行削除するマクロの基本

エクセルVBAで条件付きで行削除する基本の流れは以下の3ステップです。

  • 行を1行ずつチェック
  • 条件に合えば削除
  • 下から上へForNextを使って繰り返し処理
歩君

でも、どうやって最終行を調べるの?

ライクさん

安心して!
最終行を調べる方法があるよ!

マクロのサンプルは以下のとおりです。

エクセルの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 Sub

lastRow = 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以上を削除

このマクロを実行すると、送付対象「以外」の行が削除されます。

送付対象の行が残る
送付対象の行が残る

前章の注意点のとおり、「下から上」に繰り返し処理をすることが失敗しないコツです。

「最終行まで繰り返し処理」と聞くとDoLoopのループ処理を思い浮かべる方もいるかもしれません。

ですが、DoLoopは条件を書き間違えると止まらないマクロになります。

今回のように事前に最終行が分かる場合は、ForNextループを使うほうが安心です。

空白行をマクロで安全に削除するコツ

空白行を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 Sub

Trimは文字列の前後のスペースを削除します。

これにより、スペースしか入っていないセルを本当の空白セルとして扱えるようになります。

また、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 Sub

If 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に格納することと、ForNextループで下から上に向かって繰り返し処理をすることは前章と変わりません。

ここでのポイントは以下のとおりです。

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, Truekeyの内容がdictに追加登録される流れです。

ライクさん

If条件式
Then該当する場合の処理
Else該当しない場合の処理
の順番だよ!

なお、繰り返し処理が下から上に向かって行われるため、重複削除する場合は上にある行が削除されることに注意が必要です。

例を見てみましょう。

青森・宮城が重複
青森・宮城が重複

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

下の行が残る
下の行が残る

本来の並び順で言えば上の行を残したいところですが、下から上に向かって繰り返し処理が行われるため上の行が重複とみなされて削除されてしまいます。

必要に応じて重複削除の後にVBAでソートを追加して並び替えましょう。

重複行を手軽に削除するコードにRemoveDuplicatesがありますが、判定を細かく設定できず、担当者が変わった際に削除の仕組みが見えにくいため実務向きではありません。

本記事では、実務での応用や事故防止を重視し、「判定 → 削除」という考え方に基づいた方法を解説しています。

なお、一刻も早く機械的に重複行を削除したい場合は、以下のコードを使用してください。

Public Sub 機械的に重複行を削除()

    Range("A:F").RemoveDuplicates (Array(1, 3, 4))

End Sub

A列から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を使います。

RangeCellsは変わりません。

行削除との違いは縦方向か横方向かだけであり、考え方は全く同じです。

エクセルの行や列を挿入するマクロの基本

行や列の削除とセットで使われるのが挿入です。

挿入には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のClearDeleteの違いはなんですか?

Clearはセルの中身だけ、Deleteは行ごと削除します。

必要に応じて使い分けましょう。

くわしくは削除する2つのVBAコードとその違いの節をご覧ください。

行削除をVBAで自動化してミスをなくそう!

この記事では行削除の基本と、初心者が間違えやすい行削除のポイントと対策方法について解説しました。

行削除の基本の仕組みをしっかりと理解することで、繰り返し処理や条件付き削除など複雑なVBAをつまずかずに処理できるようになります。

解説した内容をおさらいしておきましょう。

おさらい
  1. 行を指定する際はRowsRangeCellsを使い分ける
  2. 行を削除して上に詰めるのはDelete、行の中身だけ削除するのはClear
  3. 繰り返し処理は「下から上」の順で、変数を使ったForループ推奨
  4. 結合セルは初めに解除しておくことが大事

リストが大量であるほど行削除は必須の業務となります。

手作業によるミスをなくすためにも、エクセルVBAを使った行削除をマスターしましょう!

行削除のほかにも、実務に役立つマクロの基本を解説しています。

こちらから学ぶことができますので、ぜひご参照ください。

よかったらシェアしてね!
  • URLをコピーしました!
目次