OpenArgs lifespan

What happens if you were to open the same form multiple times? passing a CustID for instance as OpenArgs? instead of a WHERE clause?

Not sure what you mean by this. If you are referring to multiple form instances (the same form opened multiple times at once) then openargs cannot be used. You cannot open multiple form instances using Docmd.openform and you cannot set openargs after it is open. You open multiple form instances like
Code:
dim frmInst1 as new Form_Form1
dim frmInst2 as new Form_Form1
frmInst1.visible = true
frmInst2.visible = true
'normally add the instances to a collection
frmInst1.caption = "Instance 1 of Form 1"
frmInst2.caption = "Instance 2 of Form1"
 
Yes, my lack of knowledge/experience showing there.:o

Not sure what you mean by this. If you are referring to multiple form instances (the same form opened multiple times at once) then openargs cannot be used. You cannot open multiple form instances using Docmd.openform and you cannot set openargs after it is open. You open multiple form instances like
Code:
dim frmInst1 as new Form_Form1
dim frmInst2 as new Form_Form1
frmInst1.visible = true
frmInst2.visible = true
'normally add the instances to a collection
frmInst1.caption = "Instance 1 of Form 1"
frmInst2.caption = "Instance 2 of Form1"
 
What happens if you were to open the same form multiple times? passing a CustID for instance as OpenArgs? instead of a WHERE clause?
Since you are talking form instances, there is no reason to pass anything because you cannot open the form ACDIALOG which means code does not stop. You can make the form modal and popup. So you would just control the instances from the calling code. In this case one instance filterer to custID 1 and the second to custid 2.

Code:
dim frmInst1 as new Form_Form1
dim frmInst2 as new Form_Form1
frmInst1.visible = true
frmInst2.visible = true
'normally add the instances to a collection here
frmInst1.filter = "CustID = 1"
frmInst1.filteron = true
frmInst2.filter = "CustID = 2"
frmInst2.filteron = true
 
Yes, my lack of knowledge/experience showing there
Did not mean that. Meant it could be interpreted many ways.
Same form opened many form instances
Same form called to "reopen"
Form opened and closed many times.
 
The OpenArgs value is a property of an individual form. See this article:

https://docs.microsoft.com/en-us/office/vba/api/access.form.openargs

As a property of the form, that means that if you open Form1 from the GUI and Form1 opens Form2 passing F1 as an OpenArg and Form2 opens Form3 passing F2 as an OpenArg then...

From Form1 code, Me.OpenArgs should be blank (because it was manually opened)

From Form2 code, Me.OpenArgs should be F1

From Form3 code, Me.OpenArgs should be F2

From outside of the chain, Forms!Form2.OpenArgs should be F1 and Forms!Form3.OpenArgs should be F2 - IF the forms are still open at the time of the test. However, if any form closes, its OpenArgs property becomes non-substantiated and thus is essentially NULL.

As to the question of whether it is even possible to open the same form multiple times in the same user session? I believe each opening of a form is a different instantiation of that form, so the different instances would have different and independent copies of the OpenArgs, one for each instance. However, I have NO idea what names would be applied to the forms for the Forms!form-name syntax. Perhaps Form2(2), Form3(2), etc?

Opening form code multiple times simultaneously in the same session would require some code to be recursive, I think. Most Access forms are not meant to be recursive, though I have done a few modules that were recursive. Trust me, it is ugly - but possible. I won't say you can't open multiple instances of a single form simultaneously, but I see it as a "touchy" situation.
 
If you want to keep the name of the last form that opened a form, (between opening and closings) then one way of achieving this would be to add a custom property to the form. This would be a variable which actually becomes part of the form, and it retains its value between opening and closings of that form. Typical use is to record the last position the form was displayed at, and to keep a date range from a previous search, things like that. For more information see my Nifty Access website here:- http://www.niftyaccess.com/sticky-form-builder/ ..... Where I provide links to the resources you would need to duplicate this functionality yourself.

Note:-
A custom property of the Form is different from a custom property added to the forms code module.
 
