「標準モジュール」とは何ものなのか
「標準モジュール」とは何ものなのか
割と最近まで、「標準モジュール」というのは、単に【コードを書く場所】ぐらいの雑なとらえ方で済ませていた。
しかし、「クラスモジュール」とか、「フォームモジュール」、「シートモジュール」、「ThisWorkbookモジュール」などを使い分けていくうちに、改めて「標準モジュールとは何ものなのか」という疑問が生じたわけである。
標準モジュールはNewできない
たとえば、標準モジュールを挿入し、オブジェクト名を「Foobar」とする。
で、こいつをNewしようとすると、
「不正」呼ばわりw
標準モジュールというものは、「オブジェクト」ではあるものの、インスタンス化はできない模様。
ちなみに、FormモジュールはNewできる。
静的(static)クラスっぽい?
インスタンス化できない、といえば、静的クラスみたいなもんだろうか。
ちょっとメソッドを持たせてみる。
リスト1 標準モジュール「Foobar」
Option Explicit Public Sub hoge() Call makeUserSick("ホゲーーー♪") End Sub Private Sub fuga() Call makeUserSick("ふがふが") End Sub
※makeUserSickメソッドのコードはコチラ。
PublicメソッドとPrivateメソッドをそれぞれ1つづつ持たせてみた。
Publicメソッドだと、
Foobar.hoge
とモジュール名を書かなくても、
hoge
だけで呼び出せてしまって、イマイチ。
もし、
このときのように、モジュール名を指定すればPrivateメソッドでも実行できるとなれば便利だと思った。
次のコードで実行してみた。
テストコード 標準モジュール「Module1」
Public Sub testFoobar() Call hoge Call fuga End Sub
これは、当然
エラーになる。当たり前だ。
次は、Privateなfugaメソッドにモジュール名を指定してみる。
テストコード 標準モジュール「Module1」
Public Sub testFoobar() Call hoge Call Foobar.fuga End Sub
コーディング中にintellisenseが働かないのはあのときと同じなので気にしない。
すると、
アチャー、ダメかw
残念!
モジュール名を指定しないと使えない、とかだったら便利だと思ったんだけどなあ。
ならばクラス(Static)変数はどうか
標準モジュールでもPropertyを持たせることができるので、クラス変数的なものは持たせられるのではないか、と考えた。
リスト1に次のようにコードを追加する。
リスト2 標準モジュール「Foobar」
Option Explicit Private Foo_ As Integer Public Property Let Foo(ByVal bar As Integer) Foo_ = bar End Property Public Property Get Foo() As Integer If Foo_ = 0 Then Foo_ = 1 Foo = Foo_ End Property Public Sub hoge() Call makeUserSick("ホゲーーー♪" & " Fooプロパティは「" & Foo & "」やでw") Foo_ = Foo_ + 1 End Sub Public Sub fuga() Call makeUserSick("ふがふが" & " Fooプロパティは「" & Foo & "」やでw") Foo_ = Foo_ + 1 End Sub
Fooというプロパティを設定し、hoge、fugaメソッドを実行するたびにFooプロパティをインクリメントする。
たったこれだけ。Fooプロパティの値は、hoge、fugaメソッド実行時に表示されるようにしてある。
んで、次のコードを何度か実行してみる。
テストコード 標準モジュール「Module1」
Public Sub testFoobar() Call Foobar.hoge Call Foobar.fuga End Sub
実行1回目
Fooプロパティは、「2」になっている。
実行2回目
再度実行してみる。
FoobarのFooプロパティは、testFoobarプロシージャの実行終了後も値を保持し続けている。
クラス変数っぽいといえばクラス変数っぽいけれど、そもそもインスタンス化できないのだから、何に役立つのか分からないw
ちなみに、オブジェクト名「Room」というクラスモジュールの宣言セクションに「numberOfRooms」というPublic変数を置いて、
Dim r As New Room Debug.Print Room.numberOfRooms
と書いたとしても、実行すると
無情にもコンパイル・エラーになる。
まとめ
およそ、次のようなことが分かった。
- 標準モジュールはNewできない。
- モジュール名を指定してもPrivateメソッドは別モジュールから呼び出せない。
- プロパティを持たせることで、クラス(static)変数っぽいことはできる。
- クラスモジュールではクラス(static)変数を持たせることができない。
おわりに
「標準モジュール」、「クラスモジュール」ともに一長一短があるんだよなあ……。