Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations dencom on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multiple instances of the same form?

Status
Not open for further replies.

sunil128

Programmer
Mar 20, 2008
45
GB
Hi all, another very newbie question so apologies in advance, but how do I get multple instances of a form to work?

The form (form2) is called by pressing a command button on a another form (Form1).Currently if i go back to Form1 and press the cmdbutton it doesnt create another instance of the form2, it just reverts focus back to the exixting instance.
Thanks
 
In the button's click event...

Code:
Private Sub Command1_Click()
    
    Dim oForm As Form2
    
    Set oForm = New Form2
    Call oForm.Show(vbModeless)
    Set oForm = Nothing
    
End Sub



-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
You need to create a new instance of the form each time. Here's a small example bit of code to get you going:
Code:
Private Sub Command1_Click()

Dim frm2 As Form2

Set frm2 = New Form2

frm2.Show

End Sub
That will allow you to open multiple instances of your Form2.

Hope this helps

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.
 
Beat me to it George (and you cleaned up after your form as well)! [wink]

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.
 
Thanks for the replies guys, i tried it and it seems to work fine, but now the forms dont apper to want to close! How do i need to adapt the form close code?
 
Just to add, here is the current code i have for closing form2 - which could be totally wroing btw...

Unload form2
Set form2= Nothing
Form1.Show
 
I assume you want all instances of form2 to close when you close form1. If so...

Code:
Private Sub Form_Unload(Cancel As Integer)

    Dim oForm As Form
    
    For Each oForm In Forms
        Unload oForm
    Next

End Sub

You could also modify this code to only close your form2's.

Code:
Private Sub Form_Unload(Cancel As Integer)

    Dim oForm As Form
    
    For Each oForm In Forms
        If oForm.Name = "Form2" Then
            Unload oForm
        End If
    Next

End Sub

-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Instead of...

[tt][blue]
Unload form2
Set form2= Nothing
Form1.Show
[/blue][/tt]

use:

Code:
Unload Me


-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Thanks gmmastros, i actually want to be able to close each instance of form2 seperately, will the code you suggested work for that too?
 
If you use Unload Me, you should be able to close each form separately.


-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Hi, I can now get multiple instances of the form to open & close now so thanks. But now I am having problems with code that refers to my form2

For example i have generic code that i use to populate two flexgrid controls that are on two different forms which looks like this:

******************************************************************************************
Public Sub FillFromRecordset_FlexGrid(p_FlexGrid As Control,p_objRecordset As Object,p_booFieldNamesAsHeaders As Boolean)

More Code….etc etc
******************************************************************************************

Before having multiple instances of my form2 I would call the procedure like this:


******************************************************************************
Form1.FillFromRecordset_FlexGrid Form2.MSFlexgrid2, rstemp, True
*****************************************************************************

Now I have instances of form2 this code (and other similar code) does not work, how do I now change the code to reference the current instance of the form rather than the actual form itself?


p.s. what is the html tag for code?
 
You need to call the method of the instance of the form:

Code:
Private Sub Command1_Click()

  Dim frm2 As Form2

  Set frm2 = New Form2

  frm2.Show

  frm2.SomePublicMethod
End Sub


 
> p.s. what is the html tag for code?

Look for the "Process TGML" link below the area where you enter your reply... it describes all the tags available when you make a post. For code, surround it between [ignore]
Code:
 and
[/ignore] tags.
 
Hi George (or anyone else) I am having a problem with the code george gave for closing the instances of the form2 (below).

Code:
Private Sub Form_Unload(Cancel As Integer)

    Dim oForm As Form
    
    For Each oForm In Forms
        If oForm.Name = "Form2" Then
            Unload oForm
        End If
    Next

End Sub


When I close form1(my main screen) I want to check if any instances of form2(ofrom) exist in the background. Form2 is actually a user input screen where the user inputs & saves a customer record. Anyway if instances exist I want to run a save record method that belongs to my form2, which then also handles the closing of form2 i.e. "Do you wish to save changes - Yes/No/Cancel"

My actual code looks something like this
Code:
Private Sub cmdExit_Click()

    Dim oForm As Form
    Dim iCount As Integer

    iCount = 0
    
    For Each oForm In Forms
        If oForm.Name = "Form2" Then
            iCount = 1
            oform.setfocus
            oForm.SaveRecordMethod
        End If
    Next

    If iCount = 0 Then
        Unload Form1    
        Set Form1 = Nothing
    End If

End Sub

