VBA入門
変数の適用範囲(スコープ,Private,Public)

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
公開日:2013年5月以前 最終更新日:2021-11-16

第108回.変数の適用範囲(スコープ,Private,Public)


変数には、その変数をVBA内で使う事ができる範囲が決められています。
マクロ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 ] 定数名 [ As データ型 ] = 値

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 ・・・新着記事一覧を見る

AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