Excel VBA - 获取用户窗体多行文本框中双击的单词
Excel VBA - get double-clicked word in userform multiline textbox
任务:我的目标是在双击后从UserForm
中的多行TextBox
中提取突出显示的单词。
使用的属性:虽然通过 TextBox
属性 .SelStart
和 .SelLength
突出显示给定的字符串位置绝对没有问题,但它反过来就不那么容易了:用户 DblClick
突出显示了整个单词字符串,但是 Excel 没有将突出显示文本的起始位置的 .SelStart
值重置为一个可以假设,.SelStart
值保留在用户双击的位置。
我的问题:有没有可能直接捕捉应用程序设置的高亮文本起始位置?
我的变通方法:我将演示一个非常简单的变通方法,只需检查以下和前面的内容即可重建高亮显示的单词,例如实际点击位置左右各20个字母(当然也可以用正则,细化示例代码):
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim sTxt As String, sSel As String ' edited due to comment below
Dim selPos As Long, i As Long, i2 As Long ' "
TextBox1.SetFocus
' this is the User's DblClick Position,
' but not the starting Position of the highlighted Word
' after DblClick
selPos = TextBox1.SelStart
sTxt = Replace(Replace(TextBox1.Text, vbCrLf, vbLf), "\", ".")
If TextBox1.SelLength > 0 Then
sSel = TextBox1.SelText
Else
sSel = Mid(sTxt, selPos + 1, 5)
' check the preceding 20 letters
i = selPos
For i = selPos To (selPos - 20) Step -1
If i < 0 Then Exit For
Select Case Left(Mid(sTxt, i + 1), 1)
Case " ", vbLf, ":", ".", "?", """", "'", "(", ")"
sSel = Mid(sTxt, i + 2, selPos - i)
Exit For
End Select
Next i
' check the following 20 letters
i2 = selPos
For i2 = selPos To (selPos + 20)
If i2 > Len(sTxt) Then Exit For
Select Case Left(Mid(sTxt, i2 + 1), 1)
Case " ", vbLf, ":", ".", "?", """", "'", ")", "("
sSel = Replace(Mid(sTxt, i + 2, i2 - i - IIf(i = i2, 0, 1)), vbLf, "")
Exit For
End Select
Next i2
End If
' Show the highlighted word
Me.Label1.Text = sSel
End Sub
Additional explanations to found solution in UserForm code module (thx @Rory)
为了真正从多行文本框中获取双击突出显示的字符串,您需要三个步骤来解决计时问题:
- 由于文本框位置属性
SelStart
和 SelLength
尚未在 DblClick
事件中设置,
有必要将 True
分配给布尔值 variable/marker (bCheck
).
- 检查
bCheck
后使用 MouseUp
事件获取最终位置属性。
为了正确计数,需要删除例如vbLf
回车 returns Chr(13)
(=vbCr
) 和 换行 Chr(10)
(=vbLf
) 在 MS 系统上。
警告: 请注意,AFAIK Mac 系统仅使用换行符 Chr(10)
作为结束符号,因此 IMO 您可以省略替换在这种情况下.
最终代码
Option Explicit
Private bCheck As Boolean
' [1] assign True to boolean variable
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
bCheck = True ' set marker to True
End Sub
Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If bCheck Then
bCheck = False ' reset marker to False
' [2][3] extract the highlighted doubleclicked word from multi-line textbox
MsgBox Trim(Mid(Replace(Me.TextBox1.Text, vbLf, ""), Me.TextBox1.SelStart + 1, Me.TextBox1.SelLength))
End If
End Sub
我认为这是一个时间问题。如果将标志变量和 MouseUp 事件与 DblClick 事件结合使用,它似乎可以工作:
Private bCheck As Boolean
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
bCheck = True
End Sub
Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If bCheck Then
bCheck = False
MsgBox Me.TextBox1.SelStart & "; " & Me.TextBox1.SelLength
End If
End Sub
任务:我的目标是在双击后从UserForm
中的多行TextBox
中提取突出显示的单词。
使用的属性:虽然通过 TextBox
属性 .SelStart
和 .SelLength
突出显示给定的字符串位置绝对没有问题,但它反过来就不那么容易了:用户 DblClick
突出显示了整个单词字符串,但是 Excel 没有将突出显示文本的起始位置的 .SelStart
值重置为一个可以假设,.SelStart
值保留在用户双击的位置。
我的问题:有没有可能直接捕捉应用程序设置的高亮文本起始位置?
我的变通方法:我将演示一个非常简单的变通方法,只需检查以下和前面的内容即可重建高亮显示的单词,例如实际点击位置左右各20个字母(当然也可以用正则,细化示例代码):
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim sTxt As String, sSel As String ' edited due to comment below
Dim selPos As Long, i As Long, i2 As Long ' "
TextBox1.SetFocus
' this is the User's DblClick Position,
' but not the starting Position of the highlighted Word
' after DblClick
selPos = TextBox1.SelStart
sTxt = Replace(Replace(TextBox1.Text, vbCrLf, vbLf), "\", ".")
If TextBox1.SelLength > 0 Then
sSel = TextBox1.SelText
Else
sSel = Mid(sTxt, selPos + 1, 5)
' check the preceding 20 letters
i = selPos
For i = selPos To (selPos - 20) Step -1
If i < 0 Then Exit For
Select Case Left(Mid(sTxt, i + 1), 1)
Case " ", vbLf, ":", ".", "?", """", "'", "(", ")"
sSel = Mid(sTxt, i + 2, selPos - i)
Exit For
End Select
Next i
' check the following 20 letters
i2 = selPos
For i2 = selPos To (selPos + 20)
If i2 > Len(sTxt) Then Exit For
Select Case Left(Mid(sTxt, i2 + 1), 1)
Case " ", vbLf, ":", ".", "?", """", "'", ")", "("
sSel = Replace(Mid(sTxt, i + 2, i2 - i - IIf(i = i2, 0, 1)), vbLf, "")
Exit For
End Select
Next i2
End If
' Show the highlighted word
Me.Label1.Text = sSel
End Sub
Additional explanations to found solution in UserForm code module (thx @Rory)
为了真正从多行文本框中获取双击突出显示的字符串,您需要三个步骤来解决计时问题:
- 由于文本框位置属性
SelStart
和SelLength
尚未在DblClick
事件中设置, 有必要将True
分配给布尔值 variable/marker (bCheck
). - 检查
bCheck
后使用MouseUp
事件获取最终位置属性。 为了正确计数,需要删除例如
vbLf
回车 returnsChr(13)
(=vbCr
) 和 换行Chr(10)
(=vbLf
) 在 MS 系统上。警告: 请注意,AFAIK Mac 系统仅使用换行符
Chr(10)
作为结束符号,因此 IMO 您可以省略替换在这种情况下.
最终代码
Option Explicit
Private bCheck As Boolean
' [1] assign True to boolean variable
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
bCheck = True ' set marker to True
End Sub
Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If bCheck Then
bCheck = False ' reset marker to False
' [2][3] extract the highlighted doubleclicked word from multi-line textbox
MsgBox Trim(Mid(Replace(Me.TextBox1.Text, vbLf, ""), Me.TextBox1.SelStart + 1, Me.TextBox1.SelLength))
End If
End Sub
我认为这是一个时间问题。如果将标志变量和 MouseUp 事件与 DblClick 事件结合使用,它似乎可以工作:
Private bCheck As Boolean
Private Sub TextBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
bCheck = True
End Sub
Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If bCheck Then
bCheck = False
MsgBox Me.TextBox1.SelStart & "; " & Me.TextBox1.SelLength
End If
End Sub