根据字符串的当前长度向字符串附加可变数量的字符

时间:2013-04-12 00:12:00

标签: string excel vba excel-vba textbox

我有一个名单,日期和标题列表,我试图输出到文本框。我希望输出的格式具有以下“列”:

姓名|日期|标题|索引号

由于这只是一个文本框,我必须使用制表符[chr(9)]来维护此表的“列”的间距。但是,由于人们有不同的长度名称,我需要能够输入不同数量的选项卡,以便每个“列”正确排列。 (问题仅在名称和日期之间,其他“列”正确间隔)

我已经尝试了以下代码,它假设(非常可能不正确)tab = 7个空格(我已尝试过其他数字)。它会尝试使用初始日期标题标题排列日期,该标题是左边缘的4个标签。作为我的符号的注释,为简单起见,我用括号内的[文本框]和[名称]替换了文本框和名称的复杂路径。以下运行循环:

[Text Box].Text = "Name" & Chr(9) & Chr(9) & Chr(9) & Chr(9) & "Date" & Chr(9) & "Reason" & Chr(9) & "Index#" & Chr(10)

[[Begin Loop]]

[Text Box].Text = [Text Box].Text & [Name]

If Len([Name]) >= 0 And Len([Name]) < 7 Then
    [Text Box].Text = [Text Box].Text & Chr(9) & Chr(9) & Chr(9) & Chr(9)
ElseIf Len([Name])>= 7 And Len([Name]) < 14 Then
    [Text Box].Text = [Text Box].Text & Chr(9) & Chr(9) & Chr(9)
ElseIf Len([Name]) >= 14 And Len([Name]) < 21 Then
    [Text Box].Text = [Text Box].Text & Chr(9) & Chr(9)
ElseIf Len([Name]) >= 21 And Len([Name]) < 28 Then
    [Text Box].Text = [Text Box].Text & Chr(9)
End If

NOTE: I found that names that were an exact multiple of 7 were one tab too short, thus I added:

If Len([Name]) = 7 Or Len([Name]) = 14 Or Len([Name]) = 21 Then
    [Text Box].Text = [Text Box].Text & Chr(9)
End If

[[End Loop]]

文本框中的100多行中的大多数都正确排列,但似乎有一些名称(并非所有)具有len = 14的名称都有一个额外的标签。当我删除为7的倍数添加额外选项卡的代码时,len = 14的某些(不是全部)名称没有足够的选项卡。

有没有人有解决方案?或者我可以用另一种方式表示这些数据(即不是文本框)?

1 个答案:

答案 0 :(得分:1)

如果你纯粹是为了视觉对齐,并且不需要能够将内容复制+粘贴到excel或其他东西(如CSV等),那么你所做的几乎是正确的。

您将需要执行两次传递,第一次传递确定每个列的最大长度,第二次传递使用第一次传递的信息将其写出以使对齐正确。

除非您使用固定宽度的字体,否则它可能会稍微具有挑战性,因为它可能会使用宽度而不是字符数来确定标签的移动方式。 (不是100%肯定这个)

<强>更新

我开始制作一些可以将工作表转换为空格对齐字符串的东西,可以做你想做的事情。)

Const TABSIZE = 3

Public Function Main2(Optional ByVal SheetName As String = "Sheet1") As String
Dim Sheet As Worksheet: Set Sheet = ThisWorkbook.Worksheets(SheetName)
Dim Data As Variant
Dim Index, Row, Column As Long
Dim Max() As Integer
Data = Sheet.UsedRange.Value2
ReDim Max(LBound(Data, 2) To UBound(Data, 2))
' configure the Max() array with default values
For Index = LBound(Max) To UBound(Max)
    Max(Index) = 0
Next Index
' populate the Max() array with the maximum width
For Index = LBound(Data, 1) To UBound(Data, 1)
    For Column = LBound(Data, 2) To UBound(Data, 2)
        If Len(Data(Index, Column)) > Max(Column) Then
            Max(Column) = Len(Data(Index, Column))
        End If
    Next Column
Next Index
' add the tabsize to the max (add a gap between columns)
' note: the loop below is not required, has been rolled into the output loop
'For Index = LBound(Max) To UBound(Max)
'    Max(Index) = Max(Index) + TABSIZE
'Next Index
' output the data!
For Row = LBound(Data, 1) To UBound(Data, 1)
    For Column = LBound(Data, 2) To UBound(Data, 2)
        'Result = Result & Pad(Data(Row, Column), Max(Column))
        Result = Result & Pad(Data(Row, Column), Max(Column) + TABSIZE)
    Next Column
    Result = Result & vbCrLf
Next Row
' return it
Main2 = Result
End Function

' pad text to length with spaces
Public Function Pad(ByVal Text As String, ByVal Length As Long) As String
Pad = Text & Space(Length - Len(Text))
End Function