Pass value to form that opened a popupform... (1 Viewer)

MackMan

Registered User.
Local time
Today, 17:05
Joined
Nov 25, 2014
Messages
174
Hi Guys.

I will try to explain as best as I can so please bare with me.

I have two subforms in a tab formation sitting on a main form.
They can both open up a single popup form (via a button) and that popup form is opened via openargs with the autoID field.

What I need to do is pass back a value on the popup forms [On Unload] event to the subform which opened it.

As the popup form is Modal, the subform which opened it can't be changed.

Am I right in thinking I can pass back the value to the form which had previous focus?

If so, I would appreciate some help with it's code.

Previously, to pass a value from a popup form to a single form I've been using

Code:
 If CurrentProject.AllForms("MyForm").IsLoaded Then
 do this
 else do this
 end if
But in this instance, how do I code the On Unload event in which to tell Access which form opened up the popup form, and pass a value back to it?

I'm guessing
Screen.PreviousControl.SetFocus
has something to do with it?

As always, Appreciate your help and patience.
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 17:05
Joined
Jul 9, 2003
Messages
16,332
What event do you want to trigger the pass back?
 

robslob

Registered User.
Local time
Today, 17:05
Joined
Apr 26, 2015
Messages
27
I think the answer here is to use TempVars object variables, these are variables that were introduced in Ac 2007 and exist in memory until Access is closed.

When you open the Main form create the variable name/value (On Load event)
TempVars.Add "varName", 0
When you open the popup from subform1 change the value to 1 (from On Click event)
TempVars![varName] = 1
DoCmd.OpenForm "Popup", acNormal
When you open the popup from subform2 change the value to 2 (from On Click event)
TempVars![varName] = 2
DoCmd.OpenForm "Popup", acNormal
And when you unload the popup
If TempVars![varName] = 1 Then
.....do this
Elseif TempVars![varName] = 2 Then
.....do that
End If


To delete the varaible use:
TempVars.Remove "varName"
 

MackMan

Registered User.
Local time
Today, 17:05
Joined
Nov 25, 2014
Messages
174
Hi Unc'

The Popup forms purpose is a breakdown of lines (and their totals) so the value I'd like to pass back is a Grand total of all lines, and do so on the form unload Event.

Before the Popup opens, on the tabbed form the user types in a Grand total, so what I'd like to be able to do is...

Pass the value to the tabbed form and Compare the two when the popup form closes, and if it's not right, re-open the popup form so the user can check entries and amounts.

I have an unbound text box [txtPopUptotal] on the each of the two tabbed forms to receive this grand total from the popup form.

What I'd ideally like to do, is keep the popup form open,and not have it close until both agree, but I'm having a lot of difficulty passing two Openargs as the popup form is a continuous one.

Many thanks for your prompt reply.
 

MackMan

Registered User.
Local time
Today, 17:05
Joined
Nov 25, 2014
Messages
174
Hi Rob!
I will give it a try!
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 17:05
Joined
Jul 9, 2003
Messages
16,332
Could you post just the very basic parts of your database related to this problem? I'd like to have a fiddle.
 

MackMan

Registered User.
Local time
Today, 17:05
Joined
Nov 25, 2014
Messages
174
For sure. I'm grateful for your help!

Although it's a Small world Unc'
I'm in Parkway at the moment. Will do when I get back home.:)
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 17:05
Joined
Sep 12, 2006
Messages
15,694
Use openargs to pass a flag indicating which form called the pop-up.
 

spikepl

Eledittingent Beliped
Local time
Today, 18:05
Joined
Nov 3, 2010
Messages
6,142
I'd go with Dave's solution. One of the basic tenets of good programming practice aimed at ease of understanding and maintenance is to set the scope of any variable to the minimum possible, hence robslob's solution, even if workable, is not recommended.
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 17:05
Joined
Jul 9, 2003
Messages
16,332
I hate open args with a vengeance. It just seems such a fudge to me, a bit like the new variables! I avoid both like the plague. No concrete programming reason, just a personal foible I reckon. If I could find a way to eliminate openargs completely I would. However I think (from memory) that ther are one or two situations where you are forced to use them.
 
Last edited:

Solo712

Registered User.
Local time
Today, 12:05
Joined
Oct 19, 2012
Messages
828
Use openargs to pass a flag indicating which form called the pop-up.

I use a similar techique with global variables for subs which are shared by several forms. To avoid having to pick up the values with a timer event I stop the main form's execution during the modal's form life so that the value is available on re-entry.

Code:
glbSubFlagOn = True
glbSender = 1
DoCmd.OpenForm "frmSetPayDate", , , , , acDialog
Do     
    DoEvents
Loop Until Not glbSubFlagOn

the global variable glbSubFlagOn is cleared by the modal form on exit and then the value from sub passed to the main form
Code:
Select Case glbSender 
    Case 1    
       [Forms]![frmMainForm].[Fieldx] = Me!Fieldy
    ....
End Select
can be picked up.

Best,
Jiri
 
