前回の投稿に続き、今回はCOMコンポーネントにイベント機能を追加します。
環境
- Excel for Microsoft365(64bit)
- Visual Studio2022
イベントインターフェースの実装
イベント機能については前回作成した公開インターフェースとは別にイベント専用のインターフェースを追加します。
イベントインターフェース
[Guid("3DAEF636-1FF7-4ABA-9E5B-47D06BF21E2B")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ISampleCalc
{
[Description("加算処理")]
int Add(int a, int b);
}
// ↓ 追加 ↓
[Guid("6DC5A491-B3AB-4BB3-979D-4DE2647E058B")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISampleEvents
{
[Description("イベント処理")]
void SampleEvent(int x);
}
// ↑ 追加 ↑
[Guid("5559398B-CF78-4418-A065-CFE6A8F2BEA6")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(ISampleCalc))]
[ComSourceInterfaces(typeof(ISampleEvents))]
public class SampleCalc:ISampleCalc
{
[ComVisible (false)]
public delegate void SampleEventHandler(int x);
public event SampleEventHandler SampleEvent;
public int Add(int a, int b)
{
if (SampleEvent != null)
{
SampleEvent(a + b);
}
return a + b;
}
}
[ComSourceInterfaces属性]
作成したインターフェースを割り当てるために設定します。
イベントの定義
デリゲートを使いイベントを定義します。
サンプルでは、イベントハンドラが登録されていれば、加算結果を引数にして処理を実行するようにしています。
イベントの定義が正しくできていれば、VBA側でイベント処理として認識されます。
VBA側の実装
イベント処理はクラスモジュールでしか定義できません。
新規にクラスモジュールを作成し、WithEventsキーワードをつけてCOMのオブジェクトを定義します。
その後イベントで呼ばれる処理を実装します。
サンプルコードは以下の通りです。(加算結果を引数で受け取りメッセージボックスで表示)
標準モジュール
Sub Test()
Dim sample As Class1
Set sample = New Class1
sample.Test
End Sub
クラスモジュール
Private WithEvents calc As SampleCalc
Public Sub Test()
Set calc = New SampleCalc
calc.Add 1, 2
End Sub
Private Sub calc_SampleEvent(ByVal x As Long)
MsgBox "Event:" & x
End Sub