OPening more than one occurrence of a form (1 Viewer)

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
Can I open the same form more than once with different data and if so what are the pitfalls and things to be wary of?
 

Galaxiom

Super Moderator
Staff member
Local time
Today, 22:15
Joined
Jan 20, 2009
Messages
12,851
You certainly can.

Code:
Dim frm1 As Form
Dim frm2 As Form

Set frm1 = New Form_formname
Set frm2 = New Form_formname

The forms are then addressed by their variable name.

Code:
frm1.RecordSource = whatever
frm1.Visible = True
 

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
You certainly can.

Code:
Dim frm1 As Form
Dim frm2 As Form

Set frm1 = New Form_formname
Set frm2 = New Form_formname

The forms are then addressed by their variable name.

Code:
frm1.RecordSource = whatever
frm1.Visible = True

I'm not getting it!
So what I want to do is say list invoices. When user double clicks on an invoice it will open a form and display invoice details. User can then go back and click on another invoice to open 2nd invoice. So how do I dynamically create the name for the form.
I'd want the form to be frmx where x is a variable number.
 

sonic8

AWF VIP
Local time
Today, 14:15
Joined
Oct 27, 2015
Messages
998
So how do I dynamically create the name for the form.
I'd want the form to be frmx where x is a variable number.
Unfortunately, that's not possible.The class name has to be hardcoded in the variable assignment.


Why do you need to open a form whose name you do not know in advance?


[Edit] I probably misinterpreted your question. If it is about the variable name and not the class name of the form, Galaxiom's hint to the collection is the way to go.[/Edit]
 
Last edited:

Galaxiom

Super Moderator
Staff member
Local time
Today, 22:15
Joined
Jan 20, 2009
Messages
12,851
. So how do I dynamically create the name for the form.
I'd want the form to be frmx where x is a variable number.

You can use a Collection to hold the instances of the form and then refer to them by whatever index names you give them.

All instances have the same Name property which is the default that is displayed in the header. However you can change that to whatever you want by using the Caption Property.

Code:
frm1.Caption = "whatever you want"
 

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
Unfortunately, that's not possible.The class name has to be hardcoded in the variable assignment.


Why do you need to open a form whose name you do not know in advance?


[Edit] I probably misinterpreted your question. If it is about the variable name and not the class name of the form, Galaxiom's hint to the collection is the way to go.[/Edit]

I know the name of the form. I want to be able to open it twice with differing data
 

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
You can use a Collection to hold the instances of the form and then refer to them by whatever index names you give them.

All instances have the same Name property which is the default that is displayed in the header. However you can change that to whatever you want by using the Caption Property.

Code:
frm1.Caption = "whatever you want"

OK i'll read up on collections!
 

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
Allen Browne covers it very well here:-


http://allenbrowne.com/ser-35.html


Sent from my SM-G925F using Tapatalk

This works but but I'd need to set this up for each form where I need a 'collection' as the name of the form is specified in the function. I've tried passing the name of the form over to the function as a parameter but I can't create a new addition to the collection in this way. Probably doing it wrong anyway but this is what I'm doing

Original code is

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

I've tried changing the function to

Function OpenAClient(CALForm As Form)
and changing the set frm to
Set frm = new CALForm

I get compile errors for this?
I resume I can't actually do this and I will need a function for each set of forms where I need a collection
 

MarkK

bit cruncher
Local time
Today, 05:15
Joined
Mar 17, 2004
Messages
8,179
You don't need to append the form to a collection if you don't want to. To keep the form alive independently it can maintain a reference to itself. Consider code like...
Code:
private m_me as form

private sub form_open(cancel as integer)
   set m_me = me
end sub
See how m_me now contains a reference to itself? That is sufficient to keep the non-default instance alive.

To test it you can run code like....
Code:
dim i as integer
for i = 1 to 5
   with new form_form1
      .visible = true
      .caption = "instance number " & i
   end with
next
...assuming the form's name is 'form1.'

To close the form from a button on that form, clear the variable m_me, and then, because there is no longer a reference count to the object, garbage collection reclaims the memory, and the form closes...
Code:
private sub cmdclose_click()
   set m_me = nothing
end sub
hth
Mark
 

Gasman

Enthusiastic Amateur
Local time
Today, 13:15
Joined
Sep 21, 2011
Messages
14,234
Wouldn't you just be passing in the name of the form as a string and then concatenate with "Form_" & CalForm or perhaps have to use EVAL() ?

