Excelでオートフィルターを使って条件に一致するデータを抽出したあと、
「抽出結果だけを残して、その他の行を削除したい」
と思ったことはありませんか?
たとえば、
- 「特定部署のデータだけ残して他を削除」
- 「指定日付の行だけ残して他を消す」
- 「フィルターで絞った結果を新しい表として残したい」
といったケースです。
しかし、通常の削除操作ではフィルター非表示の行まで削除されてしまうことがあり、誤操作でデータを失う危険もあります。
この記事では、VBAで安全かつ確実に「フィルターで表示されていない行(以外)」を削除する方法を詳しく解説します。
実務でそのまま使えるコード付きで、初心者でも理解できる構成です。
目次
- ✅ フィルター以外を削除する基本の考え方
- 可視セルを指定する構文
- ✅ 実践①:フィルターで表示されていない行を削除する基本マクロ
- コード例
- ❌ このコードは一見正しそうですが…
- ✅ 実践②:安全に「フィルター以外」を削除する正しい方法
- コード例:正しい削除処理
- ✅ 実践③:「抽出結果だけ残して他を削除」する最も簡単なコード
- コード例
- ✅ 実践④:「フィルター以外を削除」してから自動保存する
- コード例
- ✅ 実践⑤:削除前に確認メッセージを出す(安全設計)
- コード例
- ✅ よくあるエラーとその対処法
- ✅ 応用:可視セル以外を削除せず、別ブックに保存する方法
- コード例
- ✅ まとめ:フィルター以外を削除できれば、Excel処理の自動化が加速する
✅ フィルター以外を削除する基本の考え方
まず理解しておくべきは、Excelの「オートフィルター」と「可視セル(表示セル)」の仕組みです。
フィルターをかけると、条件に合わない行は「非表示」になります。
このとき、VBAで削除処理を行う場合、
「非表示の行」だけを削除するか、「表示されている行だけ残す」かを選択できます。
この操作を安全に行うために使用するのが次のメソッドです
可視セルを指定する構文
Range("範囲").SpecialCells(xlCellTypeVisible)
これを使えば、フィルターで表示されているセル(=条件一致した行)のみを対象に操作できます。
逆に、非表示の行を削除したい場合はこの範囲を「除外」すればOKです。
参考:【VBA】条件に一致するセルを取得する方法|Find・For Each・SpecialCells
✅ 実践①:フィルターで表示されていない行を削除する基本マクロ
まずは、最もシンプルな「フィルター結果以外を削除する」コードです。
コード例
Sub DeleteFilteredOutRows()
Dim rng As Range
'--- フィルター設定(B列:部署)---
Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"
'--- フィルターで表示されていないセルを削除 ---
On Error Resume Next
Range("A2:C100").SpecialCells(xlCellTypeVisible).Select
Range("A2:C100").EntireRow.Hidden = False
Range("A2:C100").EntireRow.Delete
On Error GoTo 0
'--- フィルター解除 ---
ActiveSheet.AutoFilterMode = False
End Sub
❌ このコードは一見正しそうですが…
実はこのままだと「全行削除」される危険があります。
理由は、「非表示セルだけ」を正確に指定していないためです。
安全に「フィルター以外の行を削除」するには、表示されている行を除いた残りを削除する手順が必要です。
✅ 実践②:安全に「フィルター以外」を削除する正しい方法
次のコードでは、可視セル以外(非表示行)だけを削除する安全な手順を採用しています。
コード例:正しい削除処理
Sub DeleteRowsExceptFiltered()
Dim rng As Range
Dim allRange As Range
Dim visibleRange As Range
'--- フィルター設定(例:部署列で「営業部」を抽出)---
Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"
'--- データ全体範囲を設定 ---
Set allRange = Range("A2:A100")
'--- フィルター後の可視セルを取得 ---
On Error Resume Next
Set visibleRange = allRange.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
'--- データがない場合 ---
If visibleRange Is Nothing Then
MsgBox "条件に一致するデータがありません。"
ActiveSheet.AutoFilterMode = False
Exit Sub
End If
'--- 可視セル以外の行を削除 ---
allRange.EntireRow.Hidden = False
allRange.EntireRow.Delete
visibleRange.EntireRow.Copy
Rows(2).Insert
MsgBox "抽出結果以外のデータを削除しました。"
ActiveSheet.AutoFilterMode = False
End Sub
処理の流れ
- オートフィルターを設定(例:「営業部」)
参考:【VBA】オートフィルターを「設定のみ」行う方法を徹底解説|解除しないで条件だけ変更・適用 - 全データ範囲を指定
- 可視セル(抽出結果)を特定
参考:【VBA】指定したシートを開く方法|Activate・Select・Visibleの違いと実務活用 - 非表示行を削除(または可視セルだけを残す)
- 処理結果を通知
ポイント
SpecialCells(xlCellTypeVisible)
で可視セルを正確に取得- データが0件(Nothing)の場合もエラーで止まらない
参考:【VBA】Findの戻り値を理解する方法|Nothing判定と実務での活用例を解説 - 削除前に「確認メッセージ」を追加するとさらに安全
✅ 実践③:「抽出結果だけ残して他を削除」する最も簡単なコード
次のコードは、「抽出結果だけを残して、他を削除する」という実務で最も多いパターンです。
短くてシンプルですが、安全性も兼ね備えています。
コード例
Sub KeepFilteredRowsOnly()
Dim rng As Range
'--- フィルター設定(C列の売上が100以上)---
Range("A1:C100").AutoFilter Field:=3, Criteria1:=">=100"
'--- 可視セルを取得 ---
On Error Resume Next
Set rng = Range("A2:C100").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
'--- 可視セルがない場合 ---
If rng Is Nothing Then
MsgBox "該当データがありません。"
ActiveSheet.AutoFilterMode = False
Exit Sub
End If
'--- 抽出結果をコピー ---
rng.EntireRow.Copy
'--- シート全削除+ヘッダー残す ---
Rows("2:" & Rows.Count).Delete
'--- 結果貼り付け ---
Range("A2").PasteSpecial xlPasteAll
MsgBox "抽出結果だけを残しました。"
ActiveSheet.AutoFilterMode = False
End Sub
このコードの特徴
- 可視セル(抽出結果)をコピーして残す方式
- 非表示行の削除よりも安全(元データが保護されやすい)
- 「上書き保存」せずに別ブックへ出力にも応用可能
参考:【VBA】フィルター結果を新しいbookに保存する方法
応用:別シートに抽出結果を残したい場合
rng.EntireRow.Copy Destination:=Sheets("結果").Range("A1")
この1行に変えるだけで、抽出データだけを別シートへ自動転記できます。
✅ 実践④:「フィルター以外を削除」してから自動保存する
定期処理やバッチ処理のように、「抽出→不要行削除→保存」までを一括で行いたい場合は以下のようにします。
コード例
Sub FilterAndSave()
Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Set wb = ThisWorkbook
Set ws = wb.Sheets("データ")
'--- フィルター設定(部署:開発部)---
ws.Range("A1:D100").AutoFilter Field:=2, Criteria1:="開発部"
'--- 可視セルを取得 ---
On Error Resume Next
Set rng = ws.Range("A2:D100").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "該当データがありません。"
ws.AutoFilterMode = False
Exit Sub
End If
'--- 抽出結果のみ残す ---
rng.EntireRow.Copy
ws.Rows("2:" & ws.Rows.Count).Delete
ws.Range("A2").PasteSpecial xlPasteAll
'--- 自動保存(ファイル名に日付を付加)---
wb.SaveAs Filename:=wb.Path & "\FilteredData_" & Format(Date, "yyyymmdd") & ".xlsx"
MsgBox "抽出結果のみ残し、ファイルを保存しました。"
ws.AutoFilterMode = False
End Sub
実務での活用例
- 部署・支店・顧客別のデータを日次自動出力
- 毎月の報告資料として条件別にブックを保存
- UiPathやPower AutomateなどのRPAから呼び出す自動処理
参考:【UiPath】Studioの使い方をゼロから解説|インストールから実行まで
✅ 実践⑤:削除前に確認メッセージを出す(安全設計)
データを削除するマクロは誤操作のリスクが高いため、
確認メッセージを出すのがおすすめです。
コード例
Sub DeleteExceptFiltered_WithConfirm()
Dim ans As VbMsgBoxResult
Dim rng As Range
Range("A1:C100").AutoFilter Field:=2, Criteria1:="総務部"
ans = MsgBox("フィルター以外のデータを削除してもよろしいですか?", vbYesNo + vbQuestion, "確認")
If ans = vbNo Then
ActiveSheet.AutoFilterMode = False
Exit Sub
End If
On Error Resume Next
Set rng = Range("A2:C100").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "該当データなし。"
Else
rng.EntireRow.Copy
Rows("2:" & Rows.Count).Delete
Range("A2").PasteSpecial xlPasteAll
MsgBox "抽出結果以外を削除しました。"
End If
ActiveSheet.AutoFilterMode = False
End Sub
ポイント
MsgBox
のYes/Noを使って誤操作を防止- 「No」の場合は即終了し、安心設計
参考:【VBA】Exit Subの基本~実用的な使い方 - 会社で共有マクロを使う場合は必須レベルの安全策
✅ よくあるエラーとその対処法
トラブル内容 | 原因 | 対策 |
---|---|---|
実行時エラー1004 | 該当データが0件 | On Error Resume Next +If rng Is Nothing で制御 |
フィルターが解除されない | AutoFilterMode未解除 | 処理の最後で ActiveSheet.AutoFilterMode = False |
全行削除される | 範囲指定が誤り | 必ずヘッダーを除外 (A2 から開始) |
コピーが貼り付けられない | シート保護状態 | ActiveSheet.Unprotect を追加して実行 |
✅ 応用:可視セル以外を削除せず、別ブックに保存する方法
データを消すのではなく、抽出結果だけを新しいExcelファイルに保存するのもおすすめです。
実務で「元データを残したい」場合に最適です。
コード例
Sub ExportFilteredData()
Dim rng As Range
Dim newWb As Workbook
Range("A1:D100").AutoFilter Field:=2, Criteria1:="営業部"
On Error Resume Next
Set rng = Range("A1:D100").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "営業部のデータは存在しません。"
ActiveSheet.AutoFilterMode = False
Exit Sub
End If
rng.Copy
Set newWb = Workbooks.Add
newWb.Sheets(1).Range("A1").PasteSpecial xlPasteAll
newWb.SaveAs Filename:=ThisWorkbook.Path & "\営業部抽出_" & Format(Date, "yyyymmdd") & ".xlsx"
newWb.Close
MsgBox "営業部のデータのみを新しいブックに保存しました。"
ActiveSheet.AutoFilterMode = False
End Sub
✅ まとめ:フィルター以外を削除できれば、Excel処理の自動化が加速する
- フィルターで抽出された行だけを残すには
SpecialCells(xlCellTypeVisible)
が必須 On Error Resume Next
とIf rng Is Nothing
で安全制御- 削除よりも「コピーして残す」方法が確実で安全
- SUBTOTALやAutoFilterの組み合わせで応用も簡単
- 自動保存や別ブック出力にも発展可能
VBAで「フィルター以外を削除」できるようになると、
Excelの抽出作業・レポート作成・定型業務が一気に効率化します。
特に、条件抽出 → 不要データ削除 → 出力までを自動化すれば、
手動での確認作業を減らし、業務の正確性とスピードが大幅に向上します。