PublicNotCreatableの意味
PublicNotCreatableの意味
クラスモジュール使いであっても、あっちこっちで使い回すようなクラスモジュールを作ったりしなければ、存在にすら気づかないのが、クラスモジュールのInstancing
プロパティではなかろうか。
Instancing
プロパティに、「Private
」と「PublicNotCreatable
」の二種類の設定値があることは知っていたが、余り深く意味を考えたことがなかった。
特に、「PublicNotCreatable
」の方は、「NotCreatable
」の文字だけを見て、
インスタンスが作れねえのかよ、不便だな
とか、わけのわからない理解をしていた。
ちょっとづつわかってきたかも知れないので、メモ。
Private/Publicの違い
まず、「Private
」と「Public
」の違い。
これは、
別プロジェクトに対して
「Private
」か「Public
」か、ということ。
VBAによるマクロ作成の場合、1ブック(プロジェクト)内で閉じた処理であることが多いので、普通に使っている限り、まず意識することがないポイントだと思う。
たとえば、
このようなプロジェクト構成になっているとする。(おい、ファイル名は綴りが間違えてるじゃねえかw)
「Referring
」というプロジェクトが、「Referred
」というプロジェクトを参照している。
参照しているということは、「Referring
」(参照元)から「Referred
」(参照先)へのつながりをつけているということ。
つながりがついているから、「Referring
」(参照元)からは、「Referred
」(参照先)の中の「Public
」なものについては〈見える〉(呼び出せる)ということになる。
ここで言う〈見える〉というのは、コードウインドウ等に〈表示できる〉ということではない(それは、〈ユーザーから見える〉ということだ)。
再度、プロジェクト エクスプローラー画像を。
ご覧のとおり、参照先である「Referred
」には、「HogePrivate
」と「HogePublic
」という二つのクラスモジュールが置かれている。
クラス名からも明らかなとおり、「HogePrivate
」は、Instancing
プロパティを「Private
」に、「HogePublic
」の方は「PublicNotCreatable
」に設定している。
ご覧のように、入力時のヒントには「HogePublic
」の方しか出てこない。
これが、〈見える〉ということだ。
Referring
プロジェクトからは、Referred
プロジェクト内のクラスのうち、Private
なHogePrivate
クラスは〈見えない〉が、Public
なHogePublic
クラスは〈見える〉ということだ。
では、NotCreatableとは
最初、「NotCreatable
」という字面から、「インスタンスが作れないクラス」のことだと思っていた。
しかし、Instancing
プロパティを「PublicNotCreatable
」に設定していても、普通にNew
でインスタンス化することができていたので(当たり前)、「わけわからんなー」で済ませていたのだった。
これは要するに
別プロジェクト内でインスタンスが作れない
ということだったのだ。
今回の例の場合だと、
Referringプロジェクト上で、Referredプロジェクト下のクラスのインスタンスを作ることはできない
というだけのことだった。
このように、「不正」呼ばわりされて、インスタンスが作れないのだ。
もちろん、上の例での変数hoge
にインスタンスをぶち込む方法はある。
これまで当ブログのコメント欄等でも言及があったように、参照先(クラスを持っている側のプロジェクト。今回の例で言うとReferred
プロジェクト。)にインスタンスを返すメソッドを置いておけば良い。
参考までに今回の例の場合だと、次のようなメソッドを置くことになる。
リスト1 ReferredプロジェクトのThisWorkbookモジュール
Public Function getHogeinstance() As HogePublic Set getHogeinstance = New HogePublic End Function
そして、参照元(HogePublic
クラスを呼び出す側のプロジェクト。今回の例で言うとReferring
プロジェクト。)で次のように書く。
リスト2 Referringプロジェクトの標準モジュール
Dim hoge As HogePublic Set hoge = Referred.ThisWorkbook.getHogeInstance
ちなみに、ThisWorkbook
の後に「.」(ピリオド)を入力してもヒントが出ないので不安になるが、大丈夫。
おわりに
最初にも書いたとおり、そもそもVBAでは、複数プロジェクトにまたがるような処理を書くことがあまりないので、
Private
に対するPublic
はあるのに、NotCreatable
に対するCreatable
がない
という非対称性に気づく機会が少ないのだと思う。
汎用的なオレオレメソッドが溜まってきて、それをあちこちで使い回そうという気持ちになったときに、初めてぶつかる問題なのかも。