I have a form in Access 2003 that should only be working with a single record. I can set the Cycle property to Current Record, but the form still jumps to the next record when I press Enter. My first thought was a KeyPreview property, but I'm not seeing one. My other thought is maybe the KeyPress or KeyUp event, but I thought I'd ask in case of unintended consequences. Any ideas?
The Cycle property only affects the TAB key.
To control the behaviour of the Enter Key that's a global property.
Go to Tools/Options - Keyboard tab and on "Move After Enter" select "Next Field"
There are KeyPress and KeyDown events that you can use to trap the Enter key too but that's more work.
This can also be done in vba.
Application.GetOption "Move After Enter" 'get current setting
Application.SetOption "Move After Enter", 0 'don't move
Application.SetOption "Move After Enter", 1 'Next Field
Application.SetOption "Move After Enter", 2 'Next Record
http://www.pcreview.co.uk/forums/enter-key-moving-next-field-t3454281.html
The moment keys like TAB, Alt, PgUP, PgDn, Enter are pressed at the end of adding the record (after the last field mostly), the database auto saves all the info you entered on the form and wipes out the fields so that you can enter the next value. So what happens is that the data is saved but the form looks empty.
3 things to do:
Form Cycle Property set to Current Record.
Form Key Preview Property set to Yes.
Add following code to the KeyDown Event of the form:
'33 - PgUp; 34 - PgDown; 9 - Tab; 18=Alt; 13=Enter
Select Case KeyCode
Case 33, 34, 18, 9, 13
KeyCode = 0
Case Else
'Debug.Print KeyCode, Shift
End Select
I found this while scouring the web and don't take credit/responsibility for the code but I don't know where I found it. Works for me!
The Cycle property only works with the Tab key.
There are two options you could pursue.
You could trap the Enter key in KeyDown/KeyUp/KeyPressed
- OR -
You could filter the data source to the one record you want them editing, and disable adding new records through that form.
You can add below code to your form 'BeforeUpdate' event. If use want to move to next record, it will ask user to save then close the form before they can move to another recorde.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Select Case MsgBox("Save?", vbYesNo)
Case vbYes
DoCmd.Close
Case vbNo
Cancel = True
End Select
End Sub
If you go into Access Options on the file page, go to Client Settings and the first setting will let you choose where your focus changes to when you press enter. At least in Access 2013.
Related
In an Access form I am using a textbox to filter an unbound subform. I want to allow the end user to quickly perform quick sequential searches. After the Enter key is pressed to perform a first search, I want the cursor/focus to remain in the text box and the current search text to be selected. In this way the user can directly start entering a new query, replacing the old search text.
I tried the answers to this question, but due to the Enter key, the selection always gets lost:
The solution I came up with is to intercept the Enter key press. It is important to cancel the event, otherwise the Enter key will remove the selection.
Private Sub txtSearch2_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
Call Search
If Len(Me.txtSearch2.Text & "") = 0 Then Exit Sub
Me.txtSearch2.SelStart = 0
Me.txtSearch2.SelLength = Len(Me.txtSearch2.Text)
DoCmd.CancelEvent
End If
End Sub
I have a userform with with 6 different categories in which the user must select an option between 0-4. Each option is selectable with a radio button with a set value that will be written in the parent sheet. Each set of radio buttons that belong to a category are grouped (a-e).
Could someone please help me to implement a mechanism that will make it mandatory for the user to select at one option in each category by displaying a message prompting the user to select an option?
The workflow is as such:
User selects options --> Selected options are written in the sheet --> Unload Me on the form
Ideally it would be best if the macro to write all is "paused" (not proceeding to Unload Me). Instead the message is displayed, and then the form remains as it was so that the user can go back and continue, without having to redo the whole process.
EDIT:
Thanks for all help. Hope this makes it easier:
The code I'm using is being triggered by a "Register score" button that I've placed on the UserForm that contains all the radio buttons. The button contains the following code (where aa = first radio button):
Private Sub CommandButton1_Click()
If aa.Value = False Then
MsgBox ("Please select at least one option")
Else
Range("A" & Rows.Count).End(xlUp).Offset(1).Value = "Category A"
Range("B" & Rows.Count).End(xlUp).Offset(1).Value = "0"
End If
Unload Me
End sub
I now repeat this code for every radio button. Problem is, if the user for example selects a radio button properly in every category but forgets the first, the form will reset meaning that the user must re-do the entire thing. I can of course also add (I've only included the radio buttons here for sake of simplicity, but the correct code would of course include all buttons):
Private Sub CommandButton1_Click()
If aa.Value = False and ab.Value = False And ac.Value = False Then
MsgBox ("Please select at least one option")
In this case the user must select one option every category, but it will also reset the entire form, meaning that you have to redo everything.
How about something like:
If Radio1.value = False And Radio2.value = False And Radio3.value = False And Radio4.value = False then
Msgbox "Please select something from the first four Radio Buttons"
Exit Sub
End if
To ensure one is selected simply add a section of code in the OK/Close button's event that checks that at least one button is selected - if not display message and then either Exit Sub to abort the routine, or implement the checks as a function that returns a boolean and only unload if it returns true.
Incidentally, on your proposed workflow, if you unload the form how are you going to then write the user's choices into the sheet?
Hopefully I can explain what I want to do well enough...here it goes...
I have a data entry form...the user will be entering employeeIDs. Once in normal operation, most people will be entering only their own EmpID, and they should know it, so this won't be a big problem 99% of the time once this DB goes live.
However, I need some temps to enter historical data from paper sheets into the DB. These people will not know anyone else's EmpID. I'd like to set the Student field's OnDblClick event in the subform's datasheet to open a small form with a combo box. The combo box has a list of all Employee Names, and is bound to the EmpID. Once this user enters the name, and selects the person, I have a button they can click to return to the datasheet.
I can use a function to launch the form, no problem there. But how do I return the EmpID to the field in the datasheet that was double clicked?
When user double clicks in the Student field...I want the next form to appear, and then once they type in the name and select the correct person...and then click Found Them!...I need that bound value to return.
I'd love to say I have code to share right now...but the only code I have is to launch the look up form. I'm brain farting on how to pull the value back down.
The way to do this to launch your little dialog form as “acDialog”. This will cause the calling code to WAIT.
And then the “magic” part is when they click on “Found Them” you do NOT close the popup form, but simply set the form’s visible = false. This has the effect of the calling code that popped up this form that halted to continue (the form is kicked out of dialog mode when you do this). So now your calling code continues.
So your code will look like this:
Dim strF As String ' name of popup form
strF = "frmPopUp"
' open form, wait for user selection
DoCmd.OpenForm strF, , , , , acDialog
' if for is NOT open, then assume user hit cancel buttion
' (you should likly have a cancel button on the form - that cancel buttion will
' execute a docmd.close
If CurrentProject.AllForms(strF).IsLoaded = True Then
' grab the value of thee combbo box
strComboBoxValue = Forms(strF)!NameOfComboBox
DoCmd.Close acForm, strF
End If
As noted, the code behind the Found Them button DOES NOT do a close form, but sets forms visible = false (me.Visible = false), and this trick allows the calling code to continue at which point you can examine any value on the form. Remember to then close the form after you grab the value.
It looks like your data table is in a subform so there is a little more work but it does not have to be as complex as the above solution if you don't want it to be. #Andre451 was close but you need the extra step of identifying the form and subform. For the purpose of demonstration let's call the form Attendance and subform Entry then I'll call the second form LookUp. So the code for your double click in the subform field will of course look something like this :
Private Sub Student_DblClick(Cancel As Integer)
DoCmd.OpenForm "LookUp"
End Sub
You really don't need anything else fancy there. For the button on "LookUp" you will put this:
Private Sub Command2_Click()
Forms![Attendance]![Entry].Form![Student] = Forms!Lookup!Student
DoCmd.Close acForm, "LookUp"
End Sub
And that should get you what you want without any overhead or having to leave any ghosts open.
I am trying to make a memo field be spell checked when it leaves the field, and when it leaves the subform to the main form. I want to have this done automatically without having a click button, as I need the data to be as accurate and error-free as possible.
In the main form I have used this code to spell check a title field once you move off the field.
Private Sub DetailedTitle_Exit(Cancel As Integer)
'This code works to spellcheck the title after leaving.
With Me!DetailedTitle
If Len(.Value) > 0 Then
DoCmd.SetWarnings False
.SelStart = 1
.SelLength = Len(.Value)
DoCmd.RunCommand acCmdSpelling
.SelLength = 0
DoCmd.SetWarnings True
End If
End With
End Sub
This works well, as users will 99% of the time moving from this field to another field in the main form. This does not work when I use in on the subform even when I use the on exit field event AND the on exit subform event. It seems to work, but if you click around it will actually give an error. I wasn't smart enough to note the error, and I have since removed the code.
I would also not be opposed if I could get it to loop thought the subform, as it is a continuous form, but only that one field.
Any advice or tips would be welcome. I just recently learned of the Do.Cmd.RunCommand acCmdSpelling, but there seems to be a lack of content in regards to subforms. Thanks.
I did some research: http://www.pcreview.co.uk/threads/run-the-spell-check-through-code.1636292/
One user mentions that the control you want to check has to be in focus.
Sub subformMemo_OnExit()
Me.subformMemo.setfocus
DoCmd.RunCommand acCmdSpelling
End Sub
On the other hand this code creates the problem that you cannot leave the control because you will always setfocus on it again.
Does this help?
I am writing below code for validating compulsary field account no. in form.
User's requirement is set focus back on field when error comes :
If txtAccountNo = "" Then
MessageBox.Show("Account no filed can't be left empty")
txtAccountNo.SetFocus
Exit Sub
End If
It's working properlly. But suppose user don't want to fill form and exiting from aaplication.
Message box keep on appearing till user enters account no.
How can I avoid this situation?
Please help.
Set a flag to indicate user has seen messagebox. Check the flag to prevent any future messagebox. Make sure the flag is set before setting focus back to textbox e.g.
dim bMsgBox as boolean=false
If txtAccountNo = "" and bMsgBox = false Then
MessageBox.Show("Account no filed can't be left empty")
bMsgBox=true
txtAccountNo.SetFocus
Exit Sub
End If
You could put all the validation rules in one function / procedure / subrutine (I'm not familiar with VB, mostly C++ / C# user). Then call this function only when user is committing the data filled in, and set focus to first control with mandatory data not filled or invalid data entered.
Say you have a form with 3 controls to be filled in:
a date control not mandatory - dteDate
a text box mandatory - txtAccoutInfo
a text box mandatory - txtAddress
and 2 buttons:
button Save and button Cancel.
When 'Save' button is pressed you first call the function / procedure to validate user input. If date entered is invalid in dteDate, you set focus on it and return / exit the function; if no text is entered in txtAccountInfo then set focus on it and return / exit the function; if no text is entered in txtAddress then set focus on it and return / exit.
When 'Cancel' is pressed you don't call this function, but just quit.