VBAで行や列を削除するときの注意点まとめ|ズレない安全な処理方法と実務向けコード

アイキャッチ画像

Excelで大量のデータを扱っていると、「特定の文字を含む行を削除したい」「不要な列をまとめて削除したい」という場面があります。

手作業なら数行の削除で済む場合でも、毎回同じデータ整形を行うのであれば、VBAで自動化することで作業時間を大きく削減できます。

一方で、VBAの行削除・列削除には少し注意が必要です。

  • 削除したはずなのに、一部の行が残っている
  • 削除対象ではない行まで消えてしまった
  • 列を削除したら、処理対象の列がズレた
  • ループ中に削除したら、処理対象を飛ばしてしまった
  • UsedRangeを使ったら、想定した範囲を処理できなかった
  • 「部分一致」と「完全一致」を間違えて、必要なデータまで削除してしまった

この記事では、VBAで行・列を安全に削除する基本的な考え方から、コピペして使える実務向けコード、よくある失敗例までまとめて解説します。

CSVやシステム出力データの整形など、繰り返し発生するExcel作業を自動化したい方にも役立つ内容です。

目次

この記事でわかること

  • VBAで特定の文字を含む行を削除する方法
  • VBAで特定の文字を含む列を削除する方法
  • なぜ行は下から上、列は右から左へ処理するのか
  • InStrによる部分一致と完全一致の使い分け
  • 最終行・最終列を取得する方法
  • UsedRangeを使うときの注意点
  • 複数条件で行・列を削除する方法
  • コピペして使える完成版マクロ
  • VBAの行削除・列削除で起こりやすい失敗例
  • 削除前に対象を確認する方法とバックアップの考え方

VBAで行・列を削除するときの基本

VBAで行や列を削除するとき、まず覚えておきたいのが「削除する方向」です。

削除する対象基本的な処理方向
下 → 上
右 → 左

これは、行や列を削除すると、その後ろにあるデータが詰められるためです。

削除するループを前から後ろへ進めると、削除によって位置が変わったデータを飛ばしてしまうことがあります。

なぜ行は「下から上」へ処理するのか

例えば、次のようなデータがあるとします。

A列
2商品A
3削除対象
4削除対象
5商品B

3行目を削除すると、元の4行目が3行目へ移動します。

この状態でループのカウンタを次へ進めると、移動してきたデータを確認せずに飛ばしてしまう可能性があります。

そこで、5行目 → 4行目 → 3行目 → 2行目というように、下から上へ処理します。

後ろ側の行を削除しても、それより前にある行の番号には影響しないため、削除ループではこの方法が基本になります。

VBAでは、Step -1を使うことで後ろから前へ処理できます。

For r = lastRow To 2 Step -1

列は「右から左」へ処理する

列削除も考え方は同じです。

C列を削除すると、元のD列がC列へ移動します。そのため、左から右へ処理すると、移動してきた列を飛ばしてしまう可能性があります。

そこで、列削除では右端から左へ処理します。

For c = lastCol To 1 Step -1

VBAで特定の文字を含む行を削除する

まずは、「A列に特定の文字が含まれている行を削除する」基本パターンです。

Dim ws As Worksheet
Dim r As Long
Dim lastRow As Long

Set ws = ThisWorkbook.Worksheets("データ")

lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

For r = lastRow To 2 Step -1

    If InStr(CStr(ws.Cells(r, 1).Value), "削除対象") > 0 Then
        ws.Rows(r).Delete
    End If

Next r

このコードでは、A列に「削除対象」という文字を含む行を削除しています。

"データ"の部分は、実際に処理したいシート名へ変更してください。

コードのポイント

  • lastRowで最終行を取得する
  • Step -1で下から上へ処理する
  • Cells(r, 1)でA列を判定する
  • InStrで部分一致を判定する
  • Rows(r).Deleteで該当行を削除する
  • Worksheets("データ")で対象シートを明示する

ここでは1行目を見出しとして、2行目から処理しています。

見出しがないデータなら、次のように変更できます。

For r = lastRow To 1 Step -1

「含む」と「完全一致」を使い分ける

行削除で意外と多いのが、部分一致と完全一致を間違えるケースです。

InStrを使うと、「指定した文字がセルの中に含まれているか」を判定できます。

If InStr(CStr(ws.Cells(r, 1).Value), "削除") > 0 Then

この場合、「削除」だけでなく、次のような値も対象になります。

  • 削除
  • 削除対象
  • 削除予定
  • 削除済み

