Excel VBA 遍历文本框多行中的每一行

Excel VBA loop through every row in Textbox multiline

我有一个多行文本框(可以按 Enter 键),我想遍历每一行并获取整行文本。

请注意,文本框自动换行已启用,如果通过自动换行创建的新行将类似于新行 (chr(10)),换句话说,我需要抓取每一行文本显示在屏幕上,无论是按“Enter”键创建的新行还是只是文本换行创建的新行都没有关系。

我需要像这样的伪代码:

for each line in textbox
       Debug.Pring line
next

对于用户按下“enter”的部分,这很简单。 一个简单的 Debug.Print TextBox1.Text 应该按原样打印它。
如果你不想做伪代码,你可以选择

tbText = Split(TextBox1.Text, vbNewLine)
For Each Line In tbText
    Debug.Print Line
Next

然而,这两个都无法检测到自动换行。

我从 那里得到了一个有点老套的方法 我使用隐藏的文本框,使代码更简单。

所以我创建了另一个文本框,命名为measure,设置AutoSize = TrueWordWrap = FalseVisible = False 然后将字体选项设置为与第一个文本框相同。并使用了以下代码:

Dim i As Long, w As Double, num As Long, memory As String
w = TextBox1.Width
tbText = Split(TextBox1.Text, vbNewLine)
For Each Line In tbText
    measure.Text = Line
    If measure.Width > w Then
shorten:
        memory = measure.Text
        While measure.Width > w
            num = InStrRev(measure.Text, " ")
            measure.Text = Left(measure.Text, num - 1)
            i = Len(memory) - num
        Wend
        Debug.Print measure.Text
        measure.Text = Right(Line, i)
        If measure.Width > w Then
            GoTo shorten
        Else
            Debug.Print measure.Text
        End If
    Else
        Debug.Print Line
    End If
Next

但是您可以随意使用任何其他方法来获取此代码的文本宽度,或者使用 Tim 评论的 Link 中的方法。

GetLines 函数创建一个数组,其中数组的每个元素都是传递给函数的 TextBox 中的一行。我决定删除控制字符,但如果不需要,您可以轻松更改逻辑。

捕获 GetLines return 值允许您循环遍历结果:

Option Explicit

Private Sub UserForm_Initialize()
   Text1.Text = "This is line 1" & vbNewLine & "This is a long line that will wrap"
End Sub

Private Sub Command1_Click()
   Dim lines() As String
   Dim line As Variant
   
   lines = GetLines(Text1)
   
   For Each line In lines
      Debug.Print line
   Next
End Sub

Private Function GetLines(ByVal tb As MSForms.TextBox) As String()
   Dim i As Integer
   Dim lc As Integer
   Dim c As String
   Dim lines() As String
   
   tb.SetFocus
   
   lc = 0
   ReDim lines(0 To tb.lineCount - 1)

   For i = 0 To Len(tb.Text) - 1
      tb.SelStart = i
      c = Mid(tb.Text, i + 1, 1)
      If Asc(c) >= 32 Then lines(lc) = lines(lc) & c
      If tb.CurLine > lc Then lc = lc + 1
   Next
   
   GetLines = lines
End Function