Open form - grab parameters from different calling forms

GK in the UK

Registered User.
Local time
Today, 18:52
Joined
Dec 20, 2017
Messages
281
Is there a method for an open form to get the name of the calling form, so that it can read some parameters from the calling form ?
I can't use OpenArgs as the form is already open.


The open form may be called from different 'hosts'


There may be an additional complication. Although I haven't implemented it yet, the called form may be opened as a new instance from a different host form at the same time.
So the instance of the called form needs to be able to read the actual name of the form that called it.

The purpose is for the called form to read some parameters from the calling form, when the current event fires (because the called form was refreshed with a different record).
So sort of like OpenArgs but really I want CurrentArgs.

I found this old thread
https://www.tek-tips.com/viewthread.cfm?qid=88008
but it doesn't work because the called form looks for the name of the calling form before the code SetForm.Me executes to push the name into the sub. Unless I'm doing it wrong.
 
Hi. Just a thought, but have you considered using TempVars?
 
Thanks for the quick response. Sort of. I found an old thread on here that said TempVars are only of use in SQL queries so I've avoided them. So far I haven't used TempVars or Global Variables. Plus, how would the different instance of the called form know which of the variables were the relevant ones ?

I was sort of hoping there would be a more elegant way of doing this.
 
I was sort of hoping there would be a more elegant way of doing this.
Hi. If you can describe in details what "doing this" means/entails, maybe we can think of an elegant way for you. For example, you didn't tell us how an open form would "know" it's being reopened again. TempVars are like global variables, and you can use them in queries or code or forms or reports, etc.
 
Is there a method for an open form to get the name of the calling form, so that it can read some parameters from the calling form ?
I can't use OpenArgs as the form is already open.
.

So why can you not pass the parameters as you open the form?
 
Because OpenArgs is evaluated only on first open, not on subsequent openings and the params may be different. Just composing reply to DBguy...
 
I'm not averse to using TempVars or globals as such, I just regard them as a last resort.

The open form may have been opened with a single record, with the index form still open underneath or to one side in Windows.

The user may then select a different record in the index form, and it then does DoCmd.OpenForm and 'pushes' a new record to the already open form.
The open form refreshes the data but I need to find a way of reading some variables from the calling form.

If it could only ever be called from a single form, it would be easy but the called form needs to be able to read the variables from a different host. To do that, it needs to be know which host form contains the variables.

My plan was for each of the forms that are capable of opening the called form to have (eg) a hidden text field called 'txtTransLineID'.
Then the called from could look for txtTransLineID in the calling form.

But to do that, it needs to know the name of the calling form.

The called from is frmInvoice
The calling forms could be frmRecordIdx, frmTransIdx or others.

frmInvoice is passed a 'header' record through the WhereCondition of OpenForm

I want to also pass the 'Transaction' ID so that frmInvoice opens focussed on the actual transaction line that was clicked to open frmInvoice.
 
So for clarity: Getting the form name is a means to an end. Once it's been opened first time from frmIndex, the form name won't change for this session but txtTransLineID will, every time frmInvoice is refreshed with a different WhereCondition record. So the real question is how can frmInvoice read variable(s) from one of several calling forms, so that it can open focussed on a particular record in the sub datasheet within frmInvoice.
 
So for clarity: Getting the form name is a means to an end. Once it's been opened first time from frmIndex, the form name won't change for this session but txtTransLineID will, every time frmInvoice is refreshed with a different WhereCondition record. So the real question is how can frmInvoice read variable(s) from one of several calling forms, so that it can open focussed on a particular record in the sub datasheet within frmInvoice.
Hi. Would saving the name of the calling form in a TempVar work? Also, I am still not sure I get how the called form know it's been called if it's already open? Which event are you using to do this? Or, put another way, which event would you use to initiate reading the data from the calling form, if the form doing the reading was already open previously?
 
If it is not opened dialog then add a custom property (or just a variable) the the called form.

Code:
Private m_callingForm As Access.Form

Public Property Get CallingForm() As Access.Form
  Set CallingForm = m_callingForm
End Property

Public Property Set CallingForm(TheCallingForm As Access.Form)
  Set m_callingForm = TheCallingForm
End Property

so the calling form could do something like

Code:
Private frm As Form_frmCalled
Private Sub call_Click()
  
  DoCmd.OpenForm "frmCalled"
  Set frm = Forms("frmCalled")
  Set frm.CallingForm = Me
End Sub

Private Sub Command0_Click()
  MsgBox frm.CallingForm.Name
End Sub
If it is already open just set the property.
 
The called from, frmInvoice, refreshes the current record when I do DoCmd.OpenForm.
DoCmd.OpenForm is quite happy to 'push' a new record into an already open form via a new WhereCondition. So the WhereCondition has a new record ID and frmInvoice, already open, just refreshes the record. It happens in the CurrentEvent of frmInvoice. That all works quite nicely, it's the functionality I want.


But, frmInvoice by default always highlights the very first invoice line in the sub datasheet.


