Loading

ROUTE

ルートゼロの
アクティビティ

VBA AdvancedFilterのAND・OR複数条件

3

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行のサンプルで抽出対象を手計算し、実際の結果と比較してみましょう。

カジュアル面談はこちら

すべてを開示している会社です

ポジティブな面もネガティブな面も、包み隠さず誠実にお答えします。
気になることがあれば、面談の際にすべてオープンにお話します。