PowerUser
PowerUser

Reputation: 11791

Why is my .setfocus ignored?

I have an Access form with a textbox that is meant to allow for repeatedly typing a number, hitting enter, and letting a script do stuff. For speed, the field should keep the focus after DoStuff() is done.

However, while I'm sure that DoStuff() is run, the focus always goes to the next field in the tab order. It's like Me.MyFld.SetFocus is being ignored.

How do I keep the focus on this field after DoStuff() is done?

Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)  
     If KeyCode = vbKeyReturn Then  
         DoStuff  
         Me.MyFld.SetFocus  
     End If
End Sub

Upvotes: 10

Views: 46673

Answers (6)

sjh2014
sjh2014

Reputation: 21

An easy solution that works in Excel is to set the KeyCode to 0. If DoStuff steals the focus then you should also set the focus back:

Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)  
     If KeyCode = vbKeyReturn Then  
         DoStuff 
         KeyCode = 0
         Me.MyFld.SetFocus  
     End If
End Sub

Upvotes: 0

Artik
Artik

Reputation: 21

Another solution to the problem that I use in Excel.

Let there exist UserForm1 with the TextBox1 and CommandButton1 controls.

Code in the form module:

    Option Explicit

    Private Sub CommandButton1_Click()
      Unload Me
    End Sub


    Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)

      If KeyCode = vbKeyReturn Then

        'Call DoStuff

        Application.OnTime Now, "'Control_SetFocus """ & Me.Name & """, """ & Me.ActiveControl.Name & """ '"
' The concatenation returns a string:  'Control_SetFocus "UserForm1", "TextBox1"'
      End If

    End Sub

And code in the standard module:

Option Explicit

Sub Control_SetFocus(FormName As String, ControlName As String)
    Dim oUserForm   As Object

    Set oUserForm = GetFormByName(FormName)

    If Not oUserForm Is Nothing Then
        oUserForm.Controls(ControlName).SetFocus
    End If
End Sub


Function GetFormByName(FormName As String) As Object
    Dim oUserForm   As Object
    On Error GoTo ErrHandle

    For Each oUserForm In VBA.UserForms
        If StrComp(oUserForm.Name, FormName, vbTextCompare) = 0 Then
            Exit For
        End If
    Next oUserForm

    If oUserForm Is Nothing Then
        Set oUserForm = UserForms.Add(FormName)
    End If

    Set GetFormByName = oUserForm
    Exit Function
ErrHandle:
    Select Case Err.Number
        Case 424:
            MsgBox "Userform " & FormName & " not exists.", vbExclamation, "Get userform by name"
        Case Else:
            MsgBox Err.Number & ": " & Err.Description, vbCritical, "Get userform by name"
    End Select

End Function

Artik

Upvotes: 1

Steven McCaffrey
Steven McCaffrey

Reputation: 31

Try removing the whole line for variable_name.SetFocus and simply add: Cancel = True

Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)  
     If KeyCode = vbKeyReturn Then  
         DoStuff  
         Cancel = True  
     End If
End Sub

Upvotes: 1

user10048738
user10048738

Reputation: 11

  1. click on access options
  2. select Advanced
  3. select Don't move from Move after enter
  4. click ok

It will work 100%

Upvotes: 1

techturtle
techturtle

Reputation: 2587

If you look at the order of events for a keypress that would change focus, you can see that it always follows this pattern:

KeyDown → BeforeUpdate → AfterUpdate → Exit → LostFocus

You can re-set the focus anywhere in there and it will still keep following the pattern. So we need to tell it to stop following the pattern. Replace your Me.MyFld.SetFocus with DoCmd.CancelEvent and it should fix your problem. Basically, this just kicks you out of the above pattern, so the Exit and LostFocus events never fire...

Upvotes: 19

Johan van der Slikke
Johan van der Slikke

Reputation: 765

A workaround is moving the focus to another control and then back to the first control. Like this:

Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)  
    If KeyCode = vbKeyReturn Then  
        DoStuff
        Me.anotherControl.SetFocus
        Me.MyFld.SetFocus  
    End If
End Sub

Upvotes: 6

Related Questions