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 -1VBAで特定の文字を含む行を削除する
まずは、「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 rAndなら「両方の条件を満たした場合」、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 cC列を削除すると元の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 -1UsedRange.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.Print | Delete前に確認する |
| 誤削除に備える | バックアップ | 元データを残す |
CSV・システム出力データの整形にも使える
ここまで紹介した行削除・列削除は、単純なExcelファイルだけでなく、CSVやシステムから出力されたデータの加工にも利用できます。
例えば、次のような一連の処理をVBAで自動化できます。
- CSVファイルを開く
- 不要な列を削除する
- 不要な行を削除する
- 日付や数値などの形式を整える
- 必要なデータだけを別シートへ転記する
- 集計する
- 加工後のファイルを保存する
毎回同じ加工をしているのであれば、こうした処理をマクロにまとめることで、「CSVを開いて何十分も手作業で加工する」という作業そのものをなくすことができます。
VBAの行・列削除で覚えておきたい7つのポイント
- 行削除は下から上へ処理する
- 列削除は右から左へ処理する
- 部分一致と完全一致を使い分ける
- 最終行・最終列はデータ構造に合わせて取得する
- UsedRangeは開始位置に注意して使う
- 後続処理で必要なデータを先に削除しない
- 重要なデータなら削除前の確認・バックアップを行う
このポイントを押さえておけば、VBAの行削除・列削除で起こりやすい「対象がズレる」「一部だけ残る」「必要なデータまで消える」といったトラブルをかなり減らせます。
まとめ|VBAの行・列削除は「方向」と「条件」が重要
VBAで行や列を削除する処理は、一見すると単純です。
しかし、実務で使うためには、単にRows.DeleteやColumns.Deleteを書くのではなく、「どこを対象にするのか」「どの条件で削除するのか」「どの順番で処理するのか」を考える必要があります。
特に重要なのは、次の考え方です。
- 行削除は下から上
- 列削除は右から左
InStrは部分一致=なら完全一致UsedRangeは開始位置に注意- 処理順序は後続処理への影響を考えて決める
- 重要なデータなら削除前の確認やバックアップも行う
また、行削除・列削除はそれ単体で使うだけではありません。
CSVの自動加工、システム出力データの整形、不要データの除外、集計前の前処理など、Excel業務の自動化では非常によく登場する処理です。
まずは「後ろから前へ削除する」という基本を押さえ、そこから条件分岐や複数条件、ファイル操作などを組み合わせていくと、より実用的なVBAマクロを作れるようになります。
毎回同じようなデータ整形を手作業で行っているなら、まずは「どの行・列を削除しているのか」を整理してみてください。
その作業は、VBAで自動化できる可能性があります。
