Excel VBA の if 条件ロジックを AI に聞いてみる

# Excel VBA の if 文条件式ロジックを AI に聞いてみたよ
すでに運用中の Excel VBA の要件が変わったので条件式も書き換える必要が出てきたのだけど、自分で考えて使ってたロジックがなんだか冗長だなぁと思ったので、思い切って AI に聞いてみることにしました。今回は Gemini が搭載されたと噂の Google Bard と Bing Chat Enterprise で挑戦です。
※ 一応最初に Bard に質問をしてみて、回答内容がよろしくなかったのでプロンプトを調整してから Bing に質問、同じ内容で改めて Bard に回答を求めています。
## 要件と元々使っていたロジック
元々変数 m,n,o があり 0 もしくは 1 以上の数値が入っています。これはその前のコード部分で発生回数を数えたものでそれぞれの変数は 2,3… と数値が増えていきます。数値が確定したところで今回の if 文で使用する要件が発生します。
要件は変数 m,n,o のうち 2 つ以上が 0 の場合です。つまり 3 つの変数のうち 1 つしか数値がない場合に True とします。実際に使っていたコードは以下です。
```vb
If (m = 0 And n = 0) Or (m = 0 And o = 0) Or (n = 0 And o = 0) Then
    Debug.Print "True"
End If
```
今回この要件に変数 p が加わって 4 つとなりました。 4 つの変数のうちひとつだけ 0 以上の場合に True とします。変数を 3 つずつ判定して 4 回判定すればと思いましたが、コードが長くなるな…と思い AI に相談だ！となった訳です。
## 新しい要件で AI に聞いてみる
今回使用した初期プロンプトは以下です。
> Excel VBA で 4 つの変数 m,n,o,p があり、それぞれの変数には 0 もしくは 1 以上の整数が入っています。この 4 つの変数のうちいずれか 3 つの変数が 0 である場合に true となるの if 文の分岐を作ってください。 4 つの変数のどの組み合わせでも 3 つが 0 であると判定できるようにお願いします。
### Bing Chat Enterprise の場合
Excel VBAでの条件分岐を作成します。以下のコードは、4つの変数（m, n, o, p）のうち3つが0である場合に`True`を返します。
```vb
If (m = 0 And n = 0 And o = 0) Or _
   (m = 0 And n = 0 And p = 0) Or _
   (m = 0 And o = 0 And p = 0) Or _
   (n = 0 And o = 0 And p = 0) Then
    ' ここに、3つの変数が0である場合の処理を書く
    MsgBox "True"
Else
    ' ここに、それ以外の場合の処理を書く
    MsgBox "False"
End If
```
このコードは、4つの変数のすべての組み合わせをチェックし、そのうちの3つが0であるかどうかを判定します。それぞれの`If`文の条件は、特定の3つの変数がすべて0であるかどうかをチェックします。これらの条件のいずれかが`True`であれば、`MsgBox "True"`が実行されます。それ以外の場合は、`MsgBox "False"`が実行されます。このコードを適切な場所に挿入してください。具体的な処理は、`' ここに、3つの変数が0である場合の処理を書く`と`' ここに、それ以外の場合の処理を書く`の部分に記述します。このコードを自分のプログラムに適応させて使用してください。このコードは、指定された条件を満たすかどうかを確認するための基本的なフレームワークを提供します。具体的な処理は、あなたの具体的な要件に基づいて追加または変更する必要があります。このコードがあなたの問題を解決することを願っています。他に何か質問がありましたら、お気軽にお知らせください。よろしくお願いいたします。
### Google Bard の場合
4 つの変数のうちいずれか 3 つの変数が 0 である場合を判定するには、以下の 3 つの条件を満たす必要があります。

1. m が 0 であるか、n が 0 であるか、o が 0 であるか、p が 0 である。
2. m と n のどちらか一方が 0 であるか、o と p のどちらか一方が 0 である。
3. m、n、o のいずれか 2 つが 0 である。

これらの条件を満たすかどうかを判定するには、以下の if 文の分岐を使用できます。
```vb
Sub is_three_zero()

Dim m As Long, n As Long, o As Long, p As Long

If m = 0 Or n = 0 Or o = 0 Or p = 0 Then
    MsgBox "いずれか 3 つの変数が 0 です。"
ElseIf m = 0 And n <> 0 And o <> 0 And p <> 0 Then
    MsgBox "いずれか 3 つの変数が 0 ではありません。"
Else
    MsgBox "条件を満たしません。"
End If

End Sub
```
この if 文は、まず m、n、o、p のいずれかが 0 であるかどうかを判定します。もしいずれかが 0 であれば、条件を満たすため、メッセージを表示して終了します。

もし m、n、o、p のいずれも 0 でなければ、次に m と n のどちらか一方が 0 であるかどうかを判定します。もしどちらか一方が 0 であれば、条件を満たすため、メッセージを表示して終了します。

もし m と n のどちらも 0 でなければ、次に o と p のどちらか一方が 0 であるかどうかを判定します。もしどちらか一方が 0 であれば、条件を満たすため、メッセージを表示して終了します。

