t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA Select Case文における条件式の短絡評価活用の是非について

VBA Select Case文における条件式の短絡評価活用の是非について述べる。

前提

以下の書籍で、Select Case文の条件式短絡評価について記載されているが、そのテクニックとしての是非についてTwitter上で疑問が上がっていた。

Select Case文のCase条件は、カンマで区切ることで複数記入することができる。
例) Case 条件1, 条件2, 条件3

このとき、一つでも条件を満たせばCaseにマッチする仕組みになっているが、左から順に評価され、マッチした時点で残りの条件は評価されなくなる。

例えば次のコードにおいて、Case文の2番目の式は数値をゼロで割るというコンピューターではエラーになる処理だ。

Select Case True
Case True, 1 / 0
    Debug.Print "成功"
End Select

しかしCase文は最初のTrueにマッチした時点で後ろの式を評価しなくなるので、結果的に1 / 0は処理されずにエラーにならない。
こういった処理のことを短絡評価またはショートサーキットという。

この記事では、Case文が短絡評価を行う性質をテクニックとして用いて良いかどうかについて私の意見を述べる。
また、Twitter上で、If文と比較した場合に文法上の整合性が取れていないという意見があったので、こちらも私なりに解説してみた。

結論

結論からいうと、私個人的にはこの性質をテクニックとして使って良いと思う。
ただ、積極的に推奨している訳ではなく、良いかまずいかといえば、別にまずくはないのでは?という印象。

より良い書き方はケースバイケースだと思うが、素直にIfをネストさせたほうが分かりやすいケースが大半かと思う。
私がこのテクニックを知ってから、これが極めて有効に機能するシチュエーションにまだ遭遇したことがないので、あくまで現時点の評価である。

使って差し支えないと思う理由

1) ロジックに影響を与えないから。
短絡評価でエラー回避を行ったところで、本来TrueになるものがFalseになったりすることはない。
つまりプログラムロジックに影響を与えるものではないので短絡評価するという事実を知らないプログラマーがコードを読んだ場合にもロジックを誤解させる弊害は少ない。

※OnErrorによるロジック制御を行っている場合はこの限りではないが、OnErrorをそのように使うのはおかしいので今回は考慮しない。

2) きちんとVBAのマニュアル(以下)で挙動が定義されているから。
https://msdn.microsoft.com/ja-jp/VBA/language-reference-vba/articles/select-case-statement

3) ついでにVBAの言語仕様書(リンク)でも定義されている。
※P82 Select Case Statement参照

Ifとの挙動の違いについて

Ifで複数条件のいずれかにマッチした場合を書く場合は、Or演算子を使用する。

If 条件1 Or 条件2 Then
    Debug.Print "いずれかにマッチしました。"
End If

ただしOr演算子は短絡評価されないので、条件1にマッチしたとしても必ず条件2も評価される。
AndやOrは一般的にIf文の機能だと思われているけれど、たまたまIfと一緒に使うことが多いだけでIfの機能ではない。
従って、IfとSelectで評価プロセスが異なるのではなく、Ifの後には式を一つしか書けず、Caseの後にはカンマ区切りで複数の式を書けるという違いだと思う。

IfThen
End If

Select CaseCase 式[, 式[, 式[,...]]]
End Select

ちなみにVB.Netには短絡評価される論理演算子AndAlsoとOrElseがある。この点はやっぱVBAレガシィ

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。