分离数据并放入单独的工作表Excel VBA

时间:2012-08-11 11:09:30

标签: excel excel-vba worksheet-function vba

我有一个包含以下格式超过80K条目的大型数据集:

        Name                        Date           Value
        1T17_4H19_3T19_3T21_2_a_2   09-Aug-11   -9.3159
        1T17_4H19_3T19_3T21_2_a_2   10-Aug-11   -6.9662
        1T17_4H19_3T19_3T21_2_a_2   11-Aug-11   -3.4886
        1T17_4H19_3T19_3T21_2_a_2   12-Aug-11   -1.2357
        1T17_4H19_3T19_3T21_2_a_2   15-Aug-11   0.1172
        5 25_4Q27_4T30_4H34_3_3_3   19-Jun-12   -2.0805
        5 25_4Q27_4T30_4H34_3_3_3   20-Jun-12   -1.9802
        5 25_4Q27_4T30_4H34_3_3_3   21-Jun-12   -2.8344
        5 25_4Q27_4T30_4Q32_a_a_a   25-Sep-07   -0.5779
        5 25_4Q27_4T30_4Q32_a_a_a   26-Sep-07   -0.8214
        5 25_4Q27_4T30_4Q32_a_a_a   27-Sep-07   -1.4061

此数据全部包含在单个工作表中。我希望excel根据名称分隔数据,然后将每个时间序列放在同一工作簿中的单独工作表中。这可能与VBA有关吗?

2 个答案:

答案 0 :(得分:3)

如果要录制宏以查看发生的情况,请按以下步骤操作:

  1. 打开宏录制器
  2. 按名称排序数据
  3. 复制名字
  4. 中的数据
  5. 将其粘贴到另一张纸上(如果您需要另一张纸,请添加一张纸)
  6. 命名表
  7. 重复下一个名字
  8. 我还编写了一些可用于入门的代码。为此,您需要将数据选项卡命名为“MasterList”。代码按名称对MasterList上的行进行排序,然后对于列表中的每个唯一名称,创建一个新工作表并将相应的数据复制到新工作表,重复该过程,直到所有名称都已复制到新工作表。

    将此代码添加到模块并运行DispatchTimeSeriesToSheets过程。

    Sub DispatchTimeSeriesToSheets()
        Dim ws As Worksheet
        Set ws = Sheets("MasterList")
        Dim LastRow As Long
    
        LastRow = Range("A" & ws.Rows.Count).End(xlUp).Row
    
        ' stop processing if we don't have any data
        If LastRow < 2 Then Exit Sub
    
        Application.ScreenUpdating = False
        SortMasterList LastRow, ws
        CopyDataToSheets LastRow, ws
        ws.Select
        Application.ScreenUpdating = True
    End Sub
    
    Sub SortMasterList(LastRow As Long, ws As Worksheet)
        ws.Range("A2:C" & LastRow).Sort Key1:=ws.Range("A1"), Key2:=ws.Range("B1")
    End Sub
    
    Sub CopyDataToSheets(LastRow As Long, src As Worksheet)
        Dim rng As Range
        Dim cell As Range
        Dim Series As String
        Dim SeriesStart As Long
        Dim SeriesLast As Long
    
        Set rng = Range("A2:A" & LastRow)
        SeriesStart = 2
        Series = Range("A" & SeriesStart).Value
        For Each cell In rng
            If cell.Value <> Series Then
                SeriesLast = cell.Row - 1
                CopySeriesToNewSheet src, SeriesStart, SeriesLast, Series
                Series = cell.Value
                SeriesStart = cell.Row
            End If
        Next
        ' copy the last series
        SeriesLast = LastRow
        CopySeriesToNewSheet src, SeriesStart, SeriesLast, Series
    
    End Sub
    
    Sub CopySeriesToNewSheet(src As Worksheet, Start As Long, Last As Long, _
                                                            name As String)
        Dim tgt As Worksheet
    
        If (SheetExists(name)) Then
            MsgBox "Sheet " & name & " already exists. " _
            & "Please delete or move existing sheets before" _
            & " copying data from the Master List.", vbCritical, _
            "Time Series Parser"
            End
        End If
    
        Worksheets.Add(After:=Worksheets(Worksheets.Count)).name = name
        Set tgt = Sheets(name)
    
        ' copy header row from src to tgt
        tgt.Range("A1:C1").Value = src.Range("A1:C1").Value
    
        ' copy data from src to tgt
        tgt.Range("A2:C" & Last - Start + 2).Value = _
            src.Range("A" & Start & ":C" & Last).Value
    End Sub
    
    Function SheetExists(name As String) As Boolean
        Dim ws As Worksheet
    
        SheetExists = True
        On Error Resume Next
        Set ws = Sheets(name)
        If ws Is Nothing Then
           SheetExists = False
        End If
    End Function
    

答案 1 :(得分:2)

我尝试了这个代码,它对我有用。

这将拆分数据(基于唯一名称)并将其粘贴到一个单独的工作表中,该工作表的名称与A列中的名称相同。

Sub SplitData()
    Dim DataMarkers(), Names As Range, name As Range, n As Long, i As Long

    Set Names = Range("A2:A" & Range("A1").End(xlDown).Row)
    n = 0

    DeleteWorksheets

    For Each name In Names
        If name.Offset(1, 0) <> name Then
            ReDim Preserve DataMarkers(n)
            DataMarkers(n) = name.Row
            Worksheets.Add(After:=Worksheets(Worksheets.Count)).name = name
            n = n + 1
        End If
    Next name

    For i = 0 To UBound(DataMarkers)
        If i = 0 Then
            Worksheets(1).Range("A2:C" & DataMarkers(i)).Copy Destination:=Worksheets(i + 2).Range("A1")
        Else
            Worksheets(1).Range("A" & (DataMarkers(i - 1) + 1) & ":C" & DataMarkers(i)).Copy Destination:=Worksheets(i + 2).Range("A1")
        End If
    Next i
End Sub

Sub DeleteWorksheets()
    Dim ws As Worksheet, activeShtIndex As Long, i As Long

    activeShtIndex = ActiveSheet.Index

    Application.DisplayAlerts = False
    For i = ThisWorkbook.Worksheets.Count To 1 Step -1
        If i <> activeShtIndex Then
            Worksheets(i).Delete
        End If
    Next i
    Application.DisplayAlerts = True
End Sub

我在这段代码中所做的是:

  1. 删除除初始数据表
  2. 之外的所有工作表
  3. 处理“名称”列并创建一个“标记”数组,指示每个数据拆分的位置
  4. 创建一个新工作表,并根据数组中的值
  5. 将数据复制到该工作表