2014-10-27 11 views
11

Jestem w programie Excel 2010 i wydaje mi się, że otrzymuję dziwne, raczej nieoczekiwane, zachowanie przy niestandardowych zdarzeniach.Zdarzenie niestandardowe nie jest uruchamiane

Jestem jak 99% pewien, że to podejście pracował dla mnie kilka lat temu (może to było w programie Excel 03/07 - nie pamiętam)lubmoże ja właśnie zawiedli coś ...

Oto repro:

Dodaj nowy moduł klasy i nazwij go Factory

Public Event AfterInitialize() 

Private Sub Class_Initialize() 
    RaiseEvent AfterInitialize 
End Sub 

dodać kolejny moduł klasy i nazwa jest 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 

i standard Module1 i uruchomić poniżej

Sub Main() 

    Dim fTest As FactoryTest 
    Set fTest = New FactoryTest 

End Sub 

W tym momencie ja spodziewałem się zobaczyć after initialized.. w oknie Immediate ale ja nie ...

nasilenia poprzez kod wydaje się, że nigdy nie zostanie osiągnięty Private Sub cFactory_AfterInitialize() ...

Uwaga:

mogę dodać Public Sub: RaiseAfterInitialize() do klasy Factory a następnie wywołać jawnie w wypadku w FactoryTest jak cFactory.RaiseAfterInitialize()Initialize() tak, że może być możliwe pracę wokół, ale co ja naprawdę starają się zrozumieć, dlaczego to robi działa w oryginalny sposób pokazany powyżej?

There isn't much on VBA events on MSDN

Czy ktoś może wskazać, co robię źle?

+0

Czy nie powinien to być po prostu 'Factory_AfterInitialize()'? –

+4

zdecydowanie nie :) –

+5

Podejrzewam, że to wyczucie czasu. Klasa Factory nie zakończyła inicjowania, więc zdarzenie jest wywoływane, zanim zmienna w klasie FactoryTest zostanie przypisana lub nastąpi zaniknięcie. – Rory

Odpowiedz

15

podstawie sekcji VBA Language Specification 5.3.1.10 Lifecycle Handler Declarations, to myślę, że to jest powód (Kopalnia nacisk):

Jeśli klasa definiuje obsługi Class_Initialize cyklem życia, że ​​podprogram zostanie wywołany jako metoda każdym razem instancja tej klasy jest tworzona przez operatora New przez odwołanie się do zmiennej, która została zadeklarowana za pomocą <as-auto-object> i której aktualną wartością jest nic lub przez wywołanie funkcji CreateObject (sekcja 6.1.2.8.1.4) biblioteki standardowej VBA. Obiektem docelowym wywołania jest nowo utworzony obiekt. Wywołanie występuje przed zwróceniem odwołania do nowo utworzonego obiektu z operacji, które go tworzą.

Więc w twoim przypadku, w wierszu

Set cFactory = New Factory

Class_Initialize metoda Factory jest prowadzony przed przydział jest wykonany, co oznacza, gdy zdarzenie jest wywoływane, klasa FactoryTest instancja nie wie o tym.


UPDATE

dałem szybki test dodając metodę Factory który wywołuje Class_Initialize funkcję:

Public Sub test() 
    Class_Initialize 
End Sub 

A potem dodał wezwanie do niego jako część FactoryTest.Class_Initialize method:

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

Ponieważ wywołanie metody test ma miejsce po przypisaniu New Factory do cFactory, komunikat "po zainicjowaniu ..." jest wyświetlany zgodnie z oczekiwaniami.

+1

++ Kopałem dokumenty przez około pół godziny i nie mogłem go znaleźć. Dobrze teraz wszystko jasne, –

+0

+1 doskonała odpowiedź – brettdj

Powiązane problemy