根据一列的值将一个表拆分为多个较小的表-Power Query

时间:2018-11-24 01:28:22

标签: excel powerquery m

我有一个这样的表,该表是在Power查询中使用“ combine&edit”选项获得的,该表具有来自多个.xlsx文件的多个工作表中的信息。工作表名称永远不会更改,它们将保持不变,excel文件可以更改。

enter image description here

现在,我想用column1的值firstkey拆分许多表。因此,我可以得到多个这样的表,

enter image description here

我一直在谷歌搜索以找到答案,但仍然没有成功。有诸如this之类的线程,要求您复制原始表并过滤每个值。

但是,就我而言,如果我有新的.xlsx文件,我想以某种方式实现自动化。因此,如果我得到一个值Brooklyn Park而不是Bursville,则应根据Column1的值对其进行过滤。

如何执行此超级查询?

编辑

根据要求,一个文件的原始excel工作表,

enter image description here

M代码:

let
    Source = Excel_Export,
    #"Trimmed Text" = Table.TransformColumns(Source,{{"Column1", Text.Trim, type text}}),
    #"Cleaned Text" = Table.TransformColumns(#"Trimmed Text",{{"Column1", Text.Clean, type text}}),
    #"Filtered Rows" = Table.SelectRows(#"Cleaned Text", each ([Source.Name] = "Burnsville.xlsx")),
    #"Transposed Table" = Table.Transpose(#"Filtered Rows"),
    #"Removed Top Rows" = Table.Skip(#"Transposed Table",1),
    #"Promoted Headers" = Table.PromoteHeaders(#"Removed Top Rows", [PromoteAllScalars=true]),
    #"Renamed Columns" = Table.RenameColumns(#"Promoted Headers",{{"Address", "Address Number"}, {"Column3", "StreetName"}, {"Column4", "City"}})
in
    #"Renamed Columns"

我用这段代码创建了一个自动执行每个文件的功能。

2 个答案:

答案 0 :(得分:1)

您发布的M代码表明至少有3列,但是您的第一张图片仅显示了两列。它似乎还引用了另一个查询(Excel_Export)。我希望它能在第一张图中显示您如何获得表格,所以不太确定会发生什么。

关于插入空白行,您可以尝试下面的功能。

代码:

fxInsertBlankRows = (tableToTransform as table) =>
    let
        blankRowToInsert = 
            let
                headers = Table.ColumnNames(tableToTransform),
                emptyTable = Table.FromColumns(List.Transform(headers, each {""}), headers),
                toListOfRecords = Table.ToRecords(emptyTable)
            in
                toListOfRecords,
        insertionIndexes =
            let
                isolateColumn = Table.SelectColumns(tableToTransform, {"Column1"}),
                indexes = Table.PositionOf(isolateColumn, [Column1="firstKey"], Occurrence.All)
            in
                indexes,
        insertBlankRows = List.Accumulate(insertionIndexes, tableToTransform, (tableState, currentIndex) =>
                Table.InsertRows(tableState, currentIndex, blankRowToInsert)
            ) 
    in
        insertBlankRows,

假设您要在发布的#"Renamed Columns"代码的M步骤中使用上述功能(假设#"Renamed Columns"是一个表,我很确定是这样)。您将按照以下方式更改代码的结束方式:

#"Renamed Columns" = Table.RenameColumns(#"Promoted Headers",{{"Address", "Address Number"}, {"Column3", "StreetName"}, {"Column4", "City"}})
fxInsertBlankRows = (tableToTransform as table) =>
        let
            blankRowToInsert = 
                let
                    headers = Table.ColumnNames(tableToTransform),
                    emptyTable = Table.FromColumns(List.Transform(headers, each {""}), headers),
                    toListOfRecords = Table.ToRecords(emptyTable)
                in
                    toListOfRecords,
            insertionIndexes =
                let
                    isolateColumn = Table.SelectColumns(tableToTransform, {"Column1"}),
                    indexes = Table.PositionOf(isolateColumn, [Column1="firstKey"], Occurrence.All)
                in
                    indexes,
            insertBlankRows = List.Accumulate(insertionIndexes, tableToTransform, (tableState, currentIndex) =>
                    Table.InsertRows(tableState, currentIndex, blankRowToInsert)
                ) 
        in
            insertBlankRows,
invokeFunction = fxInsertBlankRows(#"Renamed Columns")
in
    invokeFunction

答案 1 :(得分:0)

似乎是一个有趣的挑战。这是一个独立的示例,我试图使其简洁:

let
    SourceTable = Table.FromRecords({
        [Cities = "City1", Info = "Info1"],[Cities = "City1", Info = "Info2"],
        [Cities = "City1", Info = "Info3"],[Cities = "City2", Info = "Info1"],
        [Cities = "City2", Info = "Info2"],[Cities = "City3", Info = "Info1"],
        [Cities = "City3", Info = "Info2"],[Cities = "City3", Info = "Info3"],
        [Cities = "City3", Info = "Info4"],[Cities = "City3", Info = "Info5"]
    }),

    SortedTable = Table.Sort(SourceTable,{{"Cities", Order.Ascending},{"Info", Order.Ascending}}),

    DistinctCities = List.Distinct(SortedTable[Cities]),

    DistinctCitiesAfterFirst = if List.Count(DistinctCities) > 1 then List.RemoveRange(DistinctCities,0) else {},

    CityOffsets = List.Transform(DistinctCitiesAfterFirst, each (List.PositionOf(SortedTable[Cities],_) + List.PositionOf(DistinctCitiesAfterFirst,_) - 1)),

    SortedTableWithBlankRows = List.Accumulate(
        CityOffsets,
        SortedTable,
        ((tableState, currentOffset) =>
            Table.InsertRows(
                tableState,
                currentOffset,
                {
                    Record.FromList(List.Repeat({""},Table.ColumnCount(SortedTable)),Table.ColumnNames(SortedTable))
                }
            )
        )
    )

in
    SortedTableWithBlankRows