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

【VBA】フィルター後の値を取得する方法|可視セルだけを扱う実務マクロ完全ガイド

Excelのフィルター機能を使ってデータを絞り込んだあと、「表示されている値だけを取得したい」と思ったことはありませんか?
たとえば、営業部のデータを抽出して合計を出したり、抽出後の行だけを別シートに転記したいときなどです。

しかし、VBAでは単純に Range("A2:A100") のように指定しても、非表示のセルも含まれてしまうため、正確に抽出結果を扱うことができません。

そこで活躍するのが、「SpecialCells(xlCellTypeVisible)」 です。
この記事では、このメソッドを使って「フィルター後の値だけを取得・利用」する方法を徹底的に解説します。

✅ フィルター後の値を取得する基本構文

オートフィルターで抽出したデータのうち、「表示されているセル」だけを取得するには、以下の構文を使います。


基本構文

Range("範囲").SpecialCells(xlCellTypeVisible)

この「SpecialCells」は、セルの特定条件(空白・数式・コメント・可視など)を指定して取得するメソッドです。
その中でも xlCellTypeVisible は「表示されているセル(非表示を除く)」を対象にします。


例:抽出結果の可視セルを取得

Sub GetVisibleCells()
    Dim rng As Range
    Set rng = Range("A1:A100").SpecialCells(xlCellTypeVisible)
    rng.Select
End Sub

このコードでは、A1:A100のうち、現在表示されているセルのみを選択します。
もしオートフィルターで非表示になっている行があっても、それらは無視されます。

参考:【VBA】指定したシートを開く方法|Activate・Select・Visibleの違いと実務活用


⚠ 注意点

SpecialCells は「該当セルが存在しない場合」に**エラー(1004)**を返すことがあります。
安全に扱うには、On Error Resume Next でエラーを回避しておくのが一般的です。

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


✅ 実践:オートフィルターで絞り込み → 表示データの値を取得

ここからは、実際にフィルターを設定してから値を取得する一連の流れを紹介します。


例:営業部だけ抽出し、表示された「売上金額」を取得する

Sub GetFilteredValues()
    Dim rng As Range
    Dim cell As Range
    Dim total As Double

    ' フィルターを設定(B列:部署、C列:売上)
    Range("A1:C100").AutoFilter Field:=2, Criteria1:="営業部"

    ' フィルター後の可視セルを取得(C列の値を対象)
    On Error Resume Next
    Set rng = Range("C2:C100").SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    ' 抽出結果がある場合のみ処理
    If Not rng Is Nothing Then
        For Each cell In rng
            total = total + cell.Value
        Next cell
        MsgBox "営業部の売上合計は " & total & " 円です。"
    Else
        MsgBox "条件に一致するデータがありません。"
    End If

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

処理の流れ

  1. A1:C100にフィルターを設定
  2. B列で「営業部」を抽出
  3. C列のうち表示されているセルだけを取得
  4. ループで合計値を計算
  5. 最後にフィルター解除

このように、可視セルだけを対象にすることで、抽出結果に正確に基づいた処理ができます。


出力例

営業部の売上合計は 360 円です。

✅ フィルター後の値を配列に格納する

抽出した値を配列に格納すれば、別の処理(転記・検証・計算など)を効率的に行えます。


コード例:抽出結果を配列に格納

Sub GetFilteredArray()
    Dim rng As Range
    Dim arr As Variant
    Dim i As Long

    ' フィルターを設定
    Range("A1:C100").AutoFilter Field:=2, Criteria1:="開発部"

    ' 可視セル(B列のデータ)を取得
    On Error Resume Next
    Set rng = Range("B2:B100").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

解説


応用:配列を使って別シートへ転記

Sheets("結果").Range("A1").Resize(UBound(arr, 1), 1).Value = arr

この1行で、配列内のデータを「結果」シートに一括書き込みできます。

参考:【VBA】特定の文字を含む列の処理:検索・削除・別シートにコピー


✅ フィルター後の行番号を取得する

値ではなく、「どの行が表示されているか」を取得したい場合もあります。
これにより、特定行を削除・変更・コピーする処理が容易になります。


