みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

エクセルVBAでの変数のスコープ

基本的なことなのですが、教えて下さい。

当方、PHPやjavascriptを中心にプログラムしてきたのですが、
今回、エクセル+VBAでプログラムすることになり、VBAを勉強しているところなのですが、ちょっと戸惑っています。

いままでは、グローバル変数をなるべく使わないように、プログラミングをしてきたのですが、
VBAの勉強で、参考にしている本のコードは、全てグローバル変数を使っています。
そもそも、エクセルのシート・セルがグローバル変数のようなもの(?)なので、変数のスコープにこだわってもあまり意味がないのかな?とも思います。

エクセル+VBAである程度の規模のプログラムを作る際、
変数のスコープはどのように使い分けるのが良いのでしょうか?

すみませんが、ご教授の程、よろしくお願いします。

投稿日時 - 2007-01-28 19:04:09

QNo.2703665

すぐに回答ほしいです

質問者が選んだベストアンサー

誤解されているかもしれないので・・・釈迦に説法だったらごめんなさい。
[XL] Visual Basic for Applications 変数の適用範囲
http://support.microsoft.com/kb/141693/ja

あと、こちらはVB6の話ですがVBAにも共通する点が多いので一読を
http://hp.vector.co.jp/authors/VA020977/kouza/kouza000.htm
の最後に有る
『VBちょっといい話』

投稿日時 - 2007-01-28 22:57:36

お礼

ご回答ありがとうございます。
ご紹介いただいたサイトを拝見しました。
特に一つ目のサイトが、参考になりました。

投稿日時 - 2007-01-30 11:24:38

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

こんにちは。

>VBAの勉強で、参考にしている本のコードは、全てグローバル変数を使っています。

もしかしたら、誤解されているかもしれません。せいぜい、モジュールレベルのスコープだけだと思います。Private キーワードを使わなければ、結果的には、グローバルにはなりますが、ほとんど、著者の頭の中には、モジュールレベル変数ぐらいの扱いしか考えていないと思います。通常、VBAの教本で、Private やPublic を使い分けるような内容は、皆無に近いです。実際に、どうするかなんて、やはり有名なプロの人(ブックのコードを公開している人がいる)のでコードをみて勉強するしか分からないです。VBのコードは、かなり違う印象を受けます。

実務では、Private にして、モジュールレベルのスコープにするというのが、多いかもしれません。また、そういうモジュール単位にプロシージャ群を管理していくことが良いと、本で読んだことがあります。

実際の私は、グローバル変数を使うというのは、多くは、定数か、定数がらみ(その定数を加工して配列変数にする)が多いですね。

>エクセルのシート・セルがグローバル変数のようなもの(?)なので、変数のスコープにこだわってもあまり意味がないのかな?

VBAは、iniファイルや外部ファイルを置くということを嫌います。おっしゃっているセルに置くというのも、いくら、ワークシートを非表示しても、不安を感じることがあります。つまり、そこで、ワークシートのRangeオブジェクトというものを取り扱わなくてはならなくなるからです。Rangeオブジェクトというのは、VBAにとっては、不純物も多いような気がするのです。私は、いつも、なるべくワークシート側とVBA側は、分離したほうがよい、と考えて作っています。

しかし、また、グローバル変数は、時々壊れることがあるので、その点、コード的にも内容的にも複雑なものや、オブジェクト型のものは、必ず、エラー処理をさせるようにしています。思ってもみない失敗に出会うことがあります。それと、あまり、プロシージャの中でその変数を弄り回すようなものは避けたほうがよいとしか言いようがありません。

>バンバン参照渡しを使っていくのが、VBAの流儀なんですかね。

変数を弄り回す場合は、やはり参照渡しにはなってしまいますね。参照渡しにすれば、その点は、確実なので変数の壊れやすさを、カバー出来ますが、ただ、サブルーチンを行ったり来たりしていると、ややこしくなりますね。三つも四つもプロシージャを渡り歩く変数よりは、モジュールレベルの変数に出来るなら、そのほうが良いかと思います。

それから、気がついたことですが、中級ぐらいの人が、Excel VBAで、Names オブジェクトを使う人がいます。あれは、いけませんね。Names オブジェクトは、ワークシート側のもので、VBA側では、なぜかきちんと管理出来ないことがあるのです。その場合は、グローバル変数を使ったほうがよいです。

投稿日時 - 2007-01-29 12:30:28

お礼

くわしいご回答ありがとうございます。

ワークシートが使えるところが便利ですが、自由度が高すぎて、逆に難しいところですね。
おっしゃられるように、ワークシートを変数代わりに使うのは、危なっかしいですね。

ワークシートは、入力と結果表示だけに用いる。
変数はモジュールレベルまでにし、Public変数は使わない。
定数はPublicも可とする。
というのが良さそうな気がしてきました。

まだまだ、Excel VBAに慣れないので、当分は試行錯誤が続きそうです。

投稿日時 - 2007-01-30 11:38:02

ANo.1

Excelのグローバル変数…Public…のスコープは、プロジェクトの中(同一Book内)に限定されるので、ライブラリ間の名前の干渉のようなことをほとんど気にせずにつかえると思います
無制限に使うのはちょっとと思いますが、共通して使用するオブジェクトや定数などの定義など、便利に使えばいいと思います
プログラム経験豊かなようなので、自分がちょっと楽できるという程度に使ってみてはどうでしょうか?
(なんでもかんでも引数で渡すってのは面倒ですよね)

投稿日時 - 2007-01-28 20:34:16

お礼

ご回答ありがとうございます。

>(なんでもかんでも引数で渡すってのは面倒ですよね)
いままで、全て、引き渡していたもんで、不安になってしまいます。

変数の宣言を、プロシージャ内、モジュール内、publicで使い分けて、
バンバン参照渡しを使っていくのが、VBAの流儀なんですかね。

投稿日時 - 2007-01-28 21:14:39

あなたにオススメの質問