AutoFilterで2つ以上の条件が組めなくて困っていませんか?ExcelVBAの AdvancedFilter を使えば、AND/OR条件の自由な組み合わせ・別シートへの直接出力・重複の自動除去が「1メソッド」で実現できます。今回はコピペOKのサンプルコードつきで、AdvancedFilterの使い方を完全網羅します。
この記事で学べること
- AdvancedFilter と AutoFilter の違い
- 引数(Action / CriteriaRange / CopyToRange / Unique)の正しい使い方
- 条件範囲(CriteriaRange)の作り方:AND条件・OR条件・ワイルドカード
- 別シートへの抽出方法
- 重複削除(ユニークリスト作成)
- よくあるエラーと対処法
AdvancedFilter とは?AutoFilter との違い
AdvancedFilterの3大メリット
まずは、よく使われる AutoFilter との違いを比較表で確認しましょう。
| 比較項目 | AutoFilter | AdvancedFilter |
|---|---|---|
| 同時指定できる条件数 | 1列につき最大2条件 | 制限なし |
| AND/OR の組み合わせ | 同一列のみ | 複数列をまたいで自在 |
| 抽出結果の出力先 | 元データの場所のみ | 別シート・別セルに直接出力可 |
| 重複除去 | 不可 | Unique:=True で可能 |
| 元データへの影響 | あり(フィルター表示) | xlFilterCopyなら変更なし |
✅ 結論:AutoFilterで対応できない「複雑な条件」「別シート出力」「重複除去」はAdvancedFilterの出番です!
基本構文と引数の説明
構文
Range.AdvancedFilter(Action, CriteriaRange, CopyToRange, Unique)
引数一覧表
| 引数名 | 必須/省略可 | 説明 |
|---|---|---|
Action | 必須 | xlFilterInPlace(元の場所で絞込)または xlFilterCopy(別場所にコピー) |
CriteriaRange | 省略可 | 検索条件を書いたセル範囲。省略すると条件なし(全件対象) |
CopyToRange | 省略可 | ActionがxlFilterCopyのときの出力先(xlFilterCopyの場合は実質必須) |
Unique | 省略可 | True=重複除去して抽出。False(既定)=重複を含む |
Action 定数の説明
| 定数 | 値 | 動作 |
|---|---|---|
xlFilterInPlace | 1 | 元のデータ範囲で非表示・表示を切り替え(AutoFilterに近い動作) |
xlFilterCopy | 2 | 条件に合う行を別場所にコピー。元データは変更なし ← 実務では主にこちら |
条件範囲(CriteriaRange)の作り方【最重要】
基本ルール
⚠️ 重要:条件範囲の1行目(ヘッダー)は元データの列名と完全一致させる必要があります!大文字・小文字・スペースのズレでも動作しません。
AND条件の作り方
「条件を同じ行に横並びに書く → 全条件を満たす行だけ抽出(AND)」
サンプル条件範囲(シートのG1:H2に入力):
| 担当者 | 売上金額 |
|---|---|
| 田中 | >100000 |
Sub AdvancedFilter_AND条件()
Dim ws As Worksheet
Set ws = ActiveSheet
' 条件範囲(AND条件):担当者が「田中」かつ売上が100000より大きい
' G1:H2 に以下の内容が入力済み前提
' G1=担当者, H1=売上金額
' G2=田中, H2=>100000
' 抽出前に出力先をクリア
ws.Range("J1:N1000").ClearContents
ws.Range("A1").CurrentRegion.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=ws.Range("G1:H2"), _
CopyToRange:=ws.Range("J1")
MsgBox "AND条件で抽出しました!"
End Sub
OR条件の作り方
「条件を別々の行に書く → どちらかを満たす行を抽出(OR)」
サンプル条件範囲(シートのG1:G3に入力):
| 担当者 |
|---|
| 田中 |
| 鈴木 |
Sub AdvancedFilter_OR条件()
Dim ws As Worksheet
Set ws = ActiveSheet
' 条件範囲(OR条件):担当者が「田中」または「鈴木」
' G1:G3 に以下の内容が入力済み前提
' G1=担当者
' G2=田中
' G3=鈴木
ws.Range("J1:N1000").ClearContents
ws.Range("A1").CurrentRegion.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=ws.Range("G1:G3"), _
CopyToRange:=ws.Range("J1")
MsgBox "OR条件で抽出しました!"
End Sub
AND+ORの複合条件
「同じ行=AND、別の行=OR」の組み合わせで複雑な条件も表現できます。
例:「田中かつ売上>100000」 OR 「鈴木かつ売上>50000」
| 担当者 | 売上金額 |
|---|---|
| 田中 | >100000 |
| 鈴木 | >50000 |
ワイルドカードの使い方
| 記号 | 意味 | 条件セルの書き方 | マッチする例 |
|---|---|---|---|
* | 任意の文字列(0文字以上) | 東京* | 「東京都」「東京都新宿区」など |
? | 任意の1文字 | 田? | 「田中」「田村」(2文字限定) |
~ | エスケープ文字 | ~* | 「*」という文字そのもの |
Sub AdvancedFilter_ワイルドカード()
Dim ws As Worksheet
Set ws = ActiveSheet
' 条件範囲:商品名が「ノート」で始まる行を抽出
' G1=商品名, G2=ノート* ← シートに入力済み前提
ws.Range("J1:N1000").ClearContents
ws.Range("A1").CurrentRegion.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=ws.Range("G1:G2"), _
CopyToRange:=ws.Range("J1")
MsgBox "ワイルドカード抽出しました!"
End Sub
別シートへの抽出方法【実務でよく使う!】
⚠️ 重要:別シートへ抽出するとき、AdvancedFilter を呼び出すのは「元データがあるシート側」からです。出力先を別シートに指定するだけでOKです。
Sub AdvancedFilter_別シート抽出()
Dim srcWs As Worksheet ' 元データのシート
Dim destWs As Worksheet ' 出力先のシート
Set srcWs = Worksheets("売上データ")
Set destWs = Worksheets("抽出結果")
' 出力先シートをクリア(ヘッダーも含めてリセット)
destWs.Cells.ClearContents
' 条件範囲は srcWs の I1:J2 に設定済みとする
' ★ 元データ側のシートから呼び出す(重要!)
srcWs.Range("A1").CurrentRegion.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=srcWs.Range("I1:J2"), _
CopyToRange:=destWs.Range("A1")
Dim cnt As Long
cnt = destWs.Range("A1").CurrentRegion.Rows.Count - 1
MsgBox "別シートへの抽出が完了しました!" & vbCrLf & "件数:" & cnt & "件"
End Sub
- CopyToRangeには出力先シートの先頭セル(A1)だけ指定すればOK
- 出力前に
destWs.Cells.ClearContentsで前回の結果をクリアすることを忘れずに - CriteriaRange と元データは同じシート(srcWs)に置く
重複削除してユニークリストを作成する
売上リストから「担当者名の重複なし一覧」を作るなど、マスタリスト作成に最適です。
Sub AdvancedFilter_重複削除()
Dim ws As Worksheet
Set ws = ActiveSheet
' A列の担当者名から、重複を除いたユニークリストをD列に作成
ws.Range("D:D").ClearContents
ws.Range("A1:A1000").AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=ws.Range("D1"), _
Unique:=True
MsgBox "ユニークリストを作成しました!" & vbCrLf & _
"件数:" & ws.Range("D1").CurrentRegion.Rows.Count - 1 & "件"
End Sub
応用:別シートにユニーク担当者リストを作成
Sub AdvancedFilter_別シートユニーク()
Dim srcWs As Worksheet
Dim destWs As Worksheet
Set srcWs = Worksheets("売上データ")
Set destWs = Worksheets("担当者マスタ")
destWs.Range("A:A").ClearContents
' B列(担当者列)のユニークデータを別シートへ
srcWs.Columns("B").AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=destWs.Range("A1"), _
Unique:=True
MsgBox "担当者マスタを更新しました!"
End Sub
実務サンプル:条件範囲をVBAで動的に作成する【応用編】
条件を毎回手動でシートに書くのではなく、VBA内で条件値を変数として扱い、条件範囲を自動生成するパターンです。
Sub AdvancedFilter_動的条件作成()
Dim srcWs As Worksheet
Dim destWs As Worksheet
'-------------------------------------------
' シートの参照を設定
'-------------------------------------------
Set srcWs = Worksheets("売上データ")
Set destWs = Worksheets("抽出結果")
'-------------------------------------------
' 条件を一時的に書き込む(Z列以降などデータ外の空きエリアを使用)
'-------------------------------------------
srcWs.Range("Z1") = "担当者" ' 元データの列名と一致させる!
srcWs.Range("AA1") = "売上金額" ' 元データの列名と一致させる!
srcWs.Range("Z2") = "田中" ' 条件値(変数で渡してもOK)
srcWs.Range("AA2") = ">50000" ' 数値条件
'-------------------------------------------
' 出力先をクリアして抽出実行
'-------------------------------------------
destWs.Cells.ClearContents
srcWs.Range("A1").CurrentRegion.AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=srcWs.Range("Z1:AA2"), _
CopyToRange:=destWs.Range("A1")
'-------------------------------------------
' 一時条件エリアをクリア(後片付け)
'-------------------------------------------
srcWs.Range("Z1:AA2").ClearContents
' 結果確認
Dim cnt As Long
cnt = destWs.Range("A1").CurrentRegion.Rows.Count - 1
If cnt > 0 Then
MsgBox "抽出完了!" & cnt & "件が見つかりました。"
Else
MsgBox "条件に一致するデータがありませんでした。"
End If
End Sub
✅ ポイント:条件値を変数化することで、InputBox や UserForm から受け取った値を条件として動的に使えます。業務ツール化に最適なパターンです。
よくあるエラーと対処法
| エラー/症状 | 原因 | 対処法 |
|---|---|---|
| 実行時エラー 1004 | 別シート抽出でsrcWs以外からAdvancedFilterを呼び出している | 必ずsrcWs.Range(...).AdvancedFilterの形で呼び出す |
| 抽出件数が0件になる | 条件範囲のヘッダーが元データの列名と不一致 | ヘッダー名を元データからコピーして完全一致させる |
| 全件が抽出される | CriteriaRangeの条件行が空白 | 条件値を正しく入力し、範囲指定を正確に |
| 前回の結果が残る | 出力先のクリアを忘れている | 実行前にdestWs.Cells.ClearContentsを追加 |
| ワイルドカードが効かない | 条件セルの書式が数値になっている | 条件セルの書式を「文字列」か「標準」に変更 |
| 比較演算子(>等)が文字として扱われる | 条件セルが文字列扱いになっていない | セル値を ">50000" のように文字列で代入する |
FAQ(よくある質問)
Q1. AdvancedFilterで日付の範囲指定はできますか?
A. できます。条件セルに >2025/1/1 のように日付比較演算子で記述してください。AND条件で >=2025/1/1(同じ行の別セルに)<=2025/3/31 と書けば日付範囲指定になります。
Q2. 抽出結果の列順を元データと変えることはできますか?
A. できます。CopyToRangeに「見たい列名のヘッダーだけ」を事前に入力しておくと、その列だけ・その順番で出力されます。不要な列を省いた抽出結果を作れます。
Q3. 元データがテーブル(ListObject)の場合でも使えますか?
A. 使えます。テーブルの場合は ListObject.Range.AdvancedFilter(...) のように呼び出してください。DataBodyRangeではなくRangeを指定するのがポイントです。
Q4. 共有ブックでAdvancedFilterは使えますか?
A. 旧形式の共有ブック(レガシー共有)ではAdvancedFilterが使えない場合があります。その場合はAutoFilterで代替するか、共同編集(共有ブック)の設定を見直してください。
Q5. AutoFilterよりAdvancedFilterの方が速いですか?
A. 条件が単純な場合はAutoFilterの方が速いことが多いです。AdvancedFilterは「複雑な条件」「別シート出力」「重複除去」が必要なときに使うのが最適です。
まとめ
AdvancedFilterのポイントまとめ:
- AND条件 → 条件範囲の同じ行に横並び
- OR条件 → 条件範囲の別々の行に縦並び
- 別シート出力 → 元データ側のシートからメソッドを呼び出す
- 重複除去 →
Unique:=True - 毎回出力先を
ClearContentsでリセットする習慣をつける - ヘッダー名は元データと完全一致が鉄則
AutoFilterでは対応できなかった複雑な抽出処理が、AdvancedFilterひとつで解決できます。ぜひ実務で活用してください!

コメント