Multiple Instance of a Form

J

John F

Is it possible to display multiple instances of an access form and if so how
is this done?

John.
 
A

Allen Browne

You can do that with the New keyword.

For example, if you have a form named Form1 that is already open, this code
will display a second instance:
Dim frm As Form
Set frm = New Form_Form1
frm.Visible = True
Stop

The trouble is that the form closes again as soon as the frm variable goes
out of scope, i.e. as soon as that procedure ends. So, you need to append
the variable to a custom collection to manage the instances of the form.

There's a downloadable example of how to do that in this article:
Managing Multiple Instances of a Form
at:
http://allenbrowne.com/ser-35.html
 
D

David C. Holley

Nope. I would ask though *WHY* do you want to? What are you trying to
accomplish with displaying multiple forms?
 
A

Allen Browne

Simple example, David, would be to view the details of 2 clients at the same
time.
 
D

David C. Holley

Property Management System for a small little destination resort in
Orlando with 28,000 rooms, give or take, where you end up with 3
different Client Access Sessions (it runs on a AS/400, oops make that an
iSeries server) so that you can see two different reservations and the
room rack simulatenously.
 
D

dommo

Slightly off-topic, but does anyone know if there's a way to set
the'SourceObject' of a subform from code, using a reference to a form
instance? Access only seems to allow it to be set via the form name
(specified as a string), which is no good if the required sub-form is in a
referenced library database. If it's possible, it'd be the cure to a big
headache for me!
 
G

Graham R Seach

No, it can't be done.

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia
 
E

Ed Adamthwaite

Hi Graham,
It can be done. Check the following code that opens a form with a subform 3
times.
On the second instance, it changes the subform's (Child16) sourceobject to a
different subform.

Sub test3Forms()
Static frm1 As Form
Static frm2 As Form
Static frm3 As Form

Set frm1 = New Form_frmAdditivesAndInnerIngr

With frm1
.Visible = True
.Caption = "Hello SIG!"
.Detail.BackColor = vbYellow
.Controls("lblSort").BackColor = vbYellow
End With

'move to top left corner of window
DoCmd.MoveSize 0, 0

'create a new (second) instance of the same form
Set frm2 = New Form_frmAdditivesAndInnerIngr

With frm2
.Visible = True
.Caption = "Hello Again SIG!"
.Detail.BackColor = vbRed
.Controls("lblSort").BackColor = vbRed
.Controls("Child16").SourceObject = "sbfrmAdditives"
End With

'offset from top left corner
DoCmd.MoveSize 500, 500

'create a new (third) instance of the same form
Set frm3 = New Form_frmAdditivesAndInnerIngr

With frm3
.Visible = True
.Caption = "Hello Again, No Changes"
End With

'offset from top left corner
DoCmd.MoveSize 1000, 1000
End Sub

Regards,
Ed.

Ed Adamthwaite
Melbourne PC Access SIG Convener
AH 03 9754 2334
BH 03 9708 5700
Mob 0419 516 644
(e-mail address removed)
 
E

Ed Adamthwaite

Hello again Graham,
I forgot to add the extra code for changing on the fly after the form
opening code has been run.
Notice that we find the instance that we are looking for by using it's
caption:

Sub changesubform()
Dim frm As Form
Dim i As Integer
i = 0
For Each frm In Forms
Set frm = Forms(i)
If frm.Caption = "Hello Again SIG!" Then Exit For
i = i + 1
Next
frm.Controls("Child16").SourceObject = "sbfrmAdditiveAndInnerIngrWarnings"
frm.Requery
Set frm = Nothing
End Sub

Cheers.

Ed Adamthwaite
Melbourne PC Access SIG Convener
AH 03 9754 2334
BH 03 9708 5700
Mob 0419 516 644
(e-mail address removed)
 
D

Dirk Goldgar

[...]
On the second instance, it changes the subform's (Child16)
sourceobject to a different subform. [...]
With frm2 [...]
.Controls("Child16").SourceObject = "sbfrmAdditives"
End With

