• ベストアンサー

Excel97のVBAで、出てくるPublic(プロージャ)とPrivate(プロシージャ)の違い

最近、ExcelのVBAを勉強してるのですが、そこで書籍の中に、 >《挿入》→《プロシージャ》を実行すると、 >作成するプロシージャがPublicかPrivateかを選択します。 >Privateにすると、そのプロシージャは >そのモジュール内でしか実行できません。 とあるのですが、「そのモジュール内でしか実行できません」っていうのがよくわからないのですけど、具体的にはどういった使い分けが出来るのでしょうか?

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

  • ベストアンサー
noname#21585
noname#21585
回答No.2

新しくエクセルブックを作成します。 VBEを開き、Module1を作り、これにprivateプロシージャとpublicプロシージャを それぞれひとつずつ記述してみます。 Private Sub TestSub1()   MsgBox ("私はModule1のTestSub1です。") End Sub と Public Sub TestSub2()   MsgBox ("私はModule1のTestSub2です。") End Sub 次に、エクセルのSheet1にコマンドボタンを追加します。そしてこのボタンの イベントプロシージャを次のように記述します。 Private Sub CommandButton1_Click()   Call TestSub1 End Sub これは、CommandButton1をクリックすると、TestSub1を呼び出して実行するという 意味になります。早速クリックしてみましょう。「私はModule1のTestSub1です。」 というメッセージボックスが出るでしょうか。 結果は、出ません。代わりに「SubまたはFunctionが定義されていません。」と 出ます。 なぜ?TestSub1はModule1内に定義してあるじゃないか。 なぜなら、Module1内に定義されたTestSub1は、Privateとされているからです。 TestSub1は、Privateと宣言されているため、Sheet1内で使うことはできない わけです。TestSub1は、Module1内でしか使うことができないわけです。 それでは、Sheet1のCommandButton1のイベントプロシージャを書き換えてみます。 Private Sub CommandButton1_Click()   Call TestSub2 End Sub これは、CommandButton1をクリックすると、TestSub2を呼び出して実行するという 意味になります。早速クリックしてみましょう。「私はModule1のTestSub2です。」 というメッセージボックスが出るでしょうか。 出ますね。さっきのTestSub1は呼び出せなかったのに、なぜ今度は呼び出せるのか? なぜなら、TestSub2はPublicとされているからです。testSub2はPublicと宣言されて いるため、Module1内のみならずSheet1内でも使うことができるというわけです。 これが、 Public と Private の違いです。また、この、プロシージャや 変数を使える範囲のことを「スコープ」といいます。 では次にModule2を作成して(新規標準モジュールを追加して)、これに次の プロシージャを記述してみます。 Public Sub TestSub2()   MsgBox ("私はModule2のTestSub2です。") End Sub このプロシージャは、Module1のTestSub2と同名です。違うのはMsgBox内の文字列が 違うだけです。 Module1、Module2それぞれに同じ名前のPublicプロシージャ「TestSub2」がある状態で、 Sheet1から「TestSub2」を呼び出すと、どのようなことが起きるか、やってみます。 どうなるでしょうか。 結果は「名前が適切ではありません:TestSub2」というアラートが出ます。 これは、Module1にもModule2にもPublicな同名のプロシージャ「TestSub2」が 定義されているため、CommandButton1_Clickで呼び出すときにどちらを呼んでよいか 判断できないために表示されるものです。例えばもしもどちらかのTestSub2が Privateになっていれば、こうなならないわけですし、名前が一文字でも違っていれば こうはなりません。 が、このような事態を防ぐために、どちらかのスコープを変えるとか名前を 変えるというのは、本来の方法ではありません。こういう場合は、CommandButton1_Click をこう書き換えます。 Private Sub CommandButton1_Click()   Call Module1.TestSub2 End Sub または Private Sub CommandButton1_Click()   Call Module2.TestSub2 End Sub TestSub2の前に「Module1.」とか「Module2.」とかをつけることによって、 どのモジュール内に書かれたプロシージャかを区別することができるようになり、 正しく動くようになるというわけです。 長くなりました。スコープとはこういうことだと思います。間違えたことを 書いていたらどなたか正してください。

noitigo
質問者

お礼

