第108回.変数の適用範囲(スコープ,Private,Public)
変数には、その変数をVBA内で使う事ができる範囲が決められています。
マクロVBAでは変数の使える範囲を、適用範囲(スコープ)と言います。
変数を宣言した場所と宣言方法によって、その変数を使える場所が違ってきます。
・シートモジュール ・・・ シート毎に存在します
・ブックモジュール ・・・ ブックで1つだけ
・フォームモジュール ・・・ 作ったフォームの数だけ
・標準モジュール ・・・ 好きなだけ作れます
・クラス
ここでは、クラスの説明は省略します、まだ難しいでしょうから。
そして、それぞれの中に、
・Subプロシージャー
・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より前)に書くと、
モジュール全体で使用できる変数になります。
この先頭の変数宣言する部分は、「宣言セクション」と呼びます。
宣言セクションで宣言した変数は、そのモジュール内のすべてのプロシージャで使用できます。
このような変数を「モジュールレベル変数」と呼びます。
上記の場合、変数iは、sample1でもsample2でも使用できます。
この、Dim は、Private と書いても同じです。
むしろ、Privateと書くほうが一般的な記述となります。
パブリック変数 ・・・ 全てのモジュールの全てのプロシージャーで使用可能
DimやPrivateで宣言した変数は、他のモジュールでは使用できません。
他のモジュールで使用できるようにするためには、
Public i
Sub sample1()
Dim j
・・・
End Sub
Sub sample2()
Dim j
・・・
End Sub
上記のように、Publicで宣言します。
こうする事で、変数iは、他のモジュールでも使用できます。
Dim ・・・ そのモジュールのみ
Private ・・・ そのモジュールのみ
Public ・・・ 全てのモジュール
VBAではあまり言わないようですが、他のプログラミング言語では、
グローバル変数
と言う言い方もします。
・標準モジュール
・ブックモジュール
・シートモジュール
・ユーザーフォーム
・クラスモジュール
変数の適用範囲について簡単にまとめてると
モジュールの先頭でDimまたはPrivateで宣言した変数は、そのモジュール内でのみ使用可能
モジュールの先頭でPublicで宣言した変数は、全てのモジュールで使用可能
定数(Const)の適用範囲について
Constステートメント
PublicおよびPrivateは、宣言セクションでのみ使用できます。
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 の順にメッセージ表示されます。
つまり、何も指定しなければ、自身の中で定義した変数が使われます。
Module1.i
こののように、モジュール名で修飾することで、「モジュールレベル変数」を使う事が出来ます。
上記は、ちょっと極端な例で、説明の為に無理やり書いたものです。
同一モジュール内で、変数が重複するような使い方は、絶対にダメです。
ただ、指定方法はこれが全てです。
上記のように、モジュール名で修飾して使います。
ただし、これとて、決して良いことでは無く、
「モジュールレベル変数」は、全てのモジュールで一意にしておく事が望ましいです。
いや、望ましい事を言えば、
「モジュールレベル変数」は、あまり使わないことに越したことはありません。
どうしても、「可読性」も悪く、「堅牢性」も落ちます。
出来る限り、プロシージャーをCallする場合は、引数で渡すようにします。
変数は、極力狭いスコープで使う事が望ましいとされます。
いくつものプロシージャーを作り、それぞれをCallしている場合、
意図しない変数の推移となってしまう事を避けるためです。
つまりは、バグを減らす為の工夫になります。
というものです。
変数のスコープを狭くというのは、何もそういう事ではありません。
変数を使う直前で宣言しておきながら、パプリック変数を多用している事も多々見受けられます。
完全に言葉の意味を勘違いしています。
1,000行もあるプロシージャーなら分かりますが、
たかが数十行のプロシージャーにおいて、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 ・・・新着記事一覧を見る
VBA100本ノック 100本目:WEBから100本ノックのリストを取得|VBA練習問題(3月3日)
VBA100本ノック 99本目:自動席替え(行列と前後左右が全て違うように)|VBA練習問題(3月2日)
VBA100本ノック 98本目:席替えルールが守られているか確認|VBA練習問題(3月1日)
VBA100本ノック 97本目:Accessデータを取得(グループ集計)|VBA練習問題(2月27日)
VBA100本ノック 96本目:Accessデータを取得(マスタ結合&抽出)|VBA練習問題(2月26日)
VBA100本ノック 95本目:図形のテキストを検索するフォーム作成|VBA練習問題(2月24日)
VBA100本ノック 94本目:表範囲からHTMLのtableタグを作成|VBA練習問題(2月23日)
VBA100本ノック 93本目:複数ブックを連結して再分割|VBA練習問題(2月22日)
VBA100本ノック 92本目:セルの色を16進で返す関数|VBA練習問題(2月20日)
VBA100本ノック 91本目:時間計算(残業時間の月間合計)|VBA練習問題(2月19日)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.マクロって何?VBAって何?|VBA入門
5.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
6.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
7.繰り返し処理(For Next)|VBA入門
8.セルに文字を入れるとは(Range,Value)|VBA入門
9.マクロはどこに書くの(VBEの起動)|VBA入門
10.とにかく書いてみよう(Sub,End Sub)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。