Excelのオートフィルター機能で必要なデータだけを抽出した後、「その抽出されたデータだけを残して、非表示になっている他の行はすべて削除したい」という場面は、データ整理の際によく発生します。
手作業でこれを行うのは困難ですが、VBAを使えばこの処理を自動化できます。
この記事では、SpecialCells(xlCellTypeVisible)
を応用した、フィルターで非表示になっている行だけを高速に一括削除する、少しトリッキーで非常に効果的なテクニックを解説します。
完成したVBAコード
以下は、まずA列で「東京」という基準でフィルターをかけ、そのフィルターで**非表示になった行(「東京」以外の行)**をすべて削除するVBAコードです。
Sub DeleteFilteredOutRows()
' 変数を宣言します
Dim dataArea As Range
Dim visibleRows As Range
' アクティブシートのオートフィルターが適用されている範囲全体を取得
If Not ActiveSheet.AutoFilterMode Then
MsgBox "このシートではオートフィルターが設定されていません。", vbExclamation
Exit Sub
End If
Set dataArea = ActiveSheet.AutoFilter.Range
' --- 1. まず、残したいデータをフィルターで抽出 ---
' (この例ではA列が「東京」のデータを抽出)
dataArea.AutoFilter Field:=1, Criteria1:="東京"
' --- 2. 抽出された可視セル(残したい行)を変数に格納 ---
' SpecialCells(xlCellTypeVisible) で、見えているセルだけを取得
On Error Resume Next ' フィルター結果が0件の場合のエラーを回避
Set visibleRows = dataArea.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If visibleRows Is Nothing Then
MsgBox "抽出されたデータがありません。処理を中断します。"
Exit Sub
End If
' --- 3. フィルターを一旦解除 ---
' これにより、絞り込みは解除されるが、行の非表示状態は維持される
ActiveSheet.AutoFilterMode = False
' --- 4. 【重要】残したい行を、逆に非表示にする ---
' これにより、「削除したい行」だけが表示された状態になる
visibleRows.EntireRow.Hidden = True
' --- 5. 表示されている行(削除したい行)を一括削除 ---
dataArea.SpecialCells(xlCellTypeVisible).EntireRow.Delete
' --- 6. 非表示にしていた残したい行を再表示 ---
ActiveSheet.Rows.Hidden = False
MsgBox "フィルターで非表示だった行を削除しました。"
End Sub
コードのポイント解説(処理の流れ)
このコードは少しトリッキーな手順を踏んでいるため、ステップごとに解説します。
① データをフィルター抽出し、② 可視セルを特定
dataArea.AutoFilter Field:=1, Criteria1:="東京"
Set visibleRows = dataArea.SpecialCells(xlCellTypeVisible)
まず、通常通りオートフィルターを実行し、残したいデータを表示させます。そして、SpecialCells(xlCellTypeVisible)
を使い、その見えているセル範囲(visibleRows
)への参照を保持します。
③ フィルターを解除し、④ 表示/非表示を反転させる
ActiveSheet.AutoFilterMode = False
visibleRows.EntireRow.Hidden = True
ここがこのテクニックの核心部分です。
- まず、フィルターモードを解除します。これにより、フィルターの▼ボタンは消えますが、抽出されなかった行はまだ非表示のままです。
- 次に、先ほど変数に保持しておいた**「残したい行」(
visibleRows
)を、.Hidden = True
で強制的に非表示**にします。
結果として、画面上では**「削除したい行」だけが表示され、「残したい行」がすべて非表示**という、状態の「反転」が起こります。
⑤ 表示されている行を削除し、⑥ すべて再表示
dataArea.SpecialCells(xlCellTypeVisible).EntireRow.Delete
ActiveSheet.Rows.Hidden = False
ここまで来れば、あとは簡単です。
- 再び
SpecialCells(xlCellTypeVisible)
を使い、今画面に見えているセル(=削除したい行)を特定し、.EntireRow.Delete
で一括削除します。 - 最後に、シート全体の非表示設定(
.Rows.Hidden
)をFalse
に戻すことで、④で隠しておいた「残したかった行」が再び画面に現れます。
まとめ
フィルターで抽出されなかったデータを削除するこの方法は、一見すると複雑ですが、
- 残したい行を
SpecialCells(xlCellTypeVisible)
で特定する。 - フィルターを解除し、特定しておいた**「残したい行」を逆に隠す**。
- その結果、画面に**表示されている「削除したい行」**を
SpecialCells
で再度特定して一括削除する。 - 最後に、隠しておいた「残したい行」を再表示する。
という流れを理解すれば、応用が可能です。
ループで行を一つずつ削除する方法に比べて、SpecialCells
を使ったこの方法は、データ量が膨大であっても非常に高速に処理できるという大きなメリットがあります。