But that is not what the OP was asking, and what Graham was saying
couldn't be done. Specifically, the OP asked,

As I interpret this, and I think it's also how Graham understood it, the
OP would like to be able to do something like this:

<BEGIN INVALID CODE>

Dim frm As Form

' Create an instance of the form to be used as a subform.
Set frm = LibraryDatabase.FormFactory("SomeForm")

Set .Controls("SubformName").SourceObject = frm

<END INVALID CODE>

But you can't do that; at least, not using any normal method. I suppose
it might be possible by manipulating memory with pointers and such, but
it would be very difficult at best.
 
D

dommo

Yeah, Dirk's <INVALID CODE> represents exactly what I would like to be able
to do. I didn't expect to be able to do it by "any normal method" (as Dirk
put it), but I thought that perhaps someone might know an undocumented trick
for achieving the goal - I've seen people post such things here before...

Anyway, thanks everybody for their input - it's great to have a resource
like this one!!

Regards,
Dom.

Dirk Goldgar said:
[...]
On the second instance, it changes the subform's (Child16)
sourceobject to a different subform. [...]
With frm2 [...]
.Controls("Child16").SourceObject = "sbfrmAdditives"
End With

But that is not what the OP was asking, and what Graham was saying
couldn't be done. Specifically, the OP asked,

As I interpret this, and I think it's also how Graham understood it, the
OP would like to be able to do something like this:

<BEGIN INVALID CODE>

Dim frm As Form

' Create an instance of the form to be used as a subform.
Set frm = LibraryDatabase.FormFactory("SomeForm")

Set .Controls("SubformName").SourceObject = frm

<END INVALID CODE>

But you can't do that; at least, not using any normal method. I suppose
it might be possible by manipulating memory with pointers and such, but
it would be very difficult at best.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)
 
E

Ed Adamthwaite

Hi Dirk,
Yes, I bypassed the point about using a string, to me it still doesn't
matter. If you change the code of the second instance to:

Static frm2 As Form

Set frm2 = New Form_frmAdditivesAndInnerIngr

With frm2
.Visible = True
.Caption = "Hello Again SIG!"
.Detail.BackColor = vbRed
.Controls("lblSort").BackColor = vbRed
.Controls("Child16").SourceObject = Form_sbfrmAdditives.Name
End With

We are still referencing it as a string (sbfrm.Name), but a literal string
is not used. If you open a completely empty database and reference the
database with this code in it, it still runs without a problem.
We can still change the subform by code by doing the same with the altered
"changesubform" procedure below.
You don't even have to Requery the form.

Sub changesubform()
Dim frm As Form
Dim i As Integer
i = 0
For Each frm In Forms
Set frm = Forms(i)
If frm.Caption = "Hello Again SIG!" Then Exit For
i = i + 1
Next
frm.Controls("Child16").SourceObject =
Form_sbfrmAdditiveAndInnerIngrWarnings.Name
'frm.Requery
Set frm = Nothing
End Sub

The only problem is that you need to have the code in the referenced
database. Graham is correct if the code is in the referencing database. From
what I have found it seems that Form Objects are not passed to the VBA IDE
via the reference, only modules with their types, enums, properties and
methods. It would be nice if it could, but this could open up a few more
security issues to contend with.


Cheers,
Ed.

Dirk Goldgar said:
[...]
On the second instance, it changes the subform's (Child16)
sourceobject to a different subform. [...]
With frm2 [...]
.Controls("Child16").SourceObject = "sbfrmAdditives"
End With

But that is not what the OP was asking, and what Graham was saying
couldn't be done. Specifically, the OP asked,

As I interpret this, and I think it's also how Graham understood it, the
OP would like to be able to do something like this:

<BEGIN INVALID CODE>

Dim frm As Form

' Create an instance of the form to be used as a subform.
Set frm = LibraryDatabase.FormFactory("SomeForm")

Set .Controls("SubformName").SourceObject = frm