Last edited:

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 17:05
Joined
Sep 12, 2006
Messages
15,694
jiri,

I don't like dialog/modal forms, because I can't resize them.

I use openargs rarely. In this sort of case, I open a normal form, instead of dialog mode, and just wait for it to close in a slightly different way

Code:
 while isopen("formname")
    doevents
 wend
 

robslob

Registered User.
Local time
Today, 17:05
Joined
Apr 26, 2015
Messages
27
Can I ask why it's done this way (I am still on the learning path), I think I emulated the scenario more or less. I have a main form with 2 subs and a popup, both subs have an On Click event opening the popup and the popup returns a value to populate a textbox on each sub. I have found that opening the popup when using global variables without acDialog only works after the 2nd time it pops up whereas it works first time using acDialog but dont know why.
Also I am confused as to why the DoEvents is needed as I think I've done it without needing it.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 17:05
Joined
Sep 12, 2006
Messages
15,694
what happens is you have code like this


1. open popup form
2. set some value
3. etc

the problem is that after you open the popup form, the above code immediately does step 2 without waiting for the popup to close. So in your case, by doing the process again, the second process is actually getting the result of the first popup! (I should think)

what you are trying to do is this, instead.

Code:
 1. open popup form
 [B][COLOR=blue]2. wait for popup to close[/COLOR][/B]
 3. set some value
 4. etc
  
 so to achieve step 2, you either need
  
 a) 1. open popup form IN DIALOG MODE
      (which just waits for the dialog to close before proceeding)
  
 or
 b) 1. open popup form in normal mode
     2. specifically add code that effectively does this
 
         while the popup form is open
         do
               do nothing
 [COLOR=red]              DOEVENTS[/COLOR]
         loop
          carry on processing
Now, if you do the latter without the DoEvents, access just waits for the popup to close, as before. Now That may be OK, but if instead you realise you want to do something else in another window, then DoEvents allows that to happen, which often gives a much better user interface. Doevents allows Access to process any events that need dealing with before continuing to the next iteration of the loop.

It does the same job. opens the popup and waits for a response, but now it lets you (and access) do anything else that needs doing. [you may know how running a query that takes a long time leaves you twiddling your thumbs. That because a query is a single "atomic" command, and you can't get a DoEvents inside the process. Sometimes, it would be much better for a query that takes 2 minutes to run, to instead take 4 minutes to run in the background, if you could do other stuff at the same time]

It's more complex programming in some ways, because you will need to consider the effect of having several potentially interacting forms open at the same time - but most good apps let you have multiple open forms - just using one form at a time is a bit old school.

Hope that helps
 
Last edited:

robslob

Registered User.
Local time
Today, 17:05
Joined
Apr 26, 2015
Messages
27
Thanks for explaining, I have looked more closely when debugging and can see how DoEvents and acDialog effectlively halt the code in the subforms whereas without either it processes all the events code instead.
So my next question is why Solo712 uses both DoEvents and acDialog in his code, although I have noticed that while in the DoEvents loop it wont trigger the unload event of the popup while in debug mode but it will with both DoEvents and acDialog, so maybe that is why.
 

Solo712

Registered User.
Local time
Today, 12:05
Joined
Oct 19, 2012
Messages
828
Can I ask why it's done this way (I am still on the learning path), I think I emulated the scenario more or less. I have a main form with 2 subs and a popup, both subs have an On Click event opening the popup and the popup returns a value to populate a textbox on each sub. I have found that opening the popup when using global variables without acDialog only works after the 2nd time it pops up whereas it works first time using acDialog but dont know why.
Also I am confused as to why the DoEvents is needed as I think I've done it without needing it.

If you open a form in 'modal' mode (with the acDialog set), the control returns immediately to the calling routine that launched the form - without waiting for the modal form to close. This will pose a challenge when you return to the module of the main form, if your code wants to use the values newly set by the pop-up. You would have to set up some event to do that. You could use on-Timer on the calling form set by the pop up form and that shut down from the calling form, but that is clumsy. So doing the DoEvents loop until the pop up closes assures you that you your code resumes on the next line after the loop. Then you do whatever you want to do on the basis of the popup results. Note also, as I have shown you, that if your pop up is used by more than one calling form you can id the calling routine by a semaphor (glbSender), ie. you can run different chores based on which routine uses the pop up.

Best,
Jiri
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 17:05
Joined
Sep 12, 2006
Messages
15,694
I think both mine and jiri's suggestions are similar ideas, and you can use whichever you are more comfortable with. You find you need a different approach for different circumstances.

popup calendar date pickers work in a similar way. They halt execution of your program until you select a date. What they often do is become hidden

so then in the calling code you can see if the calendar form closed, in which case the picker was cancelled, or whether it is still open, but hidden, in which case you can read the value, and then close it.
 

robslob

Registered User.
Local time
Today, 17:05
Joined
Apr 26, 2015
Messages
27
I did read about hidden forms elsewhere but without an explanation, it's all clever stuff.
 

Users who are viewing this thread

Top Bottom