You can use the Terminate and QueryClose events if you put code in the template userform.
Here is another variation on the code. Instead of an array it uses a collection.
The button on the userform creates another clone of itself.
Code for your standard code module
Public g_colMyForms As Collection
Public g_lngActiveMyForm As Long
Sub Demo()
' entry point
AddUserform
End Sub
Sub AddUserform()
' add another userform
Dim objMyForm As UserForm1
If g_colMyForms Is Nothing Then
Set g_colMyForms = New Collection
End If
Set objMyForm = New UserForm1
g_colMyForms.Add objMyForm, CStr(g_colMyForms.Count + 1)
Load objMyForm
With objMyForm
.Label1.Caption = "This is copy " & g_colMyForms.Count
.Caption = "Copy " & g_colMyForms.Count
.Tag = g_colMyForms.Count
.Show vbModeless
End With
End Sub
Sub DestroyUserforms()
' release userforms from memory
Do While g_colMyForms.Count > 0
Unload g_colMyForms.Item(g_colMyForms.Count)
g_colMyForms.Remove g_colMyForms.Count
Loop
Set g_colMyForms = Nothing
End Sub
Code for userform, containing Label1, CommandButton1
Private Sub CommandButton1_Click()
AddUserform
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
MsgBox "Query close " & Me.Name & " " & Me.Caption
End Sub
Private Sub UserForm_Terminate()
MsgBox "Terminating " & Me.Name & " " & Me.Caption
End Sub
Private Sub UserForm_Deactivate()
Me.Caption = "Inactive"
End Sub
Private Sub UserForm_Activate()
g_lngActiveMyForm = CLng(Me.Tag)
Me.Caption = "I'm Active"
End Sub