这是一种方法:
假设
- 每个数据行中的位置条目实际上并不存在
- 所有列标题都在第一组中
- 每个组至少由一个空行分隔
- 每个组的列从第一列开始(但它们不必都具有相同的列数)
请阅读代码 cmets,并探索 Applied Steps 窗口,以了解算法
M 代码
已编辑以从最后一行删除硬编码的列名
let
Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
//add shifted column
shifted = Table.FromColumns(
Table.ToColumns(#"Changed Type") &
{{null} & List.RemoveLastN(#"Changed Type"[Column1])},
type table[Column1=text, shiftedCol1 =text]),
//create a column which adds an index number at the first row of each group
//then fill down to create a column on which to group
#"Added Index" = Table.AddIndexColumn(shifted, "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "grouper", each if [Column1] <> null and [shiftedCol1] = null then [Index] else null),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Index"}),
#"Filled Down" = Table.FillDown(#"Removed Columns",{"grouper"}),
#"Removed Columns1" = Table.RemoveColumns(#"Filled Down",{"shiftedCol1"}),
//remove the empty rows
#"Filtered Rows" = Table.SelectRows(#"Removed Columns1", each ([Column1] <> null)),
//group by the "grouper" column
//then transpose each sub table
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"grouper"}, {
{"transpose", each Table.Transpose(Table.SelectColumns(_,"Column1"))}
}),
#"Removed Columns2" = Table.RemoveColumns(#"Grouped Rows",{"grouper"}),
//combine the grouped subtables, and promote the headers
comb = Table.Combine(#"Removed Columns2"[transpose]),
#"Promoted Headers" = Table.PromoteHeaders(comb, [PromoteAllScalars=true]),
#"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",
List.Transform(Table.ColumnNames(#"Promoted Headers"), each {_, type text}))
in
#"Changed Type1"
编辑
如果如您的 cmets 中所暗示的那样,数据集之间确实没有空白行,但您知道最终结果中的列数,
- 硬编码列数(或将其设置为参数)
- 通过对 Index 列执行 IntegerDivide 来更改“grouper”列的构造方式,而不是我在上面使用的公式。
M 码
let
Source = Excel.CurrentWorkbook(){[Name="dataTable"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Data", type text}}),
//hard coded number of columns
numCols = 3,
//add grouper
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
#"Inserted Integer-Division" = Table.AddColumn(#"Added Index", "grouper", each Number.IntegerDivide([Index], numCols), Int64.Type),
#"Removed Columns" = Table.RemoveColumns(#"Inserted Integer-Division",{"Index"}),
//group by the "grouper" column
//then transpose each sub table
#"Grouped Rows" = Table.Group(#"Removed Columns", {"grouper"}, {
{"transpose", each Table.Transpose(Table.SelectColumns(_,"Data"))}
}),
#"Removed Columns2" = Table.RemoveColumns(#"Grouped Rows",{"grouper"}),
//combine the grouped subtables, and promote the headers
comb = Table.Combine(#"Removed Columns2"[transpose]),
#"Promoted Headers" = Table.PromoteHeaders(comb, [PromoteAllScalars=true]),
#"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",
List.Transform(Table.ColumnNames(#"Promoted Headers"), each {_, type text}))
in
#"Changed Type1"