Access での条件分岐
SQL などで条件分岐を行う場合、大抵は以下のような式や関数を使用します。
アプリケーション | 使用する式・関数 |
---|---|
SQL 標準 | CASE 式 |
Oracle Database | CASE 式 DECODE 関数 |
Microsoft SQL Server | CASE 式 IIF 関数 |
MySQL | CASE 式 IF 関数 |
PostgreSQL | CASE 式 |
Microsoft Access | IIf 関数 Switch 関数 |
Microsoft Excel | IF 関数 IFS 関数 VLOOKUP 関数 – 特殊な書き方で可能 |
この中で Excel は完全に「余談」の範疇ですが、Excel から Access に入った人にはよく聞かれる事柄ではありますし、念のため書いておきましょう。
構文からすると、Access の IIf 関数 と Excel のIF 関数、Access の Switch 関数 と Excel の IFS 関数 は、 大雑把に言ってしまえばだいたい同じですね。
こう見ると、Access の浮きっぷりはやはり際立っていますよね。
特に、CASE 式を使用できないのは痛い。CASE 式は非常に応用範囲が広い式ですし、これが使えれば Access の SQL も少しは使い勝手が良くなったのですが‥。
Access で使用できる関数
ただ、Access の SQL には大きな特徴があります。
それは、一部例外はあるものの* 1たとえば、MsgBox 関数は使用不可。、VBA で使用できる関数を基本的には使用できるということです。
上で挙げた IIf 関数 や Switch 関数 も、厳密に言えば VBA の関数なんですよね。
- IIf 関数 (Visual Basic for Applications) | Microsoft Docs
- Switch 関数 (Visual Basic for Applications) | Microsoft Docs
ということはつまり、Access で使用しても VBA で使用しても、これらの関数は同じ挙動を示すのでしょうか?
実際私はそう思っていたのですが、実際には挙動に大きな違いがありました。
VBA における、IIf 関数・Switch 関数の基本
上記のリファレンスを見るとわかりますが、
IIf(expr, truepart, falsepart)
IIf では、 truepart または falsepart のいずれか一方だけが返されますが、評価は両方の引数に対して行われます。このため、予期しない結果が起きることがあります。 たとえば、 falsepart を評価した結果 0 による除算エラーが発生する場合は、 expr が True であってもエラーが発生します。
Switch(expr-1, value-1, [ expr-2, value-2..., [ expr-n, value-n ]])
Switch は、1 つの式しか返しませんが、すべての式を評価します。 このため、予期しない副作用が引き起こされていないかどうかに気を付ける必要があります。 たとえば、式の評価によってゼロによる除算エラーが引き起こされると、エラーが発生します。
従って、極論ですが次のような書き方をしてしまえば、当然エラーが返ります。
Public Sub Test()
Dim a As Long
a = IIf(True, 1 + 0, 1 / 0)
End Sub
上の IIf 関数の第三引数はどうやっても実行されませんが、お構いなしです。
Access SQL で IIf 関数を利用する
では、クエリ(SQL)で IIf 関数を利用するとどうなるのでしょうか?
VBA での挙動から想像すると、以下の SQL 文はエラーになりそうですよね。
SELECT IIf(TRUE, 1 + 0, 1 / 0) AS Result
ところがこの結果は、
こうなります。エラーにはならないんですよね。
これはかなり意外な結果でした。
VBA の関数には NULL を渡してしまうとエラーになるものが多い一方、Access ではその性質上 NULL を渡すことが多い都合上、こうなっているのでしょうか‥?
Access SQL で Switch 関数を利用する
では、Switch 関数での挙動はどのようになるのでしょうか?
次のような SQL 文で試してみましょう。
SELECT SWITCH(TRUE, 1 + 0, FALSE, 1 / 0) AS Result;
IIf 関数の結果から推測すると、これはエラーとならず1を返すと思われます。
しかし、‥
これは、VBA 同様に(絶対に実行されないはずの)第4引数が評価され、エラーになるんですよね。
このように、Access SQL は一見不可解な挙動を示すことがある点、注意が必要かもしれません。
注釈