ExcelVBAでデータ処理を自動化する際、よく利用されるのが 「オートフィルタ」 機能です。
特定の条件でデータを抽出したり、該当する行を削除・転記するなど、業務効率化に欠かせない機能ですが、同時に「フィルター関連のエラー」でマクロが止まることも多いものです。
たとえば、
- フィルタをかけたが該当データがなかった
- オートフィルタが未設定のシートで
.AutoFilter.Range
を呼び出した - フィルタを解除し忘れて次の処理でエラーになった
といったトラブルは、実務で非常によく起こります。
この記事では、VBAでフィルタ処理を行う際の典型的なエラー原因とその回避方法を、実際のコード例を交えて詳しく紹介します。
目次
- ✅ フィルターでよく起こる3つのエラー原因
- ・① 「指定された種類のセルは見つかりません」エラー(1004)
- ・② 「オートフィルタが設定されていません」エラー
- ・③ フィルタ解除忘れによる後続処理エラー
- ✅ エラー回避の基本構文:On Error と Nothingチェック
- ・基本的な安全構成の例
- ✅ コード解説:なぜこの方法で安全に動くのか
- ・1. On Error Resume Next で一時的にエラーを無視
- ・2. If visibleRange Is Nothing で該当なしを判定
- ・3. AutoFilterMode = False でフィルタ解除
- ✅ フィルタ設定前に「オートフィルタが存在するか」を確認
- ✅ 応用:エラー回避付きの「動的条件フィルタ」
- ✅ 応用:複数条件フィルタでもエラーを防ぐ
- ✅ 高速化と安定化のための補足テクニック
- ・1. 画面更新を止める
- ・2. 再計算を一時停止
- ・3. フィルタ解除を忘れない
- ✅ 実務での活用例:自動レポート作成のエラー防止
- ✅ まとめ:VBAフィルターのエラーは事前チェックで確実に防げる
✅ フィルターでよく起こる3つのエラー原因
VBAでフィルタを使うときに特に多いのは、次の3つのエラーです。
・① 「指定された種類のセルは見つかりません」エラー(1004)
これは、SpecialCells(xlCellTypeVisible)
を使ったときに可視セルが存在しない場合に発生します。
つまり、フィルタ結果が0件だった場合です。
参考:【VBA】特定のセル(空白セル・数式セル・エラーセル)を見つけ出す:SpecialCells メソッド
・② 「オートフィルタが設定されていません」エラー
ws.AutoFilter.Range
を参照したときに、シートにオートフィルタが存在しないとエラーになります。
意図せず削除されていたり、新しいデータに置き換えた後などに発生しやすいです。
参考:【VBA】可視セルがない場合の安全な処理方法|エラー回避と実務での応用
・③ フィルタ解除忘れによる後続処理エラー
一度フィルタを設定したまま次の操作に進むと、意図しないデータが隠れた状態で処理が実行され、削除・コピーなどの結果が崩れることがあります。
これらを防ぐには、「事前チェック」+「エラー回避構文」+「フィルタ解除」 の3つを徹底することがポイントです。
参考:【VBA】フィルターの一部だけを解除する方法|特定列だけ再表示したいときの解決策
✅ エラー回避の基本構文:On Error と Nothingチェック
・基本的な安全構成の例
Sub SafeFilterProcess()
Dim ws As Worksheet
Dim visibleRange As Range
Set ws = ThisWorkbook.Sheets("データ")
' --- フィルタ設定(例:A列で「完了」を抽出) ---
ws.Range("A1").AutoFilter Field:=1, Criteria1:="完了"
' --- 可視セルを取得(ヘッダーを除く) ---
On Error Resume Next
Set visibleRange = ws.AutoFilter.Range.Offset(1, 0).Resize(ws.AutoFilter.Range.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
' --- 可視セルがない場合の処理 ---
If visibleRange Is Nothing Then
MsgBox "該当データがないため、処理をスキップします。", vbInformation
ws.AutoFilterMode = False
Exit Sub
End If
' --- データ処理(例:削除) ---
visibleRange.EntireRow.Delete
' --- フィルタ解除 ---
ws.AutoFilterMode = False
MsgBox "完了データを削除しました。", vbInformation
End Sub
この構文では、フィルタで該当データがなかったときもマクロが止まらず、
「該当なし→スキップ」という安全な流れを実現しています。
参考:【VBA】Findの戻り値を理解する方法|Nothing判定と実務での活用例を解説
参考:【VBA】On Error Resume Nextでエラーを無視してエラーの制御
✅ コード解説:なぜこの方法で安全に動くのか
・1. On Error Resume Next で一時的にエラーを無視
SpecialCells(xlCellTypeVisible)
は、表示セルが存在しないときにエラー1004を返します。
これを防ぐために、一時的にエラーを無視し(Resume Next)、その直後で明示的に判定を行います。
・2. If visibleRange Is Nothing で該当なしを判定
該当セルがなかった場合、visibleRange
には何も代入されず「Nothing」になります。
この状態を利用して「スキップ」などの条件分岐を行うのが最も安定的です。
・3. AutoFilterMode = False でフィルタ解除
どんな場合でも最後にフィルタを解除しておくことで、後続処理への影響を防ぎます。
特に連続でマクロを実行するような環境では重要なポイントです。
✅ フィルタ設定前に「オートフィルタが存在するか」を確認
オートフィルタが設定されていない状態で AutoFilter.Range
を呼び出すとエラーになります。
この場合は、If ws.AutoFilterMode = False Then
で事前チェックを行いましょう。
If ws.AutoFilterMode = False Then
MsgBox "オートフィルタが設定されていません。", vbExclamation
Exit Sub
End If
また、「シートにオートフィルタはあるが、フィルタ条件が未設定」の場合は、FilterMode
プロパティを使って確認できます。
If ws.FilterMode = False Then
MsgBox "現在フィルタは適用されていません。", vbInformation
End If
この2つを組み合わせることで、どのような状態でもマクロが安全に動作します。
参考:【VBA】フィルター結果を取得する方法|抽出データを自在に活用する実践テクニック
✅ 応用:エラー回避付きの「動的条件フィルタ」
実務では、毎回同じ条件ではなく、セルや変数の値を使って条件を設定するケースも多いです。
動的条件でも同じ構文でエラーを防げます。
Sub DynamicFilterSafe()
Dim ws As Worksheet
Dim key As String
Dim visibleRange As Range
Set ws = ThisWorkbook.Sheets("データ")
key = ws.Range("E1").Value ' 条件をセルから取得
' --- オートフィルタ設定 ---
ws.Range("A1").AutoFilter Field:=1, Criteria1:=key
' --- 可視セル取得(安全構文) ---
On Error Resume Next
Set visibleRange = ws.AutoFilter.Range.Offset(1, 0).Resize(ws.AutoFilter.Range.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If visibleRange Is Nothing Then
MsgBox "条件「" & key & "」に該当するデータはありません。", vbInformation
ws.AutoFilterMode = False
Exit Sub
End If
' --- 該当がある場合の処理 ---
visibleRange.Copy Destination:=ThisWorkbook.Sheets("結果").Range("A1")
ws.AutoFilterMode = False
MsgBox "条件「" & key & "」のデータを転記しました。", vbInformation
End Sub
このように、「可視セルがない場合はスキップ」+「フィルタ解除」 を組み合わせれば、
どんな条件でも止まらない安定したマクロを実現できます。
参考:【VBA】オートフィルタの対象がない場合に何もしないようにする方法|安全な自動処理の基本
✅ 応用:複数条件フィルタでもエラーを防ぐ
Operator:=xlOr
などを使って複数条件を設定した場合も、基本は同じ構文でエラーを防げます。
Sub MultiConditionSafe()
Dim ws As Worksheet
Dim visibleRange As Range
Set ws = ThisWorkbook.Sheets("データ")
ws.Range("A1").AutoFilter Field:=1, Criteria1:="完了", Operator:=xlOr, Criteria2:="中止"
On Error Resume Next
Set visibleRange = ws.AutoFilter.Range.Offset(1, 0).Resize(ws.AutoFilter.Range.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If visibleRange Is Nothing Then
MsgBox "完了・中止データが見つかりません。", vbInformation
ws.AutoFilterMode = False
Exit Sub
End If
visibleRange.EntireRow.Delete
ws.AutoFilterMode = False
MsgBox "該当データを削除しました。", vbInformation
End Sub
複数条件でも同じエラー(1004)が発生するため、この「Nothingチェック」は必須です。
✅ 高速化と安定化のための補足テクニック
・1. 画面更新を止める
フィルタや削除を繰り返す処理では、画面更新を止めると処理速度が向上します。
Application.ScreenUpdating = False
' 処理本体
Application.ScreenUpdating = True
参考:【VBA】Application.ScreenUpdatingプロパティの使用方法と特徴
・2. 再計算を一時停止
数式が多いブックでは、再計算を止めると安定します。
Application.Calculation = xlCalculationManual
' 処理
Application.Calculation = xlCalculationAutomatic
・3. フィルタ解除を忘れない
マクロ終了時に必ず ws.AutoFilterMode = False
を入れておきましょう。
フィルタが残ると、次回実行時に範囲指定がずれて予期せぬ挙動になります。
参考:【VBA】フィルター解除を全て実行する方法|複数シート・複数フィルター対応の完全自動化解説
✅ 実務での活用例:自動レポート作成のエラー防止
日次・週次レポートの自動生成では、営業部門などのデータを条件ごとに抽出する処理が多く使われます。
たとえば、全社員リストから部門別にデータを抽出する場合、
「該当データがない部門」があってもマクロを止めずに処理を続行する必要があります。
For Each 部門名 In 部門一覧
Call FilterByDepartment(部門名)
Next 部門名
ここに「可視セルがない場合はスキップ」を入れておけば、
どの部門にもデータがなくても全体処理が止まることはありません。
これが“止まらない自動化”の鍵です。
✅ まとめ:VBAフィルターのエラーは事前チェックで確実に防げる
SpecialCells(xlCellTypeVisible)
は可視セルがないとエラー1004を返すOn Error Resume Next
とIf visibleRange Is Nothing Then
の組み合わせで回避可能AutoFilterMode
とFilterMode
でフィルタ状態をチェック- フィルタ解除 (
AutoFilterMode=False
) を常に最後に入れる - 動的条件・複数条件にも共通して使える汎用構文
オートフィルタはVBAの中でも特に便利な機能ですが、
エラー対策を入れないと「現場で止まるマクロ」になってしまいます。
今回紹介した安全構文を取り入れることで、どんなデータ状況でも落ちない堅牢なVBA を構築できます。
ぜひ、あなたの業務マクロにもこのエラー回避テクニックを組み込み、
「安定して動くプロのVBA」を目指してください。