Как выбрать содержимое текстового поля после его активации?

У меня есть эта простая Userform, где у меня есть только TextBox1 и TextBox2. Я ввожу в них текст. Предположим, что фокус включен (курсор находится) TextBox2. Когда я нажимаю TextBox1, я хочу, чтобы весь текст в этом элементе управления был выделен (выбран). Таким образом, я использую этот код:

Private Sub TextBox1_Enter()
    With TextBox1
        .SetFocus
        .SelStart = 0
        .SelLength = Len(.Text)
    End With
    MsgBox "enter event was fired"
End Sub

В конце загружается MsgBox, что означает, что событие работает. Однако текст не подсвечивается. Как это исправить?

Я использую событие Enter и не хочу использовать событие MouseDown, потому что мне нужен код, который также работает, когда TextBox1 активируется программно, поэтому я чувствую, что событие Enter лучший выбор, поскольку он выстрелил в обоих случаях! Еще один недостаток события MouseDown: когда я нажимаю второй раз на TextBox1, я бы не ожидал, что весь текст будет выделен больше, потому что фокус был установлен на первый клик, и он не был изменен после Во второй раз я нажал на один и тот же элемент управления; поэтому в этом случае я бы хотел, чтобы курсор работал нормально (не для того, чтобы текст был помечен).

Обновление
Когда я нажимаю один раз на TextBox1, я ожидаю получить этот результат: enter image description here
Если щелкнуть снова, подсветка будет удалена, и курсор будет помещен в то место, где он был нажат.

Ответ 1

Не может быть проще, чем это, я думаю...

Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
    With TextBox1
        .SelStart = 0
        .SelLength = Len(.Text)
    End With
End Sub

Если вы нажмете на текстовое поле или вкладку в него, он будет делать то, что вы хотите. Чтобы отменить выбор текста, используйте клавиши со стрелками.

Объяснение

Если вы отлаживаете код, вы увидите, что даже если вы сказали .SetFocus, фокус не находится в текстовом поле. .SetFocus не работает в TextBox1_Enter(), и вам нужно сосредоточиться на остальной части кода для работы. И, следовательно, моя альтернатива...

Alternative

Вам также может понравиться эта версия:) Это преодолевает ограничение использования мыши в TextBox

Dim boolEnter As Boolean

Private Sub TextBox1_Enter()
    boolEnter = True
End Sub

Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
    If boolEnter = True Then
        With TextBox1
            .SelStart = 0
            .SelLength = Len(.Text)
        End With
        boolEnter = False
    End If
End Sub

Ответ 2

Pff, взял меня. На самом деле, ваш код работает, но он выделяет текст до того, как произойдет событие клика. Таким образом, вы щелкаете в ящике, мгновенно переопределяя выбор, созданный кодом. Я использовал отложенный выбор, и он работает, хотя это немного отвратительно...

Код для текстовых полей:

Private Sub TextBox1_Enter()
  Application.OnTime Now + TimeValue("00:00:01"), "module1.SelectText1"
End Sub

Private Sub TextBox2_Enter()
  Application.OnTime Now, "module1.SelectText2"
End Sub

Обратите внимание, что он работает даже с частью {+ TimeValue ( "00:00:01" )}, но это теоретически может помешать ему работать время от времени. Хм, подумав, просто оставьте это. Я сомневаюсь, что это когда-нибудь вызовет проблему.

Теперь код в модуле 1:

Sub SelectText1()
  UserForm1.TextBox1.SelStart = 0
  UserForm1.TextBox1.SelLength = Len(UserForm1.TextBox1.Text)
End Sub

Sub SelectText2()
  UserForm1.TextBox2.SelStart = 0
  UserForm1.TextBox2.SelLength = Len(UserForm1.TextBox2.Text)
End Sub

Надеюсь, это сработает и для вас. Инертная проблема.:) Приветствия!

Ответ 3

Мне не удавалось выбрать/выделить текст в событии Enter, поскольку события mousedown и mouseup, следующие после этого, несколько сбрасывают выбор.

Я думаю, что самый правильный способ добиться того, чего вы хотите, это:

' if you want to allow highlight more then once, reset the  variable LastEntered prior to call SelectTboxText:
'       LastEntered = ""
'       SelectTboxText TextBox2


Dim LastEntered As String


' Button to select Textbox1
Private Sub CommandButton1_Click()
    SelectTboxText TextBox1