<END INVALID CODE>

But you can't do that; at least, not using any normal method. I suppose
it might be possible by manipulating memory with pointers and such, but
it would be very difficult at best.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)
 
D

Dirk Goldgar

Ed Adamthwaite said:
Hi Dirk,
Yes, I bypassed the point about using a string, to me it still doesn't
matter. If you change the code of the second instance to:

Static frm2 As Form

Set frm2 = New Form_frmAdditivesAndInnerIngr

With frm2
.Visible = True
.Caption = "Hello Again SIG!"
.Detail.BackColor = vbRed
.Controls("lblSort").BackColor = vbRed
.Controls("Child16").SourceObject = Form_sbfrmAdditives.Name
End With

We are still referencing it as a string (sbfrm.Name), but a literal
string is not used.

Sure, you can do that, but you've just loaded two instances of
Form_sbfrmAdditives -- one as a (hidden) main form, and one as the
subform control's SourceObject. I'd consider that an undesirable side
effect.
If you open a completely empty database and
reference the database with this code in it, it still runs without a
problem.

Yes, and that might be a solution for some problems. I don't think it
solves dommo's problem, though, as it appears he has a main form in the
current database and wants to load a subform control (on that main form)
with a form object from the library database.
 
G

Graham R Seach

Ed,

But you're not referencing the same form instance!

Using Set frm = New Form_whatever
....is not the same instance as...
..Controls("Child16").SourceObject = Form_whatever

If you could set it as follows, it would be what the OP wanted:
.Controls("Child16").SourceObject = frm

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia

Ed Adamthwaite said:
Hi Dirk,
Yes, I bypassed the point about using a string, to me it still doesn't
matter. If you change the code of the second instance to:

Static frm2 As Form

Set frm2 = New Form_frmAdditivesAndInnerIngr

With frm2
.Visible = True
.Caption = "Hello Again SIG!"
.Detail.BackColor = vbRed
.Controls("lblSort").BackColor = vbRed
.Controls("Child16").SourceObject = Form_sbfrmAdditives.Name
End With

We are still referencing it as a string (sbfrm.Name), but a literal string
is not used. If you open a completely empty database and reference the
database with this code in it, it still runs without a problem.
We can still change the subform by code by doing the same with the altered
"changesubform" procedure below.
You don't even have to Requery the form.

Sub changesubform()
Dim frm As Form
Dim i As Integer
i = 0
For Each frm In Forms
Set frm = Forms(i)
If frm.Caption = "Hello Again SIG!" Then Exit For
i = i + 1
Next
frm.Controls("Child16").SourceObject =
Form_sbfrmAdditiveAndInnerIngrWarnings.Name
'frm.Requery
Set frm = Nothing
End Sub

The only problem is that you need to have the code in the referenced
database. Graham is correct if the code is in the referencing database.
From what I have found it seems that Form Objects are not passed to the
VBA IDE via the reference, only modules with their types, enums,
properties and methods. It would be nice if it could, but this could open
up a few more security issues to contend with.


Cheers,
Ed.

Dirk Goldgar said:
[...]
On the second instance, it changes the subform's (Child16)
sourceobject to a different subform. [...]
With frm2 [...]
.Controls("Child16").SourceObject = "sbfrmAdditives"
End With

But that is not what the OP was asking, and what Graham was saying
couldn't be done. Specifically, the OP asked,
does anyone know if there's a way to set
the'SourceObject' of a subform from code, using a reference to a
form instance? Access only seems to allow it to be set via the form
name (specified as a string), which is no good if the required
sub-form is in a
referenced library database. If it's possible, it'd be the cure to
a big headache for me!

As I interpret this, and I think it's also how Graham understood it, the
OP would like to be able to do something like this:

<BEGIN INVALID CODE>

Dim frm As Form

' Create an instance of the form to be used as a subform.
Set frm = LibraryDatabase.FormFactory("SomeForm")

Set .Controls("SubformName").SourceObject = frm

