二回宣言すると怒られる

Excel VBA では、同じ変数を二回宣言すると怒られる。
f:id:Infoment:20210204222055p:plain

例えば、こんな感じだ。
f:id:Infoment:20210204222132p:plain

変数の型を変えても、見逃してはもらえない。
f:id:Infoment:20210204222229p:plain

ところが先日、自分では意図せず、このように宣言したものが
あることに気づいた。
f:id:Infoment:20210204222346p:plain

片方は、モジュールレベル変数。同一モジュール内であれば、
共通の変数として使用できる。

もう一つは、宣言したサブプロシージャ内でのみ有効な変数だ。

なぜかどこかで何時からか、このような変数宣言もシステムから
咎められるものと思い込んでいた。
しかしこれが許されるならば、
その挙動をきちんと理解しておかないと事故につながりそうだ。

例えば、こんなのはどうだろう。
f:id:Infoment:20210204222832p:plain

Test1とTest2のそれぞれで宣言した変数iは、同じ名前の変数では
あるが、宣言した場所が違うため別物として扱われる。従って、
Test1は呼び出されるたびにiが宣言し直され(仕切り直され)る
ため、iは2以上になることはない(初期値0なので、0+1=1)。
f:id:Infoment:20210204223245p:plain

この結果は、モジュールレベル変数が存在した場合も同じだった。
(プロシージャ内で宣言された変数が優先される)。
f:id:Infoment:20210204223318p:plain

では、Test1内の宣言を省くとどうなるか。
f:id:Infoment:20210204223412p:plain

この場合、モジュールレベル変数iとしてカウントアップされるため、
最初とは異なる結果となった。
f:id:Infoment:20210204223517p:plain

逆にTest2側の場合は、単にループカウンタとしてカウントアップされる
だけなので、この場合は影響なしだった(たまたま)。
f:id:Infoment:20210204223631p:plain

それでは、両方省くとどうなるか。
f:id:Infoment:20210204223705p:plain

Test1 と Test2 の変数iは、どちらも同じものが使われるため、このような
結果となった。
f:id:Infoment:20210204223855p:plain

あな恐ろしや。誤動作防止のためにも、変数宣言は極力プロシージャ
単位で行った方がよさそうです。

参考まで。