変数の宣言と初期化、有効(適用)範囲

変数は、その宣言場所と宣言方法で有効(適用)範囲が異なります。



「変数」とは!?
自動記録(マクロの記録)では「変数」は一切発生しません。
ですから、自動記録で作成されたマクロのコード記述を見ているだけでは「変数」を理解することはできません。
自動記録ではワークシート上のセルの値に対する処理を行なうことがあるので、これが「変数」と同義的なものと考えているかも知れません。 ですが、セルの値は通常は視覚的に見えるものですが、「変数」は視覚的な実体がなく値も通常は見えません。
実は既に「繰り返しや判断、分岐などは昔からあるBASICと同じ。」のサンプルでは利用しています。 「変数」は処理上必要な値などの「一時置き場」と考えて下さい。

変数を宣言する場所と宣言の方法による違いは実際の記述はこのようになります。


'***************************************************************************************************
'   変数宣言の説明
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
Option Explicit
' プロシージャを超えて参照する変数/定数は動作するプロシージャの前(外)で宣言する。
Public X                        ' ←他モジュールからも参照可(変数)
Private Y                       ' ←このモジュールからのみ参照可(変数)
Public Const A = "AAA"          ' ←他モジュールからも参照可(定数)
Private Const B = "BBB"         ' ←このモジュールからのみ参照可(定数)

'***************************************************************************************************
'  テスト
'***************************************************************************************************
Sub TEST()
     ' プロシージャ固有の変数/定数はプロシージャ内で使用する手前で宣言する。
    Dim Y                       ' ←同一名はモジュールレベルよりプロシージャレベルが優先
    Static Z                    ' ←制御がプロシージャを抜けても保持される
    Const C = "CCC"             ' ←プロシージャレベルでの定数

End Sub

'------------------------------------------<< End of Source >>--------------------------------------


※データ型の説明がまだなので、ここではデータ型を明示していません。



変数は必要があって宣言するものであって、不要な変数を宣言することはありません。 「たぶん必要だろう」で宣言して利用せずに放置してもエラーにはなりませんが、テスト工程で邪魔になるだけなので削除するようにして下さい。

モジュールレベルの変数
プロシージャ内部での宣言ではなく、モジュール内でプロシージャが始まる前(上)に記述する変数です。上のサンプルだと「X」と「Y」がそれに当たります。モジュールレベルの変数は、プログラムの先頭で初期化され、以降制御がどのモジュールのどのプロシージャに移ってもプログラムの終了まで内容が保持されています。
一般にモジュールレベルの変数は保持期間が長いため、不必要に宣言すべきではないと言われています。つまり、プロシージャレベルで済むものはプロシージャレベルで宣言するべきということになります。
  • Public」で宣言する変数は、プロジェクト内の全ての場所から参照することができます。
    Public」は「Global」と書いても同じです。(「Global」は古い書き方なので避けましょう)
  • Private」で宣言する変数は、このモジュール内の各プロシージャからは参照できますが、プロジェクト内の他のモジュールからは参照できません。 「Private」は「Dim」と書いても同じです。
  • Const」での宣言は、定数の宣言です。定数名の右に「=」で内容を書き込みます。これは定数であり、処理中での内容の書き換えはできません。 「Const」の前に「Public」、「Private」が明示できます。明示しない場合は「Private」と同じになります。
有効(適用)範囲は「スコープ」とも呼ばれています。
ここでの説明から「面倒だし良く解らないから広め(Public)にしておこう」というのは早計な考え方です。
ExcelVBAの特殊性はありますが、「Public」は本来、プロジェクトの外へ「公開」するということであり、セキュリティ面でも必要最小限にすべきものです。 さらに、プロジェクト内に「Public AAA」と「Private AAA」の両方があったらどうなるかなども理解しておかなければなりません。
有効(適用)範囲(スコープ)は、できるだけ狭く設定しておくべきなのです。

ExcelVBAはこれだけですが、VB.NETには「Friend」という有効(適用)範囲(スコープ)があります。
  これは他モジュールからの参照は許すが、プロジェクト外からの参照は許さないというものになります。

※変数名は本来は社内規約などの約束事があり、このサンプルのような「A」「B」...という無意味な名称は許されません。

プロシージャレベルの変数
プロシージャ内部では、実際にその変数を使用する記述より上で変数を宣言しておく必要があります。一般にはプロシージャの先頭にまとめて記述します。モジュールレベルで宣言されている変数と同じ名前の変数がある場合はプロシージャ内の変数が参照されます。
  • Dim」で宣言する変数は、そのモジュール内のみが適用範囲(参照できる範囲)となります。「Dim」で宣言する変数は、そのプロシージャが呼び出される都度初期化されます。
  • Static」で宣言する変数も、そのモジュール内のみが適用範囲となりますが、「Dim」で宣言する変数と異なりプロシージャ内での処理が終了し、制御が他に移ってもその変数は初期化されません。次回そのプロシージャが呼び出された時に、以前の内容が保持されたままになります。
  • Const」での宣言は、定数の宣言です。定数名の右に「=」で内容を書き込みます。これは定数であり、処理中での内容の書き換えはできません。