Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 根据字符串的当前长度向字符串追加可变数量的字符_String_Vba_Excel_Textbox - Fatal编程技术网

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

String 根据字符串的当前长度向字符串追加可变数量的字符,string,vba,excel,textbox,String,Vba,Excel,Textbox,我有一个姓名、日期和标题的列表,我正试图将其输出到文本框中。我希望输出的格式具有以下“列”: 姓名|日期|头衔|索引号 因为这只是一个文本框,所以我必须使用tabs[chr(9)]来保持这个表中“列”的间距。然而,由于人们有不同长度的名称,我需要能够输入不同数量的选项卡,以便每个“列”正确排列。(问题仅在名称和日期之间,其他“列”的间距正确) 我试过下面的代码,它假设(很可能是错误的)tab=7个空格(我试过其他数字)。它尝试将日期与初始日期标题对齐,该标题从左边缘起有4个选项卡。作为注释,为了

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

姓名|日期|头衔|索引号

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

我试过下面的代码,它假设(很可能是错误的)tab=7个空格(我试过其他数字)。它尝试将日期与初始日期标题对齐,该标题从左边缘起有4个选项卡。作为注释,为了简单起见,我将文本框和名称的复杂路径替换为括号内的[Text Box]和[Name]。以下内容在循环中运行:

[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]]
[文本框].Text=“Name”&Chr(9)&Chr(9)&Chr(9)&Chr(9)&Date”&Chr(9)&Reason&Chr(9)&Index#&Chr(10)
[[开始循环]]
[文本框].Text=[文本框].Text&[名称]
如果Len([Name])>=0且Len([Name])<7,则
[文本框].Text=[文本框].Text&Chr(9)&Chr(9)&Chr(9)&Chr(9)&Chr(9)
ElseIf Len([Name])>=7,Len([Name])<14
[文本框].Text=[文本框].Text&Chr(9)&Chr(9)&Chr(9)
ElseIf Len([Name])>=14,Len([Name])<21
[文本框].Text=[文本框].Text&Chr(9)&Chr(9)
ElseIf Len([Name])>=21,Len([Name])<28
[文本框].Text=[文本框].Text和Chr(9)
如果结束
注意:我发现如果名称是7的精确倍数,则一个标签太短,因此我添加了:
如果Len([Name])=7或Len([Name])=14或Len([Name])=21,则
[文本框].Text=[文本框].Text和Chr(9)
如果结束
[[结束循环]]
文本框中的100+行中的大多数都已正确排列,但似乎有些len=14的名称(并非全部)有一个额外的选项卡。当我删除为7的倍数添加额外制表符的代码时,len=14的一些(不是全部)名称没有足够的制表符


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

如果您这样做纯粹是为了视觉对齐,而不需要能够将内容复制粘贴到excel或其他东西(如CSV等),那么您所做的几乎是对的

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

除非您使用固定宽度字体,否则它可能会稍微有点困难,因为它可能使用宽度而不是字符数来确定选项卡的移动方式。(对此不是100%确定)

更新

我曾尝试过制作一些东西,将工作表转换为一个空格对齐的字符串,它可能会满足您的需要:)


您可以在文本框中使用固定宽度的字体,如Courier(如@NickSlash所建议的),只需填充空格,而不必使用制表符。更容易设置,但固定宽度字体通常不是很好看…请重新阅读您的问题,“有其他方法吗?”是的!您可以使用列表框,因为它们支持列。我决定只使用fixed with字体,并或多或少使用我上面的代码。如果我将来遇到问题,@NickSlash的答案将是解决方案。
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