VBAでAND・ORを組み合わせるとき、括弧を省略すると意図と異なる動きになることがあります。VBAではANDの方がORより優先されるため、「AまたはBかつC」と書いたつもりが「AまたはBかつC」ではなく「AまたはBかつC」という別の意味になるケースがあります。括弧で明示的にグループ化するか、条件を変数に切り出すだけで、ミスを大幅に防げます。
この記事では、次の内容を順番に解説します。
- ANDとORの優先順位と落とし穴
- 括弧でグループ化して意図を明確にする方法
- 条件をBoolean変数に切り出して読みやすくする方法
- Notを使った否定条件の書き方
- 条件が多い場合にSelect Caseで整理する方法
- よくある質問(ANDとORの混在・3条件以上・否定の書き方等)
ANDとORの優先順位と落とし穴を理解するには?
まず、次のコードを見てください。
If Cells(i, 1).Value = "A" And Cells(i, 2).Value = "完了" Or Cells(i, 3).Value = "" Then
Cells(i, 4).Value = "確認要"
End If
「A列がAで、B列が完了で、C列が空の場合」を意図しているように見えますが、実際の動作は次の通りです。
| VBAの解釈 | 意味 |
|---|---|
(A列="A" And B列="完了") Or (C列="") | 「A列がAかつB列が完了」または「C列が空」 |
VBAでは ANDがORより先に評価されます。そのため括弧がないと、ANDでまとめた条件とORの右側が別々に扱われます。C列が空さえあれば条件を満たしてしまうため、意図しない行に「確認要」が入ることになります。
括弧でグループ化して意図を明確にするには?
条件のグループを括弧で明示することで、評価の順番をコントロールできます。
「AかつB」または「C」という条件にしたい場合
If (Cells(i, 1).Value = "A" And Cells(i, 2).Value = "完了") Or _
(Cells(i, 3).Value = "") Then
Cells(i, 4).Value = "確認要"
End If
「A」かつ「BまたはC」という条件にしたい場合
If Cells(i, 1).Value = "A" And _
(Cells(i, 2).Value = "完了" Or Cells(i, 3).Value = "") Then
Cells(i, 4).Value = "確認要"
End If
括弧の位置が変わるだけで意味がまったく異なります。条件を書き終えたら「括弧ごとに何を判定しているか」を声に出して確認する習慣をつけると、読み違いを防げます。
また、条件が長くなる場合は行継続文字(_)で折り返すと読みやすくなります。
条件をBoolean変数に切り出して読みやすくするには?
条件が3つ以上になってきたら、条件式を変数に入れてからIfで使う方法が効果的です。
Sub CheckRows()
Dim i As Long
Dim lastRow As Long
Dim isTargetDept As Boolean
Dim isCompleted As Boolean
Dim isBlank As Boolean
Dim shouldFlag As Boolean
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
isTargetDept = (Cells(i, 1).Value = "A")
isCompleted = (Cells(i, 2).Value = "完了")
isBlank = (Trim(Cells(i, 3).Value) = "")
' 「A部門かつ完了」または「C列が空」
shouldFlag = (isTargetDept And isCompleted) Or isBlank
If shouldFlag Then
Cells(i, 4).Value = "確認要"
End If
Next i
End Sub
変数名を読むだけで条件の意味がわかるため、複雑なロジックでも追いやすくなります。また、条件の変更が必要になったときに修正箇所が明確になるメリットもあります。
Notを使った否定条件を書くには?
「〇〇でない場合」という否定条件には Not または <> を使います。
' 「完了」でない行だけを対象にする
If Cells(i, 2).Value <> "完了" Then
Cells(i, 4).Value = "未完了"
End If
' Boolean変数を否定する
If Not isCompleted Then
Cells(i, 4).Value = "未完了"
End If
Boolean変数を使っている場合は Not 変数名 でシンプルに書けます。If isCompleted = False Then よりも If Not isCompleted Then の方が自然で読みやすい書き方です。
条件が多い場合にSelect Caseで整理するには?
同じ変数に対して複数の値を比較する場合は、Select Case を使うとIfのネストよりすっきり書けます。
If〜ElseIfで書いた場合(読みにくい)
If Cells(i, 1).Value = "A" Then
Cells(i, 2).Value = "優先"
ElseIf Cells(i, 1).Value = "B" Then
Cells(i, 2).Value = "通常"
ElseIf Cells(i, 1).Value = "C" Then
Cells(i, 2).Value = "保留"
Else
Cells(i, 2).Value = "対象外"
End If
Select Caseで書いた場合(読みやすい)
Select Case Cells(i, 1).Value
Case "A"
Cells(i, 2).Value = "優先"
Case "B"
Cells(i, 2).Value = "通常"
Case "C"
Cells(i, 2).Value = "保留"
Case Else
Cells(i, 2).Value = "対象外"
End Select
分岐が3つ以上ある場合は Select Case の方が条件を追加・削除しやすく、見落としも起きにくくなります。
まとめ
- VBAでは ANDがORより先に評価されるため、混在する場合は括弧が必須
- 括弧でグループ化することで 評価の順番を明示 できる
- 条件が複雑になったら Boolean変数に切り出す と読みやすくなる
- 否定条件は
Not 変数名または<>で書く - 同じ変数への複数比較は
Select Caseを使うとすっきりする
よくある質問
ANDとORを混在させるとき、括弧をどこに入れればいい?
「先にまとめたい条件のグループ」を括弧で囲むのが基本です。「AかつB」を先に評価したいなら (A And B) Or C、「BまたはC」を先に評価したいなら A And (B Or C) と書きます。迷ったら、条件式を日本語で声に出して読んでみて、その通りに括弧を当てはめましょう。
条件が5つ以上になった場合はどうすればいい?
Boolean変数に切り出してグループ化するのが最も管理しやすくなります。たとえば「申請条件を満たしているか」「承認済みか」といった意味のまとまりで変数名をつけると、If文が1行で読めるようになります。それでも複雑な場合は、条件チェック専用のFunctionを作ってTrue/Falseを返す設計にすると、メインのコードがすっきりします。
Select CaseでANDやORに相当する条件を書けますか?
書けます。Case の後に複数の値をカンマ区切りにするとOR相当になります。
Select Case Cells(i, 1).Value
Case "A", "B" ' AまたはB
Cells(i, 2).Value = "対象"
Case Else
Cells(i, 2).Value = "対象外"
End Select
数値範囲は Case 10 To 20、それ以上は Case Is >= 50 と書けます。
条件式をBoolean変数に入れると処理が遅くなる?
ほとんど影響はありません。Boolean変数への代入はごく軽い処理です。むしろ同じセル参照を複数回行うよりも、一度変数に入れてから参照する方が若干速くなることもあります。
条件が正しいか確認する方法は?
テストデータを用意してF8キー(ステップ実行)で1行ずつ追うのが確実です。Boolean変数を使っている場合は、ウォッチウィンドウに変数を登録しておくと、各行でTrue/Falseの切り替わりをリアルタイムで確認できます。


