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

【VBA】オートフィルタの件数が0件のときの対処法|エラーを防いで安全に自動処理する方法

ExcelのVBAでオートフィルタを使ってデータを抽出するとき、
「条件に一致するデータがない(件数0)」というケースはよくあります。

例えば:

  • 指定した部署名が存在しない
  • 売上金額が条件未満
  • データの誤入力で空欄になっている

このような場合、VBAでそのまま後続処理を続けると、
「実行時エラー1004」(対象セルが見つからない)が発生してしまうことがあります。

この記事では、フィルター結果が0件のときに安全に処理を分岐させる方法を、初心者でも理解できるように解説します。

✅ オートフィルタで件数が0件になると起きる問題

まずは、なぜ「件数が0件」だとエラーが発生するのかを理解しましょう。


典型的なコード例(エラーになる)

Sub FilterErrorSample()
    Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"
    Range("A2:A100").SpecialCells(xlCellTypeVisible).Copy Range("E1")
End Sub

上記のコードは、B列(部署)で「営業部」を抽出し、結果をコピーしています。
しかし、もし「営業部」が存在しなかった場合、
SpecialCells(xlCellTypeVisible)該当セルが1つもないため、実行時エラー1004が発生します。


エラーの原因

SpecialCells は「表示されているセルが1つもない」場合に空の範囲を返せず、
強制的にエラーを出してしまう仕様になっています。

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


✅ エラーを回避して安全に処理する方法(基本)

最も簡単で確実なのは、エラー制御を入れて可視セルが存在するかを判定する方法です。


基本構文

On Error Resume Next
Set rng = Range("A2:A100").SpecialCells(xlCellTypeVisible)
On Error GoTo 0

If rng Is Nothing Then
    MsgBox "条件に一致するデータがありません。"
Else
    MsgBox "抽出データがあります。"
End If

解説


実際の処理フロー

  1. オートフィルタを実行
  2. 可視セルを取得
    参考:【VBA】フィルター後の値を取得する方法|可視セルだけを扱う実務マクロ完全ガイド
  3. 件数0の場合はメッセージを出して終了
  4. 件数ありの場合は次の処理へ

✅ 実践例①:件数が0件ならメッセージを出して終了する

最もよく使われるパターンがこちらです。
データがない場合に「処理を止める」「ユーザーへ通知する」コードです。