ishikawa1105jpさん、ご親切な御回答、誠にありがとうございます!!!!! コマンドボタンのイベントプロシージャの記述の所がよくわからず、うまくいかなかったのですが、他の出来るところは色々試してやってみました! あと >Module1、Module2それぞれに同じ名前のPublicプロシージャ「TestSub2」がある状態で、 Sheet1から「TestSub2」を呼び出すと、どのようなことが起きるか、やってみます。 どうなるでしょうか。 >結果は「名前が適切ではありません:TestSub2」というアラートが出ます。 これが、Sheet1でやっても上のアラートが出ず、普通に実行できちゃいました・・・ なんかやり方がまずいんでしょうね^^; でも、例えば、(Sheet1などで)マクロの登録・実行の所で、「Private」で記述したもの(TestSub1)は登録・実行できない(見えない)ようになってたり、Module1内でしか実行できなかったりと、少しイメージがわかったような気がします 改めてお礼申し上げますm(_ _)m

その他の回答 (3)

  • sanakazu
  • ベストアンサー率18% (43/230)
回答No.4

#1です。 >> そこで、Module1内で・・・ そうです、そういった考え方で間違いありません。細かな使い分けをするだとかといった理由でPublicとPrivateとを区別するケースもありますが、大まかにはpopesyuさんの言われるとおりだと理解してください。「大は小を兼ねる」と言いますが、無駄に大きいとリソース(メモリ)を消費するだけで動作が遅くなったりするのを避けるため、小には小で対処すれば良いという解釈でOKでしょう(大;Public、小;Private)。 詳細は、ishikawa1105jpさんが回答されておりますので割愛。懇切丁寧な回答に敬意、です。一度試されてみては? 細かな意味合いの理解も大切ですが、とにかく慣れることです。全てを解読、理解しながらだとなかなか前へ進めませんよ(経験談)。

noitigo
質問者

お礼

再びきてくださいまして、sanakazuさん、ありがとうございます!!!!! >とにかく慣れることです。 私も最近そう思うようになってきました! 今、ひたすらコードを打ち込んだりしていますが、なんとなく前より、プログラムへの拒否反応がなくなりましたし、英数字・記号のタイピングも慣れてきました。少し法則性もつかめてきましたし、今日もどしどし、実験練習してみます! アドバイス、改めてお礼申し上げますm(_ _)m

  • popesyu
  • ベストアンサー率36% (1782/4883)
回答No.3

Publicはその名の通り公共的な公のという意味で、公開・共有されます。つまり、どこからでも使える(参照できる)ということです。 一方Privateは個人的なとかいう意味で、参照範囲が限定されています。 例えばPC同士をLANで接続してフォルダを共有させる場合、そのフォルダはPublicになりますね。どのPCからでも参照できます。共有させなフォルダはそのPCからでしか参照できません。これはPrivateです。 同様にModule1内で、Privateで宣言された関数・変数はModule1からでしか参照できませんし、Module1でPublicで宣言された関数・変数はどこからでも参照できます。 使い分けに関しては 何でもかんでもPublicにしておくというのも一つの手なんですがw まぁ混乱のもとになりますし、リソースを無駄に消費させますし、あまりお勧めはできません。 基本はPrivateで。他のところからも参照させたい関数・変数のみPublicにするというのが王道です。

noitigo
質問者

お礼

色々、使い分けがあるのですね!! でも、私にはまだ使い分けできるスキルがないので、当分はPublicでやって慣れてきたらPrivateの方も試していきたいと思います。 popesyuさん、ご回答ありがとうございました!!!

  • sanakazu
  • ベストアンサー率18% (43/230)
回答No.1

定数で例えます。 Publicで宣言した定数は、変更しない限りどのモジュールでも同じ値です(例;Public Const abc = 1、どのモジュールでabcを呼び出しても必ず"1"が入っています)。それに対して、Privateで宣言した場合にはそのモジュール内でしか定数は与えられません(例;Private Const abc = 1、他のモジュールではabcは"empty(からっぽ)")。 Subですと、Module1で"Public Sub step1"とすればModule2からでもstep1を実行できますが、Module1で"Private Sub step1"とすればModule2からだとstep1を実行できない、となります。 いや、そうだったはずです・・・。以前の記憶なので、すみません。

noitigo
質問者

お礼

sanakazuさん、御回答ありがとうございます!!!!! すみません、なんとなくわかったようなわからないような・・・(ーー;) 例えば、エクセルのVBEでいうと、挿入メニューで、どんどん「標準モジュール」を「Module1,Module2」と追加できますよね? そこで、Module1内で、Privateプロシージャを使ったら、その中でしか、宣言した定数(?)とやらは使えないということですか? その逆で、Publicの場合でしたら、Module1で宣言した定数なども、他で追加したModulu2でもそのまま使えるという事でしょうか? いたらなくてすみません(T_T)もう一度、ここ覗かれましてお時間とれましたら教えて下さいm(_ _)m