如何 select 激活文本框后的内容?
How to select the contents of a textbox once it is activated?
我有这个简单的用户表单,其中只有 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
是loaded,表示活动有效。但是,文本未突出显示。如何解决这个问题?
我使用 Enter
事件但不想使用 MouseDown
事件,因为我需要代码在以编程方式激活 TextBox1
时也能正常工作,所以我感觉 Enter
事件是最好的选择,因为它在两种情况下都会被触发! MouseDown
事件的另一个缺点是:当我第二次单击 TextBox1
时,我不希望整个文本都被突出显示,因为焦点设置在第一次单击上并且它在我第二次点击同一个控件后没有改变;所以在这种情况下,我希望光标正常运行(而不是保持文本标记)。
更新
当我点击一次 TextBox1
时,我希望得到这样的结果:
如果再次单击,突出显示将被移除,光标将放置在单击的位置。
使用这个
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
噗,花了我一段时间。实际上,您的代码有效,但它会在点击事件发生之前突出显示文本。因此,您单击该框会立即覆盖代码创建的选择。
我用过延迟选择,效果不错,虽然有点恶心...
文本框的代码:
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")} 部分它也能正常工作,但理论上它有时可能会停止工作。嗯,再想一想,就把它放在一边吧。我怀疑它会不会引起问题。
现在module1中的代码:
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
希望这对你也有用。有趣的问题。 :) 干杯!
我无法在 Enter 事件中 select/highlight 文本,因为之后的 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,这在我看来并不是很烦人。我为此做了2个按钮作为例子。
您尝试实现的行为已内置于 TextBox
。当您将鼠标移到文本框的左侧时,鼠标指针将指向右侧。如果单击,它将 select 字段中的所有文本。单击其他任何地方都会删除select 文本。
我会尝试一些其他策略,看看我是否可以在一个 Sub 中使用它。
我想再简单不过了...
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
无论您是单击文本框还是按 Tab 键进入文本框,它都会按照您的要求进行操作。要取消选择文本,请使用箭头键。
说明
如果您调试代码,您会发现即使您已经说过 .SetFocus
,焦点也不在文本框上。 .SetFocus
在 TextBox1_Enter()
中不起作用,您需要专注于其余代码才能正常工作。因此我的选择...
备选
您可能也喜欢这个版本:)这克服了在文本框中使用鼠标的限制
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
这在某种程度上增强了@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
使用 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
我知道这已经过时了,但我把它留在这里,以防它能帮助我这个位置的人。
我想要的是:
- 如果我第一次点击该框:select所有文本
- 如果我下次点击它:将光标放在鼠标所在的位置并允许我使用鼠标 select 一个子字符串
首先,重要的是要知道 "Select all the text" 是在 TextBox 中切换时的默认行为,而 "Put the cursor here" 是单击 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
Private Sub UserForm_Initialize()
TextBox1.SetFocus
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1.Text)
End Sub
将此添加到表单的代码中
除 Siddharth 给出的解决方案外,还有另一种解决方案。
编辑:但是有这个,所以我在下面提出的解决方案比 Siddharth 的解决方案差很多。我保留它以防有一天错误被纠正...
它依赖于TextBox字段的属性 EnterFieldBehavior
。此 属性 仅在按下 Tab 键进入该字段时有效,如果此 属性 是 fmEnterFieldBehaviorSelectAll
(0) 整个字段文本自动 selected.
因此,当显示表单时,字段之间的虚拟插入符移动将自动激活该功能。例如,可以通过按 Tab 移动到下一个字段,然后按 Shift+Tab[=38 来实现此移动=] 移动到上一个字段(回到原来的字段):
Private Sub UserForm_Activate()
SendKeys "{TAB}+{TAB}"
End Sub
此解决方案的(非常小的)优点是您可以通过手动编辑属性 EnterFieldBehavior
、TabIndex
、TabKeyBehavior
和 TabStop
来调整您的用户表单不再更改 VBA 代码以在具有初始焦点的字段上设置“select 全部”。
简而言之,上面的VBA代码告诉我们要考虑显示用户表单时具有初始焦点的字段的属性 EnterFieldBehavior
(前提是它是一个TextBox当然是 ComboBox 字段)。
我有这个简单的用户表单,其中只有 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
是loaded,表示活动有效。但是,文本未突出显示。如何解决这个问题?
我使用 Enter
事件但不想使用 MouseDown
事件,因为我需要代码在以编程方式激活 TextBox1
时也能正常工作,所以我感觉 Enter
事件是最好的选择,因为它在两种情况下都会被触发! MouseDown
事件的另一个缺点是:当我第二次单击 TextBox1
时,我不希望整个文本都被突出显示,因为焦点设置在第一次单击上并且它在我第二次点击同一个控件后没有改变;所以在这种情况下,我希望光标正常运行(而不是保持文本标记)。
更新
当我点击一次 TextBox1
时,我希望得到这样的结果:
如果再次单击,突出显示将被移除,光标将放置在单击的位置。
使用这个
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
噗,花了我一段时间。实际上,您的代码有效,但它会在点击事件发生之前突出显示文本。因此,您单击该框会立即覆盖代码创建的选择。 我用过延迟选择,效果不错,虽然有点恶心...
文本框的代码:
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")} 部分它也能正常工作,但理论上它有时可能会停止工作。嗯,再想一想,就把它放在一边吧。我怀疑它会不会引起问题。
现在module1中的代码:
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
希望这对你也有用。有趣的问题。 :) 干杯!
我无法在 Enter 事件中 select/highlight 文本,因为之后的 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,这在我看来并不是很烦人。我为此做了2个按钮作为例子。
您尝试实现的行为已内置于 TextBox
。当您将鼠标移到文本框的左侧时,鼠标指针将指向右侧。如果单击,它将 select 字段中的所有文本。单击其他任何地方都会删除select 文本。
我会尝试一些其他策略,看看我是否可以在一个 Sub 中使用它。
我想再简单不过了...
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
无论您是单击文本框还是按 Tab 键进入文本框,它都会按照您的要求进行操作。要取消选择文本,请使用箭头键。
说明
如果您调试代码,您会发现即使您已经说过 .SetFocus
,焦点也不在文本框上。 .SetFocus
在 TextBox1_Enter()
中不起作用,您需要专注于其余代码才能正常工作。因此我的选择...
备选
您可能也喜欢这个版本:)这克服了在文本框中使用鼠标的限制
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
这在某种程度上增强了@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
使用 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
我知道这已经过时了,但我把它留在这里,以防它能帮助我这个位置的人。
我想要的是:
- 如果我第一次点击该框:select所有文本
- 如果我下次点击它:将光标放在鼠标所在的位置并允许我使用鼠标 select 一个子字符串
首先,重要的是要知道 "Select all the text" 是在 TextBox 中切换时的默认行为,而 "Put the cursor here" 是单击 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
Private Sub UserForm_Initialize()
TextBox1.SetFocus
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1.Text)
End Sub
将此添加到表单的代码中
除 Siddharth 给出的解决方案外,还有另一种解决方案。
编辑:但是有这个
它依赖于TextBox字段的属性 EnterFieldBehavior
。此 属性 仅在按下 Tab 键进入该字段时有效,如果此 属性 是 fmEnterFieldBehaviorSelectAll
(0) 整个字段文本自动 selected.
因此,当显示表单时,字段之间的虚拟插入符移动将自动激活该功能。例如,可以通过按 Tab 移动到下一个字段,然后按 Shift+Tab[=38 来实现此移动=] 移动到上一个字段(回到原来的字段):
Private Sub UserForm_Activate()
SendKeys "{TAB}+{TAB}"
End Sub
此解决方案的(非常小的)优点是您可以通过手动编辑属性 EnterFieldBehavior
、TabIndex
、TabKeyBehavior
和 TabStop
来调整您的用户表单不再更改 VBA 代码以在具有初始焦点的字段上设置“select 全部”。
简而言之,上面的VBA代码告诉我们要考虑显示用户表单时具有初始焦点的字段的属性 EnterFieldBehavior
(前提是它是一个TextBox当然是 ComboBox 字段)。