• ベストアンサー

【VBA】SUBプロシージャーは標準モジュール以外に書いてもいい?

ThisWorkbookのコードを書く場所や Sheetのイベントプロシージャーが実行されるところに Sub test() MsgBox "あああ" End Sub と書いて実行するとメッセージボックスが表示されます。 クラスモジュールとフォームのイベントプロシージャーを書くところではできませんでした。 ということはSUBプロシージャーは 標準モジュールでなくてもいいのでしょうか?

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

  • ベストアンサー
  • A88No8
  • ベストアンサー率52% (836/1606)
回答No.1

こんにちは  標準モジュールに書けば、ブック中のどのシートでも使えるプロシージャになると思います。  一方、Sheetに書くとそのシートからフォーカスが他のシートに移ったとたんにエラーとなることで判るようにSheetの中でしか使えませんよね。  プロシージャを標準モジュールに書いて保存するときに「*.xla」に指定してアドインでエクセルに組み込むとどのブックでも使用できるプロシージャになります。  ということで、プロシージャーを書く場所で使用時のスコープ(有効範囲)が変わります。

fdshjs
質問者

お礼

なるほど。 ありがとうございます。

その他の回答 (2)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 >クラスモジュールとフォームのイベントプロシージャーを書くところではできませんでした。 標準モジュール Public myClass As Class1 Sub SetClass() Dim myClass As New Class1 myClass.test1 'myClass オブジェクトのメソッドになる End Sub Class1 Sub test() MsgBox "あああ" End Sub 'これで通ります。 ------------------------------ 'UserForm モジュール Private Sub CommandButton1_Click()  Call test2 End Sub Sub test2() MsgBox "あああ" End Sub --------------------------------- >SUBプロシージャーは標準モジュールでなくてもいいのでしょうか? Excelの場合は、オブジェクトが複数あるのが建前なので、SUB/Function プロシージャは、標準モジュールに書くのが基本的です。それ以外の場所に書くときは、それそれの必要性によって書きます。標準モジュール以外に対して、何でもよいわけではありません。 簡単にいうと、親オブジェクトの違いということになります。シートモジュールなどは、その直接の親オブジェクトの配下で動くことになっていますから、そのままにすると、親オブジェクトに直結しています。例えば、Cells(1,1) と書いても、標準モジュールの場合は、Activesheet ですが、シートモジュールは、書いたモジュールのシートが親オブジェクトになっています。シートモジュールで省略すれば、その範囲が限られてしまいます。 シートへのイベントなど、基本的には、そのシートしか使わないので、Private とつきますが、他の場所から呼び出さないということを理由にしているからです。他から呼び出して、不都合があるかどうかは、個人で使う分にはあまり大差はないと思います。 ------------------- シートモジュール側にPrivate が付いていなければ、  Worksheets("Sheet1").Test1  または、  'Call Worksheets("Sheet1").Test1 で、Sheet1のマクロをどこからでも呼び出せます。 エラーになるのは、親オブジェクトを考慮していないから、不整合が起こるからです。 シートモジュールに、  With ActiveSheet '←標準モジュールでは、親オブジェクトを考えなくてよい  MsgBox .Cells(1, 1).Value  End With -------------------- シートを替えても、このようなコードですと、元のシートモジュールの親のシートのセル情報しか得られない。 MsgBox Cells(1,1).Value -------------------- ThisWorkbook は、そのブックの玄関のようなもので、Open, Before_Close など、必ず、起動するとき、終了するときに、そこを通っていきますから、それを利用してあげればよいのです。標準モジュールは、家族が集まる、居間のようなもので、そこは、シート・モジュールを直接名指ししなくても、動きます。 また、クラスモジュールは、計画表や設計図のようなところです。設計図だけでは何も起きません。一度、イスンタンスを作ってあげないと動きません。 なお、Sub の前につける Private キーワードは、よそのモジュールから呼び出せませんが、シートモジュールにつけるPrivate ステートメントは、Option Private Module と書く方法は、標準モジュールにつけるもので、他のプロジェクトから呼び出せないようにするものです。 しかし、私の不勉強かもしれませんが、変数に関しては、Private/Public とか、そのモジュールのみに範囲を指定するとか、全体に対して、範囲を拡大するとか、標準モジュールに書く場合に、スコープに関係していますが、プロシージャに関しては、単に、マクロのCall (呼び出し)に関係するものだと解釈しています。

fdshjs
質問者

お礼

なかなか難しいので勉強してみます。ありがとうございます。

回答No.2

Subは、標準モジュール内だけとは限りませんよ。 各シートでのイベントプロシージャは、そのVBAのソースコードを見てみると「Private Sub」という記述があると思います。Subは、「Public Sub」の省略系です。 これらのプロシージャの意味は、その名のとおり、局所的なものと、公のものであるという意味で、A88No8さんが書かれているように、それぞれ影響範囲(スコープ)が異なります。 Privateは、その名のとおり、局所的なスコープになり、シートで宣言している場合には、そのシートのみで有効なプロシージャとなります。Publicは、公のものではありますが、エクセルのVBAでは、標準モジュール以外(シートやフォームなど)での宣言は、PrivateもPublicも同じく扱われるはずです。(つまりは、シートやフォーム内のプロシージャからしか呼び出せない)

fdshjs
質問者

お礼

難しいですがよく読んで理解してみます。 ありがとうございます。

関連するQ&A