便利なのに知名度のイマイチな関数「IIf関数」を紹介します。
この関数を使うと、簡単なIf~Else~EndIfを1行にまとめることができます。
IIf関数の書き方
IIf([条件式], [Trueのときの値], [Falseのときの値])
IIf関数は初めて見る方でも、()の中身は見覚えがあると思います。
早い話、「シート関数のIF」のVBA版がIIf関数です。
そのまんま過ぎて、説明になっていないかもしれませんが、
[条件式]がTrueの時は[Trueの時の値]、
[条件式]がFalseの時は[Falseの時の値]を返します。
IIf関数の使いどころ
If文だと長たらしくなる、代入などの簡単な分岐を、1行で書くことができます。
If x = A Then y = B Else y = C End If ' ↑をIIfで書き替える y = IIf(x = A, B, C)
ただし、注意点としてTRUEのときでも、FALSEまで計算されます。
(FALSEのときでも、TRUEも計算されます)
y = IIf(x = 0, 0, A/x)
↑この式を処理するとき、「0」も「A/x」もどっちも計算して、そのあとで「x=0」を判定するため、この式ではエラーが出てしまいます。
0の除算を回避するなどには使えませんので、十分注意してください。
IIf関数を使う効果が高いと感じる場面は、文字列の操作です。
作りたい文字列 = 作りたい文字列 & "," & 追加文字列
みたいな、文字列結合ってよくありますよね。
","の部分は、" "だったり、改行vbCrLfだったり、パスの区切り\だったりします。
そして、一番最初の結合だけ、カンマから始まらないように
If 作りたい文字列 = "" Then 作りたい文字列 = 追加文字列 Else 作りたい文字列 = 作りたい文字列 & "," & 追加文字列 End If
こんな風に分岐を書きますが、これを
作りたい文字列 = IIf(作りたい文字列="", "", 作りたい文字列 & ",") & 追加文字列
こう書くことができます。
ものすごくすっきりしますね。
この例のように、IIf(○ ="", "", ~) という空白の場合分けは、
IIf関数の弱点である「1行になる代わりに読みづらくなる」のがあまり気にならないので、トータルで読みやすくなることが多いと思います。
あとは大量の引数を使うメソッドの、引数の分岐にも便利です。
○○.メソッド名 , 引数1, 引数2, 引数3, IIf(条件式, 引数4, 引数4'), 引数5
みたいなやつですね。
If文で書こうとすると、メソッドと引数をすべて2回書くことになってしまいます。
IIf関数の注意点
IIfの注意点は、先ほどの通り「TRUEのときでも、FALSEまで計算」です。
と、その前に。
最初の「IIf関数の書き方」の時、すみませんひとつ嘘をつきました。
IIf([条件式], [Trueのときの値], [Falseのときの値])
こう書いたんですが、正確には、
IIf([条件式], [Trueのときの処理], [Falseのときの処理])
こうです。
Excelのシート関数と形は一緒ですが、ここはVBAですので、
ただの値ではなく、処理が書けてしまうのです。
※ 正確には「値を返す処理」が書けます。
値を返さない、例えばSubプロシージャを書くとエラーになります。
これと「TRUEのときでも、FALSEまで評価」という性質を合わせると、
凶悪なトラップを生みます。
間抜けな例をあげましょう。
MsgBox(IIf(is最後まで実行完了 = True _ ,"データの集計を完了しました。", "何らかのエラーにより処理を中断しました。"))
これは見やすいIIf関数の使い方ですね。
ですが、これを
IIf(is最後まで実行完了 = True _ , MsgBox("データの集計を完了しました。"), MsgBox("何らかのエラーにより処理を中断しました。"))
こう書いてしまうと、
残念ながらメッセージボックスが二つでます。
データの集計を完了しつつ、何らかのエラーが出ているので、
1週回って間違いではないですが(笑)
まあこれは笑えますが、笑えないバグの温床になりえます。
IIf([条件式], シートAを書き換える処理, シートBを書き換える処理)
このとき、条件式の結果に関わらず、どちらのシートも書き換えられてしまうという罠になります。
そもそもIIf関数を使う理由は、見やすいからというだけなので、
処理の分岐をIIfにやらせるといった暴挙に出ないようにしましょう。
シート関数のIFですら、めっちゃ長いと読めなくなって困ったことがありますよね?
ここに処理を書こうなんてとんでもない!
IIf関数は、
IIf([条件式], [Trueのときの値], [Falseのときの値])
と、値の時だけ使うものと覚えてください。
作りたい文字列 = IIf(作りたい文字列="", "", 作りたい文字列 & ",") & 追加文字列
などのように、IIfを使ったおかげで見やすいときだけ使いましょう。
おまけ:豆知識
この「条件、TRUEの時、FALSEの時」という3つの並びのことを、
プログラミングの世界では「三項演算子」と呼びます。
C言語とかだと、
条件式 ? TRUEのときの値 : FALSEのときの値
と、「?」と「:」で区切って書くそうですよ。
え?マジで?
わかりにくw
y = X = A ? B : C
絶望的ですよね。
割と嫌われています。
まあ「+-*/」と同じ「演算子」なのでしょうがない。
IIf関数は、その名の通り(○,△,□)の形で書く「関数」なのでちょっと違います。
(○,△,□)の形で書けて、IF関数で慣れているから、VBAでは使ってOKです。
他の言語だと使用禁止な規約もあるそうですのでお気をつけて。
ちなみに他言語の「三項演算子」は、TRUEの時はFALSEは処理しないものが多いようです。
この「TRUEの時にFALSEを計算しない」ことを、
「ショートサーキット」と呼びます。
IIf関数はショートサーキットではありませんが、
シート関数のIF関数はショートサーキットです。
(もちろんIfステートメントもショートサーキット)
別に覚える必要はありませんが、
「VBAの三項演算子はショートサーキットじゃないからな~」
って他言語のプログラマが気取って言っていたら、
「VBAのIIf関数はTrueでもFalse部分が処理されるからな~」
って意味ですよ。