t-hom’s diary

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

VBA Boolean型をTrueやFalseと比較することの是非について

f:id:t-hom:20170509093420p:plain
If文の条件式でBoolean型をTrueやFalseと比較することは昔から論争の種だった。

たとえば以下のようなIf文。

If IsNumeric(x) = True Then
If IsDate(x) = False Then

わざわざTrueやFalseと比較しなくても、このように書くことができる。

If IsNumeric(x) Then
If Not IsDate(x) Then


Boolean型を返す関数をTrueやFalseと比較するのは初心者に多い書き方であるが、上級者のなかには冗長であることは承知のうえであえてTrueやFalseと比較するという方もいる。以降、この勢力を比較派と呼ぶことにする。

そしてこれに反対する勢力、つまり後者の書き方を較派と呼ぶことにする。

※ちなみにここで論じるのはあくまでBoolean型とTrue/Falseとの比較の是非であって、それ以外の数値や文字列については非較派であっても比較演算子を用いる。もちろん。

さあ、比較派と非較派、あなたはどっち?

ちなみに私は非較派。

ここから先は、なんちゃって対談形式で双方の主張を戦わせる。
もちろん、参加者も評者も私なので、どっちにしても私が肩入れする非較派が勝つんだけど。フハハハ。

比較派と非較派の対談

非較派:
さっそくだけど、まず、If IsNumeric(x) = True Thenって書きかたは無駄が多いよね。
たとえばIsNumeric(x)がTrueを返したらIf True = True Thenになるでしょ、その次にTrueとTrueをイコールで比較するとTrueになるからIf True Thenになるでしょ。
このひと手間無駄じゃない?IsNumeric(x)がTrue/Falseを返すんだから、そのまま使えばいいじゃない。

比較派:
いやいや。無駄っていうけど最近のPCだと実行時間は殆ど変らないでしょ。コンピューターはますます速くなってくるのにそんなケチくさいこと言わなくても。それにIf IsDate(x) = False Thenのケースはどうなの。たとえばTrueを返してFalseと比較しても、Trueを返してNotで反転させてもどちらにしても手間は変わらなくない?

非較派:
うーん。それは確かに。でも美しくないんだよな。たとえ速度が変わらなくても中で無駄なことしてるってのは。それに文章としても不自然に見えるんだよね。もし「xが日付」が偽と等しければ、なんて言い方しないよね。If Not IsDate(x) Thenであれば、そのまま、もしxが日付でなければと読めるし。

比較派:
プログラミング言語は英語とはまた別でしょ。

非較派:
それはそうだけど、VBってどちらかといえば英語みたいに読めることを目指した言語じゃない?C言語だと条件は丸カッコで括るところをVBAだとIf 条件 Thenだし、AndとかOrも記号じゃなくて英単語そのまま使っちゃってるし。英語には成れないけど、なるべく英語に近づけたほうが自然だと思うな。

比較派:
なるほどね。じゃあこれはどう?If文には条件式を書くって教わるでしょ?例外が増えちゃうのは良くないと思うんだ。

非較派:
うん、そこは賛成。でも「If IsNumeric(x) Then」って書いてもちゃんと「条件式」になってるし、例外も増えないよ。

比較派:
えっ?どういうこと?

非較派:
条件式って数式の親戚みたいなものと勘違いしてない?
ここでいう条件式ってのは、Boolean型に評価される式全般のことだよ。

比較派:
ちょっと待って、いきなりムズっ!Boolean型は分かるけど評価って何?式全般ってさっきのIsNumeric(x)のどのへんが式なの?式ってふつうはイコールとか、プラスとかマイナスとか記号使うよね?

非較派:
うーん。見事に数学を引きずってるね。世の中には数式以外の式もあるでしょ。たとえば化学式とか。

比較派:
あーっ。あれも式か。ん?じゃあ式って言葉の定義はなんなんだ?

非較派:
ググってみたら、「ある関係・構造を表すために、記号を連ねて書いたもの。」だってさ。

比較派:
ほらやっぱ記号…。IsNumeric(x)のどの辺が記号なの?まさかカッコとか言わないよね。

非較派:
記号をググってみたら「一定の事柄を指し表すために使う、文字・しるし等の総称。」だってさ。

比較派:
え?プラスとかマイナスとか、ハテナとか、そういうのが記号でしょ?

非較派:
それは「特殊記号」。ふつうにABCも記号だし、漢字もひらがなも記号ってこと。一般的には「特殊記号」を指して記号って呼ぶほうが多いけどね。

話を戻すと、つまり式ってのは特殊記号を使った数式だけじゃなくて、何かの関係とか構造を表してたらそれで式ってこと。たとえばIsNumeric(x)だと、「関数(変数)」っていう構造だよね。プログラミングでは関数だけじゃなくて、変数とか等価式(a > bなど)、リテラル(100とか"あ"とか直接値を書いたもの)、計算式(1 + 2など)、論理式(And、Orなど)も全部式なんだ。
式の定義は「評価すると値になる」ってこと。

比較派:
さっきから言ってるその「評価」ってのは何なのさ。

非較派:
プログラミング用語としての「評価」ってのは、何かの値を確定すること。計算って言わないのは、"A" & "B"みたいな式もあるから。これは"AB"って値になるけど計算じゃないよね。

比較派:
たしかに。

非較派:
あとたとえば単体のリテラルも一応、評価はされるんだ。
"100"は評価しても"100"だと思うでしょ。もちろんそのケースが普通だけど、そうじゃないケースもある。

たとえば文字列"100"はイチマルマルっていう文字列なんだけど、Dim a As Integer: a = "100"っていう状況なら?