「セルの値が完全に『削除』の場合だけ削除したい」という場合は、=を使います。

If CStr(ws.Cells(r, 1).Value) = "削除" Then
    ws.Rows(r).Delete
End If
判定方法コード意味
部分一致InStr文字を含んでいれば対象
完全一致=セルの値が完全に同じなら対象

削除処理では、「何を削除対象とするのか」を最初に明確にしておくことが重要です。

VBAで特定の文字を含む列を削除する

次は、1行目の見出しを確認して、不要な列を削除する方法です。

Dim ws As Worksheet
Dim c As Long
Dim lastCol As Long

Set ws = ThisWorkbook.Worksheets("データ")

lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

For c = lastCol To 1 Step -1

    If InStr(CStr(ws.Cells(1, c).Value), "削除対象") > 0 Then
        ws.Columns(c).Delete
    End If

Next c

例えば1行目が次のようになっている場合を考えます。

A列B列C列D列
商品コード商品名削除対象売上金額

このコードを実行すると、C列が削除されます。

列削除でも、右から左へ処理することがポイントです。

最終行・最終列を取得する方法

データを削除するときには、「どこまで処理するのか」を決める必要があります。

VBAでは、基準となる列や行を決めて、End(xlUp)End(xlToLeft)を使う方法がよく利用されます。

最終行を取得する

lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

これは、A列の一番下から上方向へ検索し、最後にデータが入っている行を取得します。

例えばC列を基準にするなら、列番号を3に変更します。

lastRow = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row

最終列を取得する

lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

これは、1行目を基準として右端から左方向へ検索し、最後にデータが入っている列を取得します。

ポイントは、どの列・行を「データが存在する基準」とするかを決めておくことです。

UsedRangeを使う場合の注意点

Excel VBAでは、使用されている範囲を取得するためにUsedRangeを使うこともできます。

Set rng = ws.UsedRange

便利な機能ですが、UsedRange.Rows.Countをそのままワークシート上の行番号として扱わないように注意してください。

例えばUsedRangeが5行目から始まっている場合、UsedRange.Rows.Countは「5行目」という意味ではありません。

あくまでUsedRange内に何行あるかを表す値です。

そのため、次のようなコードは、データの開始位置によっては意図した処理にならない可能性があります。

For r = ws.UsedRange.Rows.Count To 1 Step -1

データ構造が分かっている場合は、基準列を決めてEnd(xlUp)で最終行を取得する方法のほうが分かりやすいでしょう。

複数条件で行を削除する

実務では、「A列に削除対象があり、なおかつB列がキャンセルの場合」のように、複数の条件を組み合わせることもあります。

For r = lastRow To 2 Step -1

    If InStr(CStr(ws.Cells(r, 1).Value), "削除対象") > 0 _
       And CStr(ws.Cells(r, 2).Value) = "キャンセル" Then

        ws.Rows(r).Delete

    End If

Next r

Andなら「両方の条件を満たした場合」、Orなら「どちらか一方でも条件を満たした場合」という意味になります。

複数の文字を対象にする

例えば、「エラー」「キャンセル」「不要」のいずれかを含む行を削除したい場合は、Orを使います。

If InStr(CStr(ws.Cells(r, 1).Value), "エラー") > 0 _
   Or InStr(CStr(ws.Cells(r, 1).Value), "キャンセル") > 0 _
   Or InStr(CStr(ws.Cells(r, 1).Value), "不要") > 0 Then

    ws.Rows(r).Delete

End If

対象となる文字が増えてきた場合は、配列やSelect Caseなどを使って条件を整理する方法もあります。

行削除と列削除、どちらを先にする?

行削除と列削除を組み合わせる場合、「必ず列削除→行削除」という固定ルールがあるわけではありません。

重要なのは、後続処理で必要になるデータを先に削除しないことです。

状況考え方
不要列を先に確定できる列削除 → 行削除
特定列を基準に行を判定する判定が終わるまで列を残す
行削除後に列構成を整理する行削除 → 列削除

つまり、「どちらを先に削除するか」よりも、処理に必要な情報を残したまま順番を組み立てることが大切です。

コピペして使える完成版マクロ

ここまでの内容を組み合わせて、実務で使いやすい形にしたサンプルです。

このマクロでは、次の処理をまとめて行います。

  • 1行目の見出しを確認して不要列を削除
  • A列を確認して不要行を削除
  • 列は右から左、行は下から上へ処理
  • 処理対象のシートを明示
