Store and manipulate a Control on form (1 Viewer)

Babycat

Member
Local time
Today, 06:52
Joined
Mar 31, 2020
Messages
281
Hi all.
I have forms A1, A2, A3... that contains subforms, and on these subforms I have textbox named Txt_ProductName
It could be located at:
"Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName" (I assigned this string to Arg_str1)
or
"Forms!FrmA2.Txt_ProductName (assigned to Arg_str2)

On event Doulble click Txt_ProductName, it opens formB with OpenArgs Arg_str1 or Arg_str2. The FormB finds desired ProductName and fill back to Txt_ProductName on corresponding forms.
The question is: How to fill the ProductName back Txt_ProductName with infomation from form's OpenArgs string?

(I dont want to manually manipulate like: Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName = ProductName
but I want something likely Magic(Arg_str1) = ProductName.

Please help me.
 
Here's one way to get selected value from FormB, example from my db:
Code:
'user prompt for entry of logout date
DoCmd.OpenForm "DialogGetDate", , , , , acDialog, "Logout"
If CurrentProject.AllForms("DialogGetDate").IsLoaded Then
    Me.tbxDate = Form_DialogGetDate.tbxDateDialog
    DoCmd.Close acForm, "DialogGetDate", acSaveNo
End If
Code in event behind DialogGetDate sets Visible property to False and this returns control to calling form, I used KeyPress:
Code:
Private Sub tbxDateDialog_KeyPress(KeyAscii As Integer)

If KeyAscii = 13 Then
    If IsNull(Me.tbxDateDialog) Then
        MsgBox "Enter date."
    Else
        If Me.OpenArgs = "Logout" Then
            'Check if logout date falls within billed accouting period
            If Nz(DLookup("Final", "AcctgPeriod", "EndDate>=#" & Me.tbxDateDialog & "#"), 0) = True Then
                MsgBox "Date is within a finalized accounting period.  Enter another date.", vbOKOnly, "DateError"
                Me.tbxDateDialog = Date
                Exit Sub
            End If
        End If
        Me.Visible = False
    End If
End If
Me.tbxDateDialog.SetFocus

End Sub

Private Sub btnCancel_Click()
Me.tbxDateDialog = Null
DoCmd.Close acForm, Me.Name, acSaveNo
End Sub

However, should you be passing ProductID instead of ProductName?
 
Last edited:
Here's how I understand your setup in frmA1, frmA2, etc
Code:
Private Sub Txt_ProductName_DblClick(Cancel As Integer)
    Dim Arg_str1 As String
    Arg_str1 = "Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName"
    DoCmd.OpenForm "frmB", , , , , , Arg_str1
End Sub

Why not just pass the value instead of the reference? like:
Code:
Private Sub Txt_ProductName_DblClick(Cancel As Integer)
    Dim Arg_str1 As String
    'just remove quotes
    Arg_str1 = Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName
    DoCmd.OpenForm "frmB", , , , , , Arg_str1
End Sub

If you still want the reference, have you tried with Eval("Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName")?

As for
How to fill the ProductName back Txt_ProductName with infomation from form's OpenArgs string
What is ProductName here? is it a textbox in frmB? if so... then just do this in frmB:
Code:
Private Sub Form_Load()
    Me.ProductName = Me.OpenArgs
End Sub

By the way, your references can be shortened like Form_FormName.Txt_ProductName to stop worrying about the long syntax. Just make sure it's your only instance of that form and HasModule = true.
 
Last edited:
After re-reading your post, I think I understand what you meant, you just want to use the reference you passed in OpenArgs, but since it's a string, you can't figure it out. I think you should actually declare a public variable in the form where you're defining Arg_str1 and Arg_str2. Remove those Arg_strN variables and put one like this at the top of that module:
Public MyProductName As TextBox
Then, in the code where you were setting Arg_str1 and Arg_str2, set the public variable to that reference, no need to pass any OpenArgs.

Let's say you had a condition to assign Arg_str1 and Arg_str2, that looked like this:
Code:
If x = 1 Then
    DoCmd.OpenForm "someForm", , , , , , Arg_str1
Else
    DoCmd.OpenForm "someForm", , , , , , Arg_str2
End If

Instead, modify it like:
Code:
If x = 1 Then
    Set MyProductName = Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName
Else
    Set MyProductName = Forms!FrmA2.Txt_ProductName
End If
DoCmd.OpenForm "someForm"

With that, at any given point in someForm, you can simply do this MyProductName.Value = ProductName

Edited to make it clearer. Hopefully.
 
Last edited:
However, should you be passing ProductID instead of ProductName?
Yeah, it could be ProductID.
I tried to study but I dont really understand your code, and i have doubt if you got my meaning in post#1.
It like Edgar mentioned in post #4: when formB is opening, it's passed OpenArgs contains information about where it is opened from (form A1, A2 or A3...), it is in string as "Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName". Thus, I can't assign value of ProductName to it.
 
After re-reading your post, I think I understand what you meant, you just want to use the reference you passed in OpenArgs, but since it's a string, you can't figure it out. I think you should actually declare a public variable in the form where you're defining Arg_str1 and Arg_str2. Remove those Arg_strN variables and put one like this at the top of that module:
Public MyProductName As TextBox
Then, in the code where you were setting Arg_str1 and Arg_str2, set the public variable to that reference, no need to pass any OpenArgs.

Let's say you had a condition to assign Arg_str1 and Arg_str2, that looked like this:
Code:
If x = 1 Then
    DoCmd.OpenForm "someForm", , , , , , Arg_str1
Else
    DoCmd.OpenForm "someForm", , , , , , Arg_str2
End If

Instead, modify it like:
Code:
If x = 1 Then
    Set MyProductName = Forms!FrmA1.Form.Level1subA1.Form.Level2subA1.Txt_ProductName
Else
    Set MyProductName = Forms!FrmA2.Txt_ProductName
End If
DoCmd.OpenForm "someForm"

With that, at any given point in someForm, you can simply do this MyProductName.Value = ProductName

Edited to make it clearer. Hopefully.
Hi Edgar

Yeah, I also think about this way, but I was hope there is a better way without using a global variable.
My understanding is that global variables could be reset if a runtime error occurred, so I avoid using it.
 
A globally scoped variable or tempvars could store the reference. Using the reference as a string to set a value is probably possible, maybe by modifying the code module itself, but that's uncharted territory for me. I tried sending the instruction using Eval, but Eval only returns the value, it does not set it, according to my tests.

If your main concern is the persistence of the variable, tempvars persists the whole session, unless you compact and repair. But tempvars only stores strings... hmm, maybe not then.
 
ChatGPT suggested me using Eval too, I tried it and I think we get same results :)
btw, about this code:
Code:
Set MyProductName = Forms!FrmA2.Txt_ProductName

