How to reference a textbox from another form? - ms-access

I'm trying to modify existing code to add a popup box. This popup box is another form, and when a user clicks on a button on this form, I want a textbox on the base form to be populated. After that the popup disappears and then I need to access that value from the textbox on the base form.
The sequence should be:
Base form button click calls modal popup
Click in button on popup saves value to base form's textbox, then returns control.
Base form then uses this value to do something.
Base Form
Sub base()
DoCmd.OpenForm "PaperType", , , , , acDialog
MsgBox Me.TheAnswer 'This line gives a null error
End Sub
Popup Form
Private Sub btnRolls_Click()
'Me.Tag = 1
Forms!ReceiptDetail_sfrm!TheAnswer = 1
Me.Visible = False
End Sub
Private Sub btnSheets_Click()
'Me.Tag = 4
Forms!("ReceiptDetail_sfrm").TheAnswer = 4
Me.Visible = False
End Sub

You can do it that way, you probably need something like:
Private Sub btnRolls_Click()
Forms!ReceiptDetail_sfrm!TheAnswer = 1
Forms!ReceiptDetail_sfrm.Refresh
Me.Visible = False
End Sub
I've done what you're doing many times. I'm not at work to check my code right now for an example, but it's doable.

What I tend to do is hide the popup, then read from it:
Main Form:
Private Sub base()
DoCmd.OpenForm "PaperType", , , , , acDialog
'code waits for modal hide here
Me!TheAnswer = Forms("PaperType").SomethingOnThatFormThatStoresTheValue
DoCmd.Close acForm, "PaperType", acSaveNo
MsgBox Me.TheAnswer
End Sub
Popup
Private Sub btnRolls_Click
'may be hidden control
Me.SomethingOnThatFormThatStoresTheValue = TheValueToRead
Me.Visible = False
End Sub
Make sure that either A) Your popup can't be closed from the form itself, or B) Your calling code will handle the error of trying to read something that's no longer loaded (or both).

Apparently the correct answer is: "Don't do it this way!". Instead of trying to pass data between the forms, which is a pain, I made a table in Access which only has 1 field in 1 record. Then I store the value in there using DoCmd.RunSQL, and retrieve it from the other form using DLOOKUP().

Related

Use VBA to enable a text box when a check box is checked

I am new to VBA and I'm trying to create a form in Access where a text box is enabled or disabled based on whether a check box is checked or unchecked.
So if the 'Survey Requested?' box is checked the 'Date Survey Requested' box is enabled for the user to enter a date.
I have the following code:
Private Sub CheckSurveyRequested_AfterUpdate()
If CheckSurveyRequested = True Then
DateSurveyReq.Enabled = True
Else
DateSurveyReq.Enabled = False
End If
End Sub
But this comes up with a '424 Object Required' error when I run line 5.
Anyone have a suggestion as to what I'm doing wrong here?
You should definitely use the AfterUpdate event---tying the behavior of your textbox to the click event means that a user using their keyboard to navigate the form won't get the same behavior.
Also, you should replicate this behavior when the form loads: If the default value for the checkbox is False, then your textbox should be disabled when the form loads.
Also, as #ErikA notes, you can do this with one readable line.
So I would recommend something like this:
Option Explicit
Private Sub chkSurveyRequested_AfterUpdate()
Me.txtDateSurveyReq.Enabled = Me.chkSurveyRequested.value
End Sub
Private Sub Form_Load()
Me.txtDateSurveyReq.Enabled = Me.chkSurveyRequested.value
End Sub
In order to not repeat yourself, you could move this code into a separate sub:
Option Explicit
Private Sub Form_Load()
' assign the function below to the AfterUpdate event of the checkbox.
Me.chkSurveyRequested.AfterUpdate = "=UpdateControls()"
' now execute the function directly
UpdateControls
End Sub
Private Function UpdateControls()
Me.txtDateSurveyReq.Enabled = Me.chkSurveyRequested.value
End Function
I would suggest the following -
Private Sub CheckSurveyRequested_AfterUpdate()
DateSurveyReq.Enabled = CheckSurveyRequested
End Sub

Opening a zoom window in MS Access

