【5分でVBA学習】マクロの記録の限界を越えた自動化の第一歩！「Ifステートメント」の使い方（後編） ～Excelフィルタリングツール コード解説 #7～

# 1. はじめに
ＡＲアドバンストテクノロジ株式会社（ＡＲＩ）の鈴木タクヤです。

今回はExcelフィルタリングツールのソースコード解説第7回です。

（ツールの詳細については以下の記事を、「Excelフィルタリングツール解説シリーズ」タグの記事一覧については以下の記事下部「5. 解説記事のリンク」をご参照ください。）

https://qiita.com/TakuyaSuzuki/items/75789a1cf0b3a7c31c0b

今回のテーマは __[解説第6回（前編）](https://qiita.com/TakuyaSuzuki/items/2bd2c757be640f252b89 "【5分でVBA学習】マクロの記録の限界を越えた自動化の第一歩！「Ifステートメント」の使い方（前編） ～Excelフィルタリングツール コード解説 #6～")__ に引き続き、「Ifステートメント」の使い方です。


# 2. ブール型（Boolean）

Ifと関連の深い変数のデータ型に __ブール型（Boolean）__ があります。これは真理値（真偽値）とよばれる、 __○：Trueか、×：False__ の2つの値のみのデータ型です。

__[真理値とは（「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典）](https://wa3.i-3-i.info/word16809.html "真理値とは | 分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典")__ 

「If ～ Then」の「～」の部分の条件式は、じつはこのブール型の変数で表すこともできます。というよりも、実はすべての条件式は __「正しい（真）」の場合は「True」、「誤り（偽）」の場合は「False」__ と、ブール型で評価されます。

```vb:Ifステートメントの使用例③
Sub a()
    Dim x As Boolean, msg As String
    x = True
    msg = "xの値は False です"
    
    If x Then
        msg = "xの値は True です"
    End If
    
    MsgBox msg
End Sub
```
この例ではブール型の変数 `x` にTrueを代入し、 `If x Then`というIfステートメントで条件分岐しています。Trueは __「正しい」__ という意味になるため、次の行でString型の変数 `msg` の値は「xの値は True です」に上書きされます。したがって実行結果は以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/c6797b17-ab11-43f5-5883-36b85f6ded70.png)

:::note
しれっと使用していますが __「Dim 変数1 As データ型, 変数2 As データ型, ・・・」__ と1行で複数の変数を宣言することができます。
:::

また、例③の `x = True` を __コメントアウト（後述）__ すると・・・
```vb:Ifステートメントの使用例③’
Sub a()

    Dim x As Boolean, msg As String
    'x = True　　　　　　　　　　　　　　👈コメントアウト（無効化）
    msg = "xの値は False です"
    
    If x Then
        msg = "xの値は True です"
    End If
    
    MsgBox msg

End Sub
```
↓実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/53040e50-9a1e-8c69-9132-290a1984bafa.png)

このように、 `x` に何も代入しないと上の例③’のIfステートメントはスキップされるため、ブール型の変数の初期値は __False__ であることが分かります。

:::note warn
しれっと使用かつ、実は今まで何度も登場していますが、VBAコードに __「'」（シングルクォート）__ が登場する場合、そこから行末まではプログラム上の命令ではなくただの「コメント」として扱われ、処理されません。コメントとして記述を無効化することを __「コメントアウト」__ と言います。
:::

# 3.よく使われるブール演算子（論理演算子）の紹介
__[ブール演算子とは（「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典）](https://wa3.i-3-i.info/word111036.html "ブール演算子とは | 分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典")__

## 3-1 And
__`And`__ は「○○かつ△△」の __「かつ」__ を表します。複数の条件式を `And` でつなぐと、すべての条件を満たす場合のみTrue（真）と判定され、1つでも条件を満たさなければFalse（偽）と判定されます。

以下の表をご覧ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/e93db757-8897-3e99-4d16-0f3e595d0455.png)
この記事の執筆時点で私は、LPICレベル1の資格取得のための学習中です。この資格の取得には101試験と102試験の両方に合格しないといけませんが、まだ101試験しか受けていません。