Sub DeleteRowsAndColumns()

    Dim ws As Worksheet
    Dim r As Long
    Dim c As Long
    Dim lastRow As Long
    Dim lastCol As Long

    '対象シート
    Set ws = ThisWorkbook.Worksheets("データ")

    '--------------------------------
    ' ① 不要な列を削除
    '--------------------------------

    lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

    For c = lastCol To 1 Step -1

        If InStr(CStr(ws.Cells(1, c).Value), "不要列") > 0 Then
            ws.Columns(c).Delete
        End If

    Next c

    '--------------------------------
    ' ② 不要な行を削除
    '--------------------------------

    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    For r = lastRow To 2 Step -1

        If InStr(CStr(ws.Cells(r, 1).Value), "削除対象") > 0 Then
            ws.Rows(r).Delete
        End If

    Next r

    MsgBox "データの整形が完了しました。"

End Sub

使用前に、"データ"の部分を実際のシート名に変更してください。

自分のデータに合わせて変更する場所

まずは次の2か所を変更すれば、基本的なカスタマイズができます。

"不要列"

ここを削除したい列の見出しに変更します。

"削除対象"

こちらを、削除したい行を判定する文字に変更します。

例えば、「エラー」という文字を含む行を削除するなら、次のようにします。

If InStr(CStr(ws.Cells(r, 1).Value), "エラー") > 0 Then
    ws.Rows(r).Delete
End If

判定する列を変更する

完成版マクロではA列を判定しています。

ws.Cells(r, 1)

例えばC列を判定したい場合は、列番号を3に変更します。

ws.Cells(r, 3)
列番号
A列1
B列2
C列3
D列4
E列5

よくあるエラー・失敗例

ここでは、VBAの行削除・列削除で特に起こりやすい失敗をまとめます。

失敗例1:上から順番に行を削除する

For r = 2 To lastRow

    If InStr(CStr(ws.Cells(r, 1).Value), "削除") > 0 Then
        ws.Rows(r).Delete
    End If

Next r

行を削除すると下の行が繰り上がるため、次のループで対象データを飛ばしてしまう可能性があります。

対策:下から上へ処理します。

For r = lastRow To 2 Step -1

失敗例2:列を左から右へ削除する

For c = 1 To lastCol

    If InStr(CStr(ws.Cells(1, c).Value), "不要") > 0 Then
        ws.Columns(c).Delete
    End If

Next c

C列を削除すると元のD列がC列へ移動します。そのまま次の列へ進むと、移動してきた列を確認せずに処理してしまう可能性があります。

対策:右から左へ処理します。

For c = lastCol To 1 Step -1

失敗例3:InStrで必要なデータまで削除される

InStrは部分一致なので、検索文字が含まれていれば対象になります。

「削除」だけを対象にしたいのに「削除予定」まで削除される場合は、完全一致への変更を検討します。

If CStr(ws.Cells(r, 1).Value) = "削除" Then

失敗例4:UsedRangeの行数をそのまま行番号にする

For r = ws.UsedRange.Rows.Count To 1 Step -1

UsedRange.Rows.Countは、ワークシート上の行番号ではなくUsedRange内の行数です。

UsedRangeがA1以外から始まる場合には、想定した行を処理できない可能性があります。

データ構造が分かっている場合は、基準列を決めてEnd(xlUp)を使う方法が分かりやすいでしょう。

失敗例5:判定に必要な列を先に削除する

例えばB列の値を見て行を削除する処理なのに、その前にB列を削除してしまうと、判定できなくなります。

処理順序を決めるときは、「列削除が先」「行削除が先」と固定するのではなく、後続処理で必要なデータが残っているかを確認しましょう。

失敗例6:ActiveSheetに依存する

次のようなコードは短く書けます。

ActiveSheet.Rows(r).Delete

しかし、操作対象のシートが変わると、意図しないシートを操作する可能性があります。

操作対象が決まっているなら、ワークシートを変数に設定しておくほうが安全です。

Dim ws As Worksheet

Set ws = ThisWorkbook.Worksheets("データ")

ws.Rows(r).Delete

特に業務用マクロでは、どのシートを操作するのかを明示することで、誤操作を防ぎやすくなります。

削除前に「本当に対象なのか」を確認する

行や列の削除は、一度実行すると元に戻すのが難しい処理です。

特にCSVやシステム出力データを自動処理する場合は、いきなり削除するのではなく、最初に削除対象を確認する方法もおすすめです。

