当源数据包含作为日期的列标题时,如何构建合并透视表?

时间:2009-09-16 17:14:42

标签: excel pivot consolidation

我有一位客户正在使用Excel进行员工规划。他们为不同的项目提供了许多工作簿,每个项目包含一个或多个包含实际人员配置数据的工作表:

Sample staff planning sheet

客户希望将所有这些工作表和工作簿中的所有数据合并到一个数据透视表中。 “合并”枢轴不是一种选择,因为它们希望能够混淆源数据中的所有(非日期)字段。他们不希望仅限于'Row'和'Column'。我目前的解决方案是一个宏,它通过一个相当复杂的复制和旋转过程来整合工作簿中的所有数据。我首先复制一行“元数据”(所有不是日期的数据),然后将元数据行的日期复制/转置到单个“日期”列中。然后我扩展元数据,以便为每个日期定义相同的数据。

我有一个单独的工作簿,可以从每个工作簿中获取合并工作表,并从中构建一个数据透视表。

它有效,但效率很低,因为任务/作业总数达到数千。在我的梦中,我希望完全消除整合步骤,但我不认为这种情况正在发生。一种更有效的整合方法是我现在所希望的最好的方法。

如果有人有一些“开箱即用”的想法,我全都耳朵! 解决方案需要在Windows XP,Office 2002和2003上运行。

1 个答案:

答案 0 :(得分:0)

如果有人有兴趣,我终于找到了acceptable solution。它使用了数据透视表和TextToColumns函数的组合。一旦我采用了这种方法,将其转化为代码非常简单。下面的代码确实引用了我使用的一些Conveniance函数,例如'DeleteSheet'和'LastRowOn',但你明白了。

Sub Foo()
    Dim ws As Worksheet
    For Each ws In Worksheets
        If IsStaffingSheet(ws) Then
            ws.Select
            DeleteSheet ws.Name & " - Exploded"
            TransposeSheet ws
        End If
    Next ws

End Sub

Sub TransposeSheet(ByVal ParentSheet As Worksheet)
    Dim ws As Worksheet
    Dim r As Range
    Dim ref As Variant
    Dim pt As PivotTable

    Set r = Range("StaffingStartCell")
    Set r = Range(r, r.SpecialCells(xlLastCell))

    ref = Array("'" & ActiveSheet.Name _
                    & "'!" & r.Address(ReferenceStyle:=xlR1C1))

    Application.CutCopyMode = False
    ActiveWorkbook.PivotCaches.Add(SourceType:=xlConsolidation, _
                                   SourceData:=ref).CreatePivotTable TableDestination:="", _
        tableName:="PivotTable1", DefaultVersion:=xlPivotTableVersion10

    Set ws = ActiveSheet
    Set pt = ws.PivotTableWizard(TableDestination:=ActiveSheet.Cells(3, 1))
    pt.DataPivotField.PivotItems("Count of Value").Position = 1
    pt.PivotFields("Row").PivotItems("").Visible = False

    ExplodePivot ParentSheet
    Application.DisplayAlerts = False
    ws.Delete
    Application.DisplayAlerts = True

    Set ws = Nothing
End Sub


Sub ExplodePivot(ByVal ParentSheet As Worksheet)
    Dim lastRow As Long
    Dim lastCol As Long

    lastRow = LastRowOn(ActiveSheet.Name)
    lastCol = LastColumnBack(ActiveSheet, lastRow)

    Cells(lastRow, lastCol).ShowDetail = True

    Columns("B:C").Select
    Selection.Cut Destination:=Columns("S:T")

    Columns("A:A").Select
    Selection.TextToColumns Destination:=Range("A1"), _
                            DataType:=xlDelimited, _
                            Semicolon:=True
    Selection.ColumnWidth = 12
    ActiveSheet.Name = ParentSheet.Name & " - Exploded"
End Sub