コード例:可視セルの行番号を取得

Sub GetVisibleRows()
    Dim rng As Range
    Dim cell As Range
    Dim msg As String

    Range("A1:C100").AutoFilter Field:=2, Criteria1:="総務部"

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

    If Not rng Is Nothing Then
        For Each cell In rng
            msg = msg & cell.Row & vbCrLf
        Next cell
        MsgBox "表示されている行番号:" & vbCrLf & msg
    Else
        MsgBox "該当データはありません。"
    End If

    ActiveSheet.AutoFilterMode = False
End Sub

出力例

表示されている行番号:
2
5
9

このように、表示された行のインデックスを正確に取得できます。

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




✅ フィルター後の値を別シートにコピーする

最も実務で使われるのが「抽出結果を別シートに転記」する処理です。
これも、可視セルをそのままコピーするだけで簡単に実現できます。


コード例:フィルター後の値をコピーして転記

Sub CopyFilteredData()
    Dim wsSrc As Worksheet
    Dim wsDst As Worksheet
    Dim rngVisible As Range

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

    wsDst.Cells.ClearContents

    ' フィルターを設定
    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
        MsgBox "条件に一致するデータがありません。"
    End If

    wsSrc.AutoFilterMode = False
End Sub

実務での使い道

  • 営業部や支店別のデータを自動で出力
  • 部署ごとのレポートを瞬時に作成
  • さらにPDF化・メール送信などにも応用可能

このように「抽出結果をそのまま出力」できるのが、VBA+フィルターの大きな強みです。


✅ エラーを防ぐためのベストプラクティス

SpecialCells(xlCellTypeVisible) は便利ですが、該当セルが存在しないときにエラーが出やすいため、以下の対策を入れておきましょう。


安全なテンプレート構文

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

If rng Is Nothing Then
    MsgBox "抽出結果がありません。"
    Exit Sub
End If

これにより、条件に一致しない場合もマクロが途中で停止せず、
「抽出結果がない」と丁寧に通知できます。


✅ よくある失敗例と解決法

問題原因対処法
取得結果に非表示行が含まれるSpecialCellsを使っていない.SpecialCells(xlCellTypeVisible)を追加
空白セルも含まれるフィルター対象がずれているRange指定を見直す(ヘッダー含む範囲)
フィルターが解除されないAutoFilterMode未解除ActiveSheet.AutoFilterMode = Falseを追加
エラー1004発生該当データがないOn Error Resume Nextでエラー制御

✅ フィルター後の値を高速に扱うコツ

大量データを扱う場合、処理速度を上げるには次の3点を組み合わせましょう。


1. 画面更新を止める

Application.ScreenUpdating = False

2. 自動計算を止める

Application.Calculation = xlCalculationManual

3. イベントを止める

Application.EnableEvents = False

これらを処理前に設定し、処理後に元に戻すとマクロ全体が格段に速くなります。


テンプレート例

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

' --- フィルター処理 ---
' 可視セル取得・転記など

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

✅ 実務応用シナリオ

① 部署ごとの売上集計を自動で出力

  • 各部門を順にフィルター
  • 表示データの売上を合計して別シートに書き出す

② 抽出データを日付フォルダに保存

  • 可視セルをコピーして新しいブックに貼り付け
  • 日付名で保存する(月次処理に最適)

③ 特定条件の抽出+メール送信

  • 条件を満たすデータを抽出
  • そのリストをHTML形式でOutlookメールに自動貼り付け

■ まとめ:フィルター後の値を取得すればExcel自動化が加速する

  • フィルター後の値は .SpecialCells(xlCellTypeVisible) で取得できる
  • 配列化・ループ・コピーなどで自由に活用可能
  • On Error Resume Next でエラー対策を忘れずに
  • 集計・転記・レポート生成まで自動化できる
  • 大量データでも画面更新停止で高速処理が可能

VBAでフィルター後の値を正確に取得できるようになると、
単なる手作業の分析から「完全自動化された集計・出力システム」へ進化します。
ぜひ、この記事のコードを自社データやレポート作成に活かしてみてください。

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