📊連載第5回！初心者のためのExcel VBA入門：IfとSelect Caseの正しい使い分け💫

# Excel VBAにおける条件分岐の基本

私はVBAの活用経験を通じて得た知識を整理し、共有する目的で記事を作成しているプログラミング歴1年半になるエンジニアです。
前回は、シート操作の基本とエラー処理について解説しました。今回は、VBAプログラミングの要となる条件分岐について詳しく説明していきます。条件分岐は、プログラムの処理を状況に応じて変更するための重要な機能です。特に業務効率化を目的としたVBAツールでは、ユーザーの入力や様々なデータの状態に応じて適切な処理を行う必要があり、条件分岐の理解は必須となります！

- [第1回: Excel VBAの基礎知識とセキュリティ設定](https://qiita.com/CodeLeaf/items/2d3e3185a725480fecc3)
- [第2回: Excel VBAの基本操作とオブジェクトの理解](https://qiita.com/CodeLeaf/items/c65d2531908aaf53649d)
- [第3回: Excel VBAにおける変数と定数の基本](https://qiita.com/CodeLeaf/items/3b36eddf7b5a8b5c5d99)
- [第4回: Excel VBAにおけるシート操作の基本とエラー処理](https://qiita.com/CodeLeaf/items/573fb7c61a756aa123ea)
- 第5回: Excel VBAにおける条件分岐（本記事）
- [第6回: Excel VBAにおける繰り返し処理の基本](https://qiita.com/CodeLeaf/items/5bc6c961a090e550bca9)
-  [第7回: Excel VBAにおける配列とFor Eachの活用](https://qiita.com/CodeLeaf/items/bdd8d488e49086219663)
- [第8回: Excel VBAにおけるFormulaとValueの使い分けとユーザー入力の取得](https://qiita.com/CodeLeaf/items/ecf312a53f7ede91bce9)
- [第9回: Excel VBAにおけるファイル操作とフォルダ管理の基本](https://qiita.com/CodeLeaf/items/e5520321e760364f6aae)
- [第10回: Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作](https://qiita.com/CodeLeaf/items/a78e9c7dd2b7e68f1d9e)
- [第11回: Excel VBAにおけるFileSystemObjectを活用した高度なファイル操作 応用編](https://qiita.com/CodeLeaf/items/4607db0151dddfb7f458)
- [第12回: Excel VBAにおけるStrConv関数の活用と応用テクニック](https://qiita.com/CodeLeaf/items/4f6358548bced6c047e0)
- [第13回: Excel VBAにおけるワークブックの安全な操作と管理テクニック](https://qiita.com/CodeLeaf/items/cf136898dd41c7dd5d9f)
- [第14回: Excel VBAにおけるFunction（関数）の作成と活用テクニック](https://qiita.com/CodeLeaf/items/a299f465bdcb1957e2be)
- [第15回: Excel VBAにおける配列を返す関数の作成と活用テクニック](https://qiita.com/CodeLeaf/items/711a93ac86b5c4150e13)
- [第16回: Excel VBAにおけるコレクションの活用と応用テクニック](https://qiita.com/CodeLeaf/items/6a28c65d5f8d19964664)
- [第17回: Excel VBAにおける辞書型（Dictionary）の活用と応用テクニック](https://qiita.com/CodeLeaf/items/5f85b2029e8d51eaa788)
- [第18回: Excel VBAにおけるEnum型を活用した関数設計と実装テクニック](https://qiita.com/CodeLeaf/items/3e91ef9556799d96aeea)
- [第19回: Excel VBAにおけるユーティリティ関数の作成と活用テクニック](https://qiita.com/CodeLeaf/items/bc156b6a9cadd7b10601)
- [第20回: Excel VBAにおける正規表現を活用したファイル名解析テクニック](https://qiita.com/CodeLeaf/items/86284498dee42aab731e)


## 目次
[はじめに](#はじめに)
[条件分岐](#条件分岐)
[If文](#if文)
[Select Case](#select-case)
[条件分岐の使い分け](#条件分岐の使い分け)
[まとめ](#まとめ)

## はじめに

条件分岐は、「もし〜なら」という処理をプログラムで実現する機能です。例えば、「もし売上が目標値を超えていれば、ボーナスを計算する」「もし在庫が不足していれば、発注処理を行う」といった業務ロジックを実装する際に不可欠な要素です。

VBAでは、`If` 文と `Select Case` 文が主に使用され、いずれも異なる条件に基づいてプログラムの流れを柔軟に制御するために用いられます。条件分岐を理解し活用することで、より複雑なVBAプログラムを作成することができ、業務の自動化を効率的に実現可能です。

## 条件分岐

条件分岐とは、プログラムの中で特定の条件を満たしているかどうかを判断し、その結果に応じて異なる処理を実行する仕組みのことです。

日常生活でも、「雨が降っていたら傘をさす」、「信号が青になったら横断歩道を渡る」といったように、無意識のうちに条件分岐を行っています。

VBAにおいても、条件分岐はプログラムの流れを変える重要な役割を担っています。 例えば、「セルの値が特定の数値以上なら文字の色を変える」、「入力されたデータによって処理内容を変える」といった処理を自動化することができます。

## If文
`If`文は、最も基本的な条件分岐の方法で、「もし～なら」という条件判断を行います。
与えられた条件が真または偽であるかを評価し、それに基づいて異なる処理を行います。

条件には比較演算子（ひかくえんざんし）を使用します。比較演算子とは、2つの値を比較して、その結果が「正しい (True)」か「間違っている (False)」かを判断するために使う記号のことです。

簡単に言うと、「AとBは等しい？」「AはBより大きい？」といった質問をコンピューターにするための道具です。

### 比較演算子の種類

| 演算子 | 意味 | 例 |
| ------ | --- | --- |
| =| 等しい | If A = B Then |
| <> | 等しくない | If A <> B Then |
| > | より大きい | If A > B Then |
| < | より小さい | If A < B Then |
| >= | 以上 | If A >= B Then |
| <= | 以下 | If A <= B Then |

### 基本構文

```vb
If 条件 Then
    ' 条件が真の場合に実行する処理
End If
```

### コード例
```vb
Dim num As Long
num = 10

If num > 5 Then
    MsgBox "numは5より大きいです"
End If
```

この例では、変数 `num` が5より大きい場合、メッセージボックスが表示されますが、5より小さい場合は、何も表示されません。

### If...Then...Elseステートメント

条件が真の場合と偽（False）の場合で、異なる処理を実行できます。
先程の例でいうと、5より小さい場合も、メッセージを表示したい場合に使用します。

```vb
If 条件 Then
    ' 条件が真の場合に実行する処理
Else
    ' 条件が偽の場合に実行する処理
End If
```

#### コード例

```vb
Dim num As Integer
num = 3

If num > 5 Then
    MsgBox "numは5より大きいです"
Else
    MsgBox "numは5以下です"
End If
```

この例では、変数 `num` が5より大きい場合は 「numは5より大きいです」、そうでない場合は 「numは5以下です"」というメッセージボックスが表示されます。


### If...Then...ElseIf...Elseステートメント

複数の条件を順に評価し、最初に真となる条件に対応する処理を実行します。

```vb
If 条件1 Then
    ' 条件1が真の場合に実行する処理
ElseIf 条件2 Then
    ' 条件2が真の場合に実行する処理
Else
    ' どの条件も真でない場合に実行する処理
End If
```

#### コード例
```vb
Dim スコア As Long
スコア = Range("A1").Value ' セルA1に入力された値を取得

' スコアに基づいて評価を表示
If スコア >= 80 Then
    MsgBox "優"
ElseIf スコア >= 60 Then
    MsgBox "可"
Else
    MsgBox "否"
End If
```

この例では、変数 `スコア` の値に応じて、"優"、"可"、"否" のいずれかのメッセージボックスが表示されます。
また、さらに条件を増やしたい場合は、その条件の数だけ `ElseIf` を記載します。

```vb
Dim スコア As Long
スコア = Range("A1").Value ' セルA1に入力された値を取得

' スコアに基づいて評価を表示
If スコア >= 80 Then
    MsgBox "優"
ElseIf スコア >= 70 Then
    MsgBox "良"
ElseIf スコア >= 60 Then
    MsgBox "可"
Else
    MsgBox "否"
End If
```

### ネストされたIf文

ネストされた `If` 文とは、`If` 文の中にさらに別の `If` 文を含めることです。これを「ネストされたIf文」や「入れ子のIf文」と呼びます。複数の条件を組み合わせて、より細かい条件分岐を作ることができます。例えば、「まず特定の条件Aが成り立つ場合に、さらに条件Bが成り立つか」というような場合に使います。

```vb
' 最初の条件：もし条件1が真なら
If 条件1 Then        

   ' 条件1が真の場合に実行される処理
    If 条件2 Then
        ' 条件1と条件2が両方とも真の場合に実行される処理

     ' 条件2が偽の場合
    Else          
        '条件1は真だが条件2が偽の場合に実行される処理      
    End If

'条件1が偽の場合  
Else               
    '条件1が偽の場合に実行される処理
End If
```

#### コード例

```vb
Dim 年齢 As Long
Dim 性別 As String

年齢 = Range("A1").Value '年齢をセルA1から取得
性別 = Range("B1").Value '性別をセルB1から取得

If 性別 = "男性" Then
    ' 最初の条件：性別が男性の場合
    If 年齢 >= 20 Then
        ' 2つ目の条件：20歳以上の場合
        MsgBox "成人男性です"
    Else
        ' 2つ目の条件：20歳未満の場合
        MsgBox "未成年男性です"
    End If
End If    
```

この例では、変数 `性別 `が「男性」かどうかをチェックします。もし「男性」なら、さらに、変数 `年齢` が20以上かどうかをチェックし「成人男性です」と表示します。もし20未満なら「未成年男性です」と表示します。

### 複合条件

複数の条件を組み合わせて、より複雑な条件判断を行うことができます。これには、And（かつ）、Or（または）、Not（～でない）といった論理演算子を使います。

- `And`: すべての条件が真の場合に真となる
- `Or`: どれか1つの条件が真の場合に真となる
- `Not`: 条件の結果を反転させる

```vb
If 条件A And 条件B Then
    ' 両方の条件が真の場合に実行する処理
End If

If 条件A Or 条件B Then
    ' どちらかの条件が真の場合に実行する処理
End If

If Not 条件A Then
    ' 条件Aが偽の場合に実行する処理
End If
```

#### コード例

```vb
Dim 数値A As Long
Dim 数値B As Long

' 例として数値を設定
数値A = 10 
数値B = 20 

' 数値Aが5より大きい、かつ数値Bが15より小さい
If 数値A > 5 And 数値B < 15 Then
    ' 数値Aは5より大きいが、数値Bは15より大きいので、下記のメッセージは、表示されない
    MsgBox "数値Aは5より大きく、かつ数値Bは15より小さい"
End If

' 数値Aが5より大きい、または数値Bが15より小さい
If 数値A > 5 Or 数値B < 15 Then
    ' 数値Aは5より大きいため、数値Bは15より大きいが、下記のメッセージは、表示される
    MsgBox "数値Aは5より大きいか、数値Bは15より小さい"
End If

' 数値Aが15より大きくない（数値Aが15以下）
If Not 数値A > 15 Then
    ' 数値Aは15以下のため、下記のメッセージは、表示される
    MsgBox "数値Aは15以下です"
End If
```

#### より実践的な複合条件の例

```vb
Dim 年齢 As Long
Dim 性別 As String
Dim 会員 As Boolean

' セルに入力された値を取得
年齢 = Range("A1").Value
性別 = Range("B1").Value
会員 = Range("C1").Value

' 女性で65歳以上、または会員である場合に割引
If (性別 = "女性" And 年齢 >= 65) Or 会員 = True Then
    MsgBox "割引対象です"
End If
```

:::note info
### If文のポイント
- 必要に応じて`ElseIf`や`Else`を追加して条件を増やすことができる
- 条件が複数ある場合は、上から順に条件が評価され、最初に満たす条件が見つかった時点でその分岐に入る
- If文は、何重にもネスト（入れ子）にできる
- あまり深くネストするとコードが読みにくくなるため、注意が必要
- `And` 、`Or` 、`Not` を使うことで、より複雑な条件分岐が可能になる
- 条件を組み合わせることで、より細かい条件に対応できる
- 条件が多くなりすぎると分かりにくくなるので、必要に応じて分割することをお勧め
:::

## Select Case

`Select Case`は、1つの式や変数が取り得る複数の値に応じて、異なる処理を行う場合に使用します。`If-ElseIf` を多用する場合の代替として有効です。（コードをより簡潔にすることができる）

### 基本構文
```vb
Select Case 変数
    Case 値1
        ' 値1の場合の処理
    Case 値2
        ' 値2の場合の処理
    Case Else
        ' その他の場合の処理
End Select
```

### コード例
```vb
' 曜日の数値を格納する変数
Dim dayOfWeek As Long

' 例として数値を設定
dayOfWeek = 3 ' 1:日曜日, 2:月曜日, ..., 7:土曜日

' 曜日の数値に応じて対応する曜日名を表示
Select Case dayOfWeek
    Case 1
        MsgBox "日曜日"
    Case 2
        MsgBox "月曜日"
    Case 3
        MsgBox "火曜日"
    Case 4
        MsgBox "水曜日"
    Case 5
        MsgBox "木曜日"
    Case 6
        MsgBox "金曜日"
    Case 7
        MsgBox "土曜日"
    ' 1から7以外の値の場合
    Case Else
        MsgBox "無効な値です"
End Select
```

この例では、`dayOfWeek` の値に応じて、曜日を表示するメッセージボックスが表示されます。

### 複数の値を指定する場合

1つの条件に対して複数の値を指定したい場合は、カンマ（ `,` ）で区切って記述します。

```vb
' 成績を格納する変数
Dim grade As String

' 例としてAを代入
grade = "A"

' 成績に応じて判定結果を表示
Select Case grade
    Case "A", "B", "C" ' A、B、Cのいずれかの場合
        MsgBox "合格"
    Case "D", "E"      ' DまたはEの場合
        MsgBox "再試験"
    Case Else          ' 上記以外の場合
        MsgBox "不合格"
End Select
```

この例では、`grade` が"A"、"B"、"C"のいずれかの場合に"合格"、"D"、"E"のいずれかの場合に"再試験"、それ以外の場合に"不合格"と表示されます。

### 範囲で値を指定する場合

数値の範囲でケースを指定する場合は `To` 演算子を使用します。

```vb
' 点数を格納する変数
Dim score As Long

' 例として85点を代入
score = 85    

' 点数の範囲に応じて評価を表示
Select Case score
    Case 90 To 100 ' 90から100までの場合
        MsgBox "S"
    Case 80 To 89  ' 80から89までの場合
        MsgBox "A"
    Case 70 To 79  ' 70から79までの場合
        MsgBox "B"
    Case Else
        MsgBox "C"
End Select
```

この例では、`score`の値が90以上100以下の場合は「S」、80以上89以下の場合は「A」、70以上79以下の場合は「B」、それ以外の場合は「C」と表示します。

### 数値の大小を比較したい場合

数値の大小比較を行う場合は `Is` 演算子と比較演算子を組み合わせて使用します。 

```vb
' スコアを格納する変数
Dim スコア As Long

' セルA1に入力された値を取得
スコア = Range("A1").Value 

' スコアに基づいて評価を表示
Select Case スコア
    Case Is >= 80
        MsgBox "優"
    Case Is >= 70
        MsgBox "良"
    Case Is >= 60
        MsgBox "可"
    Case Else
        MsgBox "否"
End Select
```

この例では、変数 `スコア` の値に応じて、"優"、"良"、"可"、"否" のいずれかのメッセージボックスが表示されます。

### あいまい検索したい場合

文字列のパターンマッチング（文字列が特定のパターンに一致するか）を行う場合は `Like` 演算子とワイルドカード（*や?）を使用します。


#### ワイルドカードについて

ワイルドカードとは、文字列検索やパターンマッチングで使用する特殊文字のことです。

- `*`：0文字以上の任意の文字列
- `?`：任意の1文字
- `#`：任意の1桁の数字（0-9）
- [文字リスト]：指定した文字のいずれか1文字と一致
    - [A-Z]：AからZまでの任意の1文字
    - [0-9]：0から9までの任意の1文字
- [!文字リスト]：指定した文字以外のいずれか1文字と一致

:::note info
より詳しい情報は、Microsoft公式ドキュメントの[文字列の比較で使用されるワイルドカード文字](https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/wildcard-characters-used-in-string-comparisons)をご参照ください。
:::

##### ワイルドカードの使用例

| 使用例             | 意味（該当例）                                                                    |
| ------------------- | -------------------------------------------------------------------------------- |
| `*花*`               | 「花」を含む文字列（花束、花瓶、花火、桜の花、花より団子）                         |
| `花*`               | 「花」で始まる文字列（花束、花瓶、花火）                                         |
| `花?`               | 「花」で始まる2文字の文字列（花束）                                             |
| `*花`               | 「花」で終わる文字列（花火、桜の花）                                             |
| `???花`             | 「花」で終わる4文字の文字列（桜の花）                                             |
| `花#本`              |  「花」の後に1桁の数字、その後に「本」が続く文字列（花1本、花2本など）          |
| `花[園寺]`            | 「花園」「花寺」のいずれかと一致                                                   |
| `花[!園寺]`           | 「花園」「花寺」以外で「花」で始まる2文字の文字列と一致                               |
| `[春夏秋冬]花`         | 「春花」「夏花」「秋花」「冬花」のいずれかと一致                                   |
| `[!春夏秋冬]花`        | 「春花」「夏花」「秋花」「冬花」以外で「花」で終わる2文字の文字列と一致               |
| `202[0-3]-[0-1]#-*` | 2020年から2023年の間で、月が01月から12月の間で、任意の年月日（例：2021-04-01） | 

:::note info 
##### ワイルドカード使用時のポイント
複雑なワイルドカードの組み合わせは混乱の原因となるため、必要最小限の使用を心がけましょう。また、頻繁に使用するパターンは変数や定数として定義しておくと、コードの可読性が向上します。 
:::

##### コード例
```vb
' ファイル名を検索するための変数を宣言
Dim fileName As String

' 検索したいファイル名を設定
fileName = "Test123.txt"

' ファイル名のパターンをチェック
Select Case fileName
    Case Like "Test*"    ' Testで始まるファイル名かチェック
        MsgBox "ファイル名はTestで始まります"
        
    Case Like "*.txt"    ' 拡張子が.txtかチェック
        MsgBox "テキストファイルです"
        
    Case Like "???##*"   ' 3文字+2桁の数字で始まるファイル名かチェック
        MsgBox "3文字+2桁の数字で始まるファイルです"
        
    Case Like "*[A-Z]*"  ' 大文字のアルファベットを含むかチェック
        MsgBox "大文字のアルファベットを含むファイルです"
        
    Case Else            ' 上記のどのパターンにも一致しない場合
        MsgBox "どのパターンにも一致しませんでした"
End Select
```

:::note info
#### Select Caseのポイント
- 各`Case`は選択する基準である
- 複数の値をコンマで区切って1つの`Case`に含めることも可能
- 数値の範囲は `To` で指定
- 比較条件は `Is` で指定
- 文字列のあいまい検索（パターンマッチング）は `Like` で指定
- `Case Else` は、全ての `Case` に該当しない場合の処理を指定
:::

:::note warn
#### Select Case文使用時の注意点
- 比較する値の型は統一する
    ※ 文字列と数値を混在させると予期せぬ動作の原因に！
- Case Elseは可能な限り実装する
    ※ 想定外の値への対応を忘れずに！
- 複数の変数を同時に条件分岐することは、可読性の観点から非推奨！ 
    ※ 「年齢が20歳以上」かつ「性別が男性」のような複数条件の指定はIf文を使用！
:::

## 条件分岐の使い分け

`If` 文と `Select Case` 文はどちらも条件分岐に使用できますが、それぞれ得意な場面が異なります。

|                | If文                                                         | Select Case文                                                         |
| :------------ | :------------------------------------------------------------ | :---------------------------------------------------------------------- |
| 条件の数        | 複雑な条件、複数の条件を組み合わせる場合に適している               | 単純な条件、1つの変数に対する複数の選択肢がある場合に適している           |
| コードの簡潔さ | 条件が複雑になるとコードが冗長になりやすい                     | 単純な条件分岐ではコードが簡潔になる                                 |


### 具体的な例

- **If文が適している例**
    - 複数の条件を組み合わせて判定する場合（例：年齢が20歳以上で、かつ性別が男性の場合）
    - 条件が複雑で、`Select Case` 文では表現しにくい場合

    ```vb
    ' ✅ If文での実装（推奨）
    ' 【理由】
    ' - 複数の条件（年齢と性別）を組み合わせた判定に適している
    ' - コードの意図が分かりやすい
    If 年齢 >= 20 And 性別 = "男性" Then
        MsgBox "成人男性です"
    ElseIf 年齢 >= 20 And 性別 = "女性" Then
        MsgBox "成人女性です"
    Else
        MsgBox "未成年です"
    End If
    
    ' ❌ Select Case文での実装（非推奨）
    ' 【理由】
    ' - 単一の変数の値を元にした判定が基本のため、初心者がわかりにくい
    ' - コードの意図が分かりにくい (↓ 詳細）
    '   Select Case True を使って複雑な論理判定を行うと、If文と大差なくなり、
    '   書き方や理解の観点から冗長になってしまうため。
     Select Case True ' 冗長なコード
        Case 年齢 >= 20 And 性別 = "男性"
            MsgBox "成人男性です"
        Case 年齢 >= 20 And 性別 = "女性"
            MsgBox "成人女性です"
        Case Else
            MsgBox "未成年です"
    End Select
    ```
    
- **Select Case文が適している例**
    - 1つの変数の値によって複数の処理に分岐する場合（例：曜日によって異なる処理を行う場合）
    - 条件が単純で、`Select Case` 文で表現しやすい場合

    ```vb
    ' ✅ Select Case文での実装（推奨）
    ' 【理由】
    ' - コードが簡潔で読みやすい
    ' - 条件の追加・変更が容易
    ' - デバッグが簡単
    Select Case 曜日
        Case "月", "火", "水", "木", "金"
            MsgBox "平日です"
        Case "土", "日"
            MsgBox "休日です"
        Case Else
            MsgBox "無効な曜日です"
    End Select
    
    ' ❌ If文での実装（非推奨）
    ' 【理由】
    ' - 同じ変数（曜日）を何度も書く必要がある
    ' - コードが長くなる
    ' - 条件を追加する際にミスが起きやすい
    If 曜日 = "月" Or 曜日 = "火" Or 曜日 = "水" Or 曜日 = "木" Or 曜日 = "金" Then
        MsgBox "平日です"
    ElseIf 曜日 = "土" Or 曜日 = "日" Then
        MsgBox "休日です"
    Else
        MsgBox "無効な曜日です"
    End If
    ```

:::note info
### 使い分けのポイント
一般的には、条件が複雑な場合（複数の論理演算子を使用するなど）は `If` 文、単純な場合は `Select Case` 文を使用することが推奨されます。
:::

状況に応じて適切な条件分岐を使い分けることで、より効率的で可読性の高いVBAプログラムを作成することができます。

## まとめ

条件分岐は、VBAプログラミングにおいて処理の流れを制御する重要な要素です。`If`文と`Select Case`文は、それぞれの特徴を活かして使い分けることで、より効率的で保守性の高いプログラムを作成することができます。特に、複雑な条件判断には`If`文を、単一の変数に基づく複数の分岐には`Select Case`文を使用するという使い分けを意識することで、より読みやすく、メンテナンスしやすいコードを実現できます。また、エラー処理や想定外の入力への対応として、`Else`や`Case Else`を適切に実装することで、プログラムの信頼性を高めることができます。

もし記事の内容で不明な点や、より詳しく知りたい部分がありましたら、コメントでお知らせください。また、実務での条件分岐の活用例や、より効率的な実装方法など、皆様のノウハウもぜひ共有していただければ幸いです。

次回は、VBAにおけるループ処理（For文、Do文）について詳しく解説する予定です。繰り返し処理を理解することで、より効率的な自動化プログラムを作成できるようになります。どうぞお楽しみに！