1

我在 VBA Excel 应用程序中有一个列表框,它读取三个不同的列并在一行中列出它们的内容。但是列中每个项目的宽度各不相同。因此,当我使用“vbtab”在列表框中显示它时,它没有正确对齐下一个项目。例如,当第一项有 4 个字符时,它将第二项拉得更近,而如果第一项有 8 个字符,则将第二项推得太远。知道如何解决这个问题吗?

下面是我正在使用的代码。

Private Sub UserForm_Activate()
With ThisWorkbook.Sheets("Sheet1").Range("a1:a50")
MySearch = Array("Tba")
For i = LBound(MySearch) To UBound(MySearch)
Set rng = .Find(what:=MySearch(i), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)

firstaddress = rng.Address


Do
j = 1
drovedate = rng.Offset(0, j)
j= j + 1
drivenby = rng.Offset(0, j)
j = j + 6
reason = rng.Offset(0, j)
x = x + 1
Dim LineOfText As String

CPHlsttheeba.AddItem (x & "   " & drovedate & vbTab() & vbTab & drivenby & vbTab & vbTab & reason)


Set rng = .FindNext(rng)
Loop While Not rng Is Nothing And rng.Address <> firstaddress
Next i
End With
End Sub
4

3 回答 3

2

如果您的文本宽度已知,那么您可以使用 的.ColumnWidthsListBox1预定义列宽。这将确保数据正确对齐。如果文本宽度未知,那么您可以将 设置为.ColumnWidths您认为可以容纳所有单词的内容。在下面的示例中,我将其设置为50

另一个技巧不是将循环中的数据添加到 中,ListBox1而是将其存储在数组中,然后将 的.List属性设置ListBox1为该数组。这将确保代码的执行速度更快。

这是一个例子。我在这里手动填充数组。你可以在你的数组中填充Do While Loop

代码

Private Sub UserForm_Activate()
    Dim Myarray(1 To 2, 1 To 4) As String

    Myarray(1, 1) = "Sid"
    Myarray(1, 2) = "Apple"
    Myarray(1, 3) = "Banana"
    Myarray(1, 4) = "Mumbai"
    Myarray(2, 1) = "New Delhi"
    Myarray(2, 2) = "New York"
    Myarray(2, 3) = "Japan"
    Myarray(2, 4) = "asdfghjkl"

    With Me.ListBox1
        .Clear
        .ColumnHeads = False
        .ColumnCount = 4

        .List = Myarray

        '~~> Change 50 to 8 in your application
        .ColumnWidths = "50;50;50;50"
        .TopIndex = 0
    End With
End Sub

屏幕截图

在此处输入图像描述

跟进

抱歉,我不确定如何使我的编码与数组一起使用并列出它们.. 你能帮我一下吗.. – user1697952 1 小时前

试试这个(未经测试

Private Sub UserForm_Activate()
    Dim n As Long

    With CPHlsttheeba
        .ColumnHeads = False
        .ColumnCount = 4
        .ColumnWidths = "8;8;8;8"
    End With

    With ThisWorkbook.Sheets("Sheet1").Range("a1:a50")
        MySearch = Array("Tba")
        For i = LBound(MySearch) To UBound(MySearch)
            Set rng = .Find(what:=MySearch(i), _
            After:=.Cells(.Cells.Count), _
            LookIn:=xlFormulas, _
            LookAt:=xlPart, _
            SearchOrder:=xlByRows, _
            SearchDirection:=xlNext, _
            MatchCase:=False)

            firstaddress = rng.Address

            Do
                j = 1
                drovedate = rng.Offset(0, j)
                j = j + 1
                drivenby = rng.Offset(0, j)
                j = j + 6
                reason = rng.Offset(0, j)
                x = x + 1
                Dim LineOfText As String

                CPHlsttheeba.AddItem "Test" & n, n
                CPHlsttheeba .List(n, 0) = drovedate
                CPHlsttheeba .List(n, 1) = drivenby
                CPHlsttheeba .List(n, 2) = reason

                n = n + 1

                Set rng = .FindNext(rng)
            Loop While Not rng Is Nothing And _
            rng.Address <> firstaddress
        Next i
    End With
End Sub
于 2012-09-25T17:49:15.680 回答
2

我认为悉达多的方法更好,但既然你问了......

而不是这个:

CPHlsttheeba.AddItem  x & "   " & drovedate & vbTab() & vbTab & _
                      drivenby & vbTab & vbTab & reason

你可以这样做:

CPHlsttheeba.AddItem RPad(x & "   " & drovedate, 20) & _
                     RPad(drivenby, 20) & reason




'pad a string "s" on the right with spaces to total length "num"
Function RPad(s, num)
    RPad = Left(s & String(num," "), num)
End Function

您可能需要根据字符串的长度调整填充量。如果您使用固定字体格式化列表框,那么您的“列”应该对齐。

于 2012-09-27T00:30:19.830 回答
0

我有类似的情况在 MsgBox 中创建一个表。我开始:

项目 1,选项卡,项目 2,选项卡,项目 3。

但有时第 1 项或第 2 项太长,需要 2 个标签才能将内容排好。立即窗口中的一些简单测试显示默认 vbTab 为 8 个字符宽。所以这是我在循环中所做的,然后 MsgBox 在循环后显示:

strMsg = strMsg & ary(1, m) & vbTab & IIf(Len(ary(1, m)) < 8, vbTab, "") & IIf(Len(ary(1, m)) < 16, vbTab, "") & ary(2, m) & vbTab & IIf(Len(ary(2, m)) < 8, vbTab, "") & ary(3, m) & vbCr

如果前一个结果的长度很小,这实际上会在结果之间放置 2 或 3 个制表符。

于 2013-05-01T02:28:49.090 回答