Class_Terminate() on project reset?

riktek

Member
Local time
Today, 08:02
Joined
Dec 15, 2023
Messages
130
I'm mostly seeking to confirm my understanding but the question is whether Class_Terminate() runs on or immediately after a project reset.

I don't think so.

Some sources (including LLMs) state otherwise, however, equating a reset with clearing the sole variable containing an instance of a class and stating affirmatively that the event procedure will, or should, run.

What I observe, however, is that, while resets that I trigger unquestionably clear variables containing pointers to class instances, this does not invoke code in the event procedure. I can trigger that code only by clearing the variable or assigning a new class instance to it, which of course displaces the prior object.

I'm curious others' thoughts on the topic, and thanks for any input.
 
when runtime error occors, variables are destroyed.
 
when runtime error occors, variables are destroyed.
Only in accdb. Not in accde. (Not sure, only per my immature experience)
 
Last edited:
I'm mostly seeking to confirm my understanding but the question is whether Class_Terminate() runs on or immediately after a project reset.

I don't think so.
You are correct.
The Reset ("Stop" icon) button in the VBE toolbar, the "End" button in the debug dialog, and the End statement in VBA code immediately terminate/reset the running project without running any further code in Class_Terminate event procedures.
[Edit]
The code in or Form_Unload/_Close event procedures will still run though.
[/Edit]
 
Only in accdb. Not in accde. (Not sure, only per my immature experience)
It depends on whether the runtime error is handled or not. The behavior is basically the same with an accdb and accde file, but with an accdb you do have the choice to debug the code, which will prevent variables from being reset.
 
Easy to test.

Class1
Code:
Private Sub Class_Initialize()
    Debug.Print "Class_Initialize"
End Sub

Private Sub Class_Terminate()
    Debug.Print "Class_Terminate"
End Sub

Module1
Code:
Public Sub Test()
    With New Class1
        Debug.Print "Module1 Test"
    End With
End Sub

Normal run
Code:
test
Class_Initialize
Module1 Test
Class_Terminate

Run with reset on break point on "Module1 Test"
Code:
test
Class_Initialize
 
It depends on whether the runtime error is handled or not. The behavior is basically the same with an accdb and accde file, but with an accdb you do have the choice to debug the code, which will prevent variables from being reset.
I have a public variable that holds the ribbon object.
I also have a function without error handling.
When testing in accdb and call the function, the public variable is destroyed and later, invalidating the ribbon causes an error, because the variable is empty.
When I create an accde and go through the same steps, invalidating the ribbon doesn't fail. That's why I assume in accde unhandled errors don't destroy public variables.
I'll test again when I'm back to my pc.
 
when runtime error occors, variables are destroyed.
Yes, of course, but the question really is, then, what? Destroying a variable containing a class instance will destroy the instance. So far, so good but do this manually and Class_Terminate() executes, do it with a reset and it doesn't.

The consensus seems to be that a reset (or an End statement) preempts the event.
 
Last edited:
It depends on whether the runtime error is handled or not. The behavior is basically the same with an accdb and accde file, but with an accdb you do have the choice to debug the code, which will prevent variables from being reset.


From above link:

I should also point out that the above statement is true of uncompiled versions (mdb, accdb, …). Compiled versions (mde, accde, …) do not re-set local, or even global variables because of un-handled errors.
 
I think the consensus is that you should handle your errors
Yes, of course, and I do so in a standard way practically everywhere. This actually has more to do with fundamentals bearing on some framework extensions I'm evolving concerning events. Access.Class.Terminate is just a piece of a larger puzzle. @sonic8 's observation about Form.Unload and Form.Close actually may be relevant.
 
I just confirmed @sonic8 's observation that the code in Form_Unload() and Form_Close() event procedures will run after a project reset even though code in Class_Terminate() does not. For the test, I simply revised the containing variable's type declaration from Access.Class to Access.Form and assigned a new form instance to the variable in the same way I had assigned a new class instance.

I find this revealing. I've long regarded forms to be class modules with a GUI, much as the VBE is a shell with a GUI. Class is hidden but it and Form both are classes in the Access namespace. Form may implement Class for all I know and even if not, I would expect common derivation to be practically certain. One distinction, though, is the form's GUI, meaning window class instances. Perhaps the main Access process can't invoke IUnknown until those are handled. Form.Unload and .Close are defined by, essentially, window messages, after all. Another is that forms are documents. Access.Form class instances created with DoCmd.OpenForm call survive reset and remain open. Instances having pointers in the VBE shell, don't.

Who knows. What we do know is some Access classes' events run after reset and others don't, which is good enough for me to call it a day.
 
The difference in behavior could be a matter of responsibility: Microsoft Access Team vs. VBA Team
 
The difference in behavior could be a matter of responsibility: Microsoft Access Team vs. VBA Team
That could be it, too. No telling how the organization allocates tasks and responsibilities.

Access class modules are a class in the Access library, however, not just generic VBIDE.VBComponent objects. Access.Class is hidden but it's what exposes the Initialize and Terminate events. No VBA class exposes events and VBIDE does so only for References, although it defines CommandBarEvents, possibly for Office members to implement.

My impression is that the shell environment (i.e., VBE) is an Automation engine (with a language, library, GUI, and built-ins) that an application can automate, and that works with instances of COM classes that support Automation, i.e., have a factory. VBIDE.Reference is how the shell knows which Automation class libraries it has available. The Access library is one of those libraries. I can develop an Automation library but have no idea about the shell's architecture. Maybe it's just an API for apps, maybe it defines a Class signature, or maybe they write a Class class for whichever app wants one. Judging solely by the libraries involved, Access.Class would seem more within the purview of the Access team, and VBIDE and VBA, the VBA team, but who knows.
 

Users who are viewing this thread

Back
Top Bottom