3

次の形式の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

このデータはすべて1つのワークシートに含まれています。名前に従ってデータを分離し、各時系列を同じワークブックの別々のワークシートに配置することに優れていることを望みます。これはVBAで可能ですか?

4

2 に答える 2

3

マクロを記録して何が起こるかを確認する場合は、次の手順に従います。

  1. マクロレコーダーの電源を入れます
  2. データを名前で並べ替える
  3. 名からデータをコピーします
  4. 別のシートに貼り付けます(別のシートが必要な場合はシートを追加します)
  5. シートに名前を付ける
  6. 次の名前について繰り返します

また、開始に使用できるコードもいくつか作成しました。これを機能させるには、データタブに「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
于 2012-08-12T05:11:40.243 に答える
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. 新しいワークシートを作成し、配列の値に基づいてデータをコピーします
于 2012-08-12T08:22:31.863 に答える