変数の有効範囲について(スコープ)

変数を宣言した場所や宣言の書き方によって、宣言した変数の使える範囲が変わってきます。変数には、一つのプログラム全体で使える変数、一つのモジュール内で使える変数、一つのプロシージャ内で使える変数があります。以下のリスト10を見てください。

[リスト10]変数の有効範囲(yuukou.xlsm)

'==== Module1 =======
Public Ph As Integer    '(1)
Dim Gh As Integer   '(2)
Sub test1()
    Dim Lh As Integer   '(3)
    Ph = 1000
    Gh = 100
    Lh = 10
    MsgBox (Ph) '結果1000
    MsgBox (Gh) '結果100
    MsgBox (Lh) '結果10
End Sub
Sub test2()
    test1
    MsgBox (Ph) '結果1000
    MsgBox (Gh) '結果100
    MsgBox (Lh) '結果無し
End Sub

'==== Module2 =======
Sub test3()
    test2
    MsgBox (Ph) '結果1000
    MsgBox (Gh) '結果無し
    MsgBox (Lh) '結果無し
End Sub

(1)はプログラム全体で使用する変数の宣言です。(2)は一つのモジュール(グループ分けされた一つのまとまり)内で使用できます。(3)は一つのプロシージャ(SubやFunction)内で使用します。

(1)はどのモジュール内でも構いませんが、モジュールの最初に「Public」を宣言して指定します。(2)の宣言場所は、各モジュールの最初に書きます。「Dim」で宣言します。(3)はプロシージャ内の最初に「Dim」で宣言します。

test3マクロを実行してみましょう。まずtest1が実行されPh/Gh/Lhとも、値が表示されます。次にtest2(同じモジュール内)が実行され、Ph/Ghに、値があることがわかります。最後にtest3内のPh/Gh/Lhが表示されますが、値が入っているのは、Phのみです。 有効範囲を図示します。

図3:変数の有効範囲

各範囲で使える変数を使い分けると、プログラムの流れもすっきりすると思います。

配列

配列については、文字列関数編(2)で少し触れています。数個のデータをまとめて扱いたい時などに、変数名を一つ作成します。一つの変数名で数個のデータを管理できるのが、配列変数と言われるものです。文字列関数編(2)でも載せた図ですが、以下にイメージを示します。

図4:配列イメージ

配列全体に名前を付けて、内容は番号で指定します。図は順に1,2,3と5までの数値が箱に入っています。 変数名をfとすると、f(1),f(2)などかっこ「()」を付けて順番に表します。(1)、(2)等の数値も変数にしてf(i)という書き方もできます。かっこの中の数値が1個のときは、横に順番に並んでいるイメージで考えると、がわかりやすいと思います。かっこの中の数値が1個の配列変数を一次元配列といいます。

縦と横に並んでいる配列を二次元配列といいます。d(i,j)のように書きます。もし 「Dim d(2,3) As Integer」と宣言した場合、2 X 3 の6個の変数枠を使えることになります。

一次元配列

一次元配列の例題を考えてみましょう。一次元配列変数に数値が入っているとして、内容をすべて足し合わせてみましょう。リスト11を見てください。

[リスト11]一次元配列例題(itizi.xlsm)

Dim f(5) As Integer
Dim i As Integer
Dim g As Integer    '合計エリア
f(1) = 5    '(1)
f(2) = 8
f(3) = 7
f(4) = 12
f(5) = 9     '数値設定

g = 0
For i = 1 To 5  '(2)
    g = g + f(i)
Next
MsgBox (g)  '結果 41

(1)で一次元配列に5個の数値をセットしました。(2)で合計の計算を行っています。配列変数の場合かっこ内に変数を使用することができるので、for文などを使って、まとめて処理することができるようになります。

二次元配列

二次元配列の場合縦、横に並んでいるイメージで考えるとわかりやすいと思います。リスト12を見てください。

[リスト12]二次元配列例題(nizi.xlsm)

Dim d(2, 3) As Integer
Dim x As Integer
Dim y As Integer
Dim g As Integer

d(1, 1) = 2     '(1)
d(1, 2) = 5
d(1, 3) = 6

d(2, 1) = 8
d(2, 2) = 3
d(2, 3) = 4

g = 0
For x = 1 To 3  '(2)
    g = g + d(1, x)
Next
MsgBox (g)      '結果 13

g = 0
For y = 1 To 2  '(3)
    For x = 1 To 3
        g = g + d(y, x)
    Next
Next
MsgBox (g)      '結果 28

2 x 3の二次元配列を宣言しました。(1)で値をセットしています。(2)は縦1行目の横3個の数値を足しています。すべてを足すには、Forの二重ループを使用します。

配列変数について

一次元配列と二次元配列を見てきましたが、同じ考え方で3次元、4次元も作成することができます、何に使うかはみなさんのアイデアしだいです。あまり次元が多くなると、想像が追い付かなくなりそうです。 今までの説明で、「dim f(5) as Integer」等としたとき、理解しやすいだろうということで、f(1)から初めていました。メモリーでの配列変数のエリアは(0)から作成されています。「dim f(5) as Integer」と宣言した場合6個の枠がとられていることになります。ただ使用していないだけです。メモリー上でも(1)からにしたい場合は「Option Base 1」をモジュールの最初に宣言します。

まとめ

今回は変数についてまとめて見ました。他の言語を使うにしても、プログラムを作成するうえで、必ず必要になるものです。基本の考え方は、どの言語でも同じです。ExcelのVBAをしっかり理解した上で、他の言語を覗いてみると、「なんだかよくわかる!」という感覚になれるのではないかと思います。

WINGSプロジェクト 横塚利津子著/山田祥寛監修
<WINGSプロジェクトについて>テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。2009年4月時点での登録メンバは30 名で、現在も一緒に執筆をできる有志を募集中。