<END INVALID CODE>

But you can't do that; at least, not using any normal method. I suppose
it might be possible by manipulating memory with pointers and such, but
it would be very difficult at best.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)
 
E

Ed Adamthwaite

Hi Graham,
Of course it isn't.

Using Set frm = New Form_frm_whatever <-- The parent form.
...is not the same instance as... it's not supposed to be...
.Controls("Child16").SourceObject = Form_sbfrm_whatever <--the subform

Where I have made a mistake (as Dirk pointed out), by using "=
Form_sbfrmAdditives.Name", this creates a hidden instance of the subform.
I have gone through msdn and help files and found that an instance of a form
can be created using this method. Whatever happened to "SET" and "NEW" when
creating an instance of an object? Why is Access / Microsoft inconsistant
here?
It's a good thing that I don't create multiple instances of huge complex
forms, I'd be running out of memory pretty fast.


Ed Adamthwaite
Melbourne PC Access SIG Convener
AH 03 9754 2334
BH 03 9708 5700
Mob 0419 516 644
(e-mail address removed)




Graham R Seach said:
Ed,

But you're not referencing the same form instance!

Using Set frm = New Form_whatever
...is not the same instance as...
.Controls("Child16").SourceObject = Form_whatever

If you could set it as follows, it would be what the OP wanted:
.Controls("Child16").SourceObject = frm

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia

Ed Adamthwaite said:
Hi Dirk,
Yes, I bypassed the point about using a string, to me it still doesn't
matter. If you change the code of the second instance to:

Static frm2 As Form

Set frm2 = New Form_frmAdditivesAndInnerIngr

With frm2
.Visible = True
.Caption = "Hello Again SIG!"
.Detail.BackColor = vbRed
.Controls("lblSort").BackColor = vbRed
.Controls("Child16").SourceObject = Form_sbfrmAdditives.Name
End With

We are still referencing it as a string (sbfrm.Name), but a literal
string is not used. If you open a completely empty database and reference
the database with this code in it, it still runs without a problem.
We can still change the subform by code by doing the same with the
altered "changesubform" procedure below.
You don't even have to Requery the form.

Sub changesubform()
Dim frm As Form
Dim i As Integer
i = 0
For Each frm In Forms
Set frm = Forms(i)
If frm.Caption = "Hello Again SIG!" Then Exit For
i = i + 1
Next
frm.Controls("Child16").SourceObject =
Form_sbfrmAdditiveAndInnerIngrWarnings.Name
'frm.Requery
Set frm = Nothing
End Sub

The only problem is that you need to have the code in the referenced
database. Graham is correct if the code is in the referencing database.
From what I have found it seems that Form Objects are not passed to the
VBA IDE via the reference, only modules with their types, enums,
properties and methods. It would be nice if it could, but this could open
up a few more security issues to contend with.


Cheers,
Ed.

Dirk Goldgar said:
[...]
On the second instance, it changes the subform's (Child16)
sourceobject to a different subform.
[...]
With frm2
[...]
.Controls("Child16").SourceObject = "sbfrmAdditives"
End With

But that is not what the OP was asking, and what Graham was saying
couldn't be done. Specifically, the OP asked,

does anyone know if there's a way to set
the'SourceObject' of a subform from code, using a reference to a
form instance? Access only seems to allow it to be set via the form
name (specified as a string), which is no good if the required
sub-form is in a
referenced library database. If it's possible, it'd be the cure to
a big headache for me!

As I interpret this, and I think it's also how Graham understood it, the
OP would like to be able to do something like this:

<BEGIN INVALID CODE>

Dim frm As Form

' Create an instance of the form to be used as a subform.
Set frm = LibraryDatabase.FormFactory("SomeForm")

Set .Controls("SubformName").SourceObject = frm

<END INVALID CODE>

But you can't do that; at least, not using any normal method. I suppose
it might be possible by manipulating memory with pointers and such, but
it would be very difficult at best.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top