I am having an issue with opening a zoom window in a sub form.
Basically, I have created a pop up window (form) which is suppose to appear upon double clicking in a memo field in a sub form to allow the user to be able to zoom in on the field and have additional ease upon entering long sentences.
I believe the problem is linked to the fact that the form which I am trying to create the zoom window is actually a sub form embedded in a form. My reasoning behind this is due to the fact that my code works perfectly well when i open the sub form alone and double click on the zoom in field..
Below is the code. The subform name is 'frmMasterListOfEventsDetails", the control / field to zoom in on in the sub form is called "notes2". The pop up window (subform) is named "frmZoom" and its control (text box) where the information is to be entered is called "txtZoom".
I would appreciate any help you may have.
Thank you
Private Sub Notes2_DblClick(Cancel As Integer)
If Me.AllowEdits = False Then
Messaggi.MessaggioExclamation
Else
Me.Refresh
DoCmd.OpenForm "frmzoom", acNormal, , , , acDialog
End If
End Sub
Private Sub Form_Close()
Forms("frmMasterListOfEventsDetails")!Notes2 = Me.txtZoom
Forms("frmMasterListOfEventsDetails").Refresh
End Sub
Private Sub Form_Open(Cancel As Integer)
Me.txtZoom = Forms("frmMasterListOfEventsDetails")!Notes2
End Sub
I believe the problem is linked to the fact that the form which I am trying to create the zoom window is actually a sub form embedded in a form
I believe you are correct. Since frmMasterListOfEventsDetails is a subform,
Forms("frmMasterListOfEventsDetails")
will not find it. You need to go through the main form:
Forms("parentFormName").Form.frmMasterListOfEventsDetails.Form.Notes2 = Me.txtZoom
I'm late but you can just use the SHIFT+F2 to get a zoom a any textbox in Microsoft Access
Probably, a better aproach (since you can reuse it on other forms) is this:
Private Sub Notes2_DblClick(Cancel As Integer)
If Me.AllowEdits = False Then
Messaggi.MessaggioExclamation
Else
Me.Refresh
DoCmd.OpenForm "frmzoom", acNormal, , , , acDialog, Me!Notes2
if IsOpened("frmzoom") then
Me!Notes2 = Forms!frmzoom!txtZoom
DoCmd.Close acForm, "frmzoom"
end if
End If
End Sub
'Independent module
Public Function IsOpened (stNameOfForm as string) As Boolean
Dim i As Integer
For i = 0 To Forms.count - 1
If Forms(i).Name = stNameOfForm Then
IsOpened = True
Exit Function
End If
Next
End Function
'frmzoom module
Private Sub Form_Open(Cancel As Integer)
Me.txtZoom = Me.OpenArgs
End Sub
Private Sub Btn_OK_Click() 'frmzoom Button OK
Me.Visible = False
End Sub
Private Sub Btn_Cancel_Click() 'frmzoom Button Cancel
DoCmd.Close
End Sub
As you can see, the zoom dialog receives the data from the form that calls it and then collects the information directly depending on the status (open / closed); thus the Zoom dialog does not need to know the name of any control and can be used by any form.

Form transition and data refresh

I have a form with a button and when I push it, it opens another form. When I close this second form I need to refresh the first form.
So I need to insert the first form name in a global variable to access the form name from the second form to refresh the first form.
I tried create this:
global formname as form
formname = activeform.name
but I receive an error saying: The option is read only.
On the Click event of the button you can pass the name of the form as the OpenArgs property of DoCmd.OpenForm.
Private Sub Command4_Click()
DoCmd.OpenForm "frmStaff", , , , , , Me.Name
End Sub
On the Close event of the second form you can check this (string) value:
Private Sub Form_Close()
If Me.OpenArgs <> "" Then
'MsgBox Me.OpenArgs
Forms(Me.OpenArgs).Refresh 'or .Requery
End If
End Sub
Why don't you just go into the VBA code behind and refresh it with the close sub? I don't understand the need for a global variable to be passed between the forms - You should be able to just do something like this in your second form:
Private Sub Form_Close()
Form_YourFormHere.Refresh
End Sub
If you must use this approach, try this in the first form's module:
Public formname as Form
Private Sub Command1_Click()
Set formname = Me
End Sub
or
Public formname as String
Private Sub Command1_Click()
formname = Me.name
End Sub
A form is an object type, and can only be assigned to a variable using a Set statement, otherwise VBA will think that you are trying to assign the value of the object to the variable.
You said that you wanted the form name, however your variable was a Form type, not a String. The first code snippet will achieve the result you appeared to be trying to achieve, and the second will achieve the result you said you wanted to achieve.
A different approach would probably be better and more reliable, though.

Clear Textbox on key press

