はじめに
「VBAで三項演算子はどうやって書くんだろう?」と思って探していると、IIF関数というものを見つけました。
パッと見だと便利に使えるように感じましたが、IIF関数を実際に使ってみると不思議な動きをしていることが分かりました。
IIF関数とは
- 引数
expr
の式の結果に応じて、truepart
もしくはfalsepart
を返す関数です。 - 関数のインターフェースだけ見ると、三項演算子と同じ動きをしそうな気がしますが...
IIf(expr, truepart, falsepart)
引数 | 説明 |
---|---|
expr | 評価する式 |
truepart | exprがtrueの時に返す値、もしくはtrueの時に評価する式 |
falsepart | exprがfalseの時に返す値、もしくはfalseの時に評価する式 |
サンプルコード
Rubyを使った三項演算子の例
-
txt.empty?
の結果がfalseなので、barメソッドが実行されます。 - 「条件式の結果がfalseなので、false時の式が評価される」という流れです。
- これが三項演算子の「普通の処理の流れ」だと思います。
TernaryOperator.rb
def foo
puts "foo"
end
def bar
puts "bar"
end
txt = "abc"
txt.empty? ? foo : bar
実行結果
bar
IIF関数の例
-
txt = ""
の結果がfalseなので、Bar関数が実行されますが... - 実際にはBar関数が呼ばれる前に、Foo関数が実行されています。
- **「条件式の結果がfalseの時は、true時の式が評価された後、false時の式が評価される」**という流れになっており、普通の三項演算子の処理の流れとは異なっています。
- 最終的な結果(MsgBoxに表示される文言)は「bar」となります。
Module1
Option Explicit
Function Foo() As String
Dim txt As String: txt = "foo"
Debug.Print txt
Foo = txt
End Function
Function Bar() As String
Dim txt As String: txt = "bar"
Debug.Print txt
Bar = txt
End Function
Sub Main()
Dim txt As String: txt = "abc"
MsgBox IIf(txt = "", Foo(), Bar())
End Sub
実行結果(イミディエイトウィンドウ)
foo
bar
まとめ
- IIF関数は表面上は三項演算子っぽいですが、実際には異なる動きをするので注意が必要です。
- 将来的にコードを引き継ぐ際のことなどを考慮すると、私は三項演算子の代わりとしてIIF関数を使わない方が良いと思います。
- Microsoftの公式APIには以下のように注意喚起する解説が書かれており、どうやら「仕様通り」の動作のようです。
- 仕様通りと言われても、何だかモヤっとした気持ちになります...
IIf では、 truepart または falsepart のいずれか一方だけが返されますが、評価は両方の引数に対して行われます。 このため、予期しない結果が起きることがあります。