自動売買でイベントハンドラーが呼ばれない件の続き
イベントハンドラーが呼ばれない理由が分かった。VB/VBA の言語仕様の癖を理解していないコーディングミスだった。
たとえば、つぎのようなコードだ。
Option Explicit Implements ITask Private WithEvents tc As TradeCmd Private Function ITask_PopCmd() As ICmd If tc Is Nothing Then Set ITask_PopCmd = Nothing Else Set ITask_PopCmd = tc Set tc = Nothing End If End Function Public Sub tc_FinishEvent(ByVal x As Long) End Sub
(間違って)期待するのは ITask_PopCmd の中で tc を Nothing にしても、tc が指していたインスタンスは、外部に渡されるので、生きたままであり、いつか RaiseEvent されて、イベントハンドラーの tc_FinishEvent が呼ばれるという動作だ。しかし、実際の挙動としては、変数 tc を Nothing にした時点で、イベントハンドラーもなくなってしまう。なぜならば、イベントハンドラーの tc_FinishEvent は、インスタンスに関連付けるイベントハンドラーではなく、変数 tc に関連付けるイベントハンドラーだからだ。
Java だと変数はあくまでも、インスタンスを指すだけの軽い位置づけなのだが、VB/VBA の変数はかなり重い扱いになっている。ByRef の存在など、変数が主体となった言語仕様になっている。