Is there any way to clear the textbox on keypress like in excel.
I tried the following code but it clears the text when clicking on the textbox. I want it to clear it when a certain key is pressed.
Private Sub Text10_GotFocus()
Text10.Value = ""
End Sub
You could select the control's entire text content whenever that control gets focus. Then your keypress would replace the selected text.
If you want that to happen for every text box on every form, you can set "Behavior entering field" setting to "Select entire field". (In Access 2007, find that setting from Office Button -> Access Options -> Advanced, then look under the Editing heading of that dialog. For Access 2003, see this page.)
Not only will that setting be applied to form controls, but also to tables and queries in datasheet view. If that's not what you want, you can use VBA in your form's module to select the text for only specific controls:
Private Sub MyTextBox_GotFocus()
Me.MyTextBox.SelStart = 0
Me.MyTextBox.SelLength = Len(Me.MyTextBox)
End Sub
If you want to do that for multiple controls, you could create a general procedure:
Private Sub SelectWholeField()
Me.ActiveControl.SelStart = 0
Me.ActiveControl.SelLength = Len(Me.ActiveControl)
End Sub
Then call that procedure from the got focus event of an individual control like this:
Private Sub MyTextBox_GotFocus()
SelectWholeField
End Sub
Private Sub Field1_KeyPress(KeyAscii As Integer)
If KeyAscii = 65 Then Me.Field1 = ""
'Or: If Chr(KeyAscii) = "A" Then Me.Field1 = ""
End Sub
change the number to the ascii value of whatever key you are wanting to use to clear the field
Declare a Form Level variable
Private CanDelete as Boolean
When the TextBox receives focus, set CanDelete to True
Private Sub txtTest_GotFocus()
CanDelete = True
End Sub
On the KeyPress event, clear the text if CanDelete is True
Private Sub txtTest_KeyPress(KeyAscii As Integer)
If CanDelete Then
Me.txtTest = ""
CanDelete = False
End If
End Sub

Access: How can I display a new record in one form after creating in a second form

Access 2007: I have one form with 100s of records displayed. I have a second form for editing or creating new records. When I return to the first form after adding a new record, I do On Activate: Me.Requery so the new record is added to the list, but I would like it to display on the screen with the record selector on the new record. Is there a way to do this? I am assuming that I save the ID in a global variable, but not sure what to do next. Thanks.
RESPONSE:
Thanks //t. Your answer got me going in the right direction. I will post my solution, which I think is more of a work-around. There has to be a better solution, but this seems to work.
Form 1 (list) -> Form 2 (edit/new) and create new record.
Private Sub Form_Current ()
glngID = Me.ID.Value
End Sub
Private Sub Form_Close
gstrLastForm = "Form2"
End Sub
When I close Form 2, Form 1 is active.
Private lngSelectedRecord as Long
Private Sub Form_Activate()
Me.Requery
FindSelectedRecord
If gstrLastForm = "Form2" Then
DoCmd.GoToRecord acDataForm, "Form1", acGoTo, lngSelectedRecord
End If
End Sub
Private Sub FindSelectedRecord()
...
Open recordset, move through records, increment counter, exit when ID found
...
lngSelectedRecord = intCounter
...
End Sub
This is usually done with a form opened in dialog mode. In most cases, you'd have a command button on your main form ADD NEW RECORD, that when clicked would run code like this:
DoCmd.OpenForm "MyAddForm", , , , acFormAdd, acDialog
This opens the form you use for adding a new record to a new, empty record, and pauses the code.
However, you need to know the PK of the record that was added, so you can't just close the form and let the code continue. So, the usual practice is to set the dialog form's Visible property to False, get the data out of it that you need, then close it and do what you want:
Dim lngPK As Long
DoCmd.OpenForm "MyAddForm", , , , acFormAdd, acDialog
If Forms!MyAddForm.Tag <> "Cancel" Then
lngPK = Forms!MyAddForm!PK
Application.Echo False
Me.Requery
With Me.RecordsetClone
.FindFirst "[PK]=" & lngPK
If Not .NoMatch Then
If Me.Dirty Then
Me.Dirty = False
End If
Me.Bookmark = .Bookmark
End If
End With
Application.Echo True
End If
DoCmd.Close acForm, "MyAddForm"
In the dialog form, you have to hide the default window controls so the user can't close it. Instead, have two command buttons SAVE and CANCEL. The SAVE button does this:
If Me.Dirty Then
Me.Dirty = False
End If.
Me.Visible = False
...and the CANCEL button does this:
Me.Undo
Me.Tag = "Cancel"
Me.Visible = False
The result is that you know that a record was not saved so you don't want to do anything to the calling form.
This is all standard Access user interface design, and it's by far the easiest and most bulletproof method for doing this kind of thing.
Use the on_close-method in your popup window to go to the inserted record,
something like:
private sub on_close()
'maby first check we're not undoing..
docmd.gotoRecord yourform,yournewid
me.close
(on osx currently, but I hope you get the concept...)