今回は、Static修飾詞について説明したいと思います。Static修飾詞は、VBAの場合、ローカル変数の宣言に利用できる仕様となっているようです。Staticは英語で、『静的』を表す単語ですので、それとは反対の『動的』を表す単語はDynamicとなります。プログラミングの用語として、この『静的』『動的』という用語は非常によく使いますので、先にこの用語について説明したいと思います。
使い方としては、『動的に確保した配列(メモリ)』、『固定サイズの静的な配列』などと使います。以下のプログラムを見てください。これが静的に確保した配列で、配列の要素数(=7)が固定の決まった変数のことを指します。
'静的な配列
Public Sub SampleFunc()
Dim days(1 To 7) As Long
…
では、次に動的に確保した場合の、配列を利用したサンプルコードを見てみましょう。このように、変数を宣言したタイミングでは、配列のサイズが決まっておらず、プログラム中で、必要に応じて可変的に要素数を指定して、配列を確保することを、動的な確保と表現します。
'動的な配列
Public Sub SampleFunc2()
Dim days() As Long
'1週間分確保
ReDim days(1 To 7)
…
'1年間分を再確保。
ReDim days(1 To 365)
…
Erase days
動的にメモリや配列を確保した変数を利用する場合の注意点なのですが、この変数が不要になったタイミングで、確保したメモリを解放する、Erase処理を必ず行なわなければなりません。これを怠ると、メモリーが、使用され続け枯渇してしまい、システムが動作できなくなってしまいます。このような現象のことを一般的に、メモリー・リークと呼びます。
ちなみに、静的に確保した配列に対してErase処理を実行すると、配列のすべての要素が0クリアされます。
簡単に『静的』『動的』について解説したところで、話しを元に戻してStatic修飾詞について説明したいと思います。このStatic修飾詞なのですが、ここまでで説明した『静的』とは少し異なる意味で、Staticという表現が使用されています。
以下のサンプルコードを見てください。上の関数が、ダウンロードしたブックの【普通の変数】ボタンが押された時の処理で、下の関数が【Static変数】ボタンが押された時の処理となっています。
サンプルのダウンロード
'普通の変数
Private Sub CBtnVar_Click()
Dim v As Long
MsgBox "vの値: " & v
v = v + 1
End Sub
'Staticな変数
Private Sub CBtnStatic_Click()
Static v As Long
MsgBox "vの値: " & v
v = v + 1
End Sub
さきに、それぞれのボタンを押して動作を確認してみましょう。まずは、【普通の変数】ボタンを1回、2回、3回と押してみてください。実行結果は、ボタンを押した回数に関わらず、同じ0の値がメッセージボックスにより表示されたかと思います。次に、【Static変数】ボタンを、1回、2回、3回と押してみると、今度は、実行結果が先ほどとは違い、1ずつ加算された値になっており、まるで、変数vが、グローバル変数のような振る舞いとなっていることが分かります。
この実行結果の違いは、変数宣言の違いにあり、プログラムコード上ではDimとStaticという記述の違いとなっています。Dimで宣言すると、過去に解説したことがありますが、変数vは、プログラムが展開されている仮想メモリ上(4Gの空間)のスタックという領域に配置されます。関数が呼び出されたタイミングで、変数がスタック上に積まれ、0初期化されていますので、ボタンを何度押しても、結果が0ということになります。
※VBAでは、変数を宣言すると必ず初期値が0クリアされている仕様となっていますが、他のプログラミング言語では、0クリアされている保証はありません。大抵の場合、関数の先頭で0を代入するような初期化を行なわなければならない場合がほとんどです。ということで、VBAは非常に楽チンなプログラミング言語と言えるでしょう。
それでは、Static宣言すると何が違うのか? その違いは、Static修飾詞により変数を宣言すると、そのローカル変数が仮想メモリ上(4Gの空間)の一意のアドレスに配置されるというところにあります。この場合、何度ボタンが押されても、同じアドレス(一意)を参照しますので、ボタンが押されるたびに、vの値がインクリメントされていく実行結果となります。
さきの、通常の変数vは、関数が呼び出されるたびに、スタック領域に配置されますので、アドレスは必ずしも、同じであるとは限りません(動的)。後者の、Static変数vは、アドレスが一意であり変わることがありませんので、そういう意味で、Static(静的)という表現が使用されている訳です。
このStatic変数のスコープ(有効範囲)は、宣言されている関数内のみという仕様のようです。この辺りが、モジュール内のグローバル変数との違いというところでしょうか。
第20回 <
以下から、今回の豆知識で紹介した内容のエクセルファイルがダウンロードできます。
サンプルのダウンロード
ご意見・ご要望等ありましたら、画面最下部のメールアドレスまでご連絡ください。