问题 自定义事件未触发


我在Excel 2010中,我似乎得到一个奇怪的意外行为使用自定义事件。

我肯定99%肯定这种方法几年前对我有用(也许是在Excel 03/07 - 不记得了)  要么  也许我刚搞砸了什么...

这是一个复制品:

添加一个新的类模块并为其命名 Factory

Public Event AfterInitialize()

Private Sub Class_Initialize()
    RaiseEvent AfterInitialize
End Sub

添加另一个类模块,名称是 FactoryTest

Private WithEvents cFactory As Factory

Private Sub Class_Initialize()
    Set cFactory = New Factory
End Sub

Private Sub cFactory_AfterInitialize()
    Debug.Print "after inialized..."
End Sub

和标准 Module1 并运行以下

Sub Main()

    Dim fTest As FactoryTest
    Set fTest = New FactoryTest

End Sub

此时我期望看到 after initialized.. 在立即窗口但我没有......

似乎单步执行代码 Private Sub cFactory_AfterInitialize() 永远不会到达......

注意:

我可以添加一个公共子: RaiseAfterInitialize() 到了 Factory 然后在类中明确地调用它 Initialize() 事件发生在 FactoryTest 喜欢 cFactory.RaiseAfterInitialize() 所以这可能是一个可能的解决方案,但我真正想要了解的是为什么它不能按照上面显示的原始方式工作?

MSDN上的VBA事件并不多

谁能指出我做错了什么?


7729
2017-10-27 13:48


起源

不应该只是 Factory_AfterInitialize()? - Mr. Mascaro
当然不 :)
我怀疑是时候了。 Factory类尚未完成初始化,因此在分配FactoryTest类中的变量或下沉事件之前引发事件。 - Rory
在VBA的所有其他位置,事件是基于Class而不是Class对象调用的。例如: Workbook_Open() 不 ThisWorkbook_Open。 - Mr. Mascaro
并且您没有使用WithEvents变量 - 如果您这样做,即使使用本机事件,您仍然可以使用 witheventsvariablename_eventname - Rory


答案:


基于VBA语言规范部分 5.3.1.10生命周期处理程序声明,我猜这是原因(强调我的):

如果一个类定义了一个Class_Initialize生命周期处理程序,那么每当New运算符创建该类的一个实例时,通过引用一个声明的变量,该子例程将被调用为一个方法。 <as-auto-object> 并且其当前值为Nothing,或者通过调用VBA标准库的CreateObject函数(第6.1.2.8.1.4节)。调用的目标对象是新创建的对象。 调用发生在从创建它的操作返回对新创建的对象的引用之前。

所以在你的情况下,在行

Set cFactory = New Factory

Class_Initialize 的方法 Factory 运行 之前 作出了分配,这意味着当事件被提出时, FactoryTest 类实例不知道它。


UPDATE

我通过添加一个方法给它一个快速测试 Factory 它叫做 Class_Initialize 功能:

Public Sub test()
    Class_Initialize
End Sub

然后添加了一个调用它作为一部分 FactoryTest.Class_Initialize 方法:

Private Sub Class_Initialize()
    Set cFactory = New Factory
    cFactory.test
End Sub

自从调用该方法 test 发生在。之后 New Factory 已被分配到 cFactory,“初始化后...”消息按预期显示。


16
2017-10-27 14:30



++我把文档挖了大约半个小时,却找不到它。干得好清楚了
+1优秀答案 - brettdj