Cannot SetFocus > userform control

Jon von der Heyden

MrExcel MVP, Moderator
Joined
Apr 6, 2004
Messages
10,912
Office Version
  1. 365
Platform
  1. Windows
Hi All

Posting a rather lengthy class here. Everything works as expected, except the .SetFocus line. Testing on textboxes, the control in question is not selected, yet the error message displays:

clsFormsControlsEvents:
Code:
Private WithEvents m_TextBoxEvents As MSForms.TextBox
Private WithEvents m_ComboBoxEvents As MSForms.ComboBox
Private m_blnOk As Boolean 'boolean to tell us whether or not all controls ok

Public Property Set Control(ctlNew As MSForms.Control)
    Select Case TypeName(ctlNew)
        Case "TextBox"
            Set m_TextBoxEvents = ctlNew
        Case "ComboBox"
            Set m_ComboBoxEvents = ctlNew
    End Select
End Property

'there's no exit event, so we use key/mouse down events, check for tab and click to a different control

Private Sub m_TextBoxEvents_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If KeyCode = vbKeyTab Then
        Call ControlEventTriggered(m_TextBoxEvents)
    End If
End Sub

Private Sub m_TextBoxEvents_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

End Sub

Private Sub ControlEventTriggered(ByVal ctl As MSForms.Control)
    Dim varArrTag As Variant
    varArrTag = Split(ctl.Tag, ",")
    'tag: (0) = Mandatory boolean
    '     (1) = Data type
    '     (2) = Length
    
    With ctl
        If varArrTag(0) = True And Len(.Object.Value) = 0 Then
            [COLOR=Red][B].SetFocus[/B][/COLOR]
            MsgBox Prompt:="Mandatory field!", Buttons:=vbExclamation + vbOKOnly, Title:=ctl.Parent.Name
            m_blnOk = False
            GoTo Finally
        End If
        Select Case varArrTag(1)
            Case "date"
                If Not IsDate(.Object.Value) Then
                    [COLOR=Red][B].SetFocus[/B][/COLOR]
                    MsgBox Prompt:="Invalid date!", Buttons:=vbExclamation + vbOKOnly, Title:=ctl.Parent.Name
                    m_blnOk = False
                    GoTo Finally
                End If
            Case "numeric"
                If Not IsNumeric(.Object.Value) Then
                    [COLOR=Red][B].SetFocus[/B][/COLOR]
                    MsgBox Prompt:="Number field!", Buttons:=vbExclamation + vbOKOnly, Title:=ctl.Parent.Name
                    m_blnOk = False
                    GoTo Finally
                End If
            'more cases here
        End Select
        If Len(.Object.Value) > CLng(varArrTag(2)) Then
            [COLOR=Red][B].SetFocus[/B][/COLOR]
            MsgBox Prompt:="Max " & varArrTag(2) & " chars!", Buttons:=vbExclamation + vbOKOnly, Title:=ctl.Parent.Name
            m_blnOk = False
            GoTo Finally
        End If
    End With
    
    m_blnOk = True
    
Finally:
    Erase varArrTag
End Sub

Private Sub Class_Terminate()
    Set m_TextBoxEvents = Nothing
    Set m_ComboBoxEvents = Nothing
    m_blnOk = Empty
End Sub
 
Fantastic stuff Jaafar. This is great and I have learned heaps in this thread.

Thanks so much!
:beerchug:
 
Upvote 0

Excel Facts

Remove leading & trailing spaces
Save as CSV to remove all leading and trailing spaces. It is faster than using TRIM().
I refer to the thread I started here (http://www.mrexcel.com/forum/showthread.php?t=519618) (read the last appends).

I tested the example workbook you posted. Try the following. First, run the code as is, and enter an invalid date. You'll get a message, the pink color and after closing the message, focus (a blinking cursor) is back in the control.

Now change your code so that the form is started modeless and repeat the test. After closing the error message, where did the cursor go ????
 
Upvote 0
I tested modeless userform and it behaves the same for me. The cursor is returned to the control that failed the test.

I'm using excel 2010 with Win7 Ult 32bit... What are you using?
 
Upvote 0
I refer to the thread I started here (http://www.mrexcel.com/forum/showthread.php?t=519618) (read the last appends).

I tested the example workbook you posted. Try the following. First, run the code as is, and enter an invalid date. You'll get a message, the pink color and after closing the message, focus (a blinking cursor) is back in the control.

Now change your code so that the form is started modeless and repeat the test. After closing the error message, where did the cursor go ????

Michael.

I am using excel 2007 and I could replicate the problem you are describing. Do not know about xl 2010.

The blinking caret disappears when leaving the TextBox using the mouse but not the TAB key.

Displaying MsgBoxes is what seems to be causing the blinking caret problem. I'll check back the code and see if this can be solved.
 
Upvote 0
This is puzzling ,but funnily enough, simply toggling the Enable Property of the TextBox Control ( Or any other control ) just before resetting the focus back seems to be all is required to solve the problem with the blinking caret disappearing when applying the Class to Modeless userforms.

See here a demo for modeless forms.


Here is the fixed code in the StartWatching Class module :

Code:
Public Sub StartWatching(Form As UserForm)

    bFormUnloaded = False
    
    Set oPrevActiveCtl = Form.ActiveControl
    RaiseEvent OnEnter(Form.ActiveControl)
    
    Do While bFormUnloaded = False
        If Not oPrevActiveCtl Is Nothing Then
            If Not oPrevActiveCtl Is Form.ActiveControl Then
                RaiseEvent OnExit(oPrevActiveCtl, bCancel)
                If bCancel Then
                   [B][COLOR=Blue] oPrevActiveCtl.Enabled = False[/COLOR][/B]
                   [B][COLOR=Blue] oPrevActiveCtl.Enabled = True[/COLOR][/B]
                    oPrevActiveCtl.SetFocus
                Else
                    RaiseEvent OnEnter(Form.ActiveControl)
                    Form.ActiveControl.SetFocus
                End If
            End If
        End If
        Set oPrevActiveCtl = Form.ActiveControl
        bCancel = False
        DoEvents
    Loop

End Sub
Hope this work for you too.
 
Upvote 0
Thanks Jafaar - it works as long as I only use your code. I noticed another quirk with the code. Assuming this form initialize
Code:
Private Sub UserForm_Initialize()
    country_combo.SetFocus   ' First control on form
End Sub
then I notice focus is not in this control when the form is first shown
 
Upvote 0
I think you need to set focus to that control in the forms Layout event, before you instatiate the class.
 
Upvote 0

Forum statistics

Threads
1,224,763
Messages
6,180,822
Members
452,997
Latest member
gimamabe71

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top