SetFocus Not Working

jketcher

Registered User.
Local time
Today, 14:12
Joined
Apr 15, 2009
Messages
77
I am stumped. This is working fine on another form in this database. What are the reasons for a SetFocus not working? I am displaying an error message if the user leaves the control without entering data (LostFocus). I then set the border on the control to red - works fine, but when I try to SetFocus to the same control it jumps to the next control instead. Puzzled and frustrated. Thanks!

Private Sub Info1_LostFocus()
If Not IsNull(Me.Finding1) And IsNull(Me.Info1) Then
Info1.SetFocus
Info1.BorderColor = vbRed
MsgBox "Finding 1 - If finding is entered, recommendations and information must also be entered 3"
Else
Info1.BorderColor = vbBlack
End If
End Sub
 
How do you handle a user tabbing through a control that needs to have data entered in it? LostFocus is the only thing I know of that handles that situation. Appreciate your help!
 
I do all testing in the before update event of the form, not each control. That way if they skip a control completely by mousing around it, you still catch it.
 
Paul's hit the nail on the head! You have no way to insure that the user actually enters the Info1 control! And what if he/she has data in Finding1, enters Info1, then realizes that they don't have the data to place in Info1? They're stuck and will have to either enter incorrect, made up data or use <Ctrl> + <alt> + <Del> to get out of the program.

Rules of thumb for Validation:​

  • Use the YourControlName_BeforeUpdate event to Validate that data entered is appropriate, i.e > 10, all alpha characters, X number of characters in length, etc.
  • Use Form_BeforeUpdate to validate that your control is not Empty/Null.
  • Use Form_BeforeUpdate for Validation that involves more than one control. Just because you would enter data in the Finding1 control first, then enter data in Info1 control, doesn't mean that your users will!
 
Sorry, forgot to explain the “why” your code doesn’t work, and never has in any form before, not set up like this!

There are certain events, such as the Lost Focus event as well as the OnExit event, where focus has really left the control, even though you don’t see the cursor in the control. And in these events you cannot set focus back to itself. IF you have a reason where you absolutely have to do this, you have to set focus to any other control then set it back to your original control.
 
I'm not positive, but after unreliable results using the SetFocus command in Enter/Exit or Got/Lost Focus events I think that the code runs before Access actually moves the focus. So, if you change the focus in the event, when you are done Access picks up where it left off and moves the focus where it had planned to from the beginning.

Evan
 
Great responses! I created a routine to edit all of the controls that need editing with the submit button but now I need help with the syntax if I trap an error. I want to bypass the updating if there is an error. Does Access know there is an error by just using the code Cancel = True. Sorry, I am an x-Cobol programmer and I my brain works literally through top->down design and I do not know how to physically trap error conditions in VBA.
 
As noted in my link, Cancel = True stops the update.
 
I put Cancel = True in each of the edit conditions if the condition is met. Then I made changes (does not work) to the subroutine 'CloseEditForm_Click' as follows but it goes ahead and does spell check and updates the table. I thought if I checked for Cancel = True it would go to the exit as requested. Can I check for 'Cancel = True'? or Cancel = 'True'? Please don't laugh. :rolleyes:

Private Sub CloseEditForm_Click()
Call Edit_entry this is routine created to trap errors
If Cancel = True Then
GoTo Exit_CloseEditForm_Click hoped this would bypass the update
End If

DoCmd.RunCommand acCmdSpelling

DoCmd.SetWarnings False

On Error GoTo Err_CloseEditForm_Click
MsgBox "Edits Successfully Completed"

If Me.Dirty Then Me.Dirty = False
DoCmd.Close
Exit_CloseEditForm_Click:
Exit Sub
Err_CloseEditForm_Click:
MsgBox Err.description
Resume Exit_CloseEditForm_Click

End Sub
 
I'm not sure what you mean by "I put Cancel = True in each of the edit conditions if the condition is met". What does that routine look like?

Cancel = True is meant to be used in the Before Update event of the form. It is all you need to stop the update. You could use a variable of your own creation, but it would be less reliable than using the Before Update event.
 
I created a variable to hold a 'switch' that is initialized to 'No'. When there is an error, the variable becomes 'Yes'. Then I check for the 'Yes' when it comes back to the calling routine. It isn't working. Here is the code. Do you see the problem?

Private Sub CloseEditForm_Click()
MsgBox "Got to Save and Close routine"
Dim entry_error As String
entry_error = "No"
Call Edit_entry
If entry_error = "Yes" Then
GoTo Exit_CloseEditForm_Click
End If

DoCmd.RunCommand acCmdSpelling

DoCmd.SetWarnings False

On Error GoTo Err_CloseEditForm_Click
MsgBox "Edits Successfully Completed"

If Me.Dirty Then Me.Dirty = False
DoCmd.Close
Exit_CloseEditForm_Click:
MsgBox "Got to Exit_CloseEditForm_Click"
Exit Sub
Err_CloseEditForm_Click:
MsgBox Err.description
Resume Exit_CloseEditForm_Click

