Excelでオートフィルターを使ってデータを絞り込んだあと、「抽出結果だけを取得したい」「別シートにコピーしたい」と思ったことはありませんか?
VBAを使えば、フィルター結果のデータだけを正確に取得・操作することができます。
 単純に Range("A1:A100") のように指定すると、非表示のデータまで含まれてしまうため、可視セル(表示されている行)だけを扱う方法を理解しておくことが重要です。
この記事では、オートフィルター後の結果(表示されているセル)の取得方法を、実務でもすぐ使える形で解説します。
目次
✅ 基本構文:フィルター後の可視セルを取得する
オートフィルター後に表示されている行だけを取得するには、SpecialCells(xlCellTypeVisible) を使用します。
 このメソッドは「可視セルのみ」を対象とするため、非表示のセルやフィルターで隠れた行を自動的に除外できます。
基本構文
Range("範囲").SpecialCells(xlCellTypeVisible)
例:A列のフィルター結果を取得
Sub GetVisibleCells()
    Dim rng As Range
    Set rng = Range("A1:A100").SpecialCells(xlCellTypeVisible)
    rng.Select
End Sub
このコードを実行すると、A列で現在表示されている行のみが選択されます。
 ただし、フィルター結果が1件もない場合には「実行時エラー1004」が発生するため、後述するエラー対策が必須です。