End Sub

' Button to select Textbox2
Private Sub CommandButton2_Click()
    SelectTboxText TextBox2
End Sub

Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    SelectTboxText TextBox1
End Sub


Private Sub TextBox2_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
     SelectTboxText TextBox2
End Sub


Public Sub SelectTboxText(ByRef tBox As MSForms.TextBox)

    If LastEntered <> tBox.Name Then

        LastEntered = tBox.Name

        With tBox
            .SetFocus
            .SelStart = 0
            .SelLength = Len(.Text)
        End With

    End If

End Sub

Итак, каждый раз, когда вы хотите программно использовать один из текстовых полей, вы должны вызвать sub SelectTboxText, что на самом деле не раздражает IMO. В качестве примера я сделал 2 кнопки.

Ответ 4

Это несколько улучшает то, что опубликовано @vacip. Вы получаете то, что вам не нужно добавлять отдельный модуль в модуль для каждого нового текстового поля.

Следующий код в пользовательской форме:

'===== User Form Code ========

Option Explicit

Private Sub TextBox1_Enter()
    OnTextBoxEnter
End Sub

Private Sub TextBox2_Enter()
   OnTextBoxEnter
End Sub

Private Sub TextBox3_Enter()
   OnTextBoxEnter
End Sub

В модуле содержится следующий код:

'===== Module Code ========

Sub SelectAllText()
    SendKeys "{HOME}+{END}", True
End Sub

Sub OnTextBoxEnter()
   Application.OnTime Now + 0.00001, "SelectAllText", Now + 0.00002
End Sub

Ответ 5

Я знаю, что это сильно устарело, но я оставляю это здесь на случай, если это поможет кому-то на моем месте.

Что я хочу это:

  • Если я нажму на поле в первый раз: выделите весь текст
  • Если я нажму на нее в следующий раз: поместите курсор туда, где находится мышь, и позвольте мне использовать мышь для выбора подстроки

Во-первых, важно знать, что "Выделение всего текста" является поведением по умолчанию при вставке в TextBox, и что "Поместить курсор здесь" является поведением по умолчанию при нажатии на TextBox, поэтому нам нужно беспокоиться только о том, что такое мышь делает.

Для этого мы можем отслеживать активный элемент управления, но только тогда, когда мышь перемещается над нашим TextBox (т.е. Перед щелчком)

Код:

Private m_ActiveControlName As String

Private Sub Text1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    m_ActiveControlName = Me.ActiveControl.Name
End Sub

Private Sub Text1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If m_ActiveControlName <> Me.Text1.Name Then
        Call Text1_Enter   'we don't have to use Text1_Enter for this, any method will do
        Exit Sub           'quit here so that VBA doesn't finish doing its default Click behaviour
    End If
End Sub

Private Sub Text1_Enter()
    With Text1
        .SelStart = 0
        .SelLength = Len(.Text)
    End With
End Sub

Ответ 6

Private Sub UserForm_Initialize()                                                                
    TextBox1.SetFocus
    TextBox1.SelStart = 0
    TextBox1.SelLength = Len(TextBox1.Text)
End Sub   

Добавьте это к коду формы

Ответ 7

используйте этот

Private Sub TextBox1_Enter()
    With TextBox2
        .ForeColor = vbBlack
        .Font.Bold = False
    End With
    With TextBox1
        .ForeColor = vbRed
        .Font.Bold = True
    End With
End Sub

Private Sub TextBox2_Enter()
    With TextBox1
        .ForeColor = vbBlack
        .Font.Bold = False
    End With
    With TextBox2
        .ForeColor = vbRed
        .Font.Bold = True
    End With
End Sub

Ответ 8

Поведение, которое вы пытаетесь реализовать, уже встроено в TextBox. Когда вы перемещаете мышь над левой стороной текстового поля, указатель мыши укажет вправо. Если вы нажмете, он выберет весь текст в поле. Щелчок в другом месте отменяет выбор текста.

Я попробую еще несколько стратегий, чтобы увидеть, могу ли я заставить это работать в одном Sub.

Ответ 9

Попробуйте использовать тот же код с TextBox1_MouseDown. Он должен работать.

Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    With TextBox1
        .SetFocus
        .SelStart = 0
        .SelLength = Len(.Text)
    End With
    MsgBox "Text in TextBox1 is selected"
End Sub