和風スパゲティのレシピ

日本語でコーディングするExcelVBA

If~Else~EndIfを1行で書く - IIf関数

便利なのに知名度のイマイチな関数「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部分が処理されるからな~」
って意味ですよ。