変数の有効範囲

今まで、Dimステートメントで、変数の宣言をしてきました。
しかし実は、変数の宣言の仕方次第で、いろいろな範囲があります。
いろいろ紹介はしますが、普段はプロシージャ内でDimで宣言した方が便利です。

1.Staticで宣言する。

今までは、Dimを使って宣言してきましたが、下のプロシージャでは、Staticで宣言しました。
Staticで宣言すると、そのプロシージャ内に限って、値を保存しておくことができます。
(他のプロシージャから、呼び出すことはできません。)

このプロシージャは、1桁のスロットマシンです。
ボタンを押すと数字が変わり、もう一度ボタンを押すと止まります。
1つのボタンで違う操作になるのは、プロシージャの処理が終わっても、
変数「スイッチ」に値が保存されているからです。

Sub test()

  Static スイッチ As Boolean ←@

  スイッチ = Not スイッチ ←A

  Do Until スイッチ = False ←B
    Cells(1, 1) = (Cells(1, 1) + 1) Mod 10 ←C
    DoEvents ←D
  Loop

End Sub
 
@ 論理値で宣言します。( True / False )

A 変数「スイッチ」の内容を反転させます。
  (TrueならFalseに、FalseならTrueに)

B スイッチの値がFalseの時、処理を終わります。

C Celss(1,1)に1を足して、10で割った余りを
  Celss(1,1)に書き込んでます。

D これは、OSに制御を渡す関数です。
  これを設定しないと、プロシージャが制御を
  占有してしまい、ボタンが押せません。

2.他の宣言の仕方を知る。

以下に、変数の宣言の仕方と範囲を書きますが、範囲が広い宣言は本当に必要なときだけ使うことが大切です。
そうしないと、どこでその影響を受けているのか、わからなくなってしまうからです。
基本的には、プロシージャ内で宣言する狭い範囲(Dim)にしておいた方が無難です。

Public c As Integer ←@
Dim d As Integer ←A
 
@ プロジェクト内全体で使えます。

A このモジュール内で使えます。 
Sub test1()

Dim a As Integer

MsgBox a
a = 11

End Sub
 
test1

表示する順番と代入する順番が逆なので、
何度実行しても、0を表示します。
Sub test2()

Static b As Integer

MsgBox b
b = 10

End Sub
 
test2

Staticで宣言しているので、値を保存します。
したがって、1度目の表示は0ですが、
2度目は10を表示します。 
Sub test3()

MsgBox a

End Sub
 
test3

aは、test1で宣言していますが、test1が終わると
解放されてしまいます。
したがって、ここでは宣言してないので、エラーになります。
Sub test4()

MsgBox b

End Sub
 
test4

bは、test2で宣言していますが、Staticで宣言しているので、
他のプロシージャからは認識できません。
したがって、エラーになります。
Sub test5()

c = 123

End Sub
 
test5

cは、行頭でPublicで宣言しているので、どこでも使えます。
したがって、ここではいきなり代入ができます。 
Sub test6()

MsgBox c

End Sub
 
test6

test5を実行したあとなら、123を表示します。
Sub test7()

d = 1234

End Sub
 
test7

dは、行頭でこのプロシージャ内で有効な形で宣言しているので、
いきなり代入ができます。
Sub test8()

MsgBox d

End Sub
 
test8

test7を実行した後なら、1234を表示します。