※本記事の数式やコードは、Microsoft 365(旧Office365)にて動作検証を行っています。
VBAでオートフィルタを操作する方法|絞り込み・解除・集計まで現場で使えるコードをコピペOK
「VBAでオートフィルタを使いたいけど、どう書けばいいかわからない…」 「フィルタをかけたまま別の処理をしたいのに、うまくいかない…」
こんな悩みはありませんか?
オートフィルタは Excelの日常業務で頻繁に使う機能ですが、VBAで操作しようとすると「あれ?思った通りに動かない」と詰まりやすい箇所も多いです。
この記事では、VBAでオートフィルタを操作するための基本から応用まで、現場ですぐ使えるコードをまるごと解説します。コピペして即戦力にできるコードばかりなので、ぜひ手元で試しながら読んでみてください。
オートフィルタとは?VBAで操作するとどんなことができる?
オートフィルタとは、表の列に条件を指定してデータを絞り込む機能です。手動でも使えますが、VBAで操作することで次のようなことが自動化できます。
- 特定の条件に一致する行だけを瞬時に絞り込む
- 絞り込んだ行だけに処理を行う(色塗り・コピー・集計など)
- 処理が終わったらフィルタを自動で解除する
手動でフィルタをかける場合と比べると、次のような違いがあります。
| 比較項目 | 手動 | VBA |
|---|---|---|
| 操作時間 | 毎回数ステップ | 1クリックで完了 |
| 再現性 | 手順を覚える必要あり | コードが手順を記憶 |
| ミスのリスク | 条件のかけ間違いが起きやすい | 条件を一度書けば確実 |
| 大量データへの対応 | 時間がかかる | 一瞬で処理 |
月次レポートの作成や、部門ごとのデータ抽出など、繰り返しの多い作業に特に威力を発揮します。
VBAでオートフィルタを使う手順
基本の構文を確認しよう
VBAでオートフィルタを操作する基本の書き方は次のとおりです。

