简体   繁体   English

Excel 2010 VBA - 按逗号拆分字符串,跳过空白结果

[英]Excel 2010 VBA - Split String by Comma, Skip Blank Results

I am using the following code to chop up a column of comma-separated lists and to return each entry in a new row:我正在使用以下代码来分割一列以逗号分隔的列表并在新行中返回每个条目:

Sub SliceNDice()
    '
    ' Splits the locations cells according to commas and pushes to new rows
    ' Code courtesy of brettdj (http://stackoverflow.com/questions/8560718/split-comma-separated-entries-to-new-rows)
    '
    Dim objRegex As Object
    Dim x
    Dim Y
    Dim lngRow As Long
    Dim lngCnt As Long
    Dim tempArr() As String
    Dim strArr
    Set objRegex = CreateObject("vbscript.regexp")

    objRegex.Pattern = "^\s+(.+?)$"
     'Define the range to be analysed
    x = Range([a1], Cells(Rows.Count, "c").End(xlUp)).Value2
    ReDim Y(1 To 3, 1 To 1000)
    For lngRow = 1 To UBound(x, 1)
         'Split each string by ","
        tempArr = Split(x(lngRow, 3), ",")
        For Each strArr In tempArr
            lngCnt = lngCnt + 1
             'Add another 1000 records to resorted array every 1000 records
            If lngCnt Mod 1000 = 0 Then ReDim Preserve Y(1 To 3, 1 To lngCnt + 1000)
            Y(1, lngCnt) = x(lngRow, 1)
            Y(2, lngCnt) = x(lngRow, 2)
            Y(3, lngCnt) = objRegex.Replace(strArr, "$1")
        Next
    Next lngRow
     'Dump the re-ordered range to columns E:G
    [e1].Resize(lngCnt, 3).Value2 = Application.Transpose(Y)

End Sub

While this code works perfectly, it has a fatal flaw in that any double-commas in the cells of column C will result in blank cells pushed to the new rows in column G.虽然这段代码运行良好,但它有一个致命的缺陷,即 C 列单元格中的任何双逗号都会导致空白单元格被推送到 G 列的新行。

Does anyone know how to edit the code so that it does not create new rows with empty cells in column G, but skips them and enters the next rows in their places as if the superfluous commas were never included in column C at all?有谁知道如何编辑代码,以便它不会在 G 列中创建带有空单元格的新行,而是跳过它们并在它们的位置输入下一行,就好像多余的逗号从未包含在 C 列中一样?

Just test for the string length of strArr as the first operation inside the For Each strArr In tempArr loop.只需测试 strArr 的字符串长度作为 For Each strArr In tempArr 循环中的第一个操作。

For Each strArr In tempArr
    If CBool(Len(strArr)) Then
        lngCnt = lngCnt + 1
         'Add another 1000 records to resorted array every 1000 records
        If lngCnt Mod 1000 = 0 Then ReDim Preserve Y(1 To 3, 1 To lngCnt + 1000)
        Y(1, lngCnt) = x(lngRow, 1)
        Y(2, lngCnt) = x(lngRow, 2)
        Y(3, lngCnt) = objRegex.Replace(strArr, "$1")
    End If
Next strArr

You could loop on the occurence of double comma to clean up the input as opposed to fixing the output, here is a working example:您可以循环出现双逗号来清理输入而不是修复输出,这是一个工作示例:

Text in A1: Hello,,World,This,,Is,,,,,,,A,,Test A1 中的文本: Hello,,World,This,,Is,,,,,,,A,,Test

Sub TestString()
Dim MyString As String
MyString = Range("A1").Text
Do Until Len(MyString) = Len(Replace(MyString, ",,", ","))
    MyString = Replace(MyString, ",,", ",")
Loop
MsgBox MyString
End Sub

You would do this just before splitting你会在分裂之前这样做

If you want it as a function (would be better in your case) do this:如果您希望将其作为函数(在您的情况下会更好),请执行以下操作:

Function FixDoubleComma(MyString As String)
Do Until Len(MyString) = Len(Replace(MyString, ",,", ","))
    MyString = Replace(MyString, ",,", ",")
Loop
FixDoubleComma = MyString
End Function

Then replace this in your code:然后在您的代码中替换它:

tempArr = Split(x(lngRow, 3), ",")

With this:有了这个:

tempArr = Split(FixDoubleComma(x(lngRow, 3)), ",")

I have a little sample that solves blanks everywhere我有一个小样本可以解决任何地方的空白

Sub RemoveBlanks()
    Dim mystr As String
    Dim arrWithBlanks() As String
    Dim arrNoBlanks() As String
    Dim i As Integer
    mystr = ",tom,jerry, ,,spike,," 'Blanks everywhere (beginning, middle and end)
    arrWithBlanks = Split(mystr, ",")
    ReDim arrNoBlanks(0 To 0)
    Debug.Print "Array with blanks:"
    'Loop through the array with blanks
    For i = LBound(arrWithBlanks) To UBound(arrWithBlanks)
        'Check if there is a blank (or element with spaces only)
        If Trim(arrWithBlanks(i)) = "" Then
            Debug.Print i & " (blank)"
        Else
            Debug.Print i & " " & arrWithBlanks(i)
            If arrNoBlanks(UBound(arrNoBlanks)) <> "" Then ReDim Preserve arrNoBlanks(0 To UBound(arrNoBlanks) + 1)
            arrNoBlanks(UBound(arrNoBlanks)) = arrWithBlanks(i)
        End If
    Next i
    Debug.Print "Array with NO blanks:"
    For i = LBound(arrNoBlanks) To UBound(arrNoBlanks)
        Debug.Print i & " " & arrNoBlanks(i)
    Next i
End Sub

Everything will be displayed in the immediate window (Press Ctrl + G to show it)所有内容都将显示在即时窗口中(按Ctrl + G显示)

The result will look like this:结果将如下所示:

Array with blanks:  
0 (blank)
1 tom
2 jerry
3 (blank)
4 (blank)
5 spike
6 (blank)
7 (blank)
Array with NO blanks:
0 tom
1 jerry
2 spike

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM