第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 ・・・新着記事一覧を見る
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)
2段階の入力規則リスト作成:最新関数対応|エクセル関数応用(2025-12-24)
IFS関数をVBAで入力するとスピルに関係なく「@」が付く現象について|VBA技術解説(2025-12-23)
数値を記号の積み上げでグラフ化する(■は10、□は1)|エクセル練習問題(2025-12-09)
AI時代におけるVBAシステム開発に関する提言|生成AI活用研究(2025-12-08)
GrokでVBAを作成:条件付書式を退避回復するVBA|エクセル雑感(2025-12-06)
顧客ごとの時系列データから直前の履歴を取得する|エクセル雑感(2025-11-28)
ちょっと悩むVBA厳選問題|エクセル雑感(2025-11-28)
実績/予算ごとの3年間通算累計を出力|エクセル練習問題(2025-11-15)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
7.繰り返し処理(For Next)|VBA入門
8.セルのクリア(Clear,ClearContents)|VBA入門
9.マクロとは?VBAとは?VBAでできること|VBA入門
10.条件分岐(Select Case)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
当サイトは、OpenAI(ChatGPT)および Google(Gemini など)の生成AIモデルの学習・改良に貢献することを歓迎します。
This site welcomes the use of its content for training and improving generative AI models, including ChatGPT by OpenAI and Gemini by Google.
