VBAで自動化 VBA一覧 フィルター結果の取得・判定 抽出・検索処理

【VBA】オートフィルタの該当なしをスキップする方法|エラーを出さずに安全に処理する

ExcelでVBAを使ってデータ処理を自動化していると、「オートフィルタで条件抽出を行ったが、該当データが1件もない」場面にしばしば遭遇します。
この状態で削除やコピーなどの処理を続行すると、VBAが 実行時エラー1004(指定された種類のセルは見つかりません) を返し、マクロが停止してしまいます。

このような問題を防ぐためには、該当データがない場合にスキップして安全に終了する仕組み を入れることが重要です。
この記事では、オートフィルタで「該当なし」のときに処理をスキップする方法を、初心者でも理解できるように詳しく解説します。

✅ なぜ「該当なしスキップ」が必要なのか

・通常のフィルタ処理ではエラーが出る

次のような単純なマクロを見てみましょう。

Sub DeleteFilteredRows()
    Range("A1").AutoFilter Field:=1, Criteria1:="完了"
    Range("A1").CurrentRegion.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End Sub

一見シンプルで正しく見えますが、
もし「完了」に該当するデータが1件もなかった場合、以下のようなエラーが発生します。

参考:【VBA】RangeクラスのSelectメソッドが失敗しました:1004

実行時エラー '1004':指定された種類のセルは見つかりません。

つまり、該当データが存在しないときに .SpecialCells(xlCellTypeVisible) が対象を見つけられずにエラーを出すのです。
このエラーを防ぐために、VBAでは「可視セルがあるかどうか」を事前に確認する必要があります。

参考:【VBA】条件に一致するセルを取得する方法|Find・For Each・SpecialCells


✅ 基本構文:該当なしならスキップする安全なコード

・最もシンプルで安定した書き方

Sub SafeDeleteFilteredRows()
    Dim ws As Worksheet
    Dim rng As Range
    Dim visibleRange As Range

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

    ' A列で「完了」を抽出
    ws.Range("A1").AutoFilter Field:=1, Criteria1:="完了"

    ' フィルタ範囲を取得
    Set rng = ws.AutoFilter.Range

    ' フィルタ後の可視セルを取得(ヘッダー除外)
    On Error Resume Next
    Set visibleRange = rng.Offset(1, 0).Resize(rng.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初心者が最初に覚えるべき「安定したオートフィルタ処理」と言っても良い構成です。

参考:【VBA】On Error Resume Nextでエラーを無視してエラーの制御


✅ コードのポイント解説

・① On Error Resume Next で一時的にエラーを無視

SpecialCells(xlCellTypeVisible) は、表示されているセルが1件もないときにエラーを返します。
そのため、一時的にエラーを無視して、後で「該当がない」かどうかを自分で判定します。

参考:【VBA】特定のセル(空白セル・数式セル・エラーセル)を見つけ出す:SpecialCells メソッド

・② If visibleRange Is Nothing Then で安全に分岐

該当データがない場合、visibleRange には何も代入されない(=Nothingのまま)ので、
この条件を利用して安全にスキップできます。

参考:【VBA】Findが見つからないときの原因と解決方法|Nothing判定・コードの書き方を解説

・③ フィルタ解除を忘れない

スキップする場合でも、最後に ws.AutoFilterMode = False でフィルタ状態を解除しておくと、
後続処理への影響を防げます。
特に複数マクロを連続実行する環境では、この行が安定動作の鍵になります。


✅ 応用:動的条件でも安全にスキップ処理を行う

実務では、固定条件だけでなく「セルや変数で指定された値」を使ってフィルタをかけることもよくあります。
この場合でも、同じ考え方で安全にスキップ処理が可能です。

Sub DynamicFilterSkip()
    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】処理を止める「Exit」の使い方|Sub・Function・ループでの中断方法を解説




✅ 応用:複数条件フィルタでもスキップを実現

オートフィルタでは Operator:=xlOr などを使って複数条件を設定することもありますが、
その場合でも可視セルの有無をチェックする方法は同じです。

Sub MultiConditionFilterSkip()
    Dim ws As Worksheet
    Dim visibleRange As Range

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

    ' A列で「完了」または「中止」を抽出
    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

複数条件のときも、「Nothingチェック」 さえ入っていれば、どんな条件にも対応可能です。


✅ 応用:該当なしの場合にログを残しておく

スキップしただけでは後から判断できないため、
「どの条件でスキップされたか」をログシートに残しておくのも実務的な工夫です。

Sub FilterSkipWithLog()
    Dim ws As Worksheet
    Dim logWs As Worksheet
    Dim visibleRange As Range
    Dim nextRow As Long
    Dim condition As String

    Set ws = ThisWorkbook.Sheets("データ")
    Set logWs = ThisWorkbook.Sheets("ログ")
    condition = ws.Range("E1").Value

    ws.Range("A1").AutoFilter Field:=2, Criteria1:=condition

    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
        nextRow = logWs.Cells(Rows.Count, "A").End(xlUp).Row + 1
        logWs.Range("A" & nextRow).Value = "条件「" & condition & "」:該当なし(" & Format(Now, "yyyy/mm/dd HH:NN:SS") & ")"
        ws.AutoFilterMode = False
        Exit Sub
    End If

    visibleRange.Copy Destination:=ThisWorkbook.Sheets("抽出結果").Range("A1")
    ws.AutoFilterMode = False
End Sub

このようにログを残せば、後で「なぜ処理されなかったのか」を簡単に確認できます。
実務で信頼性を高めるうえで非常に有効です。


✅ 注意点:スキップ処理を確実に行うためのコツ

・① フィルタ範囲は必ず AutoFilter.Range を使う

CurrentRegion でも動作しますが、フィルタ範囲外のデータが含まれる可能性があります。
確実に対象範囲を取得するために、ws.AutoFilter.Range を使うのが推奨です。

・② On Error Resume Next は必要最小限に

SpecialCells の部分だけに使い、直後で On Error GoTo 0 で解除するのが安全です。
長い範囲でエラー無視を使うと、他のバグを見逃してしまうことがあります。

・③ フィルタ解除を忘れない

AutoFilterMode = False を毎回入れておくことで、後続処理が安定します。
特にループ処理や複数条件の自動処理では欠かせません。


✅ 実務での活用例:自動レポート生成でスキップを活用

営業レポートや日次報告の自動化で、
「データが存在しない営業担当者はスキップして次へ進む」処理にこの仕組みを使うことができます。

For Each担当者 In 担当者リスト
    Call ReportFor担当者(担当者)
Next担当者

このようなループ内で「該当なしスキップ」を組み込んでおけば、
マクロが止まることなくすべての処理をスムーズに実行できます。
特に複数部門・複数日付の帳票生成では、この安全設計が大きな差を生みます。


✅ まとめ:オートフィルタの「該当なし」は安全にスキップ!

  • SpecialCells(xlCellTypeVisible) は該当なしのときエラーを返す
  • On Error Resume NextIf visibleRange Is Nothing Then の組み合わせで安全にスキップ
  • 動的条件・複数条件でも同じ仕組みで対応可能
  • ログ出力やフィルタ解除を加えるとさらに実務で安定
  • 自動レポートや削除処理など、業務自動化で欠かせない基本構文

「該当なしスキップ」を組み込むことで、マクロが途中で止まらず、安心して繰り返し運用できるようになります。
日常業務を自動化するうえで欠かせない安全設計です。
ぜひこの記事のコードをそのまま活用して、「落ちないVBA」 を実現してください。

-VBAで自動化, VBA一覧, フィルター結果の取得・判定, 抽出・検索処理