第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入門」の記事
第105回.Callステートメント
第106回.Functionプロシージャー
第107回.プロシージャーの引数
第108回.変数の適用範囲(スコープ,Private,Public)
第100回.InputBoxメソッド(インプットボックス)
第101回.Midステートメント
第102回.Intersectメソッド
第103回.UnionメソッドとAreasプロパティ
第104回.GetPhoneticメソッドとSetPhoneticメソッド(フリガナ)
第109回.列挙型(列挙体)Enum
第110回.ユーザー定義型・構造体(Type)
新着記事NEW ・・・新着記事一覧を見る
シート関数のCOUNTIFS,SUMIFS,MAXIFSと同じ処理|Power Query(M言語)入門(2023-02-28)
新旧マスタの差異比較|Power Query(M言語)入門(2023-02-28)
有効な最新単価の取得|Power Query(M言語)入門(2023-02-26)
有効な最新単価の取得|Power Query(M言語)入門(2023-02-21)
グルーブ内の最小・最大|Power Query(M言語)入門(2023-02-17)
2つのテーブルのマージ|Power Query(M言語)入門(2023-02-15)
「売上」が数値の行のみ取り込む|Power Query(M言語)入門(2023-02-13)
A列のヘッダー名を変更する|Power Query(M言語)入門(2023-02-11)
CSVのA列が日付の行だけを取り込む|Power Query(M言語)入門(2023-02-10)
列数不定のCSVの取り込み|Power Query(M言語)入門(2023-02-09)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.マクロって何?VBAって何?|VBA入門
7.並べ替え(Sort)|VBA入門
8.エクセルVBAでのシート指定方法|VBA技術解説
9.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
10.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。