t-hom’s diary

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

VBA 変数宣言はIfやFor等のコードブロック中に書いても機能する

VBAでは、変数宣言をIfやFor等の制御構文の中に書くことができる。
作法としてどうなのって話は一旦置いといて、とりあえず実証してみよう。

以下のマクロは正常に実行できる。

Option Explicit
Sub hoge()
    If False Then
        Dim variable As Integer
    End If
    variable = 1
    Debug.Print variable
End Sub

Ifの条件式がFalseなので処理されないと勘違いされるかもしれないけれど、宣言文については関係ない。
処理系は制御構文などガン無視でコードを単に上から順になぞって変数宣言を探すので、その変数を初めて使う行よりも上にあればOK。

また、変数宣言はFor文などのループ中に書いても1度しか処理されない。

Option Explicit
Sub fuga()
    Dim i As Integer
    For i = 1 To 10
        Dim variable As Integer
        variable = variable + 1
    Next
    Debug.Print variable
End Sub

しかも処理されるタイミングはどのコードよりも早い。
試しにローカルウィンドウを出してF8でステップ実行を開始すると、開始直後にはもう変数が宣言された型で認識されている。
f:id:t-hom:20180602183536p:plain

そのままF8を押していくと、変数宣言部分のコードはスキップされることが分かるだろう。それはもう処理済みだからだ。

なお、Option Explicitが無く、明示的に変数宣言がされていないケースでも、変数は初めて登場した時点で暗黙的にVariantで宣言されたものとして扱われ、プロシージャの実行直後にローカルウィンドウで確認できる。
f:id:t-hom:20180602184347p:plain

明示的に変数宣言をすると、宣言文より前に変数を参照させることはできなくなる。
たとえば以下のコードは実行できない。

Sub piyo()
    variable = 1
    Dim variable As Integer
    Debug.Print variable
End Sub

なぜかというと、処理系は最初にvariable = 1を見た時点でVariant型の暗黙の宣言として取り扱ってしまうため、次の行のDim variable As Integerを宣言の重複として取り扱う為だ。

f:id:t-hom:20180602184855p:plain

本題から脱線してしまったけれど、以上が変数宣言の仕組みである。

私の書いたコードにはFor文やIf文の中で変数宣言を行っているものがある。
一般的には制御構文の外で宣言するし、私もそのようにする場合があるけれど、変数は使用する直前で宣言するという原則も捨てがたく、制御構文内に多数の変数が登場する場合はずらっと外に並べるよりは中に入れてあげたほうが良いかなという判断。

thom.hateblo.jp

なお、「#」で始まるプリプロセッサディレクティブについては変数宣言より先に処理されるので注意。
以下は、実行できない。

Option Explicit
Sub hoge()
    #If False Then
        Dim variable As Integer
    #End If
    variable = 1
    Debug.Print variable
End Sub

f:id:t-hom:20180602185635p:plain

プリプロセッサディレクティブについては以下の記事を参照。
thom.hateblo.jp

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