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
解説
On Error Resume Next
… エラーを無視して次の行へ進む
参考:【VBA】エラーを無視して終了する方法:エラーハンドリングSet rng = ...
… 可視セル(抽出結果)を取得- 該当データがないときは
rng
がNothing
になる If rng Is Nothing Then
で0件を判定できる
実際の処理フロー
- オートフィルタを実行
- 可視セルを取得
参考:【VBA】フィルター後の値を取得する方法|可視セルだけを扱う実務マクロ完全ガイド - 件数0の場合はメッセージを出して終了
- 件数ありの場合は次の処理へ
✅ 実践例①:件数が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
処理の流れ
- 「営業部」でフィルター
- 結果が0件ならMsgBoxを出して終了
- データがあれば次の工程へ進む
実務での用途
- フィルター後にコピーや集計を行う前の「安全確認」
- 自動処理マクロで、条件未一致時に無駄な作業を防止
参考:【VBA】最後のシートまで繰り返す方法|全シート処理・応用・エラー対策を徹底解説 - レポート生成マクロで「データなし」状態を検知
✅ 実践例②:抽出件数を数値で取得する
「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
処理の流れ
- 「営業部」「開発部」「総務部」を順に抽出
- 各部署ごとにデータ件数を取得
- データなしの場合はスキップ
実務での用途
- 部署ごとのレポート作成
- 月次データを条件別に自動出力
参考:【VBA】AutoFilterの複数条件を設定する方法|AND・ORを自在に操る実務向け活用術 - データがない場合の無駄な処理を回避
✅ 実践例④:件数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 Next
+If rng Is Nothing Then
で0件判定が可能- 件数を数値で取得したいときは
.Rows.Count
を使用 - 複数条件をループ処理する場合は0件スキップで安定動作
- 実務では「0件時に通知」「ログ」「空出力」の対応が重要
VBAでオートフィルタを使う際に「0件対策」を入れておくだけで、
マクロの信頼性が大きく向上します。
たとえ条件に一致するデータがなくても、
「エラーで止まらない」「自動で次の処理に進む」設計ができれば、
夜間バッチや定期レポートなどの完全自動運用も実現可能です。