第6講 サブプロシージャの学習
第6話 変数の使用範囲(スコープ)
参考ダウンロード添付ファイル
Private Sub CommandButton1_Click()
  CommandButton2_Click '社員CommandButton2_Clickに仕事を依頼
  Dim a As Integer '整数型の箱aを用意
  a = 1 '箱aに1を代入
  Cells(3, 2) = "a=" 'B2にa=と表示
  Cells(3, 3) = a '箱の中身を表示
  f '社員fに仕事を依頼
  Cells(4, 2) = "a=" 'B2にa=と表示
  Cells(4, 3) = a '箱の中身を表示
End Sub
Sub f()
  
a = 2
End Sub
Private Sub CommandButton2_Click()
  Rows("3:2000").Select
  Selection.ClearContents
  Cells(1, 1).Select
End Sub
実は、社長CommandButton1_Clickの箱aと社員の箱aは、
名前が同じでも別の箱です。
箱は基本的には、社員専用のものであり、
C言語の絶対的な社長であるmainでさえ、
社員の箱を勝手に使うことは出来ません。
基本的にはと書いたのは、
社員全員が使える箱(変数)を用意することも出来るからです。
社員全員が使える変数をグローバル変数と呼び、
それに対してその箱(変数)を用意した社員しか使えない変数をローカル変数というのですが、
プログラミングの世界ではなるべくグローバル変数は使わない方がよいとされています。
理由は2つです。
①メモリの無駄遣い
②構造化プログラミングの思想に反する
です。
①から説明しましょう。
変数は箱であると比喩していますが、
正確には記憶装置の一部のメモリ(記憶容量)をデータ収納領域として割り振ったものが、
変数です。
今のパソコンのメモリ容量は大容量ですが、
それでもメモリはなるべく節約した方がよいのです。
この講義でも後には何千桁の整数を扱い、かけ算は割り算など考えますが、
何千桁の整数を多数扱うには莫大なメモリを必要とします。
全社員が使えるグローバル変数は、
プログラムが作動している間、
使っていなくてもメモリが割り振られています。
それに対して、社員専用のローカル変数は社員が仕事を終了すると同時に、
変数に割り振られていたメモリは解放され、自由になります。
メモリ(記憶装置の一定の容量)は、実は社員や変数が踊る舞台です。
社員や変数が必要なときだけ舞台を用意してやり、
社員や変数はその舞台で踊るわけです。
グローバル変数を使っていないときには、誰もいない舞台を用意しているようなものです。
ですから、必要なときだけ活動する舞台であるメモリを用意する方がよいわけです。
次に②の説明です。
構造化プログラミングという言葉は何度かこの講義で使ってきました。
構造化プログラミングとは、独立部品を単純に結合させてプログラムを組み立てることです。
構造化プログラミングは、プラモデルからイメージするのが最も適切です。
プラモデルの部品(パーツ)は独立しています。
そして、せいぜい数カ所で結合されています。
プログラムとは反対の例は人体とWebです。
各臓器は独立していません。
相互に依存し合っています。
例えば、膵臓をやられれば仕舞いには他の臓器もやられて、
多臓器不全になって死亡します。
どの内臓も同じで1つでも故障すれば、
最終的には他の臓器も脳なども故障して多臓器不全で死に至ります。
一昔前までは、脳による中央集権型支配であると考えられていましたが、
すべての臓器が他の臓器と会話をして、
お互いに支え合っている地方分権型であることが医学の進展でわかっています。
シナプスによって電気的に交流しているだけではなく、
ホルモンなどの化学物質によって、
情報を交換し合っていることがわかっています。
各臓器は、単純結合ではなく有機的に結びついています。
Webも蜘蛛の巣という意味から、
単純結合ではなく複雑に絡み合った結合です。
かつて、BASICがスパゲティプログラムであるとして揶揄されたのは、
Webのように各パーツ同士が複雑に結びついていたからです。
それに対してプログラミング言語の王さまであるC言語は、
独立部品を単純に結合するという構造化プログラミングの思想が徹底していました。
だからこそ、キングオブキングの地位を勝ち取ってきたのです。

部品が独立しているとは、変数の適用範囲がその部品内に限定されていることを指します。
つまり、変数=箱はその箱を用意した社員専用のもので、
他の社員は箱の中身を勝手に変えることは出来ません。
かつてのBASICが複雑なスパゲッティのようなプログラミングになってしまった原因は、
すべての変数がグローバル変数だったからなのです。
BASICにもサブルーチン(部品)という考え方はありましたが、
変数がすべてグローバル変数であったために、
すべてのサブルーチンで変数の中身が書き換えられてしまう心配があり、
プログラマーはメインルーチンだけでなくすべてのサブルーチンにも目を配らなければならず、
分業は不可能に近いものがありました。
ですがVisual Basicになった現在、
プログラミング言語のキングオブキングであるC言語にも負けない構造化プログラミングの思想
を徹底させています。
各部品(パーツ=社員)で変数の中身が書き換えられる心配がなくなり、
プログラマーは担当の部品の開発に専念できるようになりました。

スコープとは変数の使われる範囲のことですが、
この言葉を使うと、
021
図の矢印の通りとなります。
ところで、社員(サブプロシージャ)fでは、関数の宣言が成されていませんが、
VBやVBAでは、変数の宣言を省略することが出来ます。
変数の宣言を省略して場合バリアント(Variant)型という万能の変数になります。
今のVBではバリアント(Variant)型が廃止されオブジェクト(Object)型になったと私は記憶していますが、
どちらにせよ万能型変数であり一番メモリの大きい変数です。
宣言を省くと自動的に最も容量の大きい万能型変数として用意されてしまいます。

同じ変数名aであっても、
CommandButton1_Clickの用意した箱と、
fが自動的に用意された箱とはまったく別物です。

この話から、引数名が異なっていてもよいことの謎が解明されます。



第5話へ 第7話へ

トップへ