(I'm pretty sure I didn't come up with this but it's been in some of my stuff for a few years now. If I find where I got it from I'll post that link)
Typically when you open a form in Access
DoCmd.OpenForm "Name of Form"
It will open it then if when you call that code again (while still having the first form open) it will just pop focus back to the form as it was first opened. Th Open and Load events don't fire either so you can't "reinitialize" without closing it first.
To get around this you can create a New Form
and pass around the Hwnd
of that form. I use this to keep a form for creating dynamic datasheets (i.e. you pass in a recordset or recordsource and it figures out how to display it by setting all the appropriate control sources)
Public multiInstanceDic As Dictionary
'returns the window handle (long)
Public Function OpenNewDynamicDataSheetInstance(queryForRecordSource As String, Optional inputCaption As String) As Long
If multiInstanceDic Is Nothing Then
Set multiInstanceDic = New Dictionary
End If
Dim frm As Form
Set frm = New Form_DynamicDatasheet
frm.Caption = inputCaption
frm.SetRecordSource queryForRecordSource
multiInstanceDic.Add frm.Hwnd, frm 'required to keep form alive after function exits
frm.SetFocus
OpenNewDynamicDataSheetInstance = frm.Hwnd
End Function
Public Function GetDynamicDataSheetInstance(frmHandle As Long) As Form_DynamicDatasheet
Set GetDynamicDataSheetInstance = multiInstanceDic(frmHandle)
End Function
Now whenever I need to open this form I can call this:
Dim createdWindowHandle As Long
createdWindowHandle = Windows.OpenNewDynamicDataSheetInstance("ViewForRecordsource", "My Caption Text")
And if I need to access things about that specific object like setting some property uniquely for this instance I can do it like this:
Dim dDataSht As Form_DynamicDatasheet
Set dDataSht = Windows.GetDynamicDataSheetInstance(createdWindowHandle)
dDataSht.SomeProperty = "set to this"
Then I clean up the reference to the form from this statis public dictionary in the Unload
event of the form. I have this set up to only work with one type of form object. I you want multiple instances of multiple types of forms there are probably work arounds for that. I'm sure I'll need to do that some day in which case I'll update this.
Private Sub Form_Unload(Cancel As Integer)
If Not MultiFormInstance.multiInstanceDic Is Nothing Then
If MultiFormInstance.multiInstanceDic.Exists(Me.Hwnd) Then
MultiFormInstance.multiInstanceDic.Remove Me.Hwnd
End If
End If
End Sub
And in my dashboard close event I can get rid of any stragglers (which there shouldn't be any but...who knows)
If Not Windows.multiInstanceDic Is Nothing Then
'kill all the dynamic datasheets
Dim key As Variant
For Each key In Windows.multiInstanceDic.Keys
Set Windows.multiInstanceDic(key) = Nothing
Next key
End If
Related Links:
http://www.vbforums.com/showthread.php?372811-Classic-VB-Why-can-t-I-use-WithEvents-on-arrays-of-objects