Multiple instances of a form

DataMinerHome

Registered User.
Local time
Yesterday, 22:50
Joined
Jan 4, 2010
Messages
57
I need to open multiple instances of the same form, and am using Allen Brown's method from http://allenbrowne.com/ser-35.html
However, I want to feed a variable into the New Form line.
For example, his code looks like this:
Function OpenAClient()
'Purpose: Open an independent instance of form frmClient.
Dim frm As Form

'Open a new instance, show it, and set a caption.
Set frm = New Form_frmClient



frm.Visible = True
frm.Caption = frm.Hwnd & ", opened " & Now()
'Append it to our collection.
clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)
Set frm = Nothing
End Function
But I want my code to be something like:
Function OpenAClient(MyForm as WhoKnows?)
'Purpose: Open an independent instance of form frmClient.
Dim frm As Form

'Open a new instance, show it, and set a caption.
Set frm = New MyForm



frm.Visible = True
frm.Caption = frm.Hwnd & ", opened " & Now()
'Append it to our collection.
clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)
Set frm = Nothing
End Function
I thought I could just dim Myform as Form, but that doesn't work. So, how can I make this work?

Thanks for any help you can offer!
 
In VBA you can't past the type as a variable. You can pass a string (or something else) to indicate a type, or pass the object itself created by the calling code.
The first case might be something like ...
Code:
Function GetNewForm(fType as string) As Form
  Dim frm as Form

[COLOR="Green"]  'form to create is determined by some indicator[/COLOR]
  Select Case fType
    Case "Form1"
      Set frm = New Form_fForm1
    Case "OtherForm"
      Set frm = New Form_fOtherForm
    Case "12"
      Set frm = New Form_fForm12
  End Select

  frm.Visible = Not frm Is Nothing
[COLOR="Green"]  'other code here[/COLOR]
  Set GetNewForm = frm
End Function
...or calling code can create the object...
Code:
Sub Testing
  AddFormToCustomCollection New Form_Form1
End Sub

Sub AddFormToCustomCollection(frm as Form)
  if not frm is nothing then
    frm.visible = true
    MyColl.Add CStr(frm.Hwnd), frm
  end if
end sub
The actual class name of a form in Access is always prefixed with "Form_", so to create a new instance of a specific form called "SomeForm" the syntax will always be ...
Code:
  dim frm as object
  set frm = new Form_SomeForm
hth
Mark
 
Thanks, I think the select case method will work OK for me, although I would rather not have to update the select case every time I add a new form.

I am not sure I understand the other method but will give it a closer look. Should it allow me to set things up so that the name of the form is a variable?
 
Hello, I discovered this post a few days ago and was able to follow the instructions at Allen's site... however... my main form has subforms. The subforms load into the subform control based on code for an onclick event. When I open an instance of the main form, the code to load the subforms no longer works, i get this error message: Run-time Error 2450: Micorsoft Access cannot find the referenced form "NavigationForm" (navigationform is the name of my main form). This confused me because the main form opens just fine, as many times as I open it... but trying to load the subforms triggers the error message. Can anyone help please?
 
I believe the problem is that when you use non-default instances of forms, the Access.Forms collection does not index those forms by name, which makes sense since there would be duplicate indices, which is not allowed in a collection. So any references to named members of the Forms collection, like Forms("YourFormName"), or Forms!YourFormName, won't work.

Happy holidays,
 
Thanks, Lagbolt, is there not a workaround for this? Is there another way to reference the form(s)? I sure appreciate the help!
 
Ma t

If the error message contains the name of the Form as in "NavigationForm" then it would appear that the code also contains a hard coded reference to "NavigationForm".

I think you may have just found one of the reasons not to hard code names in code.
Instantiated Forms are not ‘opened’ in the normal sense, nor are subforms for that matter.

Where possible, things like the hard coded versions of Form!NavigationForm or Forms("NavigationForm") should be avoided and replaced with a soft coded alternative such as Me or Form. It depends on the code and where it is running.

Can you please post the line of code which is causing the error?
Can you also state in which Form that code is running?

Chris.
 
Presumably when you create your non-default instances you assign them to object variables or add them to collections. Workaround by referring to those variables instead of named members of the Forms collection.

Alternatively, non-default instances of forms are still in the Forms collection, they just aren't indexed by name, so you could enumerate that collection and look for the form you want based on other criteria.

But for more specific help, and as Chris mentions, post more specifics about what fails and where.

Cheers,
 
Dear Lagbolt and Chris,

Here is the code:
Option Compare Database

Private Sub Tab1ButtonLabel_Click()
Forms!MainNavigationForm!SF2Cont.SourceObject = Me.Tab1FormName
End Sub

What I have done is this...
I have a main form named "MainNavigationForm" (I changed the name of the form since my last post)
This main form contains 2 subform controls, SF1Cont and SF2Cont. The subforms that load into the two controls is based on some code that I have developed via many trips to forums like this.
The source of the SF1Cont is a subform that has 1 textbox control with the source "Nav_Tab1Q" which is a query based on the table with the fields "tabnumber", "buttonlabel" and "formname" fields.
The queries select the records by "tabnumber" so that the resulting subforms show just the rows where tabnumber = 1 for instance. I renamed the "formname" field in each query to "tab1formname" , "tab2formname" , etc. so that each query for each tabnumber group would have a unique name. What I am trying to accomplish is that I will be able to open multiple instances of the "MainNavigationForm" and be able to click on the rows in the subform (picture a list buttons in a left navigation style menu) to change which subform loads (independent of the any other main forms that are open). I can get my navigation to work if I abandon the multiple instances, and I can open multiple instances if I don't try to change the sform...
This is the code that I am using from Allen Browne to create the instances, and I figured out how to show the last, first name for the caption...

