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)

为了真正从多行文本框中获取双击突出显示的字符串,您需要三个步骤来解决计时问题:

  1. 由于文本框位置属性 SelStartSelLength 尚未在 DblClick 事件中设置, 有必要将 True 分配给布尔值 variable/marker (bCheck).
  2. 检查 bCheck 后使用 MouseUp 事件获取最终位置属性。
  3. 为了正确计数,需要删除例如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