dポイントプレゼントキャンペーン実施中!

最近、ExcelのVBAを勉強してるのですが、そこで書籍の中に、

>《挿入》→《プロシージャ》を実行すると、
>作成するプロシージャがPublicかPrivateかを選択します。
>Privateにすると、そのプロシージャは
>そのモジュール内でしか実行できません。

とあるのですが、「そのモジュール内でしか実行できません」っていうのがよくわからないのですけど、具体的にはどういった使い分けが出来るのでしょうか?

A 回答 (4件)

新しくエクセルブックを作成します。



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.」とかをつけることによって、
どのモジュール内に書かれたプロシージャかを区別することができるようになり、
正しく動くようになるというわけです。

長くなりました。スコープとはこういうことだと思います。間違えたことを
書いていたらどなたか正してください。
    • good
    • 0
この回答へのお礼

ishikawa1105jpさん、ご親切な御回答、誠にありがとうございます!!!!!

コマンドボタンのイベントプロシージャの記述の所がよくわからず、うまくいかなかったのですが、他の出来るところは色々試してやってみました!

あと

>Module1、Module2それぞれに同じ名前のPublicプロシージャ「TestSub2」がある状態で、
Sheet1から「TestSub2」を呼び出すと、どのようなことが起きるか、やってみます。
どうなるでしょうか。

>結果は「名前が適切ではありません:TestSub2」というアラートが出ます。

これが、Sheet1でやっても上のアラートが出ず、普通に実行できちゃいました・・・
なんかやり方がまずいんでしょうね^^;


でも、例えば、(Sheet1などで)マクロの登録・実行の所で、「Private」で記述したもの(TestSub1)は登録・実行できない(見えない)ようになってたり、Module1内でしか実行できなかったりと、少しイメージがわかったような気がします

改めてお礼申し上げますm(_ _)m

お礼日時:2004/06/11 09:19

#1です。



>> そこで、Module1内で・・・
そうです、そういった考え方で間違いありません。細かな使い分けをするだとかといった理由でPublicとPrivateとを区別するケースもありますが、大まかにはpopesyuさんの言われるとおりだと理解してください。「大は小を兼ねる」と言いますが、無駄に大きいとリソース(メモリ)を消費するだけで動作が遅くなったりするのを避けるため、小には小で対処すれば良いという解釈でOKでしょう(大;Public、小;Private)。

詳細は、ishikawa1105jpさんが回答されておりますので割愛。懇切丁寧な回答に敬意、です。一度試されてみては?

細かな意味合いの理解も大切ですが、とにかく慣れることです。全てを解読、理解しながらだとなかなか前へ進めませんよ(経験談)。
    • good
    • 0
この回答へのお礼

再びきてくださいまして、sanakazuさん、ありがとうございます!!!!!

>とにかく慣れることです。

私も最近そう思うようになってきました!
今、ひたすらコードを打ち込んだりしていますが、なんとなく前より、プログラムへの拒否反応がなくなりましたし、英数字・記号のタイピングも慣れてきました。少し法則性もつかめてきましたし、今日もどしどし、実験練習してみます!

アドバイス、改めてお礼申し上げますm(_ _)m

お礼日時:2004/06/11 09:35

Publicはその名の通り公共的な公のという意味で、公開・共有されます。

つまり、どこからでも使える(参照できる)ということです。
一方Privateは個人的なとかいう意味で、参照範囲が限定されています。
例えばPC同士をLANで接続してフォルダを共有させる場合、そのフォルダはPublicになりますね。どのPCからでも参照できます。共有させなフォルダはそのPCからでしか参照できません。これはPrivateです。
同様にModule1内で、Privateで宣言された関数・変数はModule1からでしか参照できませんし、Module1でPublicで宣言された関数・変数はどこからでも参照できます。

使い分けに関しては
何でもかんでもPublicにしておくというのも一つの手なんですがw
まぁ混乱のもとになりますし、リソースを無駄に消費させますし、あまりお勧めはできません。
基本はPrivateで。他のところからも参照させたい関数・変数のみPublicにするというのが王道です。
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/06/11 09:30

定数で例えます。



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を実行できない、となります。

いや、そうだったはずです・・・。以前の記憶なので、すみません。
    • good
    • 0
この回答へのお礼

sanakazuさん、御回答ありがとうございます!!!!!

すみません、なんとなくわかったようなわからないような・・・(ーー;)

例えば、エクセルのVBEでいうと、挿入メニューで、どんどん「標準モジュール」を「Module1,Module2」と追加できますよね?

そこで、Module1内で、Privateプロシージャを使ったら、その中でしか、宣言した定数(?)とやらは使えないということですか?

その逆で、Publicの場合でしたら、Module1で宣言した定数なども、他で追加したModulu2でもそのまま使えるという事でしょうか?

いたらなくてすみません(T_T)もう一度、ここ覗かれましてお時間とれましたら教えて下さいm(_ _)m

お礼日時:2004/06/10 12:37

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!