You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Power Query技术调整需求:拆分多值单元格为行且避免生成所有可能组合

Power Query技术调整需求:拆分多值单元格为行且避免生成所有可能组合

嗨,我完全懂你的困扰——目前你的Power Query代码在拆分Items NeededItem Purpose这两个多值列时,生成了所有可能的笛卡尔组合,但你想要的是让这两列里的内容一一对应着拆分成行,对吧?

问题出在你现在是依次拆分并展开每个列:先把Items Needed拆成多行,再对每一行拆分Item Purpose,自然会把每个Item和所有Purpose都组合一遍。咱们换个思路,同时处理两个列的对应关系,就能得到你要的结果:

调整后的完整M代码

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Pet Type", type text}, {"Items Needed", type text}, {"Item Purpose", type text}, {"Typical Name", type text}}),
    // 给每行添加临时索引(确保每行独立处理,可选但更稳妥)
    #"Add Row Index" = Table.AddIndexColumn(#"Changed Type", "TempIndex", 0, 1, Int64.Type),
    // 将两个多值列同时拆分为列表格式
    #"Split to Lists" = Table.TransformColumns(#"Add Row Index", {
        {"Items Needed", Splitter.SplitTextByDelimiter("#(lf)", QuoteStyle.None), type list},
        {"Item Purpose", Splitter.SplitTextByDelimiter("#(lf)", QuoteStyle.None), type list}
    }),
    // 把每行的两个列表按位置配对,转换成绑定对应关系的记录
    #"Pair Corresponding Entries" = Table.AddColumn(#"Split to Lists", "PairedData", (currentRow) => 
        List.Zip({currentRow[Items Needed], currentRow[Item Purpose]})
        |> List.Transform((pair) => [Items Needed = pair{0}, Item Purpose = pair{1}])
    ),
    // 先展开配对后的列表列
    #"Expand Paired List" = Table.ExpandListColumn(#"Pair Corresponding Entries", "PairedData"),
    // 再展开记录里的字段,还原成原始列名
    #"Expand Record Fields" = Table.ExpandRecordColumn(#"Expand Paired List", "PairedData", {"Items Needed", "Item Purpose"}, {"Items Needed", "Item Purpose"}),
    // 删除临时索引列
    #"Clean Up Temp Column" = Table.RemoveColumns(#"Expand Record Fields",{"TempIndex"})
in
    #"Clean Up Temp Column"

关键逻辑说明

  • 同时拆分列表:不再单独处理每个列,而是一次性把两个多值列都转换成列表,保证每行的Items Needed列表和Item Purpose列表是一一对应的
  • 列表配对:用List.Zip函数把两个列表按位置“拉链”式配对,比如第一个列表的第N个元素会和第二个列表的第N个元素绑定在一起,再转换成记录格式固化这种对应关系
  • 分步展开:先展开配对后的列表列,再展开记录里的字段,就能得到每个Item对应它专属Purpose的行,不会生成多余的组合

如果你的多值列用的不是换行符(#(lf))作为分隔符,只需要把代码里的Splitter.SplitTextByDelimiter("#(lf)", ...)改成你实际使用的分隔符(比如逗号,、分号;)就行。

备注:内容来源于stack exchange,提问作者Dave

火山引擎 最新活动