VBAでSelect Case文を使っていると、「1つのCaseで複数の処理を実行したい」「条件ごとにいくつもの命令を書いても問題ないのか」と疑問に思うことはありませんか。
実際の業務では、条件に応じてセルへ値を入力するだけでなく、色を変更したり、メッセージを表示したり、別のプロシージャを呼び出したりするなど、複数の処理をまとめて実行するケースがよくあります。
Select Case文は、このような複数処理とも非常に相性が良く、適切に構成することで読みやすく保守しやすいコードになります。
この記事では、Select Case文で複数処理を実行する基本から、実務で保守しやすいコードを書くポイントまで解説します。
✅ Select Case文では複数の処理を書ける
Select Case文は、Caseごとに1行しか書けないと思われがちですが、そのような制限はありません。
Caseに一致したあとであれば、必要な処理を何行でも記述できます。
例えば、
- セルへ値を書き込む
- 背景色を変更する
- メッセージを表示する
- 別の処理を呼び出す
- 変数へ値を代入する
これらを1つのCase内へまとめて記述できます。
そのため、条件ごとに一連の処理を整理しやすくなります。
・Caseごとに複数行記述できる
最も基本的な書き方は次のようになります。
Sub Sample_SelectCaseMultiple()
Dim score As Long
score = 85
Select Case score
Case Is >= 80
MsgBox "合格です"
Range("A1").Value = "合格"
Range("A1").Interior.Color = RGB(198, 239, 206)
Case Else
MsgBox "不合格です"
Range("A1").Value = "不合格"
End Select
End Sub
このように、Caseへ一致したあとであれば、複数の命令を順番に実行できます。
✅ 実務では処理をまとめることで読みやすくなる
複数処理を書けるからといって、すべての処理を1つのCaseへ詰め込むのが良いとは限りません。
実務では、「条件ごとの役割」が分かるように処理をまとめることが重要です。
例えば、
- 判定
- データ更新
- 書式変更
- メッセージ表示
といった流れを意識すると、後からコードを見返したときにも理解しやすくなります。
特に業務マクロは、数か月後に修正することも珍しくありません。
読みやすい構成にしておくことで、仕様変更にも対応しやすくなります。
・処理のまとまりを意識したコードを書く
例えば受注ステータスによって処理を切り替える場合を考えてみましょう。
単にセルへ文字を入力するだけでなく、担当者への通知や色分けなどをまとめて実行するケースがあります。
このような場合は、処理の流れが分かるように記述すると保守しやすくなります。
・保守しやすい構成を意識したサンプル
単に「動くコード」を書くのではなく、あとから仕様変更しやすい構成にしておくことが重要です。
例えば、処理対象や変数名を分かりやすくし、コメントで処理の意図を補足すると、別の担当者が見ても理解しやすくなります。
Sub UpdateOrderStatus()
'=========================================
' 注文状況に応じて表示内容を更新する
'=========================================
Dim orderStatus As String
Dim targetWorksheet As Worksheet
Set targetWorksheet = Worksheets("受注一覧")
orderStatus = targetWorksheet.Range("B2").Value
Select Case orderStatus
Case "受付"
' ステータス表示
targetWorksheet.Range("C2").Value = "受付済"
' 背景色を設定
targetWorksheet.Range("C2").Interior.Color = RGB(255, 255, 153)
' 確認メッセージ
MsgBox "受付処理を実行しました。"
Case "発送"
targetWorksheet.Range("C2").Value = "発送済"
targetWorksheet.Range("C2").Interior.Color = RGB(198, 239, 206)
MsgBox "発送処理を実行しました。"
End Select
End Sub
・ このような書き方をおすすめする理由
同じ処理は、SelectやActivateを多用したコードでも実現できます。
しかし、対象シートを明示した変数を通して処理を行うことで、アクティブシートが変わっても意図しないセルを操作する心配がありません。
また、targetWorksheetという名前を付けることで、「どのシートを操作しているのか」が一目で分かります。
さらに、コメントを「何をしているか」ではなく、「なぜこの処理が必要なのか」という観点で記述しておくと、数か月後の修正や他の担当者への引き継ぎでも理解しやすくなります。
業務マクロでは、一度作成したコードを何度も修正・流用することが多いため、読みやすさを意識した構成が結果的に保守コストの削減につながります。
✅ Caseごとに別プロシージャを呼び出す方法
Select Case文の中へ複数の処理を書き続けると、条件が増えるほどコード全体が長くなります。
最初は読みやすくても、後から入力処理、書式変更、メッセージ表示、ファイル保存などが追加されると、1つのCaseだけで何十行にもなることがあります。
このような場合は、Caseの中にすべてを書くのではなく、処理ごとに別のプロシージャへ分ける方法が有効です。
Select Case文には「どの処理を実行するか」という判断だけを担当させ、実際の処理は別のSubプロシージャへ任せます。
・条件分岐と実際の処理を分けて整理する
次の例では、注文状況に応じて異なるプロシージャを呼び出します。
Option Explicit
Sub UpdateOrderStatus()
Dim targetWorksheet As Worksheet
Dim orderStatus As String
Set targetWorksheet = ThisWorkbook.Worksheets("受注一覧")
orderStatus = Trim$(CStr(targetWorksheet.Range("B2").Value))
Select Case orderStatus
Case "受付"
ProcessOrderReceived targetWorksheet
Case "発送"
ProcessOrderShipped targetWorksheet
Case "キャンセル"
ProcessOrderCancelled targetWorksheet
Case Else
MsgBox "対応していない注文状況です。", vbExclamation
End Select
End Sub
Private Sub ProcessOrderReceived(ByVal targetWorksheet As Worksheet)
With targetWorksheet.Range("C2")
.Value = "受付済"
.Interior.Color = RGB(255, 255, 153)
End With
MsgBox "受付処理を実行しました。", vbInformation
End Sub
Private Sub ProcessOrderShipped(ByVal targetWorksheet As Worksheet)
With targetWorksheet.Range("C2")
.Value = "発送済"
.Interior.Color = RGB(198, 239, 206)
End With
MsgBox "発送処理を実行しました。", vbInformation
End Sub
Private Sub ProcessOrderCancelled(ByVal targetWorksheet As Worksheet)
With targetWorksheet.Range("C2")
.Value = "キャンセル"
.Interior.Color = RGB(255, 199, 206)
End With
MsgBox "キャンセル処理を実行しました。", vbExclamation
End Sub
この構成では、UpdateOrderStatusは注文状況を判断する役割に集中しています。
受付、発送、キャンセルごとの処理は、それぞれ独立したプロシージャへ分けています。
Select Case文の中が長くなってきた場合は、処理をどの単位で分けるかが重要です。プロシージャを分割する判断基準については、【VBA】プロシージャの分ける基準とは?|迷わない設計ルールと実務での考え方を徹底解説で詳しく解説しています。
✅ 処理を分けると仕様変更へ対応しやすくなる
処理を別プロシージャへ分ける最大のメリットは、修正範囲を限定できることです。
例えば、発送時だけ次の処理を追加したいとします。
- 発送日を記録する
- 担当者名を入力する
- 完了フォルダーへファイルを保存する
- メール送信用データを作成する
すべてをSelect Case文へ直接書いていると、分岐全体が長くなり、どこまでが発送処理なのか分かりにくくなります。
一方、ProcessOrderShippedへ分けておけば、発送に関する変更はそのプロシージャだけを確認すれば済みます。
別のCaseを誤って変更する危険も減らせます。
・引数で対象シートを渡す理由
先ほどのコードでは、各プロシージャへtargetWorksheetを引数として渡しています。
ProcessOrderShipped targetWorksheet
プロシージャの中で毎回次のようにシートを取得することもできます。
Set targetWorksheet = ThisWorkbook.Worksheets("受注一覧")
しかし、同じシートを複数のプロシージャで利用する場合は、最初に取得したWorksheetオブジェクトを渡す方が、処理対象を統一しやすくなります。
また、将来「受注一覧」以外のシートでも同じ処理を使いたくなった場合に、対象シートを差し替えやすくなります。
処理対象を引数として受け取る設計は、再利用性を高めるうえでも有効です。
別プロシージャの呼び出し方や、引数を渡して処理を再利用する基本については、【VBA】標準モジュールの呼び出し方法とは|Sub・Functionの使い分けと実務設計も参考にしてください。
処理を分割するときは、SubとFunctionのどちらを使うかも重要です。それぞれの役割や使い分けについては、【VBA】SubとFunctionの違いとは?役割・使い分け・設計基準を徹底解説で詳しく解説しています。
✅ Select Caseが長くなったときの整理方法
Caseの数が増えると、条件分岐そのものが読みにくくなることがあります。
その場合は、次のポイントを確認します。
- Caseの並び順に意味があるか
- 同じ処理を繰り返していないか
- 1つのCaseへ責任を持たせすぎていないか
- Case Elseが用意されているか
- 条件判定と実処理を分離できないか
条件が増えたときは、単にコードを追加するのではなく、処理全体の役割を整理することが重要です。
・共通処理はSelect Caseの外へ出す
複数のCaseで同じ処理を繰り返している場合は、その処理を分岐の外へ出せないか検討します。
例えば、どのステータスでも最後に更新日時を記録する場合、各Caseへ同じコードを書く必要はありません。
Sub UpdateOrderStatusWithTimestamp()
Dim targetWorksheet As Worksheet
Dim orderStatus As String
Set targetWorksheet = ThisWorkbook.Worksheets("受注一覧")
orderStatus = Trim$(CStr(targetWorksheet.Range("B2").Value))
Select Case orderStatus
Case "受付"
ProcessOrderReceived targetWorksheet
Case "発送"
ProcessOrderShipped targetWorksheet
Case "キャンセル"
ProcessOrderCancelled targetWorksheet
Case Else
MsgBox "対応していない注文状況です。", vbExclamation
Exit Sub
End Select
' 正常に処理できた場合だけ更新日時を記録する
targetWorksheet.Range("D2").Value = Now
End Sub
更新日時の記録を各Caseへ書くと、どこか1か所だけ追加し忘れる可能性があります。
共通処理を分岐の外へまとめることで、重複を減らし、仕様変更時の修正漏れも防ぎやすくなります。
複数の条件で同じ処理を実行したい場合は、Caseをまとめて記述することで、重複を減らしてコードを見やすくできます。詳しい書き方は【VBA】Select Caseで複数条件を判定する方法|Caseをまとめて保守性を高める実務テクニックをご覧ください。
✅ 複数処理を書くときによくある注意点
Select Case文で複数処理を行う場合は、処理の順番にも注意が必要です。
例えば、セルを書き換えてから判定に使おうとすると、元の値を失ってしまうことがあります。
また、途中でエラーが発生すると、それ以降の処理は実行されません。
複数処理を安全に実行するためには、どの順番で処理すべきかをあらかじめ整理しておきましょう。
・元の値を先に変数へ保存する
判定対象のセルを処理途中で変更する場合は、最初に値を変数へ保存します。
Dim orderStatus As String
orderStatus = Trim$(CStr(targetWorksheet.Range("B2").Value))
その後は、セルではなくorderStatusを使って判定します。
これにより、処理途中でB2セルの値が変わっても、判定条件が影響を受けません。
・Case Elseを省略しない
実務データには、想定していない値が入力されることがあります。
例えば、「発送」の代わりに「発送済」や「 発送 」と入力されているケースです。
Case Elseがない場合、どの条件にも一致せず、何も処理されないまま終了します。
Case Else
MsgBox "注文状況を確認してください。", vbExclamation
エラーにならず静かに終了する処理は、原因の特定が難しくなります。
想定外の値を検出できるよう、原則としてCase Elseを設けるのがおすすめです。
・前後の空白を取り除いてから判定する
文字列を判定する場合は、セルに余分な空白が含まれている可能性があります。
次のようにTrim$関数を使うことで、前後の半角スペースを除去できます。
orderStatus = Trim$(CStr(targetWorksheet.Range("B2").Value))
ただし、Trim$では全角スペースを削除できません。
全角スペースも想定される場合は、次のように置換します。
orderStatus = Replace( _
Trim$(CStr(targetWorksheet.Range("B2").Value)), _
" ", _
vbNullString _
)
業務データでは、見た目が同じでも余分な空白によって条件に一致しないケースがあるため、入力値を整えてから判定すると安全です。
条件によっては処理を実行せず、そのまま次へ進めたい場合もあります。Select Case文で「何もしない条件」を安全に作る方法については、【VBA】Select Case文で何もしない条件を作る方法|処理をスキップする書き方と注意点で解説しています。
✅ If文を重ねるよりSelect Caseが向いている場面
複数条件の処理は、If...ElseIfでも実装できます。
If orderStatus = "受付" Then
ProcessOrderReceived targetWorksheet
ElseIf orderStatus = "発送" Then
ProcessOrderShipped targetWorksheet
ElseIf orderStatus = "キャンセル" Then
ProcessOrderCancelled targetWorksheet
Else
MsgBox "対応していない注文状況です。", vbExclamation
End If
条件が少ない場合は、If文でも問題ありません。
ただし、同じ変数の値を複数パターンに分けて処理する場合は、Select Caseの方が「何を基準に分岐しているか」が分かりやすくなります。
一方で、次のように複数の異なる条件を組み合わせる場合は、If文の方が自然です。
- ステータスが「発送」である
- 金額が10万円以上である
- 担当者が入力されている
Select CaseとIf文は優劣ではなく、条件の構造に応じて使い分けることが重要です。
1つの値だけでなく、複数の条件を組み合わせて判定したい場合は、【VBA】Select Case文でAND条件を使う方法|複数条件を見やすく分岐する実務テクニックも確認してみてください。
✅ ネストを増やしすぎないための考え方
Caseの中へさらにIf文や別のSelect Case文を書くこともできます。
しかし、条件分岐を何重にもすると、処理の流れが追いにくくなります。
Select Case orderStatus
Case "発送"
If shippingMethod = "宅配便" Then
If isRemoteArea Then
' 離島向け処理
Else
' 通常地域向け処理
End If
End If
End Select
このようなコードが増えてきた場合は、発送処理を別プロシージャへ分け、その中で配送方法を判断した方が整理しやすくなります。
メインのSelect Caseには大きな処理の流れだけを残し、細かな条件は呼び出し先へ任せるのがポイントです。
条件分岐のネストを増やさず、複数の変数をまとめて判定したい場合は、【VBA】Select Case文で複数の変数を判定する方法|実務で使える条件分岐の書き方も参考になります。
✅ まとめ:複数処理は役割ごとに整理する
Select Case文では、1つのCase内に複数の処理を自由に記述できます。
ただし、処理を増やすだけでは、後から読みにくく修正しにくいコードになってしまいます。
実務で利用する場合は、次の点を意識しましょう。
- Case内には複数行の処理を書ける
- 処理が長い場合は別プロシージャへ分ける
- Select Caseには条件判断の役割を持たせる
- 共通処理は分岐の外へまとめる
- 対象シートはWorksheet変数で明示する
- Case Elseで想定外の値を検出する
- 文字列は空白などを整えてから判定する
- ネストが深くなる場合は処理を分割する
- If文とSelect Caseを条件の構造によって使い分ける
Select Case文で大切なのは、単に複数の命令を書けることではありません。
条件ごとの処理を整理し、後から変更しやすい構成にすることで、業務マクロを長く安全に運用しやすくなります。