Excel VBA - 在userform多行文本框中获取双击的单词

时间:2016-11-21 12:30:45

标签: excel vba excel-vba textbox userform

任务:我的目标是在双击后从TextBox中的多行UserForm中提取突出显示的字词。

使用的属性:通过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
  

在UserForm代码模块中找到解决方案的其他说明(thx @Rory)

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

  1. 由于SelStart事件中尚未设置文本框位置属性SelLengthDblClick,  有必要将True分配给布尔变量/标记(bCheck)。
  2. 检查MouseUp后,使用bCheck事件获取最终排名属性。
  3. 为了正确计数,有必要删除,例如{strong>回车 vbLf(= Chr(13))和换行 vbCr对中的Chr(10)(= {{ 1)})在MS系统上。

    警告: 请注意,AFAIK Mac系统仅使用换行符vbLf作为结束符号,因此在这种情况下您可以省略替换

  4. 最终代码

    Chr(10)

1 个答案:

答案 0 :(得分:2)

我认为这是一个时间问题。如果您将标志变量和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