【问题标题】:Any method equivalent to PadLeft/PadRight?任何等效于 PadLeft/PadRight 的方法?
【发布时间】:2012-08-17 02:56:18
【问题描述】:

只是想知道,VBA 中是否有与 VB .NET 的 PadLeft 和 PadRight 方法等效的方法?

到目前为止,每当我想获取一个字符串并将其设置为带有前导空格的固定长度时,我都会根据字符串的长度执行 For...Next 循环。

例如,我将使用以下代码将字符串格式化为 8 个字符并带有前导空格:

intOrdNoLen = Len(strOrdNo)
For i = 1 To (8 - intOrdNoLen) Step 1
    strOrdNo = " " & strOrdNo
Next

有没有办法在 VBA 中用更少的行来做同样的事情?

【问题讨论】:

    标签: string vba


    【解决方案1】:

    我对这个答案采取了不同的方法。它不是最简单的,但可能是最通用的。我使用了 LittleBobbyTables 和 Brad 的一些代码来制作这个。下面是几个如何使用该函数的例子:

    Sub test()
        Debug.Print PadStr("ABC", 6) 'returns "ABC   "
        Debug.Print PadStr("ABC", 6, "-") 'returns "ABC---"
        Debug.Print PadStr("ABC", 6, , xlHAlignRight) 'returns "   ABC"
        Debug.Print PadStr("ABC", 7, "*", xlHAlignCenter) 'returns "**ABC**"
        Debug.Print PadStr("ABC", 9, "*", xlHAlignDistributed) 'returns "**A**B*C*"
        Debug.Print PadStr("ABC", 7, "*", xlHAlignFill) 'returns "ABCABCA"
    End Sub
    

    函数如下:

    Function PadStr(Expression As Variant, length As Integer, Optional padChar As String = " ", Optional alignment As XlHAlign = xlHAlignGeneral) As String
    'Pads a string with a given character.
    '@Expression - the string to pad
    '@length - the minimum length of the string (if @Expression is longer than @length, the original Expression will be returned)
    '@padChar - the character to pad with (a space by default)
    '@alignment - what type of alignment to use. Uses the XlAlign object for enumeration.
    '   xlHAlignLeft            - (Default) Aligns input text to the left
    '   xlHAlignGeneral         - Same as Default
    '   xlHAlignRight           - Aligns input text to the right
    '   xlHAlignCenter          - Center aligns text
    '   xlHAlignCenterAcrossSelection       - Same as xlHAlignCenter
    '   xlHAlignDistributed     - Distributes the text evenly within the length specified
    '   xlHAlignJustify         - Same as xlHAlignDistributed
    '   xlHAlignFill            - Fills the specified length with the text
    'example: if input is "ABC", " ", "8", see code below for what the output will be given the different direction options
        If Len(Expression) >= length Or (padChar = "" And alignment <> xlHAlignFill) Then
            'if input is longer than pad-length padChar or no input given for padChar (note: padChar doesn't matter when
            'using xlHAlignFill) just return the input
            PadStr = Expression
        ElseIf Len(padChar) <> 1 And alignment <> xlHAlignFill Then
            'give error if padChar is not exactly 1 char in length (again, padChar doesn't matter when using xlHAlignFill)
            'padChar must be 1 char long because string() only accepts 1 char long input.
            Err.Raise vbObjectError + 513, , "input:'padChar' must have length 1." & vbNewLine & "SUB:PadStr"
        Else
            Dim pStr As String, i As Long
            Select Case alignment
                Case xlHAlignLeft, xlHAlignGeneral '(Default)
                    '"ABC     "
                    PadStr = CStr(Expression) & String(length - Len(CStr(Expression)), padChar)
                Case xlHAlignRight
                    '"     ABC"
                    PadStr = String(length - Len(CStr(Expression)), padChar) & CStr(Expression)
                Case xlHAlignCenter, xlHAlignCenterAcrossSelection
                    '"   ABC  "
                    pStr = String(Application.WorksheetFunction.RoundUp((length / 2) - (Len(Expression) / 2), 0), padChar)
                    PadStr = pStr & Expression & pStr
                Case xlHAlignDistributed, xlHAlignJustify
                    '"  A B C "       ("  A  B C " if lenth=9)
                    Dim insPos As Long, loopCntr As Long: loopCntr = 1
                    PadStr = Expression
                    Do While Len(PadStr) < length
                        For i = 1 To Len(Expression)
                            PadStr = Left(PadStr, insPos) & padChar & Right(PadStr, Len(PadStr) - insPos)
                            insPos = insPos + 1 + loopCntr
                            If Len(PadStr) >= length Then Exit For
                        Next i
                        PadStr = PadStr & padChar
                        loopCntr = loopCntr + 1
                        insPos = 0
                    Loop
                Case xlHAlignFill
                    '"ABCABCAB"
                    For i = 1 To Application.WorksheetFunction.RoundUp(length / Len(Expression), 0)
                        PadStr = PadStr & Expression
                    Next i
                Case Else
                    'error
                    Err.Raise vbObjectError + 513, , "PadStr does not support the direction input ( " & direction & ")." & vbNewLine & "SUB:PadStr"
            End Select
            PadStr = Left(PadStr, length) 'output cannot be longer than the given length
        End If
    End Function
    

    【讨论】:

      【解决方案2】:

      合并前两个答案(感谢 LittleBobbyTablesBrad)并注意辅助函数 ma​​x,我建议:

      Function PadLeft(ByVal text As Variant, ByVal totalLength As Integer, ByVal padCharacter As String) As String
          PadLeft = Right(String(totalLength, padCharacter) & CStr(text), max(totalLength, Len(CStr(text))))
      End Function
      
      Function PadRight(ByVal text As Variant, ByVal totalLength As Integer, ByVal padCharacter As String) As String
          PadRight = Left(CStr(text) & String(totalLength, padCharacter), max(totalLength, Len(CStr(text))))
      End Function
      
      Public Function max(ByVal x As Variant, ByVal y As Variant) As Variant
        max = IIf(x > y, x, y)
      End Function
      

      totalLength 最好命名为 minimumLength,因为总是返回整个原始字符串,可能导致结果比 minimumLength 长。

      【讨论】:

      • 站在“gaints”的肩膀上,这可能是最稳健的解决方案。也可以使用Excel.WorksheetFunction.Max,尽管这会使解决方案不再是纯 VBA/VB Classic。
      【解决方案3】:

      我通过重新分配变量解决了这个问题。
      在我的代码中,我从工作簿单元格获取数据并将其限制为 5 个字符(如有必要,填充足够的 0..):

      MB = Right(String(5, "0") & Worksheets("HOME").Range("b3"), 5)
      MB = Right(MB, 5)
      

      【讨论】:

        【解决方案4】:
        Format("abc","!@@@@@@") ' width >= 6; pad right side with spaces
        Format("abc","@@@@@@") ' width >= 6; pad left side with spaces
        

        【讨论】:

        • 很好很简单。但是对于非常大量的数据,它比 LEFT/RIGHT 方法慢 2-3 倍
        【解决方案5】:

        你可以使用这些。将它们放在公共模块中

        'NB 如果输入字符串长于总长度则失​​败

        Function PadLeft(text As Variant, totalLength As Integer, padCharacter As String) As String
            PadLeft = String(totalLength - Len(CStr(text)), padCharacter) & CStr(text)
        End Function
        
        Function PadRight(text As Variant, totalLength As Integer, padCharacter As String) As String
            PadRight = CStr(text) & String(totalLength - Len(CStr(text)), padCharacter)
        End Function
        

        【讨论】:

        • 您可以在函数中添加一个检查以查看提供的字符串是否比输入长度长并相应地处理它。
        【解决方案6】:

        您还可以在 VBA 中使用固定长度的字符串:

        Dim myString As String * 10
            myString = "test"
            Debug.Print myString, "(" & Len(myString) & ")" '// Prints "test          (10)"
        

        虽然这只对右边的填充有用。

        【讨论】:

        • 这恰好对于在 Excel 中填充数据以将 > 255 长的字符串加载到 SQL Server 中非常有用。感谢您的提示!
        • 如果你使用了两次StrReverse,你可以使用本文中描述的方法进行左填充。
        【解决方案7】:

        由于我们一般在左侧填充,所以 Format() 函数更短,更简单:

        Format(number, "    ")
        
        Format(number, "00")
        

        【讨论】:

        • 不起作用。试试? "!" &amp; Format("a"," ") &amp; "!",你会得到!a!,并带有一个数字:? "!" &amp; Format(1.23," ") &amp; "!" 给出! !
        • 格式化用空格填充的字符串时,请改用“@”格式字符占位符。见:Format Function (VBA)
        【解决方案8】:

        我不相信有任何明确的PADLEFTPADRIGHT 函数,但您可以使用SPACELEFTRIGHT 的组合在您的字符串前面添加空格,然后获取右 X 个字符。

        PADLEFT

        strOrdNo = RIGHT(Space(8) & strOrdNo, 8)
        

        如果你想要一个字符而不是空格,你可以使用STRING 来代替空格(下面的例子左-pads 与 X):

        strOrdNo = RIGHT(String(8, "X") & strOrdNo, 8)
        

        PADRIGHT

        strOrdNo = LEFT(strOrdNo & Space(8), 8)
        
        strOrdNo = LEFT(strOrdNo & String(8, "X"), 8)
        

        【讨论】:

        • 哇哦,我已经知道该怎么做了。我想是漫长的一天工作。绝对是我的首选方法。
        • 根据此处msdn.microsoft.com/en-us/library/92h5dc07(v=vs.110).aspx 对 PadLeft 的描述,此代码与 PADLEFT 的行为不匹配,因为示例:str.PadLeft(2, "forty-two") 将返回 "fo" “四十二”。这不会发生在原始代码中。
        • 我编辑并使用了 PADLEFT。最后一个参数应该是 16 而不是 8
        猜你喜欢
        • 2016-07-05
        • 2010-10-07
        • 1970-01-01
        • 2015-09-08
        • 1970-01-01
        • 2010-11-11
        • 2012-01-14
        • 1970-01-01
        • 2021-04-20
        相关资源
        最近更新 更多