条件分岐 (If / Select Case)
VBA でプログラムの処理を「条件に応じて切り替える」には、条件分岐を使用します。「もし○○なら△△する、そうでなければ□□する」という、プログラミングにおいて最も基本的かつ重要な制御構文です。
VBA には主に If 文と Select Case 文の2種類の条件分岐があります。この記事では、それぞれの構文と使い方、そして場面に応じた使い分けの基準まで詳しく解説します。
条件分岐が必要となるシチュエーション
実務では、以下のような場面で条件分岐が必要になります:
- データの分類: 売上金額に応じてランクを振り分ける
- 入力チェック: ユーザーが入力した値が有効かどうかを判定する
- エラー処理: 処理結果に応じてエラーメッセージを表示する
- 条件付き書式: 値に基づいてセルの色やフォントを変更する
- フロー制御: 状況に応じて実行する処理を切り替える
比較演算子と論理演算子
条件分岐を学ぶ前に、条件式で使用する演算子を理解しておきましょう。
比較演算子
| 演算子 | 意味 | 使用例 | 結果(A=10の場合) |
|---|---|---|---|
= | 等しい | A = 10 | True |
<> | 等しくない | A <> 10 | False |
> | より大きい | A > 5 | True |
< | より小さい | A < 5 | False |
>= | 以上 | A >= 10 | True |
<= | 以下 | A <= 10 | True |
Like | パターンマッチング | "ABC" Like "A*" | True |
Is | オブジェクト比較 | obj Is Nothing | - |
論理演算子
| 演算子 | 意味 | 使用例 | 結果 |
|---|---|---|---|
And | かつ(両方 True) | A > 0 And A < 100 | 両方の条件を満たすとき True |
Or | または(どちらか) | A = 0 Or A = 100 | いずれかの条件を満たすとき True |
Not | 否定(反転) | Not (A = 10) | 条件の True/False を反転 |
Xor | 排他的論理和 | A > 0 Xor B > 0 | どちらか一方のみ True のとき True |
Sub OperatorsExample()
Dim score As Long
score = 75
' 比較演算子
Debug.Print score > 60 ' => True
Debug.Print score = 100 ' => False
Debug.Print score <> 0 ' => True
' 論理演算子
Debug.Print score >= 60 And score < 80 ' => True(60以上80未満)
Debug.Print score = 100 Or score = 0 ' => False(100でも0でもない)
Debug.Print Not (score < 60) ' => True(60未満ではない)
End Sub
If 文の基本
単純な If 文
最もシンプルな条件分岐は、条件が True のときだけ処理を実行するパターンです。
Sub IfBasic()
Dim score As Long
score = 80
If score >= 60 Then
Debug.Print "合格です"
End If
End Sub
構文:
If 条件式 Then
' 条件が True のときに実行される処理
End If
1行で書く If 文
処理が1行の場合は、End If を省略して1行で書くこともできます。
Sub IfOneLine()
Dim score As Long
score = 80
If score >= 60 Then Debug.Print "合格です"
End Sub
1行形式は短い処理の場合こそ便利ですが、可読性の観点から複数行形式(End If あり)を使うのが一般的です。
If…Else 文
条件が True の場合と False の場合で、異なる処理を実行します。
Sub IfElse()
Dim score As Long
score = 45
If score >= 60 Then
Debug.Print "合格です"
Else
Debug.Print "不合格です"
End If
End Sub
' => 不合格です
If…ElseIf…Else 文
3つ以上の条件で分岐する場合は ElseIf を使用します。
Sub IfElseIf()
Dim score As Long
score = 85
If score >= 90 Then
Debug.Print "評価: A"
ElseIf score >= 80 Then
Debug.Print "評価: B"
ElseIf score >= 70 Then
Debug.Print "評価: C"
ElseIf score >= 60 Then
Debug.Print "評価: D"
Else
Debug.Print "評価: F(不合格)"
End If
End Sub
' => 評価: B
ElseIf は上から順に評価され、最初に True になった条件のブロックだけが実行されます。それ以降の条件は評価されません。
例えば score = 95 の場合、score >= 90 が True になるため “評価: A” が表示され、score >= 80 以降の条件は評価されません。条件の順序は厳しい条件を先に書くのが基本です。
If 文の応用
複数条件の組み合わせ(And / Or)
Sub IfMultipleConditions()
Dim age As Long
Dim hasLicense As Boolean
age = 20
hasLicense = True
' And: 両方の条件を満たすとき
If age >= 18 And hasLicense = True Then
Debug.Print "運転できます"
End If
' Or: いずれかの条件を満たすとき
Dim day As String
day = "土曜日"
If day = "土曜日" Or day = "日曜日" Then
Debug.Print "週末です"
End If
' 複雑な条件の組み合わせ
Dim score As Long
Dim attendance As Long
score = 75
attendance = 90
If (score >= 60 And attendance >= 80) Or score >= 90 Then
Debug.Print "単位取得"
Else
Debug.Print "単位不可"
End If
End Sub
複雑な条件を組み合わせる場合は、括弧 () を使って意図を明確にすることをお勧めします。VBA では And が Or より優先されますが、括弧を使えば評価順序が一目で分かります。
If 文のネスト(入れ子)
If 文の中にさらに If 文を書くことをネスト(入れ子)と呼びます。
Sub IfNested()
Dim department As String
Dim sales As Long
department = "営業部"
sales = 1500000
If department = "営業部" Then
If sales >= 2000000 Then
Debug.Print "目標達成!ボーナス支給"
ElseIf sales >= 1000000 Then
Debug.Print "もう少しで目標達成"
Else
Debug.Print "頑張りましょう"
End If
Else
Debug.Print "営業部以外の部署です"
End If
End Sub
' => もう少しで目標達成
ネストが深くなると(3段階以上)コードの可読性が著しく低下します。ネストが深くなる場合は、以下の対策を検討しましょう:
- 条件を反転して早期に
Exit Subする(ガード節) - 処理を別のプロシージャに分割する
Select Case文で書き直す
ガード節パターン(早期リターン)
ネストを減らすテクニックとして、ガード節(条件を満たさない場合に早期に抜ける)パターンがあります。
' × ネストが深い書き方
Sub ProcessData_Bad()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("データ")
If ws.Range("A1").Value <> "" Then
If IsNumeric(ws.Range("A1").Value) Then
If ws.Range("A1").Value > 0 Then
' 本来の処理
Debug.Print "処理を実行: " & ws.Range("A1").Value
End If
End If
End If
Set ws = Nothing
End Sub
' ○ ガード節で読みやすい書き方
Sub ProcessData_Good()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("データ")
Dim cellValue As Variant
cellValue = ws.Range("A1").Value
' 条件を満たさない場合は早期に抜ける
If cellValue = "" Then Exit Sub
If Not IsNumeric(cellValue) Then Exit Sub
If cellValue <= 0 Then Exit Sub
' 本来の処理(ネストなし)
Debug.Print "処理を実行: " & cellValue
Set ws = Nothing
End Sub
空文字列・Null・Empty のチェック
セルの値を判定する際によく使うパターンです。
Sub CheckEmptyValues()
Dim cellValue As Variant
cellValue = Range("A1").Value
' セルが空かどうかの判定方法
' 方法1: 空文字列との比較
If cellValue = "" Then
Debug.Print "セルは空です(方法1)"
End If
' 方法2: IsEmpty 関数を使用
If IsEmpty(cellValue) Then
Debug.Print "セルは空です(方法2)"
End If
' 方法3: Len 関数で長さを確認
If Len(cellValue) = 0 Then
Debug.Print "セルは空です(方法3)"
End If
' 数値かどうかの判定
If IsNumeric(cellValue) Then
Debug.Print "数値です: " & cellValue
End If
' 日付かどうかの判定
If IsDate(cellValue) Then
Debug.Print "日付です: " & cellValue
End If
End Sub
Select Case 文
Select Case の基本
Select Case 文は、一つの値に対して複数の候補と照合する条件分岐です。If...ElseIf の連鎖をよりすっきり書けます。
Sub SelectCaseBasic()
Dim rank As String
rank = "B"
Select Case rank
Case "A"
Debug.Print "最優秀"
Case "B"
Debug.Print "優秀"
Case "C"
Debug.Print "普通"
Case "D"
Debug.Print "要改善"
Case Else
Debug.Print "評価なし"
End Select
End Sub
' => 優秀
構文:
Select Case 評価する式
Case 値1
' 値1 に一致する場合の処理
Case 値2
' 値2 に一致する場合の処理
Case Else
' どの値にも一致しない場合の処理
End Select
複数の値を1つの Case にまとめる
カンマ区切りで複数の値を指定できます。
Sub SelectCaseMultiple()
Dim day As String
day = "土曜日"
Select Case day
Case "月曜日", "火曜日", "水曜日", "木曜日", "金曜日"
Debug.Print "平日です"
Case "土曜日", "日曜日"
Debug.Print "休日です"
Case Else
Debug.Print "不明な曜日です"
End Select
End Sub
' => 休日です
範囲指定(To キーワード)
To キーワードを使って、値の範囲を指定できます。
Sub SelectCaseTo()
Dim score As Long
score = 85
Select Case score
Case 90 To 100
Debug.Print "評価: A"
Case 80 To 89
Debug.Print "評価: B"
Case 70 To 79
Debug.Print "評価: C"
Case 60 To 69
Debug.Print "評価: D"
Case 0 To 59
Debug.Print "評価: F(不合格)"
Case Else
Debug.Print "スコアが範囲外です"
End Select
End Sub
' => 評価: B
比較演算子の使用(Is キーワード)
Is キーワードを使って、比較演算子による条件を指定することもできます。
Sub SelectCaseIs()
Dim temperature As Long
temperature = 35
Select Case temperature
Case Is >= 35
Debug.Print "猛暑日です"
Case Is >= 30
Debug.Print "真夏日です"
Case Is >= 25
Debug.Print "夏日です"
Case Is >= 0
Debug.Print "通常の気温です"
Case Is < 0
Debug.Print "氷点下です"
End Select
End Sub
' => 猛暑日です
複合条件の組み合わせ
To と Is、複数値を1つの Case で組み合わせることもできます。
Sub SelectCaseCombined()
Dim month As Long
month = 8
Select Case month
Case 3, 4, 5
Debug.Print "春"
Case 6 To 8
Debug.Print "夏"
Case 9, 10, 11
Debug.Print "秋"
Case 12, 1, 2
Debug.Print "冬"
Case Else
Debug.Print "不正な月です"
End Select
End Sub
' => 夏
Select Case で文字列を扱う
Sub SelectCaseString()
Dim extension As String
extension = LCase(Right("report.xlsx", Len("report.xlsx") - InStrRev("report.xlsx", ".")))
Select Case extension
Case "xlsx", "xls", "xlsm"
Debug.Print "Excel ファイルです"
Case "docx", "doc"
Debug.Print "Word ファイルです"
Case "pptx", "ppt"
Debug.Print "PowerPoint ファイルです"
Case "pdf"
Debug.Print "PDF ファイルです"
Case "csv", "txt"
Debug.Print "テキストファイルです"
Case Else
Debug.Print "その他のファイル形式です"
End Select
End Sub
' => Excel ファイルです
Select Case で文字列を比較する場合、VBA は既定で大文字・小文字を区別します。事前に LCase や UCase で統一しておくと安全です。モジュールの先頭に Option Compare Text を記述すると、大文字・小文字を区別しない比較になります。
If 文と Select Case の使い分け
比較表
| 特徴 | If 文 | Select Case |
|---|---|---|
| 判定対象 | 複数の変数・式を自由に判定 | 1つの式の値に対して判定 |
| 複雑な条件 | ○ And/Or で柔軟に組み合わせ | △ 単一の値に対する比較が中心 |
| 値の列挙 | △ ElseIf の繰り返しが必要 | ○ カンマ区切りで簡潔に書ける |
| 範囲指定 | ○ >= <= で指定可能 | ○ To キーワードで簡潔に指定 |
| 可読性(分岐が多い場合) | △ 長くなりがち | ○ 構造化されて読みやすい |
| パフォーマンス | ほぼ同等 | ほぼ同等 |
使い分けの基準
If 文が適しているケース:
- 複数の異なる変数を条件に含む場合
AndやOrで複雑な条件を組み合わせる場合- True/False の2択の場合
- オブジェクトの状態(
Is Nothingなど)を判定する場合
Select Case が適しているケース:
- 1つの値に対して3つ以上の分岐がある場合
- 値の列挙で判定する場合(曜日、月、ランク等)
- 数値の範囲で分岐する場合
- コードの可読性を重視する場合
' ○ If 文が適しているケース:複数の変数を条件に含む
Sub WhenToUseIf()
Dim age As Long
Dim income As Currency
Dim isStudent As Boolean
age = 25
income = 3000000
isStudent = False
If age < 18 Then
Debug.Print "未成年プラン"
ElseIf isStudent Then
Debug.Print "学生プラン"
ElseIf income >= 5000000 Then
Debug.Print "プレミアムプラン"
Else
Debug.Print "標準プラン"
End If
End Sub
' ○ Select Case が適しているケース:1つの値に対する複数分岐
Sub WhenToUseSelect()
Dim statusCode As Long
statusCode = 404
Select Case statusCode
Case 200
Debug.Print "成功"
Case 301
Debug.Print "リダイレクト"
Case 400
Debug.Print "リクエストエラー"
Case 401
Debug.Print "認証エラー"
Case 403
Debug.Print "アクセス禁止"
Case 404
Debug.Print "ページが見つかりません"
Case 500 To 599
Debug.Print "サーバーエラー"
Case Else
Debug.Print "不明なステータスコード: " & statusCode
End Select
End Sub
実践的な活用例
例1:セルの値に応じた色分け
Option Explicit
Sub ColorByScore()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("成績表")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 2 To lastRow ' 2行目から(1行目はヘッダー)
Dim score As Variant
score = ws.Cells(i, 2).Value ' B列がスコア
If Not IsNumeric(score) Then
' 数値でない場合はスキップ
ws.Cells(i, 2).Interior.Color = RGB(200, 200, 200) ' グレー
Else
Select Case CLng(score)
Case 90 To 100
ws.Cells(i, 2).Interior.Color = RGB(144, 238, 144) ' 緑
Case 70 To 89
ws.Cells(i, 2).Interior.Color = RGB(173, 216, 230) ' 水色
Case 60 To 69
ws.Cells(i, 2).Interior.Color = RGB(255, 255, 153) ' 黄色
Case 0 To 59
ws.Cells(i, 2).Interior.Color = RGB(255, 182, 193) ' ピンク
End Select
End If
Next i
Set ws = Nothing
End Sub
例2:入力値のバリデーション
Option Explicit
Sub ValidateInput()
Dim userName As String
Dim userAge As Variant
Dim userEmail As String
userName = InputBox("名前を入力してください")
userAge = InputBox("年齢を入力してください")
userEmail = InputBox("メールアドレスを入力してください")
' 名前のチェック
If userName = "" Then
MsgBox "名前が入力されていません", vbExclamation
Exit Sub
End If
' 年齢のチェック
If Not IsNumeric(userAge) Then
MsgBox "年齢は数値で入力してください", vbExclamation
Exit Sub
End If
If CLng(userAge) < 0 Or CLng(userAge) > 150 Then
MsgBox "正しい年齢を入力してください", vbExclamation
Exit Sub
End If
' メールアドレスの簡易チェック
If InStr(userEmail, "@") = 0 Or InStr(userEmail, ".") = 0 Then
MsgBox "正しいメールアドレスを入力してください", vbExclamation
Exit Sub
End If
' すべてのチェックを通過
MsgBox "登録完了!" & vbCrLf & _
"名前: " & userName & vbCrLf & _
"年齢: " & userAge & vbCrLf & _
"メール: " & userEmail, vbInformation
End Sub
例3:月末処理の判定
Option Explicit
Sub MonthEndProcess()
Dim targetDate As Date
targetDate = Date ' 今日の日付
Dim currentMonth As Long
currentMonth = Month(targetDate)
' 四半期末かどうかの判定
Dim isQuarterEnd As Boolean
Select Case currentMonth
Case 3, 6, 9, 12
isQuarterEnd = True
Case Else
isQuarterEnd = False
End Select
' 処理の分岐
If isQuarterEnd Then
Debug.Print "四半期末処理を実行します"
' 四半期レポートの生成など
If currentMonth = 3 Then
Debug.Print "→ 年度末処理も実行します"
' 年度末固有の処理
End If
Else
Debug.Print "通常の月末処理を実行します"
End If
End Sub
注意点とよくある間違い
1. 等価比較の演算子は =(== ではない)
他のプログラミング言語から来た方が間違いやすいポイントです。VBA では等価比較に = を使います。
' ○ 正しい
If score = 100 Then Debug.Print "満点"
' × 間違い(VBA ではエラーになる)
' If score == 100 Then Debug.Print "満点"
2. 文字列比較と大文字・小文字
VBA の文字列比較は既定で大文字・小文字を区別します。
Sub StringComparison()
Dim answer As String
answer = "Yes"
' 大文字・小文字を区別するため、以下は False
If answer = "yes" Then
Debug.Print "一致" ' 実行されない
End If
' 対策1: LCase で統一してから比較
If LCase(answer) = "yes" Then
Debug.Print "一致(LCase)" ' => 一致(LCase)
End If
' 対策2: UCase で統一してから比較
If UCase(answer) = "YES" Then
Debug.Print "一致(UCase)" ' => 一致(UCase)
End If
End Sub
モジュールの先頭に Option Compare Text を記述すると、そのモジュール内の文字列比較がすべて大文字・小文字を区別しなくなります。
3. Nothing の比較には Is を使う
オブジェクト変数が Nothing かどうかを判定する場合は、= ではなく Is を使用します。
Sub NothingComparison()
Dim ws As Worksheet
Set ws = Nothing
' ○ 正しい
If ws Is Nothing Then
Debug.Print "シートが設定されていません"
End If
' × 間違い(実行時エラーになる)
' If ws = Nothing Then
End Sub
4. Select Case での落とし穴
Sub SelectCasePitfall()
Dim value As Variant
value = "100" ' 文字列の "100"
' 文字列と数値は別物!
Select Case value
Case 100
Debug.Print "数値の100" ' マッチしない場合がある
Case "100"
Debug.Print "文字列の100" ' こちらにマッチ
End Select
' 型を統一してから比較するのが安全
If IsNumeric(value) Then
Select Case CLng(value)
Case 100
Debug.Print "確実に数値の100"
End Select
End If
End Sub
練習問題
まとめ
- If 文は VBA で最も基本的な条件分岐。
If...Then...End Ifの構文を基本にする - ElseIf で3つ以上の分岐が可能。条件は上から順に評価される
- Select Case は1つの値に対して複数の分岐がある場合に使用し、
To(範囲)、Is(比較)、カンマ区切り(複数値)を組み合わせて柔軟に条件を指定できる - 比較演算子(
=、<>、>、<)と論理演算子(And、Or、Not)を使いこなすことが条件分岐の鍵 - ネストが深くなる場合はガード節パターンで
Exit Subを使い、可読性を保つ - 文字列比較では大文字・小文字の区別に注意する(
LCase/UCaseで統一) - オブジェクトの
Nothing判定には=ではなくIsを使用する