Tested on: Excel 365 v2509 · Excel 2021 · Excel 2019 · last verified 2026-06-05
TL;DR — If...Then...Else runs different code depending on whether a condition is True. Copy this and adapt:
Sub GradeScore()
Dim score As Long
score = Range("A1").Value
If score >= 90 Then
Range("B1").Value = "A"
ElseIf score >= 75 Then
Range("B1").Value = "B"
ElseIf score >= 60 Then
Range("B1").Value = "C"
Else
Range("B1").Value = "Fail"
End If
End Sub
That block is 90% of what you'll ever do with conditions. But knowing which shape to reach for — and the one trap that quietly breaks If — matters more than collecting another snippet.
The one idea: If is a checklist of independent questions
If...ElseIf is a checklist. VBA reads it top to bottom, asking one yes/no question at a time, and runs the block under the first question that answers True — then skips the rest. The defining feature: each question can interrogate a different variable.
If hoursWorked > 40 Then ' question about hours
pay = "overtime"
ElseIf role = "Contractor" Then ' a different question, about role
pay = "flat rate"
Else
pay = "standard"
End If
That freedom — every branch can ask about something else — is exactly what If is for. And it's the line that tells you when you've outgrown it: the moment every branch is asking about the same value (score >= 90, score >= 75, score >= 60…), you've built a router out of checklist parts. That's the signal to switch to Select Case.
The trap that breaks more macros than any syntax error: VBA doesn't short-circuit
In most languages, If a And b stops at a when a is false — it never looks at b. VBA does not do this. It evaluates both sides, always. So this looks safe and isn't:
' CRASH when rng is Nothing — VBA still evaluates rng.Rows.Count
If Not rng Is Nothing And rng.Rows.Count > 0 Then ...
Because VBA checks rng.Rows.Count even when rng Is Nothing, you get a run-time error on a line that reads like a guard. The fix is to make the questions sequential — nest them so the second only runs when the first passed:
If Not rng Is Nothing Then
If rng.Rows.Count > 0 Then ...
End If
This single behaviour explains a huge share of "but my If condition is correct!" bugs. Once you know VBA always evaluates both operands, you stop putting risky calls inside And/Or.
The other rule: single-line If has no End If
Every If you write is one of two shapes, and mixing them is the #1 compile error ("Block If without End If"):
' Single-line — exactly one action, NO End If
If cell.Value = 0 Then cell.Value = "n/a"
' Block — the moment you need a second line or an Else, you need End If
If cell.Value = 0 Then
cell.Value = "n/a"
cell.Interior.Color = vbYellow
End If
The rule is simple: need two actions or an Else? Go block, and close it with End If. There is no in-between.
The shapes, as evidence — And, Or, nesting, IIf
You already have the model; here are the constructs that put it to work.
And requires all true; Or needs one — the distinction beginners trip over:
If amount <= 5000 And role = "Manager" Then status = "Auto-approved"
If amount > 50000 Or isFlagged Then status = "Needs review"
Nesting handles genuinely dependent questions — but two levels deep is the limit before readability collapses (and your cue, again, to consider Select Case):
If country = "US" Then
If weight <= 1 Then shipping = "Standard" Else shipping = "Heavy"
Else
shipping = "International"
End If
IIf is a function, not a statement — handy for a one-line two-way pick, but it evaluates both arguments (same no-short-circuit rule), so never put a divide-by-zero or risky call inside it:
Range("C2").Value = IIf(Range("A2").Value > 0, "Profit", "Loss")
When to use If vs Select Case
| Situation | Use |
|---|---|
| Branches ask about different variables | If...ElseIf |
| 1–2 outcomes | If...Else |
| 3+ outcomes all testing the same value | Select Case |
| Ranges of one value (1–10, 11–20…) | Select Case ... To |
The honest rule: different questions → checklist (If); same value, many answers → switchboard (Select Case).
Common errors — and why they happen
- "Block If without End If" / "Else without If". You mixed single-line and block syntax. Re-indent; each block
Ifneeds exactly oneEnd If. - The condition is always true/false. Usually a type mismatch (text vs number) or case sensitivity (
"Yes" <> "yes").Debug.Printthe condition to see what VBA actually evaluates. - A "guard" still crashes. No short-circuit — split the
Andinto nestedIfs. - Text comparison misses.
"paid" <> "Paid". Wrap both sides inLCase(), or setOption Compare Text.
When the conditions outlive the code
If is the right tool for branching on different questions — but business rules don't sit still. Every new threshold means editing, re-testing, and hoping you didn't break a branch six months later. ExcelMaster Agent lets you state the rule in plain English — "flag rows in column D where the due date has passed and status isn't Paid, and colour them red" — and generates the logic, no End If to forget. Try it free →
Related guides
- VBA Select Case — the switchboard for one value, many outcomes
- VBA For Loop in Excel — 8 Real-World Examples
- VBA While Loop — While, Do While & Do Until Explained
FAQ
When should I use If instead of Select Case?
When your branches ask about different variables, or you only have one or two outcomes. The moment every branch tests the same value against three or more options, Select Case reads better.
Does VBA short-circuit And / Or?
No. VBA evaluates both operands every time. Never put a call that could error (on a Nothing object, a missing key) in the second half of an And — nest the conditions instead.
Can I write If Then Else on one line?
Only for a single action with no multi-line Else: If x > 0 Then y = 1. Add an Else or a second statement and you must use the block form with End If.
What's the difference between If and IIf?
If is a statement that controls which lines run. IIf() is a function that returns one of two values — and it evaluates both, so keep risky expressions out of it.
