変数名スコープと関数名スコープ

VBAでは3つの変数名スコープしかない。
1)特定のプロシージャ内でのみ通用する変数
2)特定のモジュール内でのみ通用する変数
3)複数のモジュール間で通用する変数

1)プロシージャ内でDimで宣言する。
2)そのモジュールのプロシージャ外でDimで宣言する。
3)プロシージャ外でPublicで宣言する。(どこかのモジュールで宣言する)
ただし3つめは使わないことを推奨する。

関数名スコープについては2つだけあり
1)どこからも見える関数
2)モジュール内でしか見えない関数

1)特に宣言をしなければどこからも見える。明示的にはPublicで関数宣言する。
2)Privateをつけて宣言する。
直接実行することのないプロシージャは2によって外から見えなくしておくことが良いだろう。
まず変数名のスコープについて順に説明していく。
最小単位はプロシージャ単位のブロックだ。
プロシージャで宣言した変数はそのプロシージャ内でのみ有効である。

次がモジュールという単位ブロックだ。
例えばModule1というシートに書ける範囲がモジュール単位ということになる。
モジュールには標準モジュールの他に、シート・ブックモジュールとフォームモジュールとクラスモジュールがある。
標準モジュールやフォームモジュール、クラスモジュールは一つのブック(VBAProject)に任意の数のモジュールを作ることができる。
シートモジュールはシートの数だけある。一つのブックにブックモジュールは一つだけである。

Publicはややわかりにくいので例を挙げると

Module1 内
Option Explicit
Public global_x
Module2 内
Option Explicit
Sub test()
global_x = 300
MsgBox global_x
End Sub
これでtestプロシージャを実行するときちんと300がメッセージボックスに表示される。
このようにみるとそうでもないが、Module2だけをみると気持ち悪い。
global_xが未宣言に見えるにもかかわらず、このプログラムは正しくエラーも出ない。
普通の他の言語なら「他で宣言をしているので引用する」という宣言をさせるものなのだが。
この点もVBAの言語としての不備と言えよう。

さらに残念なことはVBAにはステートメント単位のブロックの概念がないことだ。
例えば
Dim i,x
x=3
For i = 1 To 3
Dim x '←ここでエラー
....
Next
等と書こうとしても「同じ適用範囲内で宣言が重複しています。」というエラーになってしまう。
コーディングの自由度が減ってしまいとても残念なことだ。
comments (0)

コメント

Comment Form