Terminate Event |
Private Sub object_Terminate( ) Private Sub Class_Terminate( )
object
Use: Required
Data Type: Object
A Form, MDIForm, User control, Property Page, or a VBA UserForm.
The Terminate event is fired when the last instance of an object or class is removed from memory.
Instances of an object or class are removed from memory by explicitly setting the object variable to Nothing or by the object variable going out of scope.
The Terminate event of a form-based object is fired after the Unload event.
If an application ends because of a runtime error, a class's Terminate event isn't fired.
The following example shows a typical terminate event in a class object that decrements a global instance counter used to ensure only a single instance of a particular utility object is created. When the counter reaches 0, the global object reference to the utility object is destroyed.
Private Sub Class_Terminate() glbUtilCount = glbUtilCount - 1 If glbUtilCount = 0 then Set goUtils = Nothing End If End Sub
If an application is terminated using the End statement prior to removing all instances of a class or form from memory, the Terminate event of that class isn't fired. This is the main reason you shouldn't use the End statement to terminate an application. Instead, you should use a Sub Main procedure. Specify Sub Main as the start-up procedure of your application; when program execution reaches the End Sub statement of the Sub Main procedure, the program terminates cleanly.
The Terminate event is also fired when the object variable holding a reference to the last instance of an object is re-referenced in a Set statement using the New keyword, or is assigned a reference to a new instance of the same type of object. In the following example, two object variables of the same object type are declared at form level. When the Command1 button is clicked, they are both referenced to new (and different) instances of the same class. When the Command2 button is clicked, the reference held by oTwoObj is assigned to the variable oOneObj; this implicitly releases the reference held by oOneObj, and the Terminate event of that original instance is fired:
Option Explicit Private oOneObj As myClass Private oTwoObj As myClass Private Sub Command1_Click() Set oOneObj = New myClass Set oTwoObj = New myClass End Sub Private Sub Command2_Click() Set oOneObj = oTwoObj End Sub
Code for the myClass class:
Option Explicit Private Sub Class_Initialize() Debug.Print "My Class Initialized" End Sub Private Sub Class_Terminate() Debug.Print "My Class Terminated" End Sub
You should get into the habit of setting object variables to Nothing explicitly. This is good programming practice, and it allows you to follow the life cycle of an object through your code. This should also include setting object variables to Nothing within error-handling routines.
During the development stage, you should make use of conditional compilation and the Debug.Print method to check that all references to an object or class are being released correctly. This can be done as shown in the snippet below, which is added to the class's Terminate event:
#If ccDebug Then Debug.Print "Class myClass Terminated" #End If
This is important, because although you are prevented from specifying circular object references (where one class references another and—perhaps indirectly—the referenced class also holds a reference to the class referencing it) within the references dialog, you can quite easily build in circular object references without realizing it or even deliberately. Classes with circular references don't release from memory until the application terminates. For more details, see Chapter 4.