如何用Power Query实现带求和的库存表特殊行格式转换?
Power Query实现分组首行显示总数量、后续行Part Number留空的方案
完全不用依赖OnChange宏,Power Query就能直接实现你要的布局效果,具体操作步骤如下:
操作流程
导入并预处理CSV数据
将ERP导出的CSV导入Power Query,提升标题行并设置对应数据类型(比如把Count设为数值型)。统计每组总数量
按Condition、Location、Part Number三列分组,统计每组的总行数(因每个Code对应Count=1,行数即为总数量),生成每组的总数量统计表。合并总数量到原表
通过Condition、Location、Part Number三列,将原表与总数量统计表做左连接,让每一行都带上本组的总数量值。标记首行并调整列内容
- 按
Condition、Location、Part Number分组,给每组内的行添加从0开始的组内索引; - 新建
Part Number列:组内索引为0的行(首行)保留原Part Number值,其余行设为空; - 新建
Count列:首行显示本组总数量,后续行可留空(若需保留原Count=1,直接用原数值即可)。
- 按
整理最终格式
删除组内索引、临时总数量列等辅助列,调整列顺序到需求的布局即可。
示例M代码
以下是完整的Power Query M代码示例,可根据你的文件路径和列名调整:
let // 导入CSV(替换为你的文件路径) 源 = Csv.Document(File.Contents("C:\你的库存报表.csv"), [Delimiter=",", Encoding=65001, QuoteStyle=QuoteStyle.Csv]), // 提升标题行 提升的标题 = Table.PromoteHeaders(源, [PromoteAllScalars=true]), // 设置数据类型 更改的类型 = Table.TransformColumnTypes(提升的标题,{{"Condition", type text}, {"Location", type text}, {"Part Number", type text}, {"Code", type text}, {"Count", Int64.Type}}), // 分组统计每组总数量 分组统计 = Table.Group(更改的类型, {"Condition", "Location", "Part Number"}, {{"Total Count", each Table.RowCount(_), Int64.Type}}), // 合并原表与总数量表 合并表 = Table.NestedJoin(更改的类型, {"Condition", "Location", "Part Number"}, 分组统计, {"Condition", "Location", "Part Number"}, "分组统计", JoinKind.LeftOuter), 展开总数量 = Table.ExpandTableColumn(合并表, "分组统计", {"Total Count"}, {"Total Count"}), // 分组添加组内索引(高效方式) 分组加索引 = Table.Group(展开总数量, {"Condition", "Location", "Part Number"}, {{"组内数据", each Table.AddIndexColumn(_, "组内索引", 0, 1, Int64.Type)}}), 展开组内数据 = Table.ExpandTableColumn(分组加索引, "组内数据", {"Code", "Count", "Total Count", "组内索引"}, {"Code", "Count", "Total Count", "组内索引"}), // 调整Part Number和Count列内容 调整PartNumber = Table.AddColumn(展开组内数据, "新Part Number", each if [组内索引]=0 then [Part Number] else null), 调整Count = Table.AddColumn(调整PartNumber, "新Count", each if [组内索引]=0 then [Total Count] else null), // 整理最终列 移除辅助列 = Table.RemoveColumns(调整Count,{"Part Number", "Count", "Total Count", "组内索引"}), 调整列顺序 = Table.ReorderColumns(移除辅助列,{"Condition", "Location", "新Part Number", "Code", "新Count"}), 重命名列 = Table.RenameColumns(调整列顺序,{{"新Part Number", "Part Number"}, {"新Count", "Count"}}) in 重命名列
注意要点
- 若CSV编码不是UTF-8(代码中
Encoding=65001),可替换为对应编码(比如GB2312对应Encoding=936); - 组内行顺序会保留原CSV的顺序,无需额外排序;
- 后续导入新报表时,只需替换文件路径并刷新查询,即可自动生成目标格式,无需重复操作。
内容的提问来源于stack exchange,提问作者Luna




