激活后如何选择文本框的内容?

时间:2015-05-08 06:34:17

标签: vba excel-vba events textbox controls

我有这个简单的Userform,我只有TextBox1TextBox2。我在两者中都输入了一些文字。假设焦点在(光标在)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
如果再次单击,高亮显示将被删除,光标将被放置在单击它的位置。

9 个答案:

答案 0 :(得分:22)

我认为不能比这更简单......

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()中工作,您需要关注其余代码才能正常工作。因此我的另类......

<强>替代

您可能也喜欢这个版本:)这克服了在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

答案 1 :(得分:4)

我无法在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

因此,每当您想以编程方式激活其中一个文本框时,您应该调用子SelectTboxText,这实际上并不是令人讨厌的IMO。我为此做了两个按钮作为例子。

答案 2 :(得分:1)

这有点是@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

答案 3 :(得分:0)

我知道这已经过时了,但是我把它留在这里,以防它对我的位置有所帮助。

我想要的是:

  • 如果我是第一次单击该框,请选择所有文本
  • 如果我下次单击它:将光标放在鼠标所在的位置,并允许我使用鼠标选择子字符串

首先,重要的是要知道在选择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

答案 4 :(得分:0)

除了悉达思(Siddharth)提供的解决方案之外,还有另一种解决方案。

编辑:但是,这里有bug of SendKeys,所以我在下面提出的解决方案比Siddharth的解决方案差很多。我保留它以防有一天错误得到纠正...

它依赖于TextBox字段的属性out。仅当按下 Tab 键输入该字段时,此属性才起作用;如果此属性为EnterFieldBehavior(0),则将自动选择整个字段文本。

因此,显示表单时,字段之间的虚拟插入符移动将自动激活功能。例如,可以通过按 Tab 移至下一个字段,然后按 Shift + Tab 移至上一个字段来实现此移动(然后回到原始字段):

fmEnterFieldBehaviorSelectAll

此解决方案的优点(很少)是,您可以通过手动编辑属性Private Sub UserForm_Activate() SendKeys "{TAB}+{TAB}" End Sub EnterFieldBehaviorTabIndexTabKeyBehavior来调整用户表单,而无需进行更改不再使用VBA代码,就可以在具有初始焦点的字段上设置“全选”。

简而言之,上面的VBA代码告诉我们考虑显示用户表单时该字段的属性TabStop最初具有焦点(当然,前提是它是TextBox或ComboBox字段)。

答案 5 :(得分:-1)

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

将此添加到表单代码中

答案 6 :(得分:-2)

使用此

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

答案 7 :(得分:-2)

您尝试实施的行为已内置于\3。当您将鼠标移到文本框的左侧时,鼠标指针将指向右侧。如果单击,它将选择字段中的所有文本。单击其他任何位置将取消选择文本。

我会尝试其他一些策略,看看我是否可以在一个Sub中使用它。

答案 8 :(得分:-2)

使用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