2014-10-27 24 views
11

Tôi đang ở trong Excel 2010 và dường như tôi đang nhận được một hành vi lạ thay vì không mong muốn khi làm việc với các sự kiện tùy chỉnh.Sự kiện tùy chỉnh không kích hoạt

Tôi như chắc chắn 99% phương pháp này đã làm việc cho tôi một vài năm trước đây (có thể đó là trong Excel 07/03 - không thể nhớ)haycó lẽ tôi đã sai lầm chỉ một cái gì đó lên ...

Dưới đây là một repro:

Thêm một mô-đun lớp mới và đặt tên nó Factory

Public Event AfterInitialize() 

Private Sub Class_Initialize() 
    RaiseEvent AfterInitialize 
End Sub 

Thêm một mô-đun lớp và tên là 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 

và một tiêu chuẩn Module1 và chạy dưới

Sub Main() 

    Dim fTest As FactoryTest 
    Set fTest = New FactoryTest 

End Sub 

Tại thời điểm này tôi mong đợi để xem after initialized.. trong Window Ngay lập tức nhưng tôi không ...

Bước qua mã có vẻ như Private Sub cFactory_AfterInitialize() không bao giờ đạt được ...

Lưu ý:

tôi có thể thêm một tiểu công cộng: RaiseAfterInitialize() đến lớp Factory và sau đó gọi đó một cách rõ ràng trong trường hợp Initialize() trong FactoryTest như cFactory.RaiseAfterInitialize() để có thể là một công việc có thể xung quanh nhưng những gì tôi đang thực sự cố gắng để hiểu là tại sao nó doesn 't làm việc theo cách ban đầu cho thấy ở trên?

There isn't much on VBA events on MSDN

Bất kỳ ai có thể chỉ ra những gì tôi đang làm sai?

+0

Không phải đơn giản là 'Factory_AfterInitialize()'? –

+4

chắc chắn không :) –

+5

Tôi nghi ngờ đó là thời gian. Lớp Factory đã không hoàn thành khởi tạo để sự kiện được nâng lên trước khi biến trong lớp FactoryTest được gán hoặc đánh chìm các sự kiện. – Rory

Trả lời

15

Dựa trên phần VBA Language Specification 5.3.1.10 Lifecycle Handler Declarations, tôi sẽ đoán đây là lý do (tôi nhấn mạnh):

Nếu một lớp định nghĩa một handler Class_Initialize vòng đời, chương trình con này sẽ được gọi là một phương pháp mỗi lần một thể hiện của lớp đó được tạo bởi toán tử New, bằng cách tham chiếu một biến được khai báo với <as-auto-object> và giá trị hiện tại của nó là Không có gì hoặc bằng cách gọi hàm CreateObject (phần 6.1.2.8.1.4) của Thư viện chuẩn VBA. Đối tượng đích của lời gọi là đối tượng mới được tạo ra. Lệnh gọi xảy ra trước khi một tham chiếu đến đối tượng mới được tạo ra được trả về từ các hoạt động tạo ra nó.

Vì vậy, trong trường hợp của bạn, trong dòng

Set cFactory = New Factory

Phương pháp Class_Initialize của Factory đang chạy trước nhiệm vụ được thực hiện, có nghĩa là trong khi sự kiện này được nâng lên, lớp FactoryTest Ví dụ không biết về nó.


CẬP NHẬT

Tôi đưa cho nó một thử nghiệm nhanh bằng cách thêm một phương pháp để Factory trong đó kêu gọi các Class_Initialize chức năng:

Public Sub test() 
    Class_Initialize 
End Sub 

Và sau đó thêm một cuộc gọi đến nó như một phần của FactoryTest.Class_Initialize phương pháp:

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

Vì cuộc gọi đến phương thức test diễn ra sau khi New Factory được gán cho cFactory, thông báo "sau khi được khởi tạo ..." hiển thị như mong đợi.

+1

++ Tôi đã đào các tài liệu trong khoảng nửa giờ và không thể tìm thấy nó. Làm tốt tất cả rõ ràng ngay bây giờ –

+0

+1 câu trả lời xuất sắc – brettdj

Các vấn đề liên quan