Basically this does not work as it does not recognise “oForm.SaveRecordMethod.”
So basically my question is how do you reference the methods (& properties,events etc) of an instantiated form and how do identify which instantiated form its actually refering to, as i dont the Me keyword will work here??

Please note im really strapped for time with this.
 
It works fine for me (except you don't unload any of the created forms in this example).

What error do you get?

Oh, while I think, SaveRecordMethod is a Public method isn't it?

Hope this helps

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.
 
Hi HarleyQuinn, thanks for that, yes I forgot to make that method public! That sorted the problem out.

But i still have an issue with georges initial code that actual sets up the instances in the first place:

Code:
Private Sub Command1_Click()
    
    Dim oForm As Form2
    
    Set oForm = New Form2
    Call oForm.Show(vbModeless)
    Set oForm = Nothing
    
End Sub

If i use this code how do i reference other properties/events of the instance if im setting oForm to nothing? Obvioulsy ive created an instance of form2 but what is it refered to as if oForm = nothing?

And also how do i identify/differentiate the different instances?

Currently ive set up oForm as public in my global bas which i know is wrong.

And then im using the code like this:
Code:
oForm1.lblLogIDResult.Caption = Rs2.Fields(0)

Again im sure this is wrong.
 
[!]This reply is from HarleyQuinn, not me.[/!]

If you're having several instances of the form open it would be a good idea to encapsulate the form's logic somewhere outside of the form creating the new instance, for example in a module, pass in the reference to the new form you've created (before you show it) e.g.

Code:
   1. 'In a Module
   2. Public Sub SetUpForm(vfrm As Form2)
   3.  
   4. vfrm.Text1.Text = "Hello"
   5.  
   6. vfrm.Label1.Caption = "Try this for size"
   7.  
   8. End Sub

And in the form calling it:
Code:
   1. Private Sub Command1_Click()
   2.  
   3. Dim frm2 As Form2
   4.  
   5.   Set frm2 = New Form2
   6.    
   7.   Call SetUpForm(frm2)
   8.    
   9.   frm2.Show
  10.  
  11.   Set frm2 = Nothing
  12.  
  13. End Sub

You can do all of your setup in the module and then the new instance of the form is created. You can pass anything you want to the module depending on how you set up the procedure inside it.

Once you have the new instance there should be no need to reference it from the calling form.

That would be one way, not saying it's definitely the best way to do it but it will work.
I'm sure othe tipsters will show you different ways of accomplishing similar tasks.

Hope this helps


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
I may be off base here since I come from a VBA background not a VB background. So if I am wrong please disregard.

However in VBA all form instances maintain the same name property. In order to get around that you need to give the form a custom property. So in the form class something like

public theName as string

Now when I open an instances I can set this property. Also in VBA forms instances are not added to the forms collection. Maybe in VB they are. So in order to manage the form instances I have to use a user defined collection. The following is done in excel VBA and demonstrates two ways to refer to a specific form instance and close it.

Code:
Public myForms As Collection
Public Sub openInstances()
  Set myForms = New Collection
  Dim frm As FormOne
  Dim frm1 As New FormOne
  Dim frm2 As New FormOne
  frm1.theName = "frm1"
  frm2.theName = "frm2"
 
  myForms.Add frm1, "frm1"
  myForms.Add frm2, "frm2"
  
  For Each frm In myForms
    With frm
      .Show
      .Caption = frm.theName
     End With
  Next frm

  MsgBox "forms open"
  closeInstance ("frm2")
  'closeInstance2 ("frm2")
End Sub

Public Sub closeInstance2(frmName As String)
 'Uses the named index of the collection
 Unload (myForms(frmName))
 myForms.Remove (frmName)
End Sub

Public Sub closeInstance(frmName As String)
 'Uses custom property
 Dim frm As FormOne
 For Each frm In myForms
    If frm.theName = frmName Then
      Unload frm
      myForms.Remove (frmName)
    End If
 Next frm
End Sub

If I was really doing this I would my own custom collection to give it some error checking, custom methods, and custom properties.

But I did not see anywhere in your code how you gave each instance a unique name. In VBA that can not be done using the forms Name property, but maybe in VB it can.
 
Seems I can't post my response, in response to MajP's post you can uniquely indentify the form by setting it's .Tag property. Setting the name in this way isn't supported in VB6 either.

Regards

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.
 
Cheers Mark, still not sure why it doesn't work for me though... [ponder]

HarleyQuinn
---------------------------------
The most overlooked advantage to owning a computer is that if they foul up there's no law against wacking them around a little. - Joe Martin

Get the most out of Tek-Tips, read FAQ222-2244 before posting.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top