VBAを使ってワークシートの行削除を行う基本的なアルゴリズムを解説します。
他人からもらったExcelファイルのデータの中には、自分にとって必要のない行が挿入されていることがありますよね。
例えば、項目グループごとに小計欄を行挿入していたり、さらに一回り大きなグループの小計がまたあったりと。そんな不要な行をVBAコードで削除する方法です。ではまずはサンプルファイルを用意しておいてくださいね。

下は今回のVBAコードになります。ぜひ今回も真似て書いてみてください。
では、実行してみましょう。
どうでしたか?上手くいけば、下のようにすべてのレコードが削除された状態になっていると思います。
いまご覧いただいたように、すべてのレコードを削除するようなケースはほとんどないと思います。ただ今回は、この簡単な基本パターンをお話して、行削除に慣れてもらいたいと思い、あえてあり得ない実行結果の例を紹介しております。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Option Explicit 'レコード削除 Sub Sample025() Dim lngERow As Integer 'データ最終行番号用変数 Dim r As Integer 'ルーチン処理用変数 'レコード最終行番号取得 lngERow = Range("A" & Rows.Count).End(xlUp).Row '繰り返し処理 For r = lngERow To 2 Step -1 '行全体削除 Cells(r, 1).EntireRow.Delete Next End Sub |
まず、5, 6, 9行目については、もう既に何度か登場してますので、お話を割愛させて頂きますね。
12行目:For r = lngERow to 2 step -1 ~ Next
今回の繰り返し処理する範囲になります。繰り返し開始が、最終行からという今回のVBAコードのパターンですが、 VBAコードでワークシートに空白行を挿入する 記事でも取り上げました。
15行目:Cells(r, 1).EntireRow.Delete
今回繰り返し実行されるVBAコードです。このVBAコードで、行全体(1レコード分)を削除しています。
「.EntireRow」は、「.」の前のRangeオブジェクトの行全体を表すプロパティでしたよね。
そして、今回初登場になります「.Delete」です。これは、「.」の前のRangeオブジェクトを「削除」するというメソッド(命令)になります。
つまり、「Cells(r, 1).EntireRow」でRangeオブジェクトの行全体を指定したものを「.Delete」で削除しなさいという意味になります。
このように、今回はレコードの最終行から始まり、先頭行(r=2)まで順番に、行削除によって1レコードづつ削除しているVBAコードだといえそうですね。
では、どうして今回はレコードの最終行から行削除したのでしょうか。
ここで試しに、12行目のVBAコードを以下のように、先頭行から実行させるように変えて実行してみましょう。下の赤枠のように変更してから再度実行してみてください。
どうでしょう。結果は以下の通りになりましたでしょうか。
今度はレコードが残っちゃいましたね。商品IDをみると偶数のレコードが削除されなかったようです。
この理由については、これ以降の図でお話ししますね。
まず、VBAコードの繰り返し処理の順番を先頭行から行削除するようにしましたので、最初の実行分 (r = 2)の処理前後の様子は下図のようになりますよね。
r = 2で2行目が行削除されますと、それ以降の行は上に移動しますから、「バナナ」のレコードが2行目になります。
この状態のまま、VBAコードでは次にr = 3が実行されます。そうなると、次の図のようになります。
VBAコードにより、r = 2の次は r = 3で行削除されますので、ご覧の通り2行目の「バナナ」のレコードは残り、3行目の「みかん」のレコードが削除されます。
もう少しだけ先をみてみましょうね。つぎに、r = 4の実行前後をみてみると、今度は3行目の「グレープフルーツ」のレコードが残りました。
ここまでくると、商品IDが偶数の商品が残っていく様子がイメージできますよね。
意図的に、偶数の商品IDだけ残して、行削除をする場合にはよいかもしれませんが、原則行削除は、VBAコードを最終レコード行番号から実行させるようにします。
まとめ
行削除を実行させるVBAコードについてお話ししました。ポイントは、最終レコードから行削除を実行させるということでしたね。
今回の例では、基本的な説明のため、全行削除の例でお話ししましたが、応用的な使い方としては、For ~ Next文などの繰り返し処理の中に、条件に合った場合に削除するような使い方ができます。