"Forms!FrmA2.Txt_ProductName" is actually value of the a textbox. Do you think you could assign it to a textbox instance? I tried it but no success.
 
If believe I do understand what you want to accomplish. You want to open FormB so user can make a selection and pass this selected value back to calling form. You want to be able to call FormB from multiple forms. My code accommodates this goal. It is not necessary for FormB to know which form called it. The calling form manages retrieving selected value from FormB.

No global variable or TempVar is needed with this approach.

Global variable loses value when there is an unhandled run-time error. TempVar does not.
 
Hi June

Yes, that is what I am trying to do.
After you selected value on form B, you make form B invisible in Keypress event.
Which event on calling from (formA1, formA2...) trigger the data retrieving?
In other words, when do you call this code
Code:
'user prompt for entry of logout date
DoCmd.OpenForm "DialogGetDate", , , , , acDialog, "Logout"
If CurrentProject.AllForms("DialogGetDate").IsLoaded Then
    Me.tbxDate = Form_DialogGetDate.tbxDateDialog
    DoCmd.Close acForm, "DialogGetDate", acSaveNo
End If
 
The calling form code is an excerpt from a button Click event. Could be called from AfterUpdate event. Whatever suits your situation. You indicate you are using Double-Click.
 
Last edited:
Hi Edgar

Yeah, I also think about this way, but I was hope there is a better way without using a global variable.
My understanding is that global variables could be reset if a runtime error occurred, so I avoid using it.
So use a Tempvar ?
 
ChatGPT suggested me using Eval too, I tried it and I think we get same results :)
btw, about this code:
Set MyProductName = Forms!FrmA2.Txt_ProductName

"Forms!FrmA2.Txt_ProductName" is actually value of the a textbox. Do you think you could assign it to a textbox instance? I tried it but no success.
Yes, you can assign it like that to a textbox if MyProductName is dimensioned as TextBox or Object making sure you're using Set for that.
 
Here's one way to get selected value from FormB, example from my db:
Code:
'user prompt for entry of logout date
DoCmd.OpenForm "DialogGetDate", , , , , acDialog, "Logout"
If CurrentProject.AllForms("DialogGetDate").IsLoaded Then
    Me.tbxDate = Form_DialogGetDate.tbxDateDialog
    DoCmd.Close acForm, "DialogGetDate", acSaveNo
End If
Hi June7

Your code closes form DialogGetDate as soon as it loaded. So, User has no chance to make any date selection on the form DialogGetDate?
In my own code, FormB is closed right after it is opening.
 

Users who are viewing this thread

Back
Top Bottom