Last edited:
As to the question of whether it is even possible to open the same form multiple times in the same user session? I believe each opening of a form is a different instantiation of that form, so the different instances would have different and independent copies of the OpenArgs, one for each instance. However, I have NO idea what names would be applied to the forms for the Forms!form-name syntax. Perhaps Form2(2), Form3(2), etc?

Opening form code multiple times simultaneously in the same session would require some code to be recursive, I think. Most Access forms are not meant to be recursive, though I have done a few modules that were recursive. Trust me, it is ugly - but possible. I won't say you can't open multiple instances of a single form simultaneously, but I see it as a "touchy" situation.

@Doc_Man,
Yes, OpenArgs is a property of each form instance and can only be set through the Docmd.OpenForm method. It is a readonly property otherwise. In multiple instances each instance would have this property just like any instantiation of a class. The only problem is there is no way to set it if opening multiple form instances. Multiple form instances a simply instantiated using the "New" callword and not opened through the Docmd.openform method.
This does not require any recursion. Normally form instances are stored in a dictionary or a collection because each form has the same name. This is not "touchy", this is normal OOP. It is very easy to do. Normally you would have a custom class to manage your form instances where you can then refer to them by name like you can in the standard Forms class. You have to roll your own way to manage since every instance has the same name (they are from the same class and the name is derived from the class name).
Here is a simple demo. Select a color on form1 and open an instance of form2. Move it to the side select new color and open another instance.
Access can and does do this all the time. Create two forms with the same subform. Open both forms, you have opened two instances of the same form within a subform control.
 

Attachments

The OpenArgs value is a property of an individual form. See this article:

https://docs.microsoft.com/en-us/office/vba/api/access.form.openargs

As a property of the form, that means that if you open Form1 from the GUI and Form1 opens Form2 passing F1 as an OpenArg and Form2 opens Form3 passing F2 as an OpenArg then...

From Form1 code, Me.OpenArgs should be blank (because it was manually opened)

From Form2 code, Me.OpenArgs should be F1

From Form3 code, Me.OpenArgs should be F2

From outside of the chain, Forms!Form2.OpenArgs should be F1 and Forms!Form3.OpenArgs should be F2 - IF the forms are still open at the time of the test. However, if any form closes, its OpenArgs property becomes non-substantiated and thus is essentially NULL.

Above is exactly what I have been trying to do.

Below - just to clarify - I am not trying to open multiple instances of the same form at the same time although it is good to know how should the need arise.

As to the question of whether it is even possible to open the same form multiple times in the same user session? I believe each opening of a form is a different instantiation of that form, so the different instances would have different and independent copies of the OpenArgs, one for each instance. However, I have NO idea what names would be applied to the forms for the Forms!form-name syntax. Perhaps Form2(2), Form3(2), etc?

Opening form code multiple times simultaneously in the same session would require some code to be recursive, I think. Most Access forms are not meant to be recursive, though I have done a few modules that were recursive. Trust me, it is ugly - but possible. I won't say you can't open multiple instances of a single form simultaneously, but I see it as a "touchy" situation.
 
Normally form instances are stored in a dictionary or a collection because each form has the same name.

MajP, I actually agree with you that normal OOP is going on - but we have to remember that Access objects are imperfect implementations of OOP. I will have to search for a thread of discussion I had with another member some years ago regarding OOP in Access. It was long enough ago that I don't remember the details. I will see if I can research that discussion.

My point is that IF you tried to multi-open a form, that collection would have two instances of the same name and therefore Access would have to take the Windows default of appending an instance number to one of them, since the names in either collections or dictionaries have to be unique. So IF you were looking at the form from the outside, you would need to consider which instance you meant.

As to recursion, I believe the compiled code is NOT replicated in the new class instance (though it would be a real beast to test). I think the compiled code is stored separately. At that point, if you have any OWN variables or store any data to Public variables in a general module, you run into side effects that are normally fixed by using principles of recursion. Granted, that is already very "dirty" programming to do those things - but you and I both know that on this forum, you see every kind of programming from crystalline and pristine to down and dirty in the compost heap.

EDIT: I have searched for the old discussion but at the moment can't find it. The gist of the discussion was that OOP inheritance doesn't work quite right with some DB objects. The way the classes are implemented originates from a non-OOP environment. However, I got back to 2007 without finding the thread in question.
 
