Подтвердить что ты не робот

Пользовательское событие не срабатывает

Я работаю в 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.. в окне Immediate, но я не...

Выполняя код, кажется, что Private Sub cFactory_AfterInitialize() никогда не достигается...

Примечание:

Я могу добавить открытый sub: RaiseAfterInitialize() в класс Factory, а затем вызывать это явно в событии Initialize() в FactoryTest как cFactory.RaiseAfterInitialize(), так что это может быть возможной работой, но что я я действительно пытаюсь понять, почему это не работает, оригинальный способ показал выше?

В MSDN не так много событий.

Может ли кто-нибудь указать, что я делаю неправильно?

4b9b3361

Ответ 1

Основываясь на разделе VBA Language Specification 5.3.1.10 Декларации обработчика жизненного цикла, я бы предположил, что это причина (внимание мое):

Если класс определяет обработчик жизненного цикла Class_Initialize, эта подпрограмма будет вызываться как метод каждый раз, когда экземпляр этого класса создается оператором New, ссылаясь на переменную, объявленную с помощью <as-auto-object> и текущее значение которой Nothing или вызовом функции CreateObject (раздел 6.1.2.8.1.4) стандартной библиотеки VBA. Целевой объект вызова - это вновь созданный объект. Вызов происходит до того, как ссылка на вновь созданный объект возвращается из операций, которые его создают.

Итак, в вашем случае в строке

Set cFactory = New Factory

Метод Class_Initialize Factory запускается до того, как будет выполнено присвоение, что означает, что при возникновении события IS экземпляр 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, сообщение "после инициализации..." отображается как ожидалось.