Range("表内のセル").AutoFilter Field:=列番号, Criteria1:="条件"Field:フィルタをかける列番号(表の左端の列を1とした番号)Criteria1:絞り込む条件(文字列や数値)
まず、フィルタをかけたい表がどのシートのどのセルにあるかを確認します。ここでは A1 を起点にした表を例にします。
次のコードは、A列〜D列のデータ表に対して、B列が「東京」のデータだけを絞り込む例です。
Sub フィルタをかける()
Dim ws As Worksheet
Dim lastRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
' 最終行を動的に取得
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 既存のフィルタをいったん解除してから設定
If ws.AutoFilterMode Then ws.AutoFilterMode = False
' A1:D[最終行] の範囲にフィルタをかける(B列=東京)
ws.Range("A1:D" & lastRow).AutoFilter Field:=2, Criteria1:="東京"
End Sub
けんけんlastRow を使って最終行を動的に取得することで、データ件数が変わっても正しい範囲にフィルタがかかります。行数を固定で書くのはNGです!複数条件を使う場合は Criteria2 と Operator を追加します。
OR条件(東京または大阪):
ws.Range("A1:D" & lastRow).AutoFilter _
Field:=2, _
Criteria1:="東京", _
Operator:=xlOr, _
Criteria2:="大阪"AND条件(数値範囲:100以上200以下):
ws.Range("A1:D" & lastRow).AutoFilter _
Field:=3, _
Criteria1:=">=100", _
Operator:=xlAnd, _
Criteria2:="<=200"処理が終わったらフィルタを解除するのが鉄則です。解除方法は2通りあります。
全フィルタを完全オフにする(オートフィルタ矢印ごと消す):
If ws.AutoFilterMode Then ws.AutoFilterMode = Falseフィルタの絞り込みだけを解除して矢印は残す:
If ws.FilterMode Then ws.ShowAllData時短・効率化テクニック|現場で使える応用コード
テクニック1:フィルタ後の見えている行だけをコピーする
フィルタで絞り込んだ後、見えている行だけを別シートにコピーしたい場面はよくあります。
Sub フィルタ後コピー()
Dim ws As Worksheet
Dim wsDest As Worksheet
Dim lastRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set wsDest = ThisWorkbook.Worksheets("抽出結果")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' フィルタをかける(C列が100以上)
ws.Range("A1:D" & lastRow).AutoFilter Field:=3, Criteria1:=">=100"
' 見えているセル(SpecialCells)だけをコピー
ws.Range("A1:D" & lastRow).SpecialCells(xlCellTypeVisible).Copy _
Destination:=wsDest.Range("A1")
' フィルタ解除
ws.AutoFilterMode = False
MsgBox "コピー完了しました!"
End Sub
けんけんSpecialCells(xlCellTypeVisible) を使うのが絞り込み後コピーの鉄板テクニックです。これを忘れると隠れている行もコピーされてしまいます。テクニック2:フィルタ後の行数を数えてメッセージ表示する
絞り込んだ件数を確認したい場合は次のように書きます。
Sub フィルタ件数確認()
Dim ws As Worksheet
Dim lastRow As Long
Dim visibleCount As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("A1:D" & lastRow).AutoFilter Field:=2, Criteria1:="東京"
' ヘッダー行を除いた可視行数をカウント
visibleCount = ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeVisible).Count
MsgBox "絞り込み結果:" & visibleCount & " 件"
End Subテクニック3:フィルタ後の合計をSUBTOTAL関数で取得する
フィルタで絞り込んだ行だけの合計を求めたい場合は WorksheetFunction.Subtotal を使います。
Sub フィルタ後合計()
Dim ws As Worksheet
Dim lastRow As Long
Dim goukei As Double
Set ws = ThisWorkbook.Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("A1:D" & lastRow).AutoFilter Field:=2, Criteria1:="東京"
' 9 = SUBTOTAL関数のSUM(見えている行だけ合計)
goukei = WorksheetFunction.Subtotal(9, ws.Range("C2:C" & lastRow))
MsgBox "東京の合計:" & goukei
End Subトラブルシューティング|うまくいかないときに確認すること
症状1:「インデックスが有効範囲にありません」エラーが出る
原因:Field に指定した列番号が、フィルタ範囲の列数を超えている。
解決策:Field:=2 は「フィルタ範囲の左端から2列目」を意味します。Range("A1:D" & lastRow) ならA列が1、B列が2、C列が3、D列が4です。範囲外の番号を指定していないか確認してください。
症状2:絞り込んだはずなのに全データが表示される
原因:条件の文字列が完全に一致していない(スペースや全角・半角の違い)。
解決策:セルの値を直接コピーしてコードに貼り付け、意図しないスペースや文字コードの違いがないか確認してください。次のデバッグコードで確認できます。
' B2セルの実際の値を確認する
MsgBox "[" & ws.Range("B2").Value & "]"症状3:ShowAllData 実行時に「エラー 1004」が出る
原因:フィルタがかかっていない状態で ShowAllData を呼び出している。
解決策:実行前に FilterMode で確認してから呼び出してください。
If ws.FilterMode Then ws.ShowAllData症状4:フィルタ後のコピーで隠れた行も含まれてしまう
原因:SpecialCells(xlCellTypeVisible) を使わずに Range.Copy をしている。
解決策:フィルタ後のコピーには必ず SpecialCells(xlCellTypeVisible) をセットで使ってください(前掲のテクニック1を参照)。
まとめ
- VBAのオートフィルタは
AutoFilterメソッドで操作する Fieldは範囲の左端から数えた列番号で指定する- 最終行は必ず
End(xlUp).Rowで動的に取得する - フィルタ後のコピーには
SpecialCells(xlCellTypeVisible)が必須 - フィルタ後集計は
WorksheetFunction.Subtotal(9, 範囲)を使う - 処理後は
AutoFilterMode = FalseまたはShowAllDataで解除する
オートフィルタをVBAで自動化できるようになると、「毎月同じ手作業でやっていたフィルタ作業」がボタン1つで完結します。ぜひ今日から業務に組み込んでみてください!
次のステップへ進もう
オートフィルタを使いこなしたら、次はこれらの機能を覚えるとさらに業務効率が上がります。
- VBA 最終行の取得:今回の記事でも使いましたが、これはVBA業務自動化の超基本テクニックです。データ件数が変わっても正しく動くコードを書くために必須の知識です。
- VBA ループ処理:フィルタで絞り込んだ行に対して1行ずつ処理を行いたい場合に必要です。オートフィルタとループを組み合わせると処理の幅が一気に広がります。
- VBA VLOOKUP・Findメソッドによるデータ検索:フィルタで絞り込む前に、別表からコードや名称を参照して条件を自動設定したい場面で役立ちます。オートフィルタと組み合わせてさらに高度な自動化が実現できます。



