複数のプロジェクトで使いまわしたいクラスは、アドインとして外部に置いておいて別のExcel VBAから参照できると便利です。(たぶん)
やり方
1. ふつうにクラスモジュールを作成する
ここではClassInXlam
という名称にします。
Option Explicit
Public str As String
' strの中身を表示する
Public Sub ShowStr()
Debug.Print "str=" & str
End Sub
2. 外部からインスタンスを取得するための関数を追加する
外部からは直接Newできないため、標準モジュールを追加し、外部からインスタンスを取得するための関数を書きます。
ここではモジュールはRoot
という名称にしています。
Option Explicit
Public Function CreateClassInXlam(str As String) As ClassInXlam
Dim tmpClass As ClassInXlam
Set tmpClass = New ClassInXlam
tmpClass.str = str
Set CreateClassInXlam = tmpClass
End Function
3. クラスのプロパティをPublicNotCreatableにする
プロパティウインドウから、クラスのInstancingプロパティを2 - PublicNotCreatable
にします。
(完全なPublicには設定できません。)
これで外部からクラス名が使えるようになります。
4. プロジェクトの名称を変更する
デフォルトのVBAProjectのままでは、他ファイルから参照したときに名称が競合してエラーになります。
プロジェクトエクスプローラから対象のプロジェクトを右クリックして適当な名称に変更します。
5. Excelアドイン形式で保存する
名前を付けて保存で、「.xlam」形式を選択して保存します。
ここまででアドイン側の準備は終了です。
外から参照してみる
新しいブックを開いて、そこから参照してみます。
1. アドインへ参照設定をする
VBEの 「ツール」>「参照設定」ダイアログの「参照」から、先ほど作成したxlamファイルを選択します。
「OK」を押すと、プロジェクトエクスプローラの「参照設定」のところに参照先として追加されています。
2. 使う
こんな感じで使えます。
Intellisenseも使えます。
Option Explicit
Sub test()
Dim instanceOfClass As ClassInXlam
Set instanceOfClass = CreateClassInXlam("test")
instanceOfClass.ShowStr ' => str=test
End Sub
外からインスタンス化するインターフェースについて
以下のようにすると、ClassInXlam.Create()
と書けてStaticメソッドから作成できているように見えてかっこいいです。
1. クラスモジュールにCreateメソッドを作成する
Createメソッドは、外部ファイルからインスタンスを作れるようにするためです。
Option Explicit
Public str As String
' strの中身を表示する
Public Sub ShowStr()
Debug.Print "str=" & str
End Sub
' ちなみにCreateには引数も渡せる
Public Function Create(str As String) As ClassInXlam
Dim tmpClass As ClassInXlam
Set tmpClass = New ClassInXlam
tmpClass.str = str
Set Create = tmpClass
End Function
2. インスタンス生成用のパブリック変数をつくる
アドイン側のRootモジュールの内容を以下のようにします。
Option Explicit
Public ClassInXlam As New ClassInXlam
このパブリック変数を経由して外部からインスタンスを取得します。
As New
としているので常にインスタンスが入っている(Nothingになっていない)ことが保証されています。
変数名はクラス名と同じでも問題ないようです。
3. 使う
これで外部から以下のように使えます。
Option Explicit
Sub test()
Dim instanceOfClass As ClassInXlam
Set instanceOfClass = ClassInXlam.Create("test")
instanceOfClass.ShowStr ' => str=test
End Sub
注意点
実際にはClassInXlam
というパブリック変数に入っているインスタンスのメソッドを使っているだけです。
生成のためだけの余計なインスタンスが1つ存在しているわけなので、問題になる場面もあるかもしれません。