half of a glazier
half of a glazier

Reputation: 2076

Access not firing custom event

I've been building testable MVC logic for my Access database using RubberDuck's answer to Best way to test a MS Access Application? but I'm stuck with the custom event handling. I can't figure out why the OnCreate event isn't firing.

Form_CreateStudents:

Option Compare Database
    Private ctrl As ctrCreateStudent
    Public Event OnCreate()

    Private Sub btnCreate_Click()
        Set ctrl = New ctrCreateStudent
        ctrl.Run
        RaiseEvent OnCreate
    End Sub

Class module ctrCreateStudent:

Private WithEvents frm As [Form_Create Students]

Public Sub Run()
    MsgBox "run called"
    Set frm = New [Form_Create Students]
End Sub

Public Sub frm_OnCreate()
    MsgBox "frm_oncreate event called"
End Sub

Run is being called, but frm_OnCreate is just ignored. I'm relatively new to VBA, what am I missing here?

Upvotes: 0

Views: 183

Answers (1)

Erik A
Erik A

Reputation: 32632

Quite simple:

frm is a New [Form_Create Students], not the one calling it.

This new form doesn't raise the OnCreate event. In fact, this new form is not even visible, because you haven't set frm.Visible = True

If you want to set it to the form that just called Run, pass it:

On the form:

Private ctrl As ctrCreateStudent
Public Event OnCreate()

Private Sub btnCreate_Click()
    Set ctrl = New ctrCreateStudent
    ctrl.Run Me
    RaiseEvent OnCreate
End Sub

On the class:

Private WithEvents frm As [Form_Create Students]

Public Sub Run(parentForm As [Form_Create Students])
    MsgBox "run called"
    Set frm = parentForm 
End Sub

Public Sub frm_OnCreate()
    MsgBox "frm_oncreate event called"
End Sub

A strong warning, though: this code contains a reference loop, and thus a memory leak.

The form has a reference to the class, and the class has a reference to the form, so neither will ever get destroyed. Every time you close and open the form, a new form and class object will get created, and none of them will ever get destroyed.

When closing the form, it turns invisible and looks gone, but it's still there and using memory.

There are many ways to work around this, but an easy one is:

In the class:

Public Sub frm_Close()
    Set frm = Nothing 'Release form object, break reference loop
End Sub

And make sure the Form's On Close property is set to "[Event Procedure]" so the close event gets raised.

Upvotes: 2

Related Questions