ExcelマクロVBA入門
第108回.変数の適用範囲(スコープ,Private,Public)

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
最終更新日:2019-07-18

第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で宣言した変数は、全てのモジュールで使用可能

変数の重複について

変数の宣言において、多少問題があります。
もし、宣言が重複してしまった場合です。

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)
第109回.列挙型(列挙体)Enum
第110回.ユーザー定義型・構造体(Type)
第111回.静的配列
第112回.動的配列(Redim)
第113回.配列に関連する関数
第114回.セル範囲⇔配列(マクロVBA高速化必須テクニック)
第115回.Split関数


新着記事NEW ・・・新着記事一覧を見る

VBAにおける変数のメモリアドレスについて|VBA技術解説(11月8日)
空文字列の扱い方と処理速度について(""とvbNullString)|VBA技術解説(1月7日)
Errオブジェクトとユーザー定義エラー|VBA入門(11月5日)
シングルクォートの削除とコピー(PrefixCharacter)|VBA技術解説(11月4日)
ユーザー定義型の制限とクラスとの使い分け|VBA技術解説(11月3日)
クリップボードに2次元配列を作成してシートに貼り付ける|VBA技術解説(11月1日)
VBAクラスを使ったイベント作成(Event,RaiseEvent,WithEvents)|VBA技術解説(10月31日)
VBAクラスのAttributeについて(既定メンバーとFor Each)|VBA技術解説(10月19日)
VBAの用語について:ステートメントとは|VBA技術解説(10月16日)
VBAのマルチステートメント(複数のステートメントを同じ行に)|VBA技術解説(10月14日)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数宣言のDimとデータ型|ExcelマクロVBA入門
6.繰り返し処理(For Next)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.ひらがな⇔カタカナの変換|エクセル基本操作
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.セルに文字を入れるとは(Range,Value)|VBA入門



  • >
  • >
  • >
  • 変数の適用範囲(スコープ,Private,Public)

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


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。




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