第108回.変数の適用範囲(スコープ,Private,Public)
変数には、その変数をVBA内で使う事ができる範囲が決められています。
マクロVBAで変数の使える範囲を、適用範囲(スコープ)と言います。
変数を宣言した場所と宣言方法によって、その変数を使える場所が違ってきます。
・ブックモジュール ・・・ ブックで1つだけ
・フォームモジュール ・・・ 作ったフォームの数だけ
・標準モジュール ・・・ 好きなだけ作れます
・クラス
・Functionプロシージャー
ブックやシートのモジュールでも、適用範囲(スコープ)は同じ規則になります。
プロシージャーレベル変数 ・・・ プロシージャー内でのみ使用可能
Sub sample1()
Dim i
・・・
End Sub
Sub sample2()
Dim i
・・・
End Sub
この場合、
変数iは、それぞれのプロシージャーの中でのみ有効です。
これが最も良く使われる変数定義になります。
1つのプロシージャーの中では、変数名は重複できません。
Sub sub1(arg1, arg2)
・・・
End Sub
このarg1とarg2は、そのプロシージャー内でのみ有効です。
つまり、
Dimで宣言する変数と同じです。
従って、Dimで同じ名前の変数は宣言できません。
モジュールレベル変数 ・・・ モジュール内でのみ使用可能
Dim i
Sub sample1()
Dim j
・・・
End Sub
Sub sample2()
Dim j
・・・
End Sub
このように、モジュールの先頭(最初のSubまたはFunctionより前)に書くと、
モジュール全体で使用できる変数になります。
宣言セクションで宣言した変数は、そのモジュール内のすべてのプロシージャーで使用できます。
この、Dim は、Private と書いても同じです。
むしろ、Privateと書くほうが一般的な記述となります。
パブリック変数 ・・・ 全てのモジュールの全てのプロシージャーで使用可能
DimやPrivateで宣言した変数は、他のモジュールでは使用できません。
他のモジュールで使用できるようにするためには、
Public i
Sub sample1()
Dim j
・・・
End Sub
Sub sample2()
Dim j
・・・
End Sub
上記のように、Publicで宣言します。
こうする事で、変数iは、他のモジュールでも使用できます。
Private ・・・ そのモジュールのみ
Public ・・・ 全てのモジュール
グローバル変数
と言う言い方もします。
・標準モジュール
・ブックモジュール
・シートモジュール
・ユーザーフォーム
・クラスモジュール
変数の適用範囲について簡単にまとめてると
モジュールの先頭でDimまたはPrivateで宣言した変数は、そのモジュール内でのみ使用可能
モジュールの先頭でPublicで宣言した変数は、全てのモジュールで使用可能
定数(Const)の適用範囲について
Constステートメント
Constの既定はPrivateになります。
モジュールの先頭でPrivateで宣言した定数は、そのモジュール内でのみ使用可能
モジュールの先頭でPublicで宣言した定数は、全てのモジュールで使用可能
変数の重複について
もし、宣言が重複してしまった場合です。
Dim i
Sub sample1()
Dim i
i = 1
Module1.i = 2
MsgBox i
MsgBox Module1.i
End Sub
Sub sample2()
Dim i
・・・
End Sub
上記の、sample1を実行すると、 1 2 の順にメッセージ表示されます。
つまり、何も指定しなければ、自身の中で定義した変数が使われます。
こののように、モジュール名で修飾することで、「モジュールレベル変数」を指定して使う事が出来ます。
同一モジュール内で、変数が重複するような使い方は、絶対にダメです。
ただ、指定方法はこれが全てです。
上記のように、モジュール名で修飾して使います。
ただし、これとて決して良いことでは無く、
「モジュールレベル変数」は、全てのモジュールで一意にしておく事が望ましいです。
「モジュールレベル変数」は、あまり使わないことに越したことはありません。
どうしても、「可読性」も悪く、「堅牢性」も落ちます。
出来る限り、プロシージャーをCallする場合は、引数で渡すようにします。
変数は、極力狭いスコープで使う事が望ましいとされます。
いくつものプロシージャーを作り、それぞれをCallしている場合、
意図しない変数の推移となってしまう事を避けるためです。
つまりは、バグを減らす為の工夫になります。
というものです。
変数を使う直前で宣言しておきながら、パプリック変数を多用している事も多々見受けられます。
完全に言葉の意味を勘違いしています。
たかが数十行のプロシージャーにおいて、3行目に宣言しようが8行目に宣言しようが、
何の違いがありますか?という事です。
そして、そもそも、あまり長いプロシージャーは作らないと言うのが基本です。
使用する直前で宣言することを否定しているわけではなく、それにこだわる必要はなく、
臨機応変に記述して構わないということを申し上げています。
ただし、
組織においてコーディング規約があるのであれば、それに従う事が優先されるのは言うまでもないことです。
同じテーマ「マクロVBA入門」の記事
第100回.InputBoxメソッド(インプットボックス)
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。