This works but but I'd need to set this up for each form where I need a 'collection' as the name of the form is specified in the function. I've tried passing the name of the form over to the function as a parameter but I can't create a new addition to the collection in this way. Probably doing it wrong anyway but this is what I'm doing

Original code is

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

I've tried changing the function to

Function OpenAClient(CALForm As Form)
and changing the set frm to
Set frm = new CALForm

I get compile errors for this?
I resume I can't actually do this and I will need a function for each set of forms where I need a collection
 

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
Wouldn't you just be passing in the name of the form as a string and then concatenate with "Form_" & CalForm or perhaps have to use EVAL() ?
I tried that before but will try again. I've not used EVAL though so will have a look at that.

OK - no idea how to use EVAL
Tried this
Eval ("Set frm = New Form_" & CALForm)
and
Set frm = New Eval ("Form_" & CALForm)

neither work
 
Last edited:

MarkK

bit cruncher
Local time
Today, 05:15
Joined
Mar 17, 2004
Messages
8,179
If you post a database that demonstrates the problem you are working on, I will modify it to show you a very simple way to enable non-default instances.
Mark
 

ryetee

Registered User.
Local time
Today, 13:15
Joined
Jul 30, 2013
Messages
952
If you post a database that demonstrates the problem you are working on, I will modify it to show you a very simple way to enable non-default instances.
Mark
OK but off to bed now s will do tomorrow
 

Gasman

Enthusiastic Amateur
Local time
Today, 13:15
Joined
Sep 21, 2011
Messages
14,234

sonic8

AWF VIP
Local time
Today, 14:15
Joined
Oct 27, 2015
Messages
998
No, I was thinking of Eval(CalForm).
You are just trying to evaluate the contents of the variable.
Sorry, but as indicated earlier, it does not work this way. You have to hardcode the form name.
You are not evaluating the content of a variable, but you are defining the type of an object to instantiate. This can be done only at compile time (In VBA).
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 08:15
Joined
May 21, 2018
Messages
8,525
I do not understand what the problem is. Here is my guess. You want to pass the "form name" to the function. Understand you can not set the name property (they all share the same name), but you can set the key in the collection so you can call it by your name and you can set the caption. You will need error checking because if you try to set a duplicate key you will get an error.
Code:
Public Function OpenAClient(FormName as string)
    '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 = FormName

    'Append it to our collection.
    clnClient.Add Item:=frm, Key:=FormName
    Set frm = Nothing
End Function
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 08:15
Joined
May 21, 2018
Messages
8,525
However, if you want to manage your forms by "name" you will have to modify the method to remove from the collection to use the "name" instead of the HWND.
Code:
Private Sub Form_Close()
    'Purpose: Remove this instance from clnClient collection.
    Dim obj As Object        'Object in clnClient

    Dim blnRemove As Boolean  'Flag to remove it.

    'Check if this instance is in the collection.
    For Each obj In clnClient
        If obj.Caption = Me.Caption Then
            blnRemove = True
            Exit For
        End If
    Next

    'Deassign the object and remove from collection.
    Set obj = Nothing
    If blnRemove Then
        clnClient.Remove Me.Caption
    End If
End Sub

Also the code for managing the form collection should go in a standard module. And it can be used for form instances of different types of form. The only problem with the caption property is that may not be what you want to show as a caption. You could use the tag property or add a custom property to your form like "MyFormName" and use that. The only requirement is that you have to provide a unique value for all forms to make this work.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 08:15
Joined
May 21, 2018
Messages
8,525
One final thing. I would rearrage the original code to put the code for removing from the collection into a standard model. That way it makes it more portable for reuse
Code:
Private Sub Form_Close()
 ‘Form Code  
  'Purpose: Remove this instance from clnClient collection.
    RemoveFromCollection Me.Caption
End Sub

Public Sub RemoveFromCollection(FormCaption as string)
  ‘Put in standard module  
  'Purpose: Remove this instance from clnClient collection.
    Dim obj As Object        'Object in clnClient
    Dim blnRemove As Boolean  'Flag to remove it.
    'Check if this instance is in the collection.
    For Each obj In clnClient
        If obj.Caption = FormCaption Then
            blnRemove = True
            Exit For
        End If
    Next
    'Deassign the object and remove from collection.
    Set obj = Nothing
    If blnRemove Then
        clnClient.Remove FormCaption
    End If
End Sub
 

Users who are viewing this thread

Top Bottom