参考:【VBA】RangeクラスのSelectメソッドが失敗しました:1004
✅ 実践例①:フィルター結果をループで取得する
抽出後のデータを1行ずつ処理したい場合、可視セルをループ処理で取得します。
コード例
Sub GetFilteredData()
    Dim rng As Range
    Dim cell As Range
    ' フィルター設定(B列:部署)
    Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"
    ' 可視セルを取得
    On Error Resume Next
    Set rng = Range("A2:A100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0
    ' 件数0件なら終了
    If rng Is Nothing Then
        MsgBox "営業部のデータは存在しません。"
        ActiveSheet.AutoFilterMode = False
        Exit Sub
    End If
    ' 抽出結果をループして出力
    For Each cell In rng
        Debug.Print cell.Value
    Next cell
    ' フィルター解除
    ActiveSheet.AutoFilterMode = False
End Sub
処理の流れ
- 「営業部」でフィルターをかける
- SpecialCells(xlCellTypeVisible)で表示行だけを取得
 参考:【VBA】条件に一致するセルを複数取得する方法|Find・For Each・SpecialCells
- ループで抽出データを1件ずつ出力(または処理)
 参考:【VBA】セルの値が一致したら処理を実行する方法|If文・ループ・実務活用例
- フィルターを解除
出力結果例(イミディエイトウィンドウ)
営業部
営業部
営業部
このように、非表示の行を除外して抽出結果だけを取得できます。
✅ 実践例②:フィルター結果を別シートにコピーする
実務で最も多いのが、「抽出結果を別シートに転記する」処理です。
 コピー元・コピー先を指定して、オートフィルターの結果を自動転送できます。
コード例
Sub CopyFilteredData()
    Dim wsSrc As Worksheet
    Dim wsDst As Worksheet
    Dim rngVisible As Range
    Set wsSrc = Sheets("データ")
    Set wsDst = Sheets("結果")
    wsDst.Cells.Clear
    ' フィルター設定(部署列:B列)
    wsSrc.Range("A1:C100").AutoFilter Field:=2, Criteria1:="開発部"
    ' 抽出結果(可視セル)を取得
    On Error Resume Next
    Set rngVisible = wsSrc.Range("A1:C100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0
    ' 該当データがある場合のみコピー
    If Not rngVisible Is Nothing Then
        rngVisible.Copy Destination:=wsDst.Range("A1")
        MsgBox "抽出結果を結果シートに転記しました。"
    Else
        wsDst.Range("A1").Value = "条件に一致するデータはありません。"
    End If
    wsSrc.AutoFilterMode = False
End Sub
処理内容
- 「開発部」のデータだけを抽出
- 表示されているセルのみをコピー
- 結果シートに転記
- 件数0件のときはメッセージ表示
実務での活用例
- 部署ごとの売上一覧を自動作成
- 支店別のデータを分割して保存
- 日次処理で条件抽出レポートを生成
このように、フィルター結果をそのまま転記できるため、報告書作成や帳票出力に最適です。
✅ 実践例③:フィルター結果を配列に格納して扱う
コピーではなく、抽出データを配列に格納して内部で処理したい場合もあります。
 これにより、画面を動かさず高速にデータ操作が可能です。
コード例
Sub GetFilteredArray()
    Dim rng As Range
    Dim arr As Variant
    Dim i As Long
    ' フィルター設定(C列:売上)
    Range("A1:C100").AutoFilter Field:=3, Criteria1:=">=100"
    ' フィルター後の可視セルを取得
    On Error Resume Next
    Set rng = Range("C2:C100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0
    ' 抽出結果がある場合のみ処理
    If Not rng Is Nothing Then
        arr = rng.Value
        For i = 1 To UBound(arr, 1)
            Debug.Print arr(i, 1)
        Next i
    Else
        MsgBox "該当データがありません。"
    End If
    ActiveSheet.AutoFilterMode = False
End Sub
メリット
- 配列を使うことで、非表示データを除外したまま高速処理が可能
- データ検証や集計など、Excelシートを操作せずに実行できる
- 大量データの処理でも安定
 参考:【VBA】セルの値を変数配列に取得:ループ処理
応用例
Sheets("集計").Range("B2").Resize(UBound(arr, 1), 1).Value = arr
このようにして、配列を一括転記すれば「抽出データを別表に即座に出力」できます。
 
 
✅ 実践例④:フィルター結果の件数を取得する
抽出結果の件数(何行抽出されたか)を知りたい場合は、可視セルの行数をカウントします。
コード例
Sub CountFilteredData()
    Dim rng As Range
    Dim cnt 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
        cnt = rng.Rows.Count
        MsgBox "抽出件数:" & cnt & "件"
    End If
    ActiveSheet.AutoFilterMode = False
End Sub
出力例
抽出件数:12件
注意
ヘッダー行を含めると件数が1件多くなる場合があるため、
 範囲をA2:A100などデータ行だけに限定するのが正確です。
✅ エラーを防ぐための基本ルール
フィルター結果の取得でよくあるエラー「実行時エラー1004」を防ぐために、
 以下のポイントを必ず押さえておきましょう。
① On Error Resume Nextで安全に処理
On Error Resume Next
Set rng = Range("A2:A100").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
→ 可視セルが存在しない場合でもエラーをスキップし、Nothing判定で制御可能。
② If rng Is Nothing で条件分岐
If rng Is Nothing Then
    MsgBox "該当データなし"
Else
    ' 処理を実行
End If
③ 処理後はフィルター解除
If ActiveSheet.AutoFilterMode Then ActiveSheet.AutoFilterMode = False
これらを組み合わせれば、抽出結果が0件でも止まらない安全なマクロが作れます。
✅ 実務応用:抽出結果を集計・転記する自動マクロ
最後に、実務でよく使われる「フィルター結果の自動集計+出力」の応用例を紹介します。
コード例
Sub AutoSummary()
    Dim wsData As Worksheet
    Dim wsResult As Worksheet
    Dim rngVisible As Range
    Dim total As Double
    Set wsData = Sheets("データ")
    Set wsResult = Sheets("結果")
    wsResult.Cells.Clear
    ' フィルター(部署が営業部)
    wsData.Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"
    ' 可視セル取得(C列:売上)
    On Error Resume Next
    Set rngVisible = wsData.Range("C2:C100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0
    If rngVisible Is Nothing Then
        wsResult.Range("A1").Value = "該当データなし"
    Else
        ' 合計値を計算
        total = Application.WorksheetFunction.Sum(rngVisible)
        wsResult.Range("A1").Value = "営業部の売上合計"
        wsResult.Range("B1").Value = total
    End If
    wsData.AutoFilterMode = False
End Sub
結果
「営業部」だけを抽出 → 可視セルを合計 → 結果シートに出力。
 この仕組みを応用すれば、部署別レポートや自動集計表を簡単に作れます。
✅ まとめ:フィルター結果を取得すれば自動集計・転記が簡単に
- SpecialCells(xlCellTypeVisible)で可視セル(抽出結果)を取得できる
- Nothing判定で0件エラーを防げる
- ループ・配列・コピーで多様な出力が可能
- 件数カウントや合計などの集計処理にも応用できる
VBAでフィルター結果を取得できるようになると、
 「抽出→集計→レポート化」の一連の処理を完全自動化できます。
 手作業の分析を効率化し、信頼性の高いデータ処理を実現しましょう。