VBAのAdvancedFilterで複数条件を抽出するには、条件表の同じ行に書いた条件がAND、異なる行に書いた条件がORになる仕組みを使います。例えば「東京かつ売上10万円以上」または「佐藤かつ売上15万円以上」は条件表を2行に分けます。別シートへ抽出する場合はxlFilterCopyとCopyToRangeを使います。
条件表は同じ行がAND、別の行がOR
| 条件表の配置 | 意味 | 抽出例 |
|---|---|---|
| 同じ行に地域=東京と売上>=100000 | AND | 東京かつ10万円以上 |
| 別の行に担当=佐藤と売上>=150000 | ORのもう一組 | 上の条件、または佐藤かつ15万円以上 |
条件表の見出しは元データの列見出しと一致させます。空欄のセルは、その行について当該列の条件を指定しないことを表します。ANDを複数組み合わせたい場合は一組を1行にまとめ、その組同士を別行へ置きます。
用語解説:CriteriaRange
AdvancedFilterが参照する「列見出しと条件行」を含むセル範囲。条件表の行の組み合わせで抽出対象が決まります。
5行のサンプルで抽出条件を確認する
「データ」シートのA1:C6に見出しと5件のレコードを置きます。売上は数値として入力します。
| 担当 | 地域 | 売上 |
|---|---|---|
| 佐藤 | 東京 | 120000 |
| 鈴木 | 大阪 | 180000 |
| 佐藤 | 大阪 | 160000 |
| 田中 | 東京 | 90000 |
| 田中 | 東京 | 220000 |
同じ「データ」シートのF1:H3に条件表を置きます。見出し行F1:H1は「担当」「地域」「売上」です。下表の(空欄)は実際には何も入力しません。
| 担当 | 地域 | 売上 |
|---|---|---|
| (空欄) | 東京 | >=100000 |
| 佐藤 | (空欄) | >=150000 |
条件表の2行目は「地域=東京 AND 売上>=100000」、3行目は「担当=佐藤 AND 売上>=150000」です。二つの条件セットのどちらかに当てはまるレコードが対象です。
別シートへコピーするVBAの実装例
「結果」シートを事前に作成し、抽出専用にしてください。次のマクロは結果シートをクリアします。既存の手入力データがあるシートでは実行しないでください。
Option Explicit
Sub ExtractByAdvancedFilter()
Dim source As Worksheet
Dim target As Worksheet
Dim lastRow As Long
Set source = ThisWorkbook.Worksheets("データ")
Set target = ThisWorkbook.Worksheets("結果")
lastRow = source.Cells(source.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then Exit Sub
' 結果シートは抽出専用
target.Cells.ClearContents
target.Activate
source.Range("A1:C" & lastRow).AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=source.Range("F1:H3"), _
CopyToRange:=target.Range("A1"), _
Unique:=False
End Sub
元データ・条件表・コピー先を、すべて該当WorksheetのRangeで指定しています。無修飾のRangeを混ぜるとActiveSheet次第で参照先が変わるため、シート名を明示します。
xlFilterCopyは一致行を別の範囲へコピーします。xlFilterInPlaceは元の一覧の行を表示・非表示で絞り込む設定です。Unique:=Falseは重複する値の組み合わせを自動除外しない指定です。
期待する抽出結果と判定の理由
東京の佐藤12万円と田中22万円は1組目の条件に一致します。大阪の佐藤16万円は2組目の条件に一致します。田中9万円、鈴木18万円はどちらも満たしません。したがって、抽出対象は次の3レコードです。
| 担当 | 地域 | 売上 |
|---|---|---|
| 佐藤 | 東京 | 120000 |
| 佐藤 | 大阪 | 160000 |
| 田中 | 東京 | 220000 |
これは条件表の論理から計算した期待値です。Excel実環境でのコード実行・結果一致テストを行った値ではありません。行順などは元データの並びに依存します。
抽出されないときの6つの確認点
- 見出し:条件表の列名と元データの列名が一致するか。末尾空白や全角・半角の差を確認する。
- AND・OR:ANDにしたい条件が同じ条件行、ORにしたい条件セットが別行か。
- 範囲:元データに見出し行、CriteriaRangeに条件見出し行が含まれているか。
- 値の型:売上列が数値でなく文字列になっていないか。
- 出力先:結果シートの選択、既存値、CopyToRangeの参照を確認する。
- 空行:条件範囲に予定外の条件行やセルを含めていないか。
実行時エラー1004が発生する場合は、Rangeの修飾、コピー先の見出しやセル状態、シート保護なども確認してください。原因は一つに限らないため、小さな検証データで再現するのが確実です。
AdvancedFilterとAutoFilterの選び分け
| やりたいこと | 主な選択肢 |
|---|---|
| 条件表のAND・ORを組み合わせる | AdvancedFilter |
| 画面上で列ごとに表示を絞り込む | AutoFilter |
| 一致したレコードを別シートへ保存する | AdvancedFilter+xlFilterCopy |
AdvancedFilterは条件表の値を変更しても抽出結果を自動更新しません。変更後はマクロを再実行します。単純な絞り込みはAutoFilterのほうが扱いやすいケースもあります。
関連するVBAの考え方
抽出対象が増減する場合は、最終行の取り方が重要です。また、別シートのセルを誤参照しないためにRangeとCellsの使い分けも確認しておくと役立ちます。
(動的な最終行取得については『VBA最終行取得の鉄板テンプレート|xlUpで空白行も完全攻略!』をご参照ください)
(シート内のRangeとCells参照については『VBA RangeとCellsの使い分け判断マップ|配列で50ms高速化』をご参照ください)
よくある疑問とまとめ
ANDとORを同時に指定できる?
はい。同じ行に置いた複数列の条件がAND、その行の条件セットと別行の条件セットはORになります。
条件を書き換えたら自動的に結果も変わる?
いいえ。AdvancedFilterは条件表の変更だけでは結果を自動更新しません。マクロを再実行してください。
重複行を削除したいときは?
Unique:=Trueを検討します。元データの列構成と期待結果を確認したうえで指定してください。
同じ条件行ならAND、別の条件行ならOR。このルールを押さえるとAdvancedFilterで複数条件を組み合わせられます。別シートへの抽出にはxlFilterCopyとCopyToRangeを使い、見出し・値の型・コピー先を確認してみてください。
まずは5行のサンプルで抽出対象を手計算し、実際の結果と比較してみましょう。