シートモジュールとインターフェイス
シートモジュールにインターフェイスを実装する
単なる実験。
インターフェイスを作成する
クラスモジュールを挿入して、次のコードを書く。
オブジェクト名はIA1ValueShowable
とする。
ちなみに、Instancing
プロパティの値を「PublicNotCreatable
」にしています。
リスト1 クラスモジュール
Option Explicit Public Sub showA1Value() End Sub
たったこれだけ。showA1Value
というメソッドだけを定義しておく。
これで、このインターフェイスをImplements
したオブジェクトには、必ずshowA1Value
というメソッドを持たせなくてはならないことになる。
シートモジュールにインターフェイスを実装する
今回は、Sheet6
モジュールとSheet7
モジュールの2つにインターフェイス「IA1ValueShowable
」を実装する。
リスト2 Sheet6モジュール
Option Explicit Implements IA1ValueShowable Public Sub IA1ValueShowable_showA1Value() Call makeUserSick(Me.Range("A1").Value) End Sub
Sheet6
モジュールのshowA1Value
メソッドでは、当ブログではおなじみのmakeUserSick
メソッドを使用してA1セルの値を表示する。
makeUserSick
メソッドについては、コチラをどうぞ。
リスト3 Sheet7モジュール
Option Explicit Implements IA1ValueShowable Public Property Get BASE_CELL() As Range Set BASE_CELL = Me.Range("A1") End Property Public Sub IA1ValueShowable_showA1Value() Call MsgBox(Me.Range("A1").Value) End Sub
Property
のところは前回の名残。
Sheet7
モジュールのshowA1Value
メソッドでは、単なるMsgBox
を使う。
これで準備完了。
使ってみる
標準モジュールに次のコードを書いて実行してみる。
リスト4 標準モジュール
Public Sub testInterfaceSheetModule() Dim Sh(1) As IA1ValueShowable '……(1)' Set Sh(0) = Sheet6 '……(2)' Set Sh(1) = Sheet7 Dim i As Long For i = 0 To 1 '……(3)' Call Sh(i).showA1Value Next End Sub
まず、(1)の
Dim Sh(1) As IA1ValueShowable
で、インターフェイスIA1ValueShowable
型の配列Sh
を準備。
(2)からの2行
Set Sh(0) = Sheet6 Set Sh(1) = Sheet7
でSheet6
とSheet7
を配列Sh
にぶち込む。
後は(3)からの3行
For i = 0 To 1 Call Sh(i).showA1Value Next
でFor
ループを用いてshowA1Value
メソッドを実行する。
実行結果
このように、同じshowA1Value
メソッドを呼び出すことでそれぞれ異なる動作をさせることができた。
おわりに
Sub
だとこのようにうまくいったのだが、Range
型のProperty
だとうまくいかなかった。なぜだろう。
追記
Property
の識別子をBase_Cell
としていたのだが、どうも「_
」(アンダースコア)がまずかった模様。クラスモジュールIA1ValueShowable
内で
Public Property Get Base_Cell() As Range End Property
このように定義し、これに合わせてSheet6
、Sheet7
モジュールのそれぞれにBase_Cell
プロパティを設定したところ、
こんなエラーが出てどうしようもなかったのだが、識別子から「_
」を取り除いて次のようなコードにすると上手くいったので、全てのコードを載っけておく。
リスト5 クラスモジュール
'オブジェクト名:IA1ValueShowable' Option Explicit Public Property Get Name() As String End Property Public Property Get BaseCell() As Range End Property Public Sub showA1Value() End Sub
リスト6 Sheet6モジュール
Option Explicit Implements IA1ValueShowable Public Property Get IA1ValueShowable_Name() As String IA1ValueShowable_Name = "Sheet6" End Property Public Property Get IA1ValueShowable_BaseCell() As Range Set IA1ValueShowable_BaseCell = Me.Range("A1") End Property Public Sub IA1ValueShowable_showA1Value() Call makeUserSick(Me.Range("A1").Value) End Sub
リスト7 Sheet7モジュール
Option Explicit Implements IA1ValueShowable Public Property Get IA1ValueShowable_Name() As String IA1ValueShowable_Name = "Sheet7" End Property Public Property Get IA1ValueShowable_BaseCell() As Range Set IA1ValueShowable_BaseCell = Me.Range("A1") End Property Public Sub IA1ValueShowable_showA1Value() Call MsgBox(Me.Range("A1").Value) End Sub
リスト8 標準モジュール
Public Sub testInterfaceSheetModule() Dim Sh(1) As IA1ValueShowable Set Sh(0) = Sheet6 Set Sh(1) = Sheet7 Dim i As Long For i = 0 To 1 Call Sh(i).showA1Value Debug.Print Sh(i).Name Debug.Print Sh(i).BaseCell.Value Next End Sub
リスト8を実行すると、リスト4実行時同様2つのメッセージが出た後、イミディエイトに
このように表示される。
VBAでインターフェイスを使う場合、どうも「_
」(アンダースコア)が特別な意味を持っているらしい。気をつけねば。
追記
面白半分にシートモジュールにインターフェイスを実装すると、えらいことになります。