If InStr(CStr(ws.Cells(r, 1).Value), "削除対象") > 0 Then

    Debug.Print "削除対象:" & r & "行目"

    'ws.Rows(r).Delete

End If

この状態で一度実行すると、イミディエイトウィンドウに削除対象となる行番号が表示されます。

対象が正しいことを確認してから、コメントアウトしているDeleteを有効にします。

「削除するコードを書く」だけではなく、「削除対象が正しいか確認できるようにする」ことも実務では重要です。

バックアップを作ってから削除する方法

本番データを扱う場合は、削除処理そのものだけでなく、間違えたときに元へ戻せる状態を作っておくことも大切です。

例えば、処理前のシートをコピーしてバックアップを作成できます。

ws.Copy After:=ws

ActiveSheet.Name = "バックアップ_" & Format(Now, "yyyymmdd_hhnnss")

このコードでは、ws.Copyによってシートを複製し、コピーされたシートをバックアップとして名前変更しています。

ただし、ws.Copy後はコピーされたシートがアクティブになるため、ActiveSheetを使うこの書き方は、バックアップ作成という限定された用途での簡易例です。

より重要な業務データでは、元ファイルそのものを別名で保存しておく方法もあります。

特にCSVなどを加工する場合は、元ファイルを上書きせず、加工後のファイルを別名で保存する方法がおすすめです。

「正しく削除できること」だけでなく、失敗しても元のデータへ戻せることまで考えておくと、より安全なマクロになります。

VBA 行削除・列削除の早見表

実際にコードを書くときに確認しやすいよう、ポイントを一覧にまとめます。

やりたいこと基本的な方法注意点
特定文字を含む行を削除InStr下から上へ
特定文字と完全一致する行を削除=下から上へ
特定文字を含む列を削除InStr右から左へ
特定文字と完全一致する列を削除=右から左へ
複数条件で削除And / Or条件を明確にする
最終行を取得End(xlUp)基準列を決める
最終列を取得End(xlToLeft)基準行を決める
削除対象を確認Debug.PrintDelete前に確認する
誤削除に備えるバックアップ元データを残す

CSV・システム出力データの整形にも使える

ここまで紹介した行削除・列削除は、単純なExcelファイルだけでなく、CSVやシステムから出力されたデータの加工にも利用できます。

例えば、次のような一連の処理をVBAで自動化できます。

  1. CSVファイルを開く
  2. 不要な列を削除する
  3. 不要な行を削除する
  4. 日付や数値などの形式を整える
  5. 必要なデータだけを別シートへ転記する
  6. 集計する
  7. 加工後のファイルを保存する

毎回同じ加工をしているのであれば、こうした処理をマクロにまとめることで、「CSVを開いて何十分も手作業で加工する」という作業そのものをなくすことができます。

VBAの行・列削除で覚えておきたい7つのポイント

  • 行削除は下から上へ処理する
  • 列削除は右から左へ処理する
  • 部分一致と完全一致を使い分ける
  • 最終行・最終列はデータ構造に合わせて取得する
  • UsedRangeは開始位置に注意して使う
  • 後続処理で必要なデータを先に削除しない
  • 重要なデータなら削除前の確認・バックアップを行う

このポイントを押さえておけば、VBAの行削除・列削除で起こりやすい「対象がズレる」「一部だけ残る」「必要なデータまで消える」といったトラブルをかなり減らせます。

まとめ|VBAの行・列削除は「方向」と「条件」が重要

VBAで行や列を削除する処理は、一見すると単純です。

しかし、実務で使うためには、単にRows.DeleteColumns.Deleteを書くのではなく、「どこを対象にするのか」「どの条件で削除するのか」「どの順番で処理するのか」を考える必要があります。

特に重要なのは、次の考え方です。

  • 行削除は下から上
  • 列削除は右から左
  • InStr部分一致
  • =なら完全一致
  • UsedRange開始位置に注意
  • 処理順序は後続処理への影響を考えて決める
  • 重要なデータなら削除前の確認やバックアップも行う

また、行削除・列削除はそれ単体で使うだけではありません。

CSVの自動加工、システム出力データの整形、不要データの除外、集計前の前処理など、Excel業務の自動化では非常によく登場する処理です。

まずは「後ろから前へ削除する」という基本を押さえ、そこから条件分岐や複数条件、ファイル操作などを組み合わせていくと、より実用的なVBAマクロを作れるようになります。

毎回同じようなデータ整形を手作業で行っているなら、まずは「どの行・列を削除しているのか」を整理してみてください。

その作業は、VBAで自動化できる可能性があります。

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