【问题标题】:Excel VBA - get double-clicked word in userform multiline textboxExcel VBA - 在用户窗体多行文本框中双击单词
【发布时间】:2016-11-21 12:30:45
【问题描述】:

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

Used Properties:虽然通过TextBox 属性.SelStart.SelLength 突出显示给定的字符串位置绝对没有问题,但反过来就不那么容易了:a用户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 代码模块中找到解决方案的附加说明(感谢 @Rory)

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

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

    警告: 请注意,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

【问题讨论】:

  • 您需要修正您的声明...必须为每个变量分配一个类型,否则默认情况下它将是一个 Variant。 (即-sTxt 不是字符串,i 不是整数)无需在 For 循环之前将变量设置为 For 循环的开头。
  • 感谢您的评论,但我认为第 2 行和第 3 行中的 Dim sTxt As String, Dim i as Long 就足够了。在这些代码行之后我应该做什么?
  • Dim sTxt as String 是正确的,但这不是你所拥有的。 Dim sText, sSel as String 将 sSel 声明为 String 并将 sText 声明为 Variant。
  • 谢谢,我确实学到了一些东西。

标签: vba excel textbox userform


【解决方案1】:

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

【讨论】:

  • 嗨,Rory,这正是我想要的——谢谢
  • 添加: 要从多行文本框中提取突出显示的双击单词,请使用:Trim(Mid(Replace(Me.TextBox1.Text, vbLf, ""), Me.TextBox1.SelStart + 1, Me.TextBox1.SelLength))
猜你喜欢
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2018-02-15
  • 1970-01-01
相关资源
最近更新 更多