この表のExcelシートを表示している状態で以下のマクロを実行すると・・・
```vb:Ifステートメントの使用例④
Sub a()
    
    If Range("A2").Value = "合格" And Range("B2").Value = "合格" Then
        Range("C2").Value = "○"
    Else
        Range("C2").Value = "×"
    End If

End Sub
```
↓実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/c8ea82f4-8091-ebc9-36fe-c8b1334d34a6.png)
C2セルに「×」が付きました！（このままでは会社に受験料を請求できない・・・）

上の例の `Range()` はセルの範囲を表す __Rangeオブジェクト__ です。 `Range("A2")` のように単一のセルも表せます。 `.Value` は「～の値」を表します。

ここで注意が必要ですが、If ～ Then の間にある `Range("A2").Value = "合格"` は、「A2セルの値が『合格』である」という条件を表します。しかし、次の行の `Range("C2").Value = "○"` は「C2セルの値に『○』を設定する」という意味になります。 `=` には「左辺と右辺が等しい」、「左辺に右辺の値を代入・設定する」という2つの意味があります。

:::note
ちなみに上の例では `.Value` を省略することができます。
:::

https://excel-ubara.com/excelvba4/EXCEL246.html

## 3-2 Or
__`Or`__ は「○○または△△」の __「または」__ を表します。複数の条件式を `Or` でつなぐと、1つでも条件を満たせばTrue（真）と判定され、すべての条件を満さない場合のみFalse（偽）と判定されます。

マンガ「ONEPIECE」には海賊（や山賊）の指名手配書が登場しますが、そこに「DEAD OR ALIVE」と書かれています。これは「そいつを __仕留め__ ても __生け捕り__ でも、懸賞金を払うぜ」という意味です。
以下の表をご覧ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/80c791de-667e-87df-32de-e9db086a8986.png)
この例では「死亡」かつ「生存」という __シュレディンガーの猫[^1]__ みたいな状況はないと思いますが、今回は指名手配犯を生け捕りにしたとしましょう。

[^1]:シュレディンガーの猫：物理学者シュレディンガーの思考実験に登場する、生きながら死んでいる猫。気になる方はググって量子力学の世界を垣間見てきてください。

この表のシートを表示している状態で以下のマクロを実行すると・・・
```vb:Ifステートメントの使用例⑤
Sub a()
    
    If Range("A2").Value = "○" Or Range("B2").Value = "○" Then
        Range("C2").Value = "○"
    Else
        Range("C2").Value = "×"
    End If

End Sub
```
↓実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/fc48ad55-6a11-0e0e-cdb0-ff128bcb4037.png)
C2セルに「○」が付きました！（受験料より懸賞金を狙うべきか・・・）

## 3-3 Not
__`Not`__ は「○○でない」の __「でない」__ を表します。 `Not` の後ろの条件式の「True」か「False」かの評価を反転させます。
```vb:Ifステートメントの使用例⑥
Sub a()
    Dim x As Boolean, msg As String
    x = True
    msg = "「いいね」がほしい…"
    
    If Not x Then
        msg = "「いいね」ください"
    End If
    
    MsgBox msg
End Sub
```
↓実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/8f902c58-94d9-0dc1-a23c-9e2e83baaaad.png)
この例では冒頭でブール型の変数 `x` にTrueを代入し、Ifステートメントで `Not x` とすることでFalseになるため、変数 `msg` に "「いいね」ください" を代入する処理はスキップされます。

