[Excel2013 で VBA] プロシージャと変数



プロシージャ〜プログラムを複数のブロックに分ける

今まで何度もプログラムを書いてきたので気づいていると思うが、 Visual Basic ではプログラムの中身を以下ような「Sub 〜 End Sub」内に記述する。

Sub 名前(引数リスト)

… (処理内容)

End Sub


このように、処理内容がひとまとめになっているものを (Visual Basic では) 「プロシージャ」と呼ぶ。
プロシージャには Sub プロシージャと Function プロシージャがあるが、 上ものは Sub 〜 End Sub で囲われているので、Sub プロシージャである。

今回はこの Sub プロシージャについてもう少し詳しく学ぼう。

[備考]
Visual Basic におけるプロシージャ (procedure) は、他のプログラミング言語では
関数手続きと呼ばれることが多い。

名前はどうであれ、プロシージャのようにプログラムを複数の部分に分けるという手法は
プログラミングを行う上で必須の知識である。


さて、今までのところはプロシージャはプログラムを記述するための 枠組み、という程度のイメージしかないかも知れないが、
プロシージャの本来の役割は、プログラムをまとまった機能をもった部品に分割することである。

例えば、大きなプログラムを複数の部品に分割し、その部品をグループで手分けして開発する、
などという手法が実際の開発現場で行われている。

機能分割の簡単な例として、以下の例を記述して実行してみよう。
(Visual Basic Editor の起動方法は「第一回:プログラムを書き始めるまでの準備」参照)



横線はプロシージャの区切りで自動的に付加される。

ひと目で分かるように、Sub プロシージャが 3 つある。

実行する際は注意が必要である。複数あるプロシージャのうち、prog8_1 を実行するようにしよう。
すなわち、第一回-02で学んだようにカーソルを prog8_1 内部において実行するようにしよう。(以下の図のように)



正しくプログラムが実行されると、 となり、プログラムが終了するので確認しよう。

この動作から、各プロシージャがどのように働いたのかは想像がつくであろう。 すなわち、 である。すなわち、プログラムを複数の機能を持つ部品に分解していることになる。

さらに、「namae」、「aisatsu」というプロシージャの名前を書くことでプロシージャが呼び出され
namae, aisatsu の処理が終ると呼び出された位置に処理が戻ることもわかる。



プロシージャにおける変数の取扱い (1) プロシージャレベル

複数のプロシージャにプログラムを分割する手法は上で学んだが、 その際、変数の有効範囲が問題になる。

次のプログラムを記述・実行してみよう。



実行結果は最初の例と全く同じであるが、プロシージャ namae と aisatsu で文字列を一旦文字列変数に格納している点が異なる。

この時、プロシージャ namae と aisatsu で同じ名前の変数 s を用いてる点が注目すべきポイントである。
重要なことであるが、プロシージャ内部で宣言した変数はそのプロシージャ内でのみ有効である。
これをプロシージャレベルの変数という。

下図に、それぞれの変数の有効な範囲を示した。
同じ名前の変数 s を使っているが、実際には下の図のように、二つの s は全く別物と考えねばならない。





プロシージャにおける変数の取扱い (2) モジュールレベル

次の例は、変数 s をプロシージャの外部で宣言した場合である。



「Dim s As String」 の位置に注意しよう。
s の宣言は一箇所のみで、各プロシージャ内には宣言はない。

このような変数をモジュールレベルの変数と言い、 そのプログラムの全ての位置から利用可能である。
有効範囲を赤で示すと以下のようにプログラム全体となる。





プロシージャにおける変数の取扱い (3) 混在させると?

このように、変数の有効範囲は、その変数がプロシージャレベルかモジュールレベルかによって異なる。
では、プロシージャレベルとモジュールレベルの変数が混在していたらどうなるだろうか。
例えば、以下の例である。



この例では、モジュールレベルの s と、プロシージャレベルの s (aisatsu 内部) が混在している。
これも試してみると今まで通りの動作が実現される。

それぞれの s の有効範囲を図示すると以下のようになる。



モジュールレベルの s はプログラム全体で使えるのだが、
aisatsu 内部に限っては、プロシージャレベルの s の宣言があるので、そちらが優先される。

変数の宣言にプロシージャレベルとモジュールレベルがあることは分かったが、
これらをどのように使い分ければ良いだろうか?

効能だけを聞くと、モジュールレベルの方がどこでも使えるので便利に思える。
しかし、一般にプログラミングではモジュールレベルよりもプロシージャレベルの変数宣言が用いられる頻度が高い。

冒頭で述べたように、プロシージャを用いる目的の一つはプログラムを複数の部品に分割することである。
せっかくいくつかの部品に分けたのに、それらの部品が一つの変数 (モジュールレベルの変数) を参照していたのでは、
部品が独立しているとは言えないであろう。

つまり、部品の独立性を高めるには、プロシージャレベルの変数を用いた方が良いのである。



←配列引数のある Sub プロシージャ→

Excel 2013 で学ぶ Visual Basic for Applications (VBA)に戻る