愚痴 目的
VBAは 90年代からご活躍なさっている偉大なる言語であり、
その前身とも呼べるVB様に至っては70年代のお生まれでございます。
われわれユーザに媚びることなく、古からの言語仕様を頑なに守り続けるその姿勢に、
今どきの言語に甘やかされ、ぬくぬくとアプリ開発を行ってきた私自身の浅学を恥じるばかりです。
この記事は、そんなVBAパイセンの素晴らしき仕様についてまとめたいと思います。
ここがすごいぞ
1. And, Or 演算子は短絡評価しない
例えば以下の関数は、col = Nothing が渡された場合、Null pointer error みたいなエラーが発生します。
Function IsEmptyCol(col As collection) As Boolean
' return文もない。値を返したい場合、関数名変数(?) に値を代入する。ちなみに、この後も処理は継続するので、制御を呼び出し元に返したいなら Exit Function と書く。
IsEmptyCol = Not col Is Nothing And col.Count > 0
End Function
「なんでや、Not col Is Nothing でnullチェックしとるやないか!」と思いのかたは甘すぎです。
パイセンは生真面目なので、And演算子の左側の式がFalseだろうと、Or演算子の左側の式がTrueだろうと、すべての式を評価するのです。
Nullチェックを入れるなら、以下のように単独でIf文に入れないといけません。
Function IsEmptyCol(col As collection) As Boolean
If col Is Nothing Then
IsEmptyCol = False
ElseIf col.Count > 0 Then
IsEmptyCol = True
End If
End Function
2. continue文がない
For, While, Do While ループ中で、途中の処理をスキップするためのあれですが、ありません!
スキップしたい場合は以下のようにGoTo文を使います。
Dim accum As Long
Dim i As Long
For i = 1 To 10
If i = 3 Then
GoTo Continue
End If
accum = accum + i
Continue:
Next i
構造化プログラミングの波が押し寄せていたはずですが、そのぶれない姿勢はみんなの憧れ。
ちなみにbreakに相当する Exit For, Exit Do はあります。(Exit Whileはない)
3. 変数宣言時の初期化
パイセンは厳しいですが、やさしい一面もあります。
変数を宣言すると、必ず初期化してくれます。(C言語だとほったらかしでしたよね。)
ただし、それは 1度きり、関数スタックが積まれたとき(?)だけです。
「ループ中で宣言しとるんやから、毎ループごとに初期化してくれるやろ?」という舐めた態度をとった我々が愚かなのです。
以下のように、自分で初期化する労力すら惜しむ者に対して、人としてあるべき姿を教えてくれるのがパイセンなのです。
' サンプルとしてはいまいち…。
Dim accum As New collection
Dim i As Long
For i = 1 To 10
Dim str As String: str = "" ' ループ中で宣言した場合でも、必ず初期化も行うこと
str = str & i
accum.Add str
Next i