比較派:
ああ、Integer型の変数に入れようとしてるから評価されると数値のヒャクになるわけね。

非較派:
そゆこと。これも計算してるわけじゃないから、「評価」っていう言葉で表すんだ。

さて、ずいぶん回り道したけど、これで「If IsNumeric(x) Then」って書いてもちゃんと「条件式」になってるってことはわかって貰えた?

比較派:
まぁそう考えると定義上は条件式だね。でも…なーんかこじ付けのような気がするんだよね。
ふつうIfに書く条件式は比較演算でしょ。関数を直接書くのってやっぱ例外だと思うけど。

非較派:
いや、例外ってわけでもないよ。さっきも言ったように条件式ってのは、Boolean型に評価される式全般のことだから関数でも変数でもなんでも書ける。

比較派:
ますます例外が増えない?いま出てるだけでもこれだけあるでしょ。

  • Ifには基本的に比較演算子を使った条件式を書きます。
  • AndやOrで複数の条件を並べて書くことができます。
  • Boolean型を返す関数はそのまま書くことができます。
  • Boolean型の変数もそのまま書くことができます。

非較派:
いやいや。そもそも、基本的に比較演算を書くって前提が間違ってるよ。If文が見てるのは評価された後のTrueかFalseだけ。つまり比較演算は、TrueかFalseを返すための一つの方法に過ぎないってこと。
AndやOrで複数の条件をってのも、まるでIfが複数条件を処理してるみたいだけど、違うね。

比較派:
えっ?だって複数条件書けるじゃない。
たとえばIf a = 10 And b > 9 Thenとか。

非較派:
結果的にはね。でもそれ、Ifの機能じゃないから。
AndとかOrは論理演算っていって、両辺がTrueかFalseかしか見てないんだ。
たとえば今言ったIf a = 10 And b > 9 Thenの計算手順を分解してコードに書くとこんな感じ。

Dim a As Integer
a = 10
Dim resultA As Boolean
resultA = a = 10
'右のイコールは比較演算子、左のイコールは代入演算子であることに注意
'aは10なので、resultAにはTrueが入る。

Dim b As Integer
b = 10
Dim resultB As Boolean
resultB = b > 9
'bは9より大きいので、resultBにもTrueが入る。

Dim result As Boolean
result = resultA And resultB
'resultAとresultBはどちらもTrueなので、resultにはTrueが入る。

If result Then
    '何かする
End If

比較派:
ということは。。

非較派:
そう。例外が増えるんじゃなくて、最初からIfに例外なんて無いんだ。だってTrueかFalseしか見てないからね。
If True Thenとか、If False Thenって書く代わりに、最終的にTrueとかFalseに評価される式も書けるってだけのこと。

比較派:
なるほどね。でもやっぱ初心者には今みたいな話って難しくない?

非較派:
そうだね。話が難しいってよりも、この手の話に興味を持ってもらうのが難しいね。やっぱやりたいことがあってプログラミングするわけだから、ピンポイントでHow Toを知りたいよね。

でもそうすると「この場合はこう」っていう個別事例の積み重ねで例外だらけの知識になっちゃうからかえって覚えることも多いと思うんだ。覚えたこと以外に応用も利かなくなっちゃうし。

比較派:
なるほど。ある程度のレベルになったらやっぱりこういう基礎をしっかり学び直して、自由にプログラムが組めるといいよね。

ってことで時間も迫ってきましたので本日の対談はここまで。
ありがとうございました。

あとがき

ただいまブログ開設から2年と4か月ちょい。文体もいい感じで崩れてきたかなということで、新たな試みである対談形式にチャレンジ。

これはやっぱ書いててこっぱずかしいな。ノリで乗り切るしかない感じがする。

こういうのってやっぱキャラ立てが重要かなと。最初片方をごてごての関西弁にしようかと思ったけど、なんかその安易さが見透かされそうで恐れをなして逃げた。

結局あまり冒険しない感じの文体で書き上げてしまったのでノッペリしてつまんなかったかもしれないけど、チキンハートなのでそこはご容赦を。

さて、内容の結論。
私の立場は非較派なので、If文の条件式でBoolean型をTrueやFalseと比較しないという項目をコーディングガイドラインに追加しようかなとは思ってるんだけれど、究極的には好みの問題でもあるので、どう書くのが絶対解というのはないかなと。

Boolean型がTrueやFalseと比較されてるのを見るとなんか気持ち悪いけれど、他人が個人的に書いてるコードにいちいち目くじらを立てるつもりはない。

ただやっぱ少なくともIfの仕組みを知ったうえでの選択であってほしいなとは思う。

ブクマで興味深い意見をいただいたので追記

それがし比較派でござる。関数名が長くなってしまうと、If の次の「NOT」を見落としやすいので「=False」の書き方に統一しようぜっていう、前の会社にいた時の規約がクセになっております。

なるほど、日本人らしい感想ですね。
アメリカンならNotを見逃すなんてことはなく、むしろ日本語の最後のちゃぶ台返し「もにょもにょもにょ~では無い」が信じれらないって感じでしょうけども。私も日本人なのでNotを見逃したらヤバイ感はわからないでもなく。
まあでも英語も勉強した身としては慣れるとNotが非常にわかりやすいので、どっち派になるのかはその人のバックグラウンドにもよるのかも。

私は冒頭にNot(違うんたぜ)を持ってくる英語の明快さを支持します。逆に日本語の、さんざん話しといて最後に否定できちゃう文法ってこれズルくない?感が理解できるようになってきたといいますか。。

英語圏の方からすると、いまさら「ない」かよ、先いえよ「Not」って。という感覚ですかね。

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