Excel VBAでデータを処理していると、「部署が営業部で、なおかつ売上が10万円以上の行だけを抽出したい」「担当者が田中または佐藤のデータを取り出したい」といった、複数条件による抽出が必要になることがあります。
1つの条件だけであれば、If文を使った判定はそれほど難しくありません。しかし、条件が2つ、3つと増えてくると、ANDとORの使い分けや条件式の組み立て方が分からなくなりやすいところです。
特に実務では、単に条件を増やせばよいわけではありません。どの列を何の条件で判定しているのかが分かりにくいコードにすると、条件変更や改修時のミスにつながります。
この記事では、Excel VBAで複数条件に一致する行を判定・抽出する方法について、AND条件とOR条件の違いから、実務で変更しやすいコードの組み立て方まで解説します。
✅ VBAで複数条件に一致する行を抽出する基本的な考え方
複数条件の抽出で最初に理解しておきたいのが、「行を抽出する処理」と「複数条件を判定する処理」は分けて考えられるという点です。実務では、この2つを一度に考えてコードを書き始めると、処理が複雑になりやすくなります。特に、条件が追加されたときにIf文をその場しのぎで増やしていくと、何を判定しているコードなのか分かりにくくなります。
また、ANDとORを取り違えると、エラーにならなくても抽出結果そのものが間違うため注意が必要です。まずは「どの行を対象にするのか」を条件式で正しく判定し、その後で必要なデータを転記する、と考えることが重要です。この考え方を押さえておくと、条件が増えた場合でもコードを整理しやすくなります。
・複数条件による行抽出の仕組み
例えば、次のようなデータが「データ」シートに入力されているとします。
| A列 | B列 | C列 | D列 |
|---|---|---|---|
| 社員番号 | 氏名 | 部署 | 売上 |
| 1001 | 田中 | 営業部 | 120000 |
| 1002 | 佐藤 | 総務部 | 80000 |
| 1003 | 鈴木 | 営業部 | 90000 |
| 1004 | 高橋 | 営業部 | 150000 |
この中から、
「部署が営業部」かつ「売上が100,000以上」
という条件を満たす行だけを抽出するとします。
処理の流れは次のようになります。
- データの最終行を取得する
- 2行目から最終行まで順番に確認する
- C列が「営業部」か判定する
- D列が100,000以上か判定する
- 両方を満たした行だけを抽出先へ転記する
重要なのは、行全体をいきなりコピーするのではなく、最初に対象行かどうかを判定していることです。
条件判定と転記処理の役割を意識しておくと、後から「売上条件を150,000以上に変更する」「部署だけでなく担当区分も追加する」といった仕様変更にも対応しやすくなります。
・AND条件とOR条件では抽出対象が変わる
複数条件を扱う場合は、ANDとORの違いを明確にしておく必要があります。
AND条件は、指定した条件をすべて満たす場合にTrueとなります。
If departmentName = "営業部" And salesAmount >= 100000 Then
この場合、
- 営業部である
- 売上が100,000以上である
という2つの条件を両方満たした行だけが対象です。
一方、OR条件では、いずれかの条件を満たしていれば対象になります。
If departmentName = "営業部" Or departmentName = "企画部" Then
この場合は、
- 営業部
- 企画部
のどちらかに該当する行が対象になります。
実務では「ANDとORのどちらを使えばコードが動くか」ではなく、業務上どのデータを抽出したいのかを先に整理することが大切です。
条件式自体は正しくても、ANDとORの選択を間違えていれば、必要なデータが抜けたり、本来不要なデータまで抽出されたりします。
まず1つの条件だけで行を判定し、別シートへ抽出する基本処理から確認したい場合は、「【VBA】条件に一致する行を別シートへ抽出する方法|データを自動転記」で基本的な処理の流れを解説しています。単一条件の抽出を理解してからAND・ORによる複数条件へ進むと、条件判定の仕組みを整理しやすくなります。
✅ VBAのAND条件で複数条件に一致する行を抽出する方法
AND条件を使った行抽出は、複数条件処理の基本となります。ただし、セルの値を直接If文へ何度も記述すると、条件が増えたときにコードが読みにくくなりがちです。開発した本人には分かっても、後から別の人が条件を変更するときに、どの列が何を意味しているのか確認する作業が必要になります。また、列位置を変更した場合にも修正箇所を見落としやすくなります。
そのため、実務では条件判定に使う値や列の意味が分かる構成を意識することが重要です。ここでは、単に動作するだけではなく、後から条件を変更しやすい形でAND条件による抽出処理を組み立てます。
・営業部かつ売上10万円以上の行を抽出するコード
ここでは、「データ」シートから条件に一致する行を探し、「抽出結果」シートへ転記します。
Sub ExtractRowsByAndCondition()
Dim sourceSheet As Worksheet
Dim outputSheet As Worksheet
Dim lastRow As Long
Dim sourceRow As Long
Dim outputRow As Long
Dim departmentName As String
Dim salesAmount As Double
Set sourceSheet = ThisWorkbook.Worksheets("データ")
Set outputSheet = ThisWorkbook.Worksheets("抽出結果")
'社員番号が入力されているA列を基準に最終行を取得
lastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
'抽出結果は2行目から書き込む
outputRow = 2
For sourceRow = 2 To lastRow
'条件判定に使用する値を取得
departmentName = sourceSheet.Cells(sourceRow, "C").Value
salesAmount = sourceSheet.Cells(sourceRow, "D").Value
'部署と売上の両方が条件を満たした行だけを抽出
If departmentName = "営業部" And salesAmount >= 100000 Then
sourceSheet.Rows(sourceRow).Copy _
Destination:=outputSheet.Rows(outputRow)
outputRow = outputRow + 1
End If
Next sourceRow
End Sub
このコードでは、C列とD列をIf文へ直接何度も記述するのではなく、
departmentName
salesAmount
という意味の分かる変数へ一度値を取得しています。
例えば、
If sourceSheet.Cells(sourceRow, "C").Value = "営業部" _
And sourceSheet.Cells(sourceRow, "D").Value >= 100000 Then
と書くこともできます。
条件が2つだけなら、この書き方でもそれほど問題には見えません。しかし実務で条件が増えていくと、「C列は何の値だったか」「D列は何を判定しているのか」をコードから読み取る負担が大きくなります。
そのため今回のコードでは、条件の意味が変数名から分かることを優先しています。
・AND条件の抽出コードを実行する手順
コードを実行する場合は、次のように準備します。
- 元データを「データ」シートへ用意します。
- 抽出先として「抽出結果」シートを作成します。
- 「Alt」+「F11」キーでVBEを開きます。
- 標準モジュールへコードを記述します。
- シート名や判定対象となる列を実際のブックに合わせて変更します。
- マクロを実行して抽出結果を確認します。
ここで注意したいのが、コードを実行する前に抽出先シートの状態を確認することです。
今回のコードは2行目から結果を書き込む設計なので、すでに「抽出結果」シートにデータが存在する場合、その内容を上書きする可能性があります。
実務では、
- 前回の抽出結果を消してから実行する
- 最終行の下へ追加する
- 実行日時ごとに別シートへ出力する
など、運用方法によって転記方法を変える必要があります。
「複数条件を判定できたから完成」と考えるのではなく、抽出した結果をどのように扱うのかまで含めて設計することが、実務で安全に使うポイントです。
抽出結果を毎回2行目から書き換えるのではなく、既存データを残したまま末尾へ追加したい場合は、「【VBA】条件に一致する行をコピーして別シートの最終行へ追加する方法」で、最終行を取得して追記する方法を解説しています。
✅ VBAでAND条件を増やして3つ以上の条件を判定する
実際の業務では、条件が2つだけとは限りません。「営業部で、売上10万円以上で、さらに対象区分が有効」といった3条件以上の判定もよく発生します。ここで条件式を無計画に長くすると、あとから条件を追加・削除するときに修正箇所を間違えやすくなります。
また、複数の条件を一行へ詰め込みすぎると、どこまでが1つの判定なのか視覚的にも把握しにくくなります。条件数が増えるほど、コードの短さよりも条件の意味が読み取れることが重要です。さらに、すべての条件が本当にANDで結ばれるのかを確認しないと、業務要件そのものを間違える可能性があります。3つ以上の条件を扱うときこそ、判定条件を整理してからコードへ落とし込むことが大切です。
・3つのAND条件を組み合わせる書き方
例えば、E列に「対象」「対象外」という区分があり、
- C列:営業部
- D列:売上100,000以上
- E列:対象
のすべてを満たす行を抽出する場合は、次のように判定できます。
Dim targetStatus As String
targetStatus = sourceSheet.Cells(sourceRow, "E").Value
If departmentName = "営業部" _
And salesAmount >= 100000 _
And targetStatus = "対象" Then
sourceSheet.Rows(sourceRow).Copy _
Destination:=outputSheet.Rows(outputRow)
outputRow = outputRow + 1
End If
条件式を改行しているのは、単に見た目を整えるためだけではありません。
複数条件を縦に並べることで、
「どの条件を満たす必要があるのか」
を確認しやすくしています。
将来、「売上条件を変更する」「対象区分の判定をなくす」といった仕様変更が発生した場合も、修正する条件を見つけやすくなります。
実務で使うVBAでは、コードを短く書くことよりも、数か月後に見直しても条件の意味を判断できることを優先した方が、保守しやすい処理になります。
✅ VBAのOR条件で複数条件に一致する行を抽出する方法
AND条件が「すべての条件を満たす行」を対象にするのに対し、OR条件は「いずれかの条件を満たす行」を対象にします。この違いは単純に見えますが、実務では抽出件数が大きく変わるため注意が必要です。
例えば、「営業部または企画部」と「営業部かつ企画部」では意味がまったく異なります。また、OR条件を増やしすぎると、想定していなかったデータまで抽出されることがあります。コードがエラーにならなくても抽出結果が正しいとは限らないため、実行後の件数や内容を確認することが重要です。特に複数の部署・担当者・ステータスなどを対象にするときは、何を「いずれかに一致」とするのかを整理してから条件式を作成しましょう。
・営業部または企画部の行を抽出するコード
例えば、C列の部署が「営業部」または「企画部」である行を抽出する場合は、OR条件を使用します。
If departmentName = "営業部" _
Or departmentName = "企画部" Then
sourceSheet.Rows(sourceRow).Copy _
Destination:=outputSheet.Rows(outputRow)
outputRow = outputRow + 1
End If
この条件では、「営業部」と「企画部」のどちらかに一致すればTrueになります。
例えば、次のデータがあるとします。
| 氏名 | 部署 |
|---|---|
| 田中 | 営業部 |
| 佐藤 | 総務部 |
| 鈴木 | 企画部 |
| 高橋 | 経理部 |
この場合は、「営業部」の田中さんと「企画部」の鈴木さんが抽出対象です。
OR条件は、複数の候補から対象データを選ぶ場面で便利です。
例えば、
- 営業部または企画部
- 東京支店または大阪支店
- 処理状況が「未処理」または「確認中」
といった条件判定に利用できます。
ただし、条件が5個、10個と増える場合、ORを延々と並べると保守しにくくなります。その場合は条件を配列などで管理し、対象値が含まれているかを別処理で判定する設計も検討するとよいでしょう。
今回は「営業部」「企画部」のような完全一致を使っていますが、セル内に特定の文字が含まれているかを条件にしたいケースもあります。部分一致を使って対象行を抽出したい場合は、「【VBA】特定の文字を含む行を抽出する方法|InStrで部分一致検索」でInStrを使った判定方法を確認できます。
✅ VBAでAND条件とOR条件を組み合わせて行を抽出する
実務では、ANDだけ、ORだけで完結するとは限りません。「営業部または企画部で、なおかつ売上が10万円以上」といった条件はよくあります。このとき特に注意したいのが、ANDとORを1つの条件式へ混在させた場合の判定順序です。条件式の意味を十分確認せずに記述すると、想定とは違う行が抽出される原因になります。しかも構文上は正しいため、マクロが停止するとは限りません。
結果だけが静かに間違うタイプの不具合は、実務では発見が遅れやすい問題です。そのためANDとORを組み合わせる場合は、括弧を使って「どの条件をひとまとまりとして判定するのか」を明確にしましょう。
・「営業部または企画部」かつ「売上10万円以上」を判定する
例えば、次の条件を考えてみます。
(営業部 または 企画部)かつ 売上100,000以上
コードでは次のように記述できます。
If (departmentName = "営業部" _
Or departmentName = "企画部") _
And salesAmount >= 100000 Then
sourceSheet.Rows(sourceRow).Copy _
Destination:=outputSheet.Rows(outputRow)
outputRow = outputRow + 1
End If
ポイントは、部署を判定している部分を括弧で囲んでいることです。
(departmentName = "営業部" Or departmentName = "企画部")
これによって、
- 営業部または企画部であるか
- 売上が100,000以上であるか
- 1と2の両方を満たしているか
という条件のまとまりが読み取りやすくなります。
・括弧を使って条件の意図を明確にする
複数条件を扱うときは、「VBAがどの順番で評価するか」だけに頼ったコードは避けた方が安全です。
例えば、次のように条件を並べることもできます。
If departmentName = "営業部" _
Or departmentName = "企画部" _
And salesAmount >= 100000 Then
しかし、この書き方ではコードを読んだ人が、
「営業部なら売上に関係なく対象なのか」
「営業部または企画部で、どちらも売上10万円以上が必要なのか」
を一目で判断しにくくなります。
実務では、開発時点で動作することだけではなく、後から条件を確認・変更する人が誤解しないことも重要です。
そのため、ANDとORを混在させる場合は、判定のまとまりを括弧で明示することをおすすめします。
AND・OR条件は、行だけでなく列を対象にした抽出にも利用できます。複数の条件から必要な列を判定して取り出したい場合は、「【VBA】複数条件に一致する列を抽出する方法|AND・OR条件でデータを判定」もあわせて確認すると、行と列それぞれの条件抽出を使い分けやすくなります。
✅ VBAで複数条件の行抽出を実務で使うときの注意点
複数条件による抽出処理は、一度作れば終わりとは限りません。実務では「対象部署を追加したい」「金額条件を変更したい」「空白データも含まれるようになった」といった仕様変更が起こります。そのとき、条件値や列番号がコードのさまざまな場所に直接書かれていると修正漏れが起こりやすくなります。
また、数値を想定した列に文字列や空白が入っていることもあり、データの状態によってはエラーにつながります。抽出処理では条件式だけを見るのではなく、元データが必ず想定どおりとは限らないことも考えておく必要があります。特に人が入力するExcelファイルでは、表記揺れや入力漏れを完全になくすことは難しいでしょう。継続的に使用するマクロでは、こうしたデータの変化も想定した設計が重要です。
・条件値をコードの先頭で管理する
例えば、「営業部」「100000」という条件を処理の途中へ直接記述するのではなく、条件値を変数として管理する方法があります。
Dim targetDepartment As String
Dim minimumSales As Double
targetDepartment = "営業部"
minimumSales = 100000
判定部分は次のようにできます。
If departmentName = targetDepartment _
And salesAmount >= minimumSales Then
この形なら、条件を変更するときに、
targetDepartment = "企画部"
minimumSales = 150000
などと条件値を変更できます。
条件が頻繁に変わる業務であれば、さらにExcelシート上へ条件入力欄を用意し、そのセルから条件値を取得する設計も有効です。
VBAコードそのものを編集しなくても条件を変更できるようにすれば、利用者と開発者の役割を分けやすくなります。
・空白や想定外の値があるデータに注意する
売上列を数値として取得する場合、元データに数値以外の値が混ざる可能性も考えておきましょう。
例えば、D列に「確認中」などの文字列が入る可能性があるなら、数値かどうかを確認してから判定する方法があります。
If IsNumeric(sourceSheet.Cells(sourceRow, "D").Value) Then
salesAmount = CDbl(sourceSheet.Cells(sourceRow, "D").Value)
If departmentName = "営業部" _
And salesAmount >= 100000 Then
sourceSheet.Rows(sourceRow).Copy _
Destination:=outputSheet.Rows(outputRow)
outputRow = outputRow + 1
End If
End If
こうしておけば、数値として扱えるデータだけを売上条件の判定へ進められます。
ただし、「数値以外なら無視すればよい」とは限りません。
業務によっては、想定外のデータが存在すること自体をエラーとして利用者へ知らせる必要があります。
除外するのか、処理を停止するのか、別途エラー一覧へ出力するのかは、元データの用途に応じて決めることが重要です。
部署名などを完全一致だけで判定できない場合は、LikeやInStrを条件式へ組み込む方法もあります。文字列の部分一致をIf文の条件として安全に扱いたい場合は、「【VBA】文字列の部分一致(IF文)|LikeとInStrで壊れない条件分岐を設計する」で、条件分岐としての使い分けを詳しく解説しています。
✅ VBAで複数条件の行抽出を保守しやすく設計するポイント
条件抽出のマクロは、最初は2条件でも運用を続けるうちに複雑になりやすい処理です。「この条件も追加してほしい」という変更を繰り返した結果、巨大なIf文になってしまうケースもあります。条件が増えるほど、コードを書いた本人でさえ後から判定内容を把握するのに時間がかかります。
また、同じ条件を複数箇所へ書くと、一方だけ変更してしまう危険もあります。こうした問題は処理速度よりも保守性に影響し、長期間使う業務マクロでは無視できません。条件が少ない段階から意味の分かる変数名やコメントを使用し、判定処理を整理しておくことが重要です。条件数がさらに増える場合は、判定処理そのものを別のFunctionへ分離することも検討しましょう。
・抽出処理と条件判定を分ける考え方
例えば、条件が増えてきた場合は、対象行かどうかを判定するFunctionを作成できます。
Private Function IsTargetRow( _
ByVal departmentName As String, _
ByVal salesAmount As Double) As Boolean
'対象部署かつ基準売上以上の場合のみTrueを返す
IsTargetRow = _
(departmentName = "営業部" Or departmentName = "企画部") _
And salesAmount >= 100000
End Function
メイン処理では次のように呼び出します。
If IsTargetRow(departmentName, salesAmount) Then
sourceSheet.Rows(sourceRow).Copy _
Destination:=outputSheet.Rows(outputRow)
outputRow = outputRow + 1
End If
この書き方のメリットは、「条件を判定する処理」と「一致した行を転記する処理」の役割を分けられることです。
条件を変更するときはIsTargetRowを中心に確認できるため、メイン処理まで細かく読み直す負担を減らせます。
一方で、条件が1つ、2つしかなく今後も変更されない小さなマクロまで無理にFunctionへ分割すると、かえってコードを追いにくくなる場合があります。
実務では「分割すればするほどよい」と考えるのではなく、条件の複雑さや今後の仕様変更の可能性に応じて構成を決めることが大切です。
また、大量データを繰り返し処理する場合は、セルを1行ずつ読み書きする方法だけでなく、対象範囲を配列へ取得してVBA内部で判定する方法もあります。データ件数や処理内容によっては、ワークシートへのアクセス回数を減らすことで処理時間を短縮できます。
✅ まとめ:VBAでAND・OR条件を使って複数条件に一致する行を正しく抽出しよう
VBAで複数条件に一致する行を抽出するときは、If文へ条件を追加するだけでなく、ANDとORが何を意味しているのかを整理することが重要です。特にANDとORを同時に使用すると、条件式が正しく動作していても、業務上想定したデータとは異なる結果になる可能性があります。
また、実務では条件が後から変更・追加されることも珍しくありません。最初から条件の意味が分かる変数名を使い、必要に応じて条件値や判定処理を分離しておくと、修正しやすいコードになります。さらに、空白や文字列など想定外のデータが存在する可能性も考慮しておけば、より安全な抽出処理を作成できます。
- AND条件は、すべての条件を満たす行を抽出するときに使用する
- OR条件は、いずれかの条件を満たす行を抽出するときに使用する
- ANDとORを組み合わせる場合は、括弧で条件のまとまりを明確にする
- 条件判定に使う値は、意味の分かる変数名で管理すると読みやすい
- 条件値を変数やセルで管理すると、仕様変更へ対応しやすくなる
- 数値列の空白や文字列など、想定外のデータも考慮する
- 条件が複雑になった場合は、Functionへ判定処理を分離する方法も有効
- 大量データでは、配列を利用してシートへのアクセスを減らす方法も検討する
複数条件による抽出は、売上データ、顧客一覧、在庫表、作業管理表など幅広い業務で利用できます。単に条件に一致する行を取り出すだけでなく、「条件判定」と「抽出後の処理」を分けて考える習慣を付けることで、条件追加や仕様変更にも対応しやすいVBAコードを作成できるようになります。