動作確認: Excel 365 v2509 · Excel 2021 · Excel 2019 · 最終確認 2026-06-05
要点 — If...Then...Else文は、条件がTrueかどうかで実行するコードを切り替えます。まずはこの雛形をコピーして使ってください。
Sub 評価する()
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 = "不合格"
End If
End Sub
このブロックだけで、VBAの条件分岐の9割はまかなえます。残りはみんながはまる落とし穴を避けるためのパターンです。
If文がなぜ重要なのか
「期限切れの請求書に印を付ける」「予算超過のセルを色分けする」「空行をスキップする」——何かを判断するマクロは、すべてIfの上に成り立っています。構造を一度きちんと押さえれば、VBAを保守しづらくしている、あの絡まった条件分岐を二度と書かずに済みます。
Ifの4つの形
| 形 | 使う場面 | End Ifは必要? |
|---|---|---|
1行のIf |
短い処理が1つ、Elseなし |
不要 |
ブロックIf...End If |
1分岐・複数行 | 必要 |
If...Else |
結果が2通り | 必要 |
If...ElseIf...Else |
結果が3通り以上 | 必要 |
' 1行 — End If不要、1文だけ
If cell.Value = 0 Then cell.Value = "該当なし"
' ブロック — 複数行はEnd Ifが必要
If cell.Value = 0 Then
cell.Value = "該当なし"
cell.Interior.Color = vbYellow
End If
目安: 処理が2つ、または
Elseが必要になった瞬間に、End If付きのブロック形へ切り替えます。1行形とブロック形を混在させるのが、コンパイルエラー 「ブロック If に対応する End If がありません」 の最大の原因です。
例1 — 期限切れの請求書に印を付ける
Sub 期限切れに印()
Dim r As Range
For Each r In Range("D2:D200") ' D = 支払期日
If r.Value < Date And r.Offset(0, 1).Value <> "入金済" Then
r.Offset(0, 2).Value = "期限切れ"
r.Offset(0, 2).Interior.Color = RGB(255, 199, 206)
End If
Next r
End Sub
Andで2つの条件を結んでいます。両方が真でなければなりません。請求書が期限切れかつ未入金、という意味です。
例2 — AndとOrの違いをはっきりさせる
Andはすべての条件が真であることを要求します。Orは1つで十分です。初心者が必ずつまずくのがここです。
' 金額が少なく かつ 申請者が管理職のときだけ承認
If amount <= 5000 And role = "管理職" Then status = "自動承認"
' 金額が大きい または 口座にフラグがあれば差し戻し
If amount > 50000 Or isFlagged = True Then status = "要確認"
VBAは既定では短絡評価をしません。1つ目が偽のときに失敗するような関数を2つ目の条件に書かないでください。その場合はネストしたIfに分けます。
例3 — 本物の判断ツリーをネストしたIfで
Sub 送料区分()
Dim weight As Double, country As String
weight = Range("A2").Value
country = Range("B2").Value
If country = "JP" Then
If weight <= 1 Then
Range("C2").Value = "通常 500円"
Else
Range("C2").Value = "重量 1,200円"
End If
Else
Range("C2").Value = "海外 2,500円"
End If
End Sub
ネストは2段までなら問題ありません。それ以上は読みづらくなります——Select Caseへ切り替える合図です(後述)。
例4 — 1行で素早く代入するIIf
2択のシンプルな分岐なら、IIf関数が1行で収まります。
Range("C2").Value = IIf(Range("A2").Value > 0, "黒字", "赤字")
注意: IIfは捨てる方も含めて両方の引数を評価します。ゼロ除算や危険な関数呼び出しは絶対に入れないでください。
例5 — 変数だけでなくセルを判定する
Sub 空白を強調()
Dim r As Range
For Each r In Range("A2:A500")
If IsEmpty(r) Then
r.Interior.Color = vbRed
ElseIf Not IsNumeric(r.Value) Then
r.Interior.Color = vbYellow
End If
Next r
End Sub
IsEmpty・IsNumeric・IsErrorは、汚れたデータでIfがクラッシュするのを防ぐ番人です。
例6 — 深くネストせず早めに抜ける
Sub 行を処理(r As Range)
If r.Value = "" Then Exit Sub ' ガード節 — すぐ抜ける
If Not IsNumeric(r.Value) Then Exit Sub
r.Offset(0, 1).Value = r.Value * 1.2
End Sub
ガード節を使うとコードが平らになります。すべてをIf 正常 Then ... End Ifで包む代わりに、不正なケースを先に弾き、本来の処理をインデントなしで走らせます。
IfとSelect Caseの使い分け
| 状況 | 使うもの |
|---|---|
| 結果が1〜2通り、または別々の変数を条件にする | If...Else |
| 同じ変数を3通り以上で判定する | Select Case |
| 値の範囲(1〜10、11〜20…) | Select Case ... To |
複数変数でAnd/Orを組み合わせる |
If...ElseIf |
同じ変数に対してElseIf x = 1 ... ElseIf x = 2 ... ElseIf x = 3と書いているなら、Select Caseの方がすっきり読めます。
よくあるエラー(と対処)
「ブロック If に対応する End If がありません」 — 複数行のIfを開いたまま閉じていません。ブロックのIfにはEnd Ifがちょうど1つ必要です。
「If に対応しない Else です」 — たいていはElseの上に余分なEnd Ifがあるか、1行のIfの後に孤立したElseがあります。ブロックをインデントし直せば、ずれが一目で分かります。
条件がいつも成立する/しない — 文字列と数値を比較している、または演算子の打ち間違いです。Debug.Printで条件を出力し、VBAが実際に何を評価しているか確認します。
文字列比較が予想外に失敗する — "入金済" = "入金済 "(末尾スペース)はFalseです。両辺をTrim()で囲む、大文字小文字ならOption Compare Textをモジュール冒頭に置きます。
条件を手書きするのはもう終わり——ルールを言葉で伝える
条件ロジックこそ、VBAが脆くなる場所です。ネストしたIfが1つ増えるだけで、半年後には誰も安全に直せなくなります。ExcelMaster Agent なら、ルールを自然な日本語で書くだけ——「D列の支払期日が過ぎていて、ステータスが入金済でない行を赤くして」——同じロジックを生成して実行します。End Ifの付け忘れもありません。無料で試す →
関連ガイド
よくある質問
If Then Elseを1行で書けますか?
書けますが、複数行のElseを伴わない単一処理に限ります(If x > 0 Then y = 1)。Elseや2つ目の文が加わったら、End If付きのブロック形が必須です。
ElseIfは何個まで書けますか?
必要なだけ書けますが、すべて同じ変数を判定するなら、3つを超えたあたりからSelect Caseの方が読みやすくなります。
なぜIf条件がいつも実行されるのですか?
多くは型の不一致(文字列と数値の比較)か、大文字小文字の違い("はい" <> "ハイ")です。Debug.Printで条件を確認してください。
IfとIIfの違いは?
Ifはどの行を実行するかを制御する「文」です。IIf()は2つの値のどちらかを返す「関数」で、両方を評価します。危険な式は入れないでください。
