Excel PowerQuery:如何将大表取消透视或转置为可读格式以进行分析

时间:2018-11-09 01:32:05

标签: excel powerquery

我有这张看起来与此类似的表: enter image description here

我想对其进行转换,使其看起来像这样:

enter image description here

该想法是取消旋转(或转置)表格,以便可以将其输入其他BI工具中,并便于分析。

我大约有20张这样的桌子,上面有100多个列,因此当然几乎不可能手动进行。

如何使用PowerQuery完成此操作?我尝试使用unpivot功能,但由于显示NYC1,NYC2等而卡住了。VBA,宏也无法正常工作。任何其他建议,我们将不胜感激,但我现在不知所措。救命!

2 个答案:

答案 0 :(得分:3)

在加载到PowerQuery中之前,请使用定界符(空格)将标题连接到[程序名称]后的空白行。如果使用office365,则可以使用TEXTJOIN函数执行此操作。结果看起来像这样(我没有复制所有数据):

enter image description here

将此范围导入PowerQuery并执行以下步骤(请勿选中my table has headers复选框)

  1. 删除前2行(“主页”标签>“删除行”)
  2. 将第一行用作标题(“主页”标签>“将第一行用作标题”)
  3. 选择第一列
  4. 取消透视其他列(“转换”选项卡上的下拉菜单取消透视列)
  5. 用定界符(空格)分隔[属性]列(“主页”标签>“分隔列”)
  6. 更改列名
  7. 将城市列移动到左侧(右键单击列>移动>左边)

脚本如下:

let
    Source = Excel.CurrentWorkbook(){[Name="table"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}, {"Column2", type any}, {"Column3", type any}, {"Column4", type any}, {"Column5", type any}, {"Column6", type any}, {"Column7", type any}, {"Column8", type any}, {"Column9", type any}}),
    #"Removed Top Rows" = Table.Skip(#"Changed Type",2),
    #"Promoted Headers" = Table.PromoteHeaders(#"Removed Top Rows", [PromoteAllScalars=true]),
    #"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",{{"Program Name", type text}, {"NY Budget", Int64.Type}, {"NY Revenue", Int64.Type}, {"NY Cost", Int64.Type}, {"NY Margin", Int64.Type}, {"LA Budget", Int64.Type}, {"LA Revenue", Int64.Type}, {"LA Cost", Int64.Type}, {"LA Margin", Int64.Type}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Program Name"}, "Attribute", "Value"),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Unpivoted Other Columns", "Attribute", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"Attribute.1", "Attribute.2"}),
    #"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Attribute.1", type text}, {"Attribute.2", type text}}),
    #"Renamed Columns" = Table.RenameColumns(#"Changed Type2",{{"Attribute.1", "City"}, {"Attribute.2", "Description"}}),
    #"Reordered Columns" = Table.ReorderColumns(#"Renamed Columns",{"City", "Program Name", "Description", "Value"})
in
    #"Reordered Columns"

这是结果(在Power Query编辑器中)

enter image description here

答案 1 :(得分:1)

这是一种非常通用的depivot方法,可以处理多个行/列标题。

在运行之前在源表中选择一个单元格(注意-这使用CurrentRegion,因此如果表中的行或列完全为空白,则会失败。)

Sub UnpivotIt()

    Dim numRowHeaders As Long, numColHeaders As Long
    Dim numRows As Long, numCols As Long, rng As Range
    Dim rngOut As Range, r As Long, c As Long, i As Long, n As Long
    Dim arrIn, arrOut, outRow As Long

    arrIn = Selection.CurrentRegion.Value

    numRowHeaders = Application.InputBox("How many header rows?", Type:=1)
    numColHeaders = Application.InputBox("How many header columns?", Type:=1)
    Set rngOut = Application.InputBox("Select output (top-left cell)", Type:=8)

    Set rngOut = rngOut.Cells(1) 'in case >1 cells selected

    numRows = UBound(arrIn, 1)
    numCols = UBound(arrIn, 2)

    ReDim arrOut(1 To ((numRows - numRowHeaders) * (numCols - numColHeaders)), _
                 1 To (numRowHeaders + numColHeaders + 1))

    outRow = 0
    For r = (numRowHeaders + 1) To numRows
    For c = (numColHeaders + 1) To numCols
        'only copy if there's a value
        If Len(arrIn(r, c)) > 0 Then
            outRow = outRow + 1
            i = 1
            For n = 1 To numColHeaders 'copy column headers
                arrOut(outRow, i) = arrIn(r, n)
                i = i + 1
            Next n
            For n = 1 To numRowHeaders '...row headers
                arrOut(outRow, i) = arrIn(n, c)
                i = i + 1
            Next n
            arrOut(outRow, i) = arrIn(r, c) '...and the value
        End If
    Next c
    Next r

    rngOut.Resize(outRow, UBound(arrOut, 2)).Value = arrOut

End Sub