もし o と p のどちらも 0 でなければ、条件を満たさないため、メッセージを表示して終了します。

この if 文は、4 つの変数のどの組み合わせでも 3 つが 0 であると判定することができます。

なお、この if 文を簡潔に書くには、以下のようにすることもできます。
```vb
Sub is_three_zero()

Dim m As Long, n As Long, o As Long, p As Long

If (m = 0 Or n = 0 Or o = 0 Or p = 0) And
   (m <> 0 Or n <> 0 Or o <> 0 Or p <> 0) Then
    MsgBox "いずれか 3 つの変数が 0 です。"
End If

End Sub
```
この if 文は、m、n、o、p のいずれかが 0 であるかどうかを判定した後、逆にいずれも 0 でないか判定しています。この場合、どちらの条件も満たす場合のみ、メッセージを表示します。
## 結果と判定
Bing の場合は自分の考えたロジックと変わりませんでした。これ以上のロジックはないのかな？
Bard の場合はそもそも要件を満たしていません。駄目ですね…念のため追加で質問を続けてみます。
### Google Bard に追加で質問

**これは 4 つの変数のうち 3 つの変数が 0 である要件を満たしていません。 4 つの変数のうちいずれか 1 つの変数が 0 であるだけで true となってしまいます。再検討をお願いします。**

おっしゃる通りです。最初の if 文は、4 つの変数のうちいずれか 1 つの変数が 0 である場合を判定しています。そのため、4 つの変数のうち 3 つの変数が 0 である場合も true となってしまいます。

4 つの変数のうち 3 つの変数が 0 である場合を判定するには、以下の if 文の分岐を使用できます。
```vb
Sub is_three_zero()

Dim m As Long, n As Long, o As Long, p As Long

If (m = 0 And n = 0) Or (m = 0 And o = 0) Or (m = 0 And p = 0) Or
   (n = 0 And o = 0) Or (n = 0 And p = 0) Or (o = 0 And p = 0) Then
    MsgBox "いずれか 3 つの変数が 0 です。"
Else
    MsgBox "条件を満たしません。"
End If

End Sub
```
この if 文は、m と n、m と o、m と p、n と o、n と p、o と p のいずれか 2 つの変数が同時に 0 であるかどうかを判定しています。もしいずれか 2 つの変数が同時に 0 であれば、条件を満たすため、メッセージを表示して終了します。

この if 文は、4 つの変数のどの組み合わせでも 3 つが 0 であると判定することができます。

なお、この if 文をさらに簡潔に書くには、以下のようにすることもできます。
```vb
Sub is_three_zero()

Dim m As Long, n As Long, o As Long, p As Long

If (m + n + o + p) <= 1 Then
    MsgBox "いずれか 3 つの変数が 0 です。"
Else
    MsgBox "条件を満たしません。"
End If

End Sub
```
この if 文は、m、n、o、p の合計が 2 以下であるかどうかを判定しています。もし合計が 2 以下であれば、条件を満たすため、メッセージを表示して終了します。

この if 文も、4 つの変数のどの組み合わせでも 3 つが 0 であると判定することができます。
### さらに質問…
```vb
If (m + n + o + p) <= 1 Then
  MsgBox "いずれか 3 つの変数が 0 です。"
Else
  MsgBox "条件を満たしません。"
End If
```
**このコードですといずれかの変数が 1 以上の要件を満たしません。仮に m,n,o が 0 であっても p が 3 であった場合に true となりません。再検討をお願いいたします。**

おっしゃる通りです。このコードは、4 つの変数の合計が 2 以下である場合を判定しています。そのため、4 つの変数のいずれかが 1 以上である場合でも true となってしまいます。

4 つの変数のうちいずれか 3 つの変数が 0 である場合を判定するには、以下の if 文の分岐を使用できます。
```vb
Sub is_three_zero()

Dim m As Long, n As Long, o As Long, p As Long

If (m + n + o + p) = 0 Then
    MsgBox "いずれか 3 つの変数が 0 です。"
Else
    MsgBox "条件を満たしません。"
End If

End Sub
```
この if 文は、m、n、o、p の合計が 0 であるかどうかを判定しています。もし合計が 0 であれば、条件を満たすため、メッセージを表示して終了します。

この if 文は、4 つの変数のどの組み合わせでも 3 つが 0 であると判定することができます。

なお、この if 文をさらに簡潔に書くには、以下のようにすることもできます。
```vb
Sub is_three_zero()

Dim m As Long, n As Long, o As Long, p As Long

If m + n + o + p = 0 Then
    MsgBox "いずれか 3 つの変数が 0 です。"
End If

End Sub
```
この if 文は、m、n、o、p の合計が 0 であるかどうかを判定するのみです。そのため、else 文は必要ありません。

この if 文も、4 つの変数のどの組み合わせでも 3 つが 0 であると判定することができます。
## 結論
うーん、 Bard は何が駄目なんだ…言っている内容を理解してもらえていないように思える。プロンプトを工夫すれば何とかなるのか？でもそれって新人エンジニアに事細かに指示しているのと何ら変わらないように思える、意図を汲んで回答してくれるのを望むのだが…
さらなる発展を望みましょう。