Sub FilterAndCheckCount()
    Dim rng As Range

    '--- オートフィルタを設定 ---
    Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"

    '--- 可視セルを取得(ヘッダーを除く) ---
    On Error Resume Next
    Set rng = Range("A2:A100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    '--- 件数チェック ---
    If rng Is Nothing Then
        MsgBox "条件に一致するデータはありません。処理を終了します。"
        ActiveSheet.AutoFilterMode = False
        Exit Sub
    End If

    '--- 抽出データがある場合の処理 ---
    MsgBox "抽出データがあります。次の処理を実行します。"

    '--- フィルター解除 ---
    ActiveSheet.AutoFilterMode = False
End Sub

処理の流れ

  1. 「営業部」でフィルター
  2. 結果が0件ならMsgBoxを出して終了
  3. データがあれば次の工程へ進む

実務での用途


✅ 実践例②:抽出件数を数値で取得する

「0件かどうか」だけでなく、実際の抽出件数(件数)を数値で知りたい場合もあります。
これは SpecialCells(xlCellTypeVisible)CountLarge を組み合わせて実現できます。


コード例:抽出件数をカウント

Sub CountFilteredRows()
    Dim rng As Range
    Dim countRows As Long

    Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"

    On Error Resume Next
    Set rng = Range("A2:A100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    If rng Is Nothing Then
        MsgBox "抽出件数は 0 件です。"
    Else
        countRows = rng.Areas(1).Rows.Count
        MsgBox "抽出件数は " & countRows & " 件です。"
    End If

    ActiveSheet.AutoFilterMode = False
End Sub

ポイント

  • .Areas(1).Rows.Count … フィルター結果の行数を取得
  • データが連続していない場合も、.Areasを使えば対応可
  • 件数0の場合は Nothing なので安全に分岐できる

出力例

抽出件数は 12 件です。

または

抽出件数は 0 件です。



✅ 実践例③:件数が0件なら処理をスキップして次の条件へ

複数の条件で連続抽出する場合、
1件もヒットしない条件でエラーになると、後続処理が止まってしまいます。

そのため、0件のときはスキップする仕組みが必要です。


コード例

Sub MultiFilterLoop()
    Dim deptList As Variant
    Dim dept As Variant
    Dim rng As Range

    deptList = Array("営業部", "開発部", "総務部")

    For Each dept In deptList
        Range("A1:C100").AutoFilter Field:=2, Criteria1:=dept

        On Error Resume Next
        Set rng = Range("A2:A100").SpecialCells(xlCellTypeVisible)
        On Error GoTo 0

        If rng Is Nothing Then
            Debug.Print dept & ":データなし"
        Else
            Debug.Print dept & ":" & rng.Rows.Count & "件"
            '--- 処理(例:コピーや集計など) ---
        End If
    Next dept

    ActiveSheet.AutoFilterMode = False
End Sub

処理の流れ

  1. 「営業部」「開発部」「総務部」を順に抽出
  2. 各部署ごとにデータ件数を取得
  3. データなしの場合はスキップ

実務での用途


✅ 実践例④:件数0ならメッセージ+別処理に分岐

データがない場合に「警告を出して別処理に切り替える」ケースも多いです。
たとえば、抽出データが0件のときに「空白の結果シートを生成」するなどです。


Sub FilterWithAlternative()
    Dim wsSrc As Worksheet
    Dim wsDst As Worksheet
    Dim rng As Range

    Set wsSrc = Sheets("データ")
    Set wsDst = Sheets("結果")

    wsDst.Cells.Clear

    wsSrc.Range("A1:C100").AutoFilter Field:=2, Criteria1:="経理部"

    On Error Resume Next
    Set rng = wsSrc.Range("A2:C100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    If rng Is Nothing Then
        wsDst.Range("A1").Value = "経理部のデータは存在しません。"
    Else
        rng.Copy wsDst.Range("A1")
    End If

    wsSrc.AutoFilterMode = False
    MsgBox "結果シートの出力が完了しました。"
End Sub

結果イメージ

  • 経理部にデータがある → 抽出データを貼り付け
  • 経理部が存在しない → 「データは存在しません」と表示

✅ よくあるトラブルと解決法

症状原因解決方法
実行時エラー1004該当データが0件On Error Resume Nextで制御し、If rng Is Nothingを追加
件数がずれるヘッダー行を含めて数えているデータ範囲を2行目以降に限定する
フィルターが解除されないAutoFilterMode未解除処理後に ActiveSheet.AutoFilterMode = False を追加
条件が重複して残る再度AutoFilterを上書きフィルター前に一度解除するか、同一範囲を使う

✅ 応用:件数が0件のときログに記録する

業務でよくあるのが、「どの条件がヒットしなかったかを記録したい」ケースです。
Debug.Printやログシートへの書き込みで簡単に記録できます。


Sub FilterWithLog()
    Dim wsLog As Worksheet
    Dim wsData As Worksheet
    Dim dep As String
    Dim rng As Range
    Dim nextRow As Long

    Set wsData = Sheets("データ")
    Set wsLog = Sheets("ログ")

    dep = "販売部"

    wsData.Range("A1:C100").AutoFilter Field:=2, Criteria1:=dep

    On Error Resume Next
    Set rng = wsData.Range("A2:A100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    nextRow = wsLog.Cells(Rows.Count, 1).End(xlUp).Row + 1

    If rng Is Nothing Then
        wsLog.Cells(nextRow, 1).Value = dep & ":データなし"
    Else
        wsLog.Cells(nextRow, 1).Value = dep & ":" & rng.Rows.Count & "件抽出"
    End If

    wsData.AutoFilterMode = False
End Sub

活用例

  • 日次バッチ処理で「抽出件数ログ」を残す
  • 管理部門で「対象なし」のエラーレポートを自動記録
  • 複数条件抽出を実行後にサマリーを出力

✅ まとめ:オートフィルタ件数0件でも止まらない堅牢なマクロを作る

  • オートフィルタ後に該当データがないとSpecialCellsでエラーが発生する
  • On Error Resume NextIf rng Is Nothing Thenで0件判定が可能
  • 件数を数値で取得したいときは .Rows.Countを使用
  • 複数条件をループ処理する場合は0件スキップで安定動作
  • 実務では「0件時に通知」「ログ」「空出力」の対応が重要

VBAでオートフィルタを使う際に「0件対策」を入れておくだけで、
マクロの信頼性が大きく向上します。

たとえ条件に一致するデータがなくても、
「エラーで止まらない」「自動で次の処理に進む」設計ができれば、
夜間バッチや定期レポートなどの完全自動運用も実現可能です。

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