End Sub
_____________________________
Here is sample of edit routine:

Private Sub Edit_entry()
If IsNull(Me.Finding1) And Not IsNull(Me.Info1) Then
Me.Finding1.BorderColor = vbRed
Me.Finding1.SetFocus
MsgBox "If Info1 is entered then Finding 1 must also be entered"
Cancel = True
entry_error = "Yes"
Else
Me.Finding1.BorderColor = vbBlack
End If
End Sub
 
I would take the code out of Edit_entry and put it in the before update event of the form. Let that event do what it does best. You're trying to do manually what it will do automatically. While that's doable, what happens when the user closes the form without clicking your button? The before update event will still fire, so it's more reliable.

Among your errors, entry_error is declared in the first routine, so it is out of scope in the second. You must not have Option Explicit at the top of the module, or you'd be getting a compile error. That is an undeclared variable in the second procedure.
 
OK -- I did what you recommended. Changed to Before Update on Form and am still having some problems. I think it is in the logic of the button routine. Recap: The user will enter a button when they are finished entering all of the findings and related information. Finding1, Info1, Finding 2, Info2 etc. through Info 10. Most records will have only one or two findings. They have to be entered in order so there is a lot of editing to make sure the user doesn't mess this up.

Code for the BeforeUpdate routine with a sample of one error message...

Private Sub Form_BeforeUpdate(Cancel As Integer)
MsgBox "Got to BeforeUpdate Form routine" (I added this to help debug)
If IsNull(Me.Finding1) And Not IsNull(Me.Info1) Then
Me.Finding1.BorderColor = vbRed
Me.Finding1.SetFocus
MsgBox "If Info1 is entered then Finding 1 must also be entered"
Cancel = True

Else
Me.Finding1.BorderColor = vbBlack
End If
...
...
End Sub

This is what the routine when the Save and Close button is pressed looks like now:

Private Sub CloseEditForm_Click()
DoCmd.RunCommand acCmdSpelling

DoCmd.SetWarnings False

On Error GoTo Err_CloseEditForm_Click
MsgBox "Edits Successfully Completed"

If Me.Dirty Then Me.Dirty = False
DoCmd.Close
Exit_CloseEditForm_Click:
Exit Sub
Err_CloseEditForm_Click:
MsgBox Err.description
Resume Exit_CloseEditForm_Click

End Sub

This is what is happening when I deliberately enter code in error:

1. Error condition produced. MsgBox displayed.
2. 'Got to Before Update Form routine' displays.
3. 'Edits Successfully Completed' Displays and shouldn't (how do I display this message when things truly are successful and bypass it when they aren't using this logic?)
4. It goes into the BeforeUpdate Form routine logic again because the 'Got to Before Update Form routine' message displays once more.
5. The same error message from item 1. displays again.
6. Then get a system produced message 'The setting you entered isn't valid for this property' displays.
7. Then it lets me fix the control that is in error.
8. Then the process ends successfully and it takes me back to the menu form.

It is going through the BeforeUpdate routine twice on the same error. Do you know how I can change the code to prevent that?

Mucho thanks!
 
I suspect it's running once for the Me.Dirty = False and again on the Close. I wouldn't bother with the first, as a bound form will try to save automatically when you close it. If you move the "success" message box to the Else portion of the before update code, you should only get it when it saves successfully. Where it is now, you'll always get it.

By the way, the fields with 1, 2, etc are a sign of a normalization problem. That data should probably be in a one-to-many related table.
 
TGIF! It is close but still not working the way it needs to. The BeforeUpdate routine processes but when there is an edit error is trapped it displays the error message and outlines the control in red, but just keeps on going to do the spell check, updates and close form. What do I need to do to get it to stop so the user can fix the problem data.

1. User presses contrl button to initiate routine CloseEditForm
2. Enters CloseEditForm
3. Bounces to AfterUpdate edits.
4. Finds the error entered and displays message. Presses the OK button on the message. (Is this where I need to do something?)
5. Returns automatically to the CloseEditForm Routine and proceeds through the spell check and DoCmd.Close etc.

The AfterUpdate routine has about 20 edits in it. A user could make multiple errors that would be trapped at the same time. I hope this explanation helps. I am very stuck. Thanks!
 
Can you post the db, or a sample of it that exhibits the problem?
 
I would have to create a clone and change some of the table data due to confidentiality issues unless you have other ideas for how to go about this. I need to be able to set something -- I tried a Variable but it did not carry back to the executing routine (sorry don't know Access/VBA language to describe easily) ---to prevent update until the problem was fixed.
 
Finally getting back to you. This is now working but I ended up using code in the 'Save' Button click and did the other edits using after update on each field. I appreciate your help! jketcher
 

Users who are viewing this thread

Back
Top Bottom