Option Compare Database

Public clnClient As New Collection 'Instances of frmClient.
Function OpenAClient()
'Purpose: Open an independent instance of form frmClient.
Dim frm As Form

'Open a new instance, show it, and set a caption.
Set frm = New Form_NavigationForm

frm.Visible = True
frm.Caption = [Forms]![Nav_PersonSearch]![SearchResultsSFCont].[Form]![Last] & ", " & [Forms]![Nav_PersonSearch]![SearchResultsSFCont].[Form]![First]

'Append it to our collection.
clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)

Set frm = Nothing
End Function

Function CloseAllClients()
'Purpose: Close all instances in the clnClient collection.
'Note: Leaves the copy opened directly from database window/nav pane.
Dim lngKt As Long
Dim lngI As Long

lngKt = clnClient.Count
For lngI = 1 To lngKt
clnClient.Remove 1
Next
End Function

Also, I am pasting a picture of my "homemade" navigation form.
 
2Q==
 
Apparently I'm not allowed to paste the picture...
 
But that code you posted works, right? You are able to open mutiple instances, which is what that does.

Boiled down, isn't this is your dilemma?
I can get my navigation to work if I abandon the multiple instances, and I can open multiple instances if I don't try to change the sform...
... so what we need to scrutinize to solve the problem is what fails when you try to change the subform. One possibility, for instance, is that your subform RecordSource is driven by SQL like ...
Code:
SELECT * FROM tTable WHERE Field1 = [COLOR="DarkRed"][B]Forms!MyBigNavForm[/B][/COLOR].txtSearchFor
... which directly references a named member of the forms collection, which doesn't exist if you opened non-default instances. See what I mean?

The failure in the subform might be in the SQL RowSource for a Combobox, might be in the RecordSource of the subform itself, might be in some DCount() run by a calculated control, and so on. If you can post the specific code that fails, or the exact steps you take before the failure, and the exact messages and errors that occur when the failure happens, that would help.

Also, if you post code, highlight that code in the post window and hit the "#" character above, which wraps your code in <code> tags, and that offsets your code, preserves your indents, uses a monospaced font, and generally makes your post way easier to read. Example...
Code:
Sub CloseAllClients()
'   Closes all instances in the clnClient collection.
    Set clnClient = New VBA.Collection
End Sub
Cheers,
 
Hello Lagbolt, and thank you so much for trying to help!

Yes, the code to open a new instance of the form works great.
The next thing that happens is I click on my left nav subform (contained in the SF control SF1Cont) to change the source of my other subform (SF2Cont) and I get the message: Run-time error 2450. Micorsoft Access cannot find the referenced form MainNavigationForm.
From there I select "debug" and this is the code- the second line has a yellow highlight...

Code:
Private Sub Tab1ButtonLabel_Click()
Forms!NavigationForm!SF2Cont.SourceObject = Me.Tab1FormName
End Sub

I think I follow what you said above re the form not being named conventionally, and what you said earlier re using "soft" coding, however I am a VBA super novice, i try to get things to work with lots of reading and copying others posts, and beyond that I am sort of lost. :confused:
 
I will try to upload a copy of what I am working with...
 
Rather than:-
Forms!NavigationForm!SF2Cont.SourceObject = Me.Tab1FormName

Try:-
Me.SF2Cont.SourceObject = Me.Tab1FormName

Or:-
Me.Parent.SF2Cont.SourceObject = Me.Tab1FormName

Chris.
 
Wow! I think I got it to work, even I amaze myself at times. Thanks to all who contributed, many times over. I am now able to switch tabs and tab "buttons" error free!
 
Nice job. Happy new year to you both.
 
Both of us? Me and the database? hehe.
Have a very good new year!
 
Yes, happy new year to you Mark and ma t.

Chris.
 
Last edited:
Hello and good day-
I am making good progress on building my forms, but I have another question, and after trial and error and a few hours searching forums I am not able to figure it out on my own.
This is what I need to do, I have the above code working perfectly, however, i need to include a "where" clause and I'm just not getting it to work. I still have the main form with 3 subforms. one of the subform controls "Nav_HeaderSFCont" contains the basic client info for the person that is currently loaded in that "instance" of the main form. In that record are two identifying id numbers, the PID (person id) and the FID (family id). the code that you helped me with yesterday for the subform control "SF2Cont" loads all of the various forms, but I need to have the correct person's (or family's) records. I did have the sf control set to link on master and child fields on PID but in some cases I need to link on FID and others PID. I am sure there is a very easy way to set this up with VBA but I am stumped. Here is the code:

Code:
Option Compare Database
Private Sub Tab2ButtonLabel_Click()
Me.Parent.SF2Cont.SourceObject = Me.Tab2FormName

Where Me.Parent.Nav_HeaderSFCont.FID = Me.Parent.SF1Cont.FID

End Sub
Any help Please? :)
 

Users who are viewing this thread

Back
Top Bottom