frmInvoice may have been refreshed (via the Where Condition in DoCmd.OpenForm) with a new header record. But as an enhancement I want to be able to pass some more variables including the TransLineID so that frmInvoice is focussed on the particular transaction line that the user is interested in. So frmInvoice does a FindFirst (in CurrentEvent) but I need to find a way of getting TransLineID in there.



I'm thinking TempVar might have to be the way. But, that MAY give me a problem if the user opens a second instance of frmInvoice from a different host form.



I would have to write a TempVar for the first instance of opening frmInvoice.
Then if the user opened a second instance of frmInvoice from a different host form, with a different Wherecondition, where does the second instance of frmInvoice look to get the correct TempVar ?
 
However, in my mind the calling form should never care who called it. That is too tightly coupled. It should be the responsibility of the calling form to set the properties of the called form. If the called form is not acdialog this is easy, if acdialog then it does get tricky.

Tempvars and custom properties are unique to any instance.
 
I'm thinking TempVar might have to be the way. But, that MAY give me a problem if the user opens a second instance of frmInvoice from a different host form.

I would have to write a TempVar for the first instance of opening frmInvoice.
Then if the user opened a second instance of frmInvoice from a different host form, with a different Wherecondition, where does the second instance of frmInvoice look to get the correct TempVar ?
How do you expect the user will manage to open a "second" instance of frmInvoice? Have you tested it?
 
Thanks, MajP. I'm going to test that and report back but it may not be tonight.


I agree about frmInvoice not caring about how it was opened, that is how it was designed, bar this issue. AcWindowMode isn't specified so I think that means AcWindowNormal. What's your preferred method (easy, you say, but how?)



DBguy, no, opening a second instance of a form isn't something I've done yet. But I'll need to, I think, unless some other obstacle comes up to make it not feasible. I'm hoping not.


The user can open frmTransIdx and create a new invoice in frmInvoice.


Whilst doing that, the user can open frmRecordIdx, navigate to some other record in the system to just 'have a look' and open another frmInvoice (read-only). For example, to see how some sale was described or priced previously.



That's the plan unless someone tells me it just won't work ...
 
See if this demo answers the question. There are 2 calling forms and 1 called form that I create two instances of.
1. Open frmCalling
2. Open frmCalling Two (move to see frmCalling)
3. from frm calling open an instance of frmCalled
4. frm frmCallingTwo open another instance of frmCalled (move to see)
5. In each instance click to see who called them.
 

Attachments

DBguy, no, opening a second instance of a form isn't something I've done yet. But I'll need to, I think, unless some other obstacle comes up to make it not feasible. I'm hoping not.
...
That's the plan unless someone tells me it just won't work ...
I guess that means you're just planning for eventualities right now. I think MajP's demo might help in that regards. Cheers!
 
Looking very promising, MajP, as I say I'll report back when I've got that coded in.
 
Like I said it is really important to know if you want to open the called form in acdialog. If not a lot of this is much easier, because you do not have to pass anything in. You simply can open the called form and then manipulate the called form. You do not have to pass in a transaction ID so that the form can know where to move. You simply move the called form from the calling form. The issue with acdialog is that all code stops in the calling form until the called form is closed. There is no way once open to manipulate the called form.
 
Following what MajP stated, You can work around opening it in dialog mode. You open the form, do what you need to do to it, then set that form to modal.
 
MajP, I got your code pasted in to my various code/form modules and it works but I'm getting an issue with it.

In frmInvoice (the called form) I put a command button like yours called 'Who Called Me' with a line to display the variable which is placed on the calling form. Once the called form opens, I press the button and It displays the result that I expect, the transaction line ID from the datasheet on the calling form.

I can leave frmInvoice open and browse the calling form list of transactions and each time I press 'Who Called Me' I get the expected ID displaying. All good so far.

But when I copy the identical code into the Current Event of the called form, I get error 91, Object variable or With block variable not set. The error message pops up before the form displays (if it's the first time it's opened) so it seems like it's a timing thing. I need to evaluate it in Current to navigate to that invoice line as soon as the user clicks on a new transaction line on the calling form.

Sequence is:

calling form > DoCmd.OpenForm executes
frmInvoice opens and Current Event is called. Or, if it's already open, it refreshes the header record.
calling form > set frm commands execute

But it's too late by then I've got the error in frmInvoice

Just to confirm frmInvoice is not acDialog, PopUp is no, Modal is no. acWindowMode isn't specified in the DoCmd.OpenForm
The whole point of this is that frmInvoice is NOT modal

Like I said it is really important to know if you want to open the called form in acdialog. If not a lot of this is much easier, because you do not have to pass anything in. You simply can open the called form and then manipulate the called form. You do not have to pass in a transaction ID so that the form can know where to move. You simply move the called form from the calling form. The issue with acdialog is that all code stops in the calling form until the called form is closed. There is no way once open to manipulate the called form.
I've got the impression this is a better way to do it. Can you expand on this please ?
 

Users who are viewing this thread

Back
Top Bottom