拆分细胞并推送到可以使用空白细胞的行

时间:2015-04-04 05:58:05

标签: excel vba for-loop with-statement delimited-text

我有一个Excel文件,其中存储了与客户端的会话描述,每个会话一行。在一列中,我有一个以逗号分隔的列表,其中包含该会话期间发生的所有活动。我一直在使用以下代码,它可以很好地用逗号分割活动列表,将每个活动推送到另一个工作表中的新行,并从该行中提取所有其他信息:

Sub SplitFoci()
    Dim Temp As Variant
    Dim CText As String
    Dim J As Integer
    Dim K As Integer
    Dim L As Integer
    Dim iColumn As Integer
    Dim lNumCols As Long
    Dim lNumRows As Long

    Set wksSource = Worksheets("OutputWorkingCopy1")
    Set wksOutput = Worksheets("OutputSplitFoci")

    iColumn = 9
    iTargetRow = 0
    With wksSource
        lNumCols = .Range("IV1").End(xlToLeft).column
        lNumRows = .Range("A65536").End(xlUp).Row
        For J = 3 To lNumRows
            CText = .Cells(J, iColumn).Value
            Temp = Split(CText, ",")
            For K = 0 To UBound(Temp)
                iTargetRow = iTargetRow + 1
                For L = 1 To 40
                    If L <> iColumn Then
                        wksOutput.Cells(iTargetRow, L) _
                          = .Cells(J, L)
                    Else
                        wksOutput.Cells(iTargetRow, L) _
                          = Temp(K)
                    End If
                Next L
            Next K
        Next J
    End With

End Sub

不幸的是,如果它到达活动列中具有空白单元格的行(即没有任何活动的管理任务),它将停止通过列表,既不会推送管理会话信息也不会推送任何后续的客户端会话。有谁知道如何编辑此代码以允许它推送所有信息而不是停止?

1 个答案:

答案 0 :(得分:0)

如果.Cells(J, iColumn).Value的活动以逗号分隔,则代码在分割时效果很好,并且分割的值通过枚举。

如果.Cells(J, iColumn).Value只有一个活动(没有逗号),则代码有效,因为Split会生成一个活动条目;例如LBound(Temp)UBound(Temp)都为零,因此只有一次通过For ... Next循环。

如果.Cells(J, iColumn).Value是一个空白单元格(例如IsEmpty(.Cells(J, iColumn) = True),则代码停止工作,因为Split会导致LBound(Temp)为零且UBound(Temp)为-1,For ... Next循环甚至不能进行单次传递。

一种方法是使用占位符填充Temp,如果UBound(Temp)&lt; LBound(Temp)有类似的东西,

    CText = .Cells(J, iColumn).Value
    Temp = Split(CText, ",")
    if ubound(Temp) < lbound(Temp) then Temp = Split("<non-activity>", ",")

这与存在单个活动的情况相同。另一种方法是确保至少有一个传递通过For ... Next循环,并在时机到来时覆盖缺少温度。

    For K = 0 To (UBound(Temp) - CBool(UBound(Temp) < LBound(Temp))) 'from 0 to 0 when UBound(Temp) < LBound(Temp)
        iTargetRow = iTargetRow + 1
        For L = 1 To 40
            If L <> iColumn Then
                wksOutput.Cells(iTargetRow, L) _
                  = .Cells(J, L)
            ElseIf Not CBool(UBound(Temp) < LBound(Temp)) Then
                wksOutput.Cells(iTargetRow, L) _
                  = Temp(K)
            End If
        Next L
    Next K

至少通过所有列进行一次传递。当没有活动时,将完全跳过第9列。

最后两个代码段中的一个应该修复你的循环。选择对你最有意义的那个。