Ken Ismert
KIsmert at TexasSystems.com
Thu Jan 22 12:41:53 CST 2004
David,
Intriguing ... assigning the responsibility of creating the form instance to
the form class itself.
I have several comments regarding your code:
1. If you copied "TestForm" to "New_Form", New_Form.NewInstance would create
TestForm instances, an implicit mismatch. To catch this error, I would
suggest:
Public Function NewInstance() As Access.Form
If Not (TypeOf Me Is Form_TestForm) Then
' Raise Type Mismatch Error
Err.Raise 13, "Form_" & Me.Name & ".NewInstance", "Type
mismatch"
End If
Set NewInstance = New Form_TestForm
End Function
This way, TestForm.NewInstance works, but New_Form.NewInstance generates a
runtime error, prompting you to fix the routine.
2. To avoid the screen flicker, you could try opening the form with acHidden
3. Regarding the problem you mentioned, I would suggest putting all form
references into a collection. You could key it with the Form.Hwnd property,
as MarkH did in his code. Closing a form would be a matter of setting focus
to the form, issuing a DoCmd.Close, and removing it from the collection.
This approach is as workable as any other. The nice thing about it is, if
you delete a form, you don't have to update your form creation function. If
you copy a form, you still have to remember to modify its NewInstance
function, which is not a bad tradeoff.
-Ken
-----Original Message-----
From: David Beckles [mailto:becklesd at tiscali.co.uk]
Sent: Wednesday, January 21, 2004 7:11 PM
To: accessd at databaseadvisors.com
Subject: [AccessD] RE: Instantiate Forms as Objects
Dear Ken,
One way of achieving (most of) what you want to do is as follows:
1. In each of your forms create the function
Public Function NewInstance() As Form
Set NewInstance = New Form_TestForm
End Function
Its purpose is merely to return a reference to a new instance of the form.
You could also define it as a new public property of the form, instead of a
function.
2. Define the following function in some general module
Public Function OpenFormMultiple(FormName As String) As Form
' check the Forms collection, and if the form is in it then use the
NewInstance() method of the form
' otherwise open the form in the usual way and return a reference to
it.
' in either case, the form will not be visible.
' if any errors occur, then the value Nothing will be returned, so
remember to test for it.
On Error Resume Next ' You could use fancier error handling if
you wanted
Dim F As Form
Set OpenFormMultiple = Nothing
Set F = Forms(FormName)
If F Is Nothing Then
Application.Echo False ' this is to suppress the screen flicker
DoCmd.OpenForm FormName
Set F = Forms(FormName)
F.Visible = False
Set OpenFormMultiple = F
Application.Echo True
Else
Set OpenFormMultiple = F.NewInstance()
End If
End Function
One problem with this arrangement is that you can close all the instances
of a form except the first by setting the reference to Nothing. The first
instance has to be closed by going into the Forms collection. I have not
found a way around that as yet.
I hope that this helps,
David