VBAで条件によって処理を切り替える場合、最初に思い浮かぶのはIf文かもしれません。
条件が2つ程度であればIf~Elseでも十分ですが、ステータスや区分、数値の範囲など、判定する候補が増えてくるとコードが長くなり、条件の全体像を把握しにくくなります。
そのような場面で役立つのが、Select Case文です。
Select Case文を使うと、1つの値に対する複数の条件を上から順に整理して記述できます。文字列の一致判定だけでなく、複数候補、数値範囲、比較演算子を使った判定にも対応できます。
この記事では、Select Case文の基本構文から、文字列・数値・複数条件を判定する方法、Case Elseの役割、If文との使い分けまで、実務で保守しやすいコードを交えて解説します。
✅ VBAのSelect Case文とは
Select Case文は、1つの値を複数の条件と比較し、該当した条件に応じて処理を切り替える構文です。
たとえば、セルに入力されたステータスに応じて、次のように処理を分けられます。
- 「未処理」なら受付処理を行う
- 「処理中」なら確認メッセージを表示する
- 「処理済」なら何もしない
- それ以外なら入力エラーとして扱う
同じ処理はIf~ElseIfでも作成できますが、判定対象が1つに決まっている場合は、Select Case文の方が条件を一覧として確認しやすくなります。
Select Case文は、特に次のような処理に向いています。
- ステータスや区分による処理の切り替え
- 曜日や月ごとの処理
- 評価ランクの判定
- 金額や点数による段階判定
- 複数の候補を同じ処理へまとめる
- 想定外の値をエラーとして検出する
✅ Select Case文の基本構文
Select Case文の基本構文は次のとおりです。
Select Case 判定対象
Case 条件1
条件1に一致した場合の処理
Case 条件2
条件2に一致した場合の処理
Case Else
どの条件にも一致しなかった場合の処理
End Select
Select Caseの後ろには、判定したい値や変数を指定します。
各Caseには条件を記述し、一致したCaseの処理だけが実行されます。該当する処理が終了すると、残りのCaseは判定されず、End Selectの後へ進みます。
Case Elseは必須ではありませんが、想定外の値を検出するために、実務ではできるだけ記述することをおすすめします。
・基本の流れが分かる簡単なコード
次のコードでは、セルB2に入力されたステータスを判定します。
Option Explicit
Public Sub CheckOrderStatus()
Dim targetWorksheet As Worksheet
Dim orderStatus As String
Set targetWorksheet = ThisWorkbook.Worksheets("注文管理")
orderStatus = Trim$(CStr(targetWorksheet.Range("B2").Value))
Select Case orderStatus
Case "未処理"
MsgBox "注文はまだ処理されていません。", vbInformation
Case "処理中"
MsgBox "注文を処理しています。", vbInformation
Case "処理済"
MsgBox "注文処理は完了しています。", vbInformation
Case Else
MsgBox "ステータスの入力内容を確認してください。", vbExclamation
End Select
End Sub
・判定前に値を整えている理由
このコードでは、セルの値を直接Select Case文へ渡さず、orderStatusという変数へ格納しています。
また、CStrで文字列へ変換し、Trim$で前後のスペースを取り除いています。
判定対象を変数へ格納することで、「何を比較しているのか」が明確になります。後から入力元のセルが変わった場合も、値を取得する部分だけを修正できます。
セルの値を各Caseで何度も取得するより、値の取得と条件分岐を分けた方が、コードの流れを把握しやすくなります。
文字列の前後に不要なスペースがあると、見た目が同じでもCaseに一致しないことがあります。TrimとReplaceを使ったスペース削除の違いや使い分けは、【VBA】スペースを一括削除する方法|Replace関数・Trim関数の使い分けと実務活用で詳しく解説しています。
✅ 文字列をSelect Case文で判定する方法
Select Case文では、文字列をそのままCaseへ指定できます。
Select Case departmentName
Case "営業部"
' 営業部向けの処理
Case "総務部"
' 総務部向けの処理
Case "経理部"
' 経理部向けの処理
End Select
文字列の完全一致を判定する場合に、特に分かりやすい書き方です。
・部署ごとに出力先を切り替える実務例
Public Sub SetDepartmentOutput()
Dim targetWorksheet As Worksheet
Dim departmentName As String
Dim outputMessage As String
Set targetWorksheet = ThisWorkbook.Worksheets("社員情報")
departmentName = Trim$(CStr(targetWorksheet.Range("B2").Value))
Select Case departmentName
Case "営業部"
outputMessage = "営業実績シートへ出力します"
Case "総務部"
outputMessage = "管理台帳へ出力します"
Case "経理部"
outputMessage = "会計データへ出力します"
Case Else
outputMessage = "登録されていない部署です"
End Select
targetWorksheet.Range("C2").Value = outputMessage
End Sub
このコードでは、条件分岐の中で直接セルを何度も更新せず、結果をoutputMessageへ格納し、最後に1回だけ出力しています。
出力先が1つである場合は、このように「判定」と「出力」を分けると処理の重複を減らせます。
Select Case文で文字列を扱う場合は、完全一致だけでなく、複数候補の整理や表記ゆれへの対策も重要です。文字列判定を実務向けに詳しく確認したい方は、【VBA】Select Caseで文字列を判定する方法|複数条件を見やすく分岐する実務テクニックも参考にしてください。
✅ 複数の値を同じCaseで判定する方法
複数の条件で同じ処理を実行したい場合は、Caseの後ろへ条件をカンマ区切りで指定します。
Select Case orderStatus
Case "未処理", "保留"
MsgBox "確認が必要な注文です。"
Case "処理済", "取消"
MsgBox "追加処理は不要です。"
End Select
同じ処理を条件ごとに繰り返して書く必要がないため、コードを簡潔にできます。
・同じ意味を持つ条件はまとめて管理する
Public Sub CheckAttendanceStatus()
Dim attendanceStatus As String
attendanceStatus = Trim$(CStr( _
ThisWorkbook.Worksheets("勤怠").Range("B2").Value _
))
Select Case attendanceStatus
Case "出勤", "在宅勤務", "出張"
MsgBox "勤務日として集計します。", vbInformation
Case "有給", "特別休暇"
MsgBox "休暇日として集計します。", vbInformation
Case "欠勤", "未入力"
MsgBox "勤怠内容を確認してください。", vbExclamation
Case Else
MsgBox "未登録の勤怠区分です。", vbExclamation
End Select
End Sub
複数条件をまとめるときは、「同じ処理になる」という理由だけでなく、業務上の意味も近い条件をまとめると読みやすくなります。
理由が異なる条件を無理にまとめると、仕様変更時に分離が必要になるため注意しましょう。
複数の値で同じ処理を実行する場合は、Caseをまとめることでコードの重複を減らせます。条件の整理方法や、まとめすぎを防ぐ実務上の考え方は、【VBA】Select Caseで複数条件を判定する方法|Caseをまとめて保守性を高める実務テクニックで詳しく解説しています。
✅ 数値の範囲をSelect Case文で判定する方法
Select Case文では、Toを使って数値の範囲を判定できます。
Select Case score
Case 0 To 59
result = "不合格"
Case 60 To 79
result = "合格"
Case 80 To 100
result = "優秀"
End Select
点数、年齢、金額、在庫数などを段階的に分ける処理に適しています。
・点数から評価を判定するコード
Public Sub EvaluateScore()
Dim targetWorksheet As Worksheet
Dim scoreValue As Variant
Dim evaluationResult As String
Set targetWorksheet = ThisWorkbook.Worksheets("評価")
scoreValue = targetWorksheet.Range("B2").Value
If Not IsNumeric(scoreValue) Then
MsgBox "点数には数値を入力してください。", vbExclamation
Exit Sub
End If
Select Case CDbl(scoreValue)
Case 0 To 59
evaluationResult = "要改善"
Case 60 To 79
evaluationResult = "標準"
Case 80 To 89
evaluationResult = "良好"
Case 90 To 100
evaluationResult = "優秀"
Case Else
evaluationResult = "点数の範囲を確認してください"
End Select
targetWorksheet.Range("C2").Value = evaluationResult
End Sub
・数値判定の前に入力値を確認する
このコードでは、Select Case文を実行する前にIsNumericで数値かどうかを確認しています。
数値を想定しているセルに文字列や空白が入力される可能性がある場合、いきなり数値として判定すると、意図しない結果やエラーにつながります。
また、Case Elseを用意することで、マイナス値や100を超える値も検出できます。
条件分岐だけでなく、判定前後の入力チェックまで含めることで、実務で使いやすいコードになります。
数値以外が入力されている場合など、条件分岐を行う前に処理を終了させたいときはExit Subが役立ちます。入力チェックと処理中断を安全に設計する方法は、【VBA】Exit Subの基本~実用的な使い方|処理制御と安全なマクロ設計を完全解説で詳しく解説しています。
✅ Case Isで比較条件を指定する方法
Case Isを使うと、「以上」「以下」「より大きい」といった比較条件を指定できます。
Select Case salesAmount
Case Is >= 1000000
salesRank = "A"
Case Is >= 500000
salesRank = "B"
Case Else
salesRank = "C"
End Select
この場合、条件は上から順番に判定されます。
100万円以上の値は最初のCaseに一致するため、次の50万円以上のCaseは実行されません。
・条件は厳しいものから並べる
Public Sub DetermineSalesRank()
Const HIGH_SALES_THRESHOLD As Currency = 1000000
Const MIDDLE_SALES_THRESHOLD As Currency = 500000
Dim salesAmount As Variant
Dim salesRank As String
salesAmount = ThisWorkbook.Worksheets("売上").Range("B2").Value
If Not IsNumeric(salesAmount) Then
MsgBox "売上金額を確認してください。", vbExclamation
Exit Sub
End If
Select Case CCur(salesAmount)
Case Is >= HIGH_SALES_THRESHOLD
salesRank = "Aランク"
Case Is >= MIDDLE_SALES_THRESHOLD
salesRank = "Bランク"
Case Is >= 0
salesRank = "Cランク"
Case Else
salesRank = "金額要確認"
End Select
ThisWorkbook.Worksheets("売上").Range("C2").Value = salesRank
End Sub
100万円以上の条件より先に50万円以上を記述すると、100万円以上の値も50万円以上に一致してしまいます。
段階判定では、上限の高い条件や限定範囲の狭い条件から順番に記述することが重要です。
また、基準額を定数にしておくと、後から金額条件が変更された場合も修正箇所を見つけやすくなります。
✅ Case Elseは想定外の値を検出するために使う
Case Elseは、どのCaseにも一致しなかった場合に実行されます。
構文上は省略できますが、業務データを扱う場合は、できるだけ記述する方が安全です。
Select Case paymentMethod
Case "現金"
' 現金処理
Case "振込"
' 振込処理
Case "カード"
' カード処理
Case Else
MsgBox "支払方法を確認してください。", vbExclamation
End Select
Case Elseがない場合、未登録の値や入力ミスがあっても、何も起こらずに処理が進むことがあります。
エラーを表示する、ログを残す、対象セルへ確認メッセージを出力するなど、想定外の状態を見逃さない仕組みを作りましょう。
・Case Elseで何もしない場合は理由を残す
業務上、該当しない値を意図的に無視したいこともあります。
Case Else
' 指定した区分以外は処理対象外のため何もしない
完全な空欄にすると、処理の書き忘れかどうか判断できません。
何もしないこと自体が仕様である場合は、理由が分かるコメントを残すことが大切です。
Case Elseや特定のCaseで意図的に処理を行わない場合は、後続処理が実行されるかどうかにも注意が必要です。「何もしない条件」の安全な設計については、【VBA】Select Case文で何もしない条件を作る方法|処理をスキップする書き方と注意点で詳しく解説しています。
✅ Select Case文をループ処理で使う実務例
Select Case文は、一覧表を1行ずつ処理するループとも相性がよい構文です。
次のコードでは、注文ステータスに応じて各行の処理を切り替えます。
・条件分岐と更新処理を分けた構成
Option Explicit
Private Const STATUS_COLUMN As String = "B"
Private Const RESULT_COLUMN As String = "C"
Private Const FIRST_DATA_ROW As Long = 2
Public Sub ProcessOrderList()
Dim targetWorksheet As Worksheet
Dim lastRow As Long
Dim currentRow As Long
Dim orderStatus As String
Set targetWorksheet = ThisWorkbook.Worksheets("注文管理")
lastRow = targetWorksheet.Cells( _
targetWorksheet.Rows.Count, STATUS_COLUMN _
).End(xlUp).Row
If lastRow < FIRST_DATA_ROW Then
MsgBox "処理対象のデータがありません。", vbInformation
Exit Sub
End If
For currentRow = FIRST_DATA_ROW To lastRow
orderStatus = Trim$(CStr( _
targetWorksheet.Cells(currentRow, STATUS_COLUMN).Value _
))
Select Case orderStatus
Case "未処理"
ProcessPendingOrder targetWorksheet, currentRow
Case "処理中"
targetWorksheet.Cells(currentRow, RESULT_COLUMN).Value = _
"処理中のため更新しません"
Case "処理済", "取消"
' 再処理を防ぐため何もしない
Case Else
targetWorksheet.Cells(currentRow, RESULT_COLUMN).Value = _
"ステータス要確認"
End Select
Next currentRow
End Sub
Private Sub ProcessPendingOrder( _
ByVal targetWorksheet As Worksheet, _
ByVal targetRow As Long _
)
With targetWorksheet
.Cells(targetRow, RESULT_COLUMN).Value = "処理完了"
.Cells(targetRow, STATUS_COLUMN).Value = "処理済"
End With
End Sub
・分岐の中へ処理を詰め込みすぎない
このコードでは、未処理データの更新をProcessPendingOrderへ分けています。
Select Case文の役割は、「どの処理を実行するか決めること」です。更新処理が長くなる場合は、別のSubやFunctionへ分けた方が、条件分岐の全体像を確認しやすくなります。
1つのCaseに数十行の処理を書くと、他の条件が見えにくくなり、修正時の影響範囲も判断しづらくなります。
処理を分割することで、条件の追加・削除と、実際の更新内容を別々に管理できます。
✅ Select Case文とIf文の違い
Select Case文とIf文は、どちらも条件分岐に使いますが、向いている場面が異なります。
| 比較項目 | Select Case文 | If文 |
|---|---|---|
| 判定対象 | 基本的に1つの値 | 複数の値や条件 |
| 候補が多い場合 | 見やすい | 長くなりやすい |
| 範囲判定 | To・Case Isで対応 | 比較演算子で対応 |
| AND・OR条件 | 書き方に工夫が必要 | 直接記述しやすい |
| 条件の自由度 | 比較的限定的 | 高い |
| 一覧性 | 高い | 条件が増えると低下しやすい |
・Select Case文が向いている場面
次のように、1つの値を複数候補と比較する場合です。
Select Case statusValue
Case "未処理"
Case "処理中"
Case "処理済"
End Select
・If文が向いている場面
複数の変数を組み合わせる場合です。
If salesAmount >= 1000000 And stockQuantity < 10 Then
' 売上と在庫の両方を判定する
End If
Select Case文ですべてを表現しようとすると、かえって複雑になる場合があります。
「Select Caseの方が優れている」「If文は使わない」と決めるのではなく、判定対象と条件の種類に応じて使い分けることが重要です。
Select Case文は1つの値を整理して判定するのに向いていますが、複数の条件を組み合わせたい場面もあります。Select CaseでAND条件を扱う方法や、If文との使い分けは、【VBA】Select Case文でAND条件を使う方法|複数条件を見やすく分岐する実務テクニックも参考になります。
✅ Select Case文でよくある間違い
Select Case文は読みやすい構文ですが、条件の書き方によっては意図しない結果になります。
・条件の順番を間違える
Select Case salesAmount
Case Is >= 500000
salesRank = "B"
Case Is >= 1000000
salesRank = "A"
End Select
この順番では、100万円以上も最初の「50万円以上」に一致するため、Aランクになりません。
大きい条件から小さい条件へ並べましょう。
・Case Elseを省略して入力ミスを見逃す
Case Elseがないと、どの条件にも一致しない値が静かに無視されます。
手入力や外部データを扱う場合は、Case Elseで警告やログ出力を行うと安全です。
・表記ゆれを考慮していない
「処理済」と「処理済 」は、末尾のスペースによって別の文字列として扱われます。
判定前にTrim$で前後のスペースを削除するなど、入力値を整えておきましょう。
・Case内へ処理を書きすぎる
条件ごとの処理が長いと、Select Case文の一覧性が失われます。
処理内容が増えた場合は、役割ごとにSubやFunctionへ分けると保守しやすくなります。
・文字列の大文字・小文字を意識していない
英字を比較する場合は、モジュール先頭のOption Compare設定などによって比較結果が変わることがあります。
大文字・小文字を区別したくない場合は、判定前にUCase$やLCase$で表記を統一する方法もあります。
英字の比較結果は、モジュール先頭に記述するOption Compare BinaryまたはOption Compare Textの設定によって変わる場合があります。比較ルールの違いと設定方法は、【VBA】Option Compareステートメントの使い方|Binary・Textの違いと設定方法で詳しく解説しています。
✅ 実務で保守しやすくするポイント
Select Case文を長く安全に使うためには、構文だけでなく設計も重要です。
・判定対象を意味の分かる変数へ格納する
セル参照をSelect Caseへ直接書くより、orderStatusやdepartmentNameなどの変数へ格納した方が、何を判定しているのか分かりやすくなります。
・条件値を定数として管理する
金額や点数の基準が変更される可能性がある場合は、定数へまとめます。
Const HIGH_SALES_THRESHOLD As Currency = 1000000
条件式へ数値を直接書くより、変更理由や用途が伝わりやすくなります。
・想定外の状態をCase Elseで拾う
Case Elseは単なる「その他」ではなく、入力ミスや未登録値を見つけるための安全装置として利用できます。
・分岐と実処理を分離する
Select Case文には処理の選択を担当させ、複雑な更新処理は別のプロシージャへ分けます。
条件と処理を分離すると、どちらか一方だけを変更しやすくなります。
・コメントは処理内容より理由を書く
次のようなコメントでは、コードを見れば内容が分かります。
' メッセージを表示する
MsgBox "処理済です"
実務では、なぜその処理が必要なのかを残す方が役立ちます。
' 二重更新を防ぐため、処理済みの場合は通知だけ行う
MsgBox "処理済です"
Select Case文はコロンを使って1行で記述することもできますが、短く書くことが必ずしも読みやすさにつながるとは限りません。1行記述の方法と、実務で使うべき場面については、【VBA】Select Caseを1行で書く方法|コロン(:)を使った簡潔な記述と実務判断で解説しています。
✅ まとめ
Select Case文は、1つの値を複数の条件と比較し、条件ごとに処理を切り替える構文です。
ステータス、区分、曜日、点数、金額など、判定候補が複数ある処理を整理して記述できます。
この記事のポイントは次のとおりです。
- Select Case文は1つの値を複数条件で判定するのに向いている
- 一致したCaseの処理だけが実行される
- 複数候補はカンマ区切りでまとめられる
- 数値範囲は
Toで指定できる - 以上・以下の判定には
Case Isを使う - 段階判定は厳しい条件から順番に記述する
- 想定外の値は
Case Elseで検出する - 判定前に空白やデータ型を確認する
- 処理が長い場合は別のSubやFunctionへ分ける
- 1つの値を比較するならSelect Case、複数条件ならIf文が使いやすい
- 条件値を定数にすると仕様変更へ対応しやすい
- コメントには「なぜその処理をするのか」を残す
Select Case文は、単にIf文を短く書き換えるための構文ではありません。
条件の全体像を一覧で把握し、追加や変更をしやすくするための設計手段です。判定対象、条件の順番、Case Elseの扱いを整理し、後から読み返しても処理の意図が分かるコードを目指しましょう。