## 3-4 Excelフィルタリングツールにおける使用例
`And`、`Or` はFunctionプロシージャ `checkFormat` の以下の部分で登場します。
```vb:Excelフィルタリングツールより抜粋（流し見でOK）
    '英字部分が3桁の場合の整合性チェック
    If startingPositionOfRowNo = 4 Then
        If (Mid(cellReference, 1, 1) Like "[Y-Z]") _
            Or (Mid(cellReference, 1, 1) = "X" And Mid(cellReference, 2, 1) Like "[G-Z]") _
            Or (Mid(cellReference, 1, 1) = "X" And Mid(cellReference, 2, 1) = "F" And Mid(cellReference, 3, 1) Like "[E-Z]") _
            Then
            
            Call showFormatErrorMessage(3)
        End If
    End If
```
また `Not` は例えばSubプロシージャ `activateSheet` の以下の部分で登場します。
```vb:Excelフィルタリングツールより抜粋（流し見でOK）
If Not sheetExists Then
        MsgBox "シート「" & sheetName & "」が「" & wb.Name & "」に存在しません。"
        Call endMacro
    End If
```

# 4. おわりに
以上、前後編にわたる「Ifステートメント」の解説でした。
普段手作業で行っているExcelの編集作業を「マクロの記録」で保存し、「Ifステートメント」を使用しながら条件分岐を追加することで、自動化できる処理の幅を広げることができます。なるべく仕事はマクロに任せて楽をしましょう！

次回は、処理の幅をさらに広げる「For...Next ステートメント」について解説します。

👇次回

https://qiita.com/TakuyaSuzuki/items/4bad627f7a8a71eb1b30


# 5. おまけ；ド・モルガンの法則
ブール型と関係が深い「ド・モルガンの法則」について紹介します。高校数学で習った記憶のある方もいると思いますが、これを知っているとコードを読みやすいものにできる場合があります。

これは数学者オーガスタス・ド・モルガンが発案したといわれる法則で
>・「"P __かつ__ Q"でない」は「"Pでない" __または__ "Qでない"」に等しい
・「"P __または__ Q"でない」は「"Pでない" __かつ__ "Qでない"」に等しい


というものです。

要は、`And`でつながった条件全体を否定（`Not`）すると、それぞれの条件の否定を`Or`でつないだものと同じ意味になり、`Or` でつながった条件全体を否定すると、それぞれの条件の否定を`And`でつないだものと同じ意味になるというものです。

>___あの日 あの時 あの場所で 君に会えなかったら　僕等は いつまでも 見知らぬ二人のまま___（「ラブ・ストーリーは突然に」©小田和正）

という歌詞があります。これは
```vb:
    If Not(あの日君に会えた And あの時君に会えた And あの場所で君に会えた) Then
        僕等はいつまでも見知らぬ二人のまま = True
    End If
    '※日本語の部分はブール型変数
```
ということかと思います。このIfステートメントはド・モルガンの法則により
```vb:
    If (Not あの日君に会えた) Or (Not あの時君に会えた) Or (Not あの場所で君に会えた) Then
        僕等はいつまでも見知らぬ二人のまま = True
    End If
```
と書き換えられるということです。（例えば、あの日あの時に会っていたとしてもあの場所じゃなかったら、ただすれ違っただけで知り合いにはならなかった・・・みたいな？）

ド・モルガンの法則を利用することで、例えば以下のようなIfステートメントは意味を変えずにすっきりと書き換えることができます。（「以上」の否定は「未満」、否定の否定は肯定。）
```vb:書き換え前
    If Not( i >= 0 And (Not str = "○")) Then
    '※「iが0以上かつ『strが"○"でない』」でない場合
```

```vb:書き換え後
    If i < 0 Or str = "○" Then
    '※「iが0未満またはstrが"○"」の場合
```
条件式が複雑で否定が絡むような場合には、書き換えを検討してみてください。

# 6. 参考文献
こちらはMicrosoftの公式ドキュメントです。

https://learn.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/data-types/boolean-data-type

こちらは私がものすごくお世話になっている「エクセルの神髄」という解説サイト。より深く学習を進めたい方は是非。

https://excel-ubara.com/excelvba4/EXCEL243.html

ド・モルガンの法則（Wikipedia）

https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%BB%E3%83%A2%E3%83%AB%E3%82%AC%E3%83%B3%E3%81%AE%E6%B3%95%E5%89%87