Last edited:
My point is that IF you tried to multi-open a form, that collection would have two instances of the same name and therefore Access would have to take the Windows default of appending an instance number to one of them, since the names in either collections or dictionaries have to be unique. So IF you were looking at the form from the outside, you would need to consider which instance you meant.

Not sure what you are trying to say, but all I can say is that I have have been building Access applications for 20 years that open and control multiple form instances.
It is really not that uncommon and have seen many other developers do the same. It is no different than instantiating any class. Each form has its own hwnd and that is normally what you store in a custom collection to manage. Access just will not allow you to change the name property of the instance. So normally you put a custom property like MyName and set that or refer to it by HWND. I cannot remember what gets added to the Forms collection, if the instances are added or not. I think they are in fact added, but if you reference by name it only returns a pointer to the first instantiation.
 
MajP - that actually reinforces my point. The first instantiation has no "instance number" added to it. Only the 2nd and later instances have that addendum.
 
MajP - that actually reinforces my point. The first instantiation has no "instance number" added to it. Only the 2nd and later instances have that addendum.
I have no idea what that means.
 
If I use OpenArgs to pass data from Form1 to Form2, is the value in openArgs cleared after it is used or do I need to clear it some how to use another OpenArgs statement to open Form3 from Form2 while Form1 is still open underneath Form2?

Hi All!

I just mocked up what I was wondering about. It's attached. It seems to pass OpenArgs from Form1 to Form2 and then from Form2 to Form3 as I would have hoped it would.

In other words, it appears that OpenArgs resets itself after I have used it/placed its value, etc.

My mockup with forms staying open is exactly how I am using this situation in the real DB.
 

Attachments

Hi All!

I just mocked up what I was wondering about. It's attached. It seems to pass OpenArgs from Form1 to Form2 and then from Form2 to Form3 as I would have hoped it would.

In other words, it appears that OpenArgs resets itself after I have used it/placed its value, etc.

My mockup with forms staying open is exactly how I am using this situation in the real DB.

Set Form3 to Data Entry = Yes
 

Attachments

Hi. Thanks for the update.
 
Yes BUT you are setting a new open args value in Form 2 which is then carried forward to form 3

However, if you change the code below to:
Code:
Private Sub cmdOpenForm3_Click()
    DoCmd.OpenForm "frmForm3", OpenArgs:= Me.OpenArgs 
End Sub

... then the original open args value from form 1 is transferred through to form 3
In other words the open args value is retained across your application until some other code changes it.
 
if you change the code below to:
Code:
Private Sub cmdOpenForm3_Click()
    DoCmd.OpenForm "frmForm3", OpenArgs:= Me.OpenArgs 
End Sub

... then the original open args value from form 1 is transferred through to form 3

I can SO use that. :-)
 
In other words, it appears that OpenArgs resets itself after I have used it/placed its value, etc.
Hi. Pardon me. I just reread your post and I don't think I can agree with the above statement (perhaps because I haven't looked at your demo yet). Anyway, I would expect the value in the OpenArgs to "not" reset itself as long as the form containing it stays open. As already mentioned, this property is "read only," so no amount of code should be able to change or delete it.
 
Hi. Pardon me. I just reread your post and I don't think I can agree with the above statement (perhaps because I haven't looked at your demo yet). Anyway, I would expect the value in the OpenArgs to "not" reset itself as long as the form containing it stays open. As already mentioned, this property is "read only," so no amount of code should be able to change or delete it.

All I can tell is that I am passing the expected values from Form1 to Form2 and then different yet correct ones from Form2 to Form3......so it at least appears to be either 1) clearing because I restated the DoCmd.OpenForm phrase or 2) is DoCmd.OpenForm dependent.

Ya'll are way more knowledgeable than I - obviously - but it does appear to be "letting go" of its value and acquiring the new one when I call DoCmd.OpenForm the second time - all this happening with Form1 and Form2 open and Form2 having focus.
 
I think it would be more accurate to say you were setting a new value in form 2. It wasn't 'letting go' of the value. It was being replaced.
 

Users who are viewing this thread

Back
Top Bottom