Power Query动态计算表格各列百分比分布的实现难题求助
Power Query动态计算列百分比分布问题解决
问题概述
作为Power Query新手,仅完成过简单查询,现需制作动态查询处理表格数据,计算绝对值的百分比分布,卡在记录值除以对应列总和的核心计算步骤。要求实现周期列新增时自动识别,无需手动修改代码。
示例数据
原始数据(周期列会动态新增)
| Product | Q1 - 2020 | Q2 - 2020 | Q3 - 2020 | Q4 - 2020 | Q1 - 2021 | Q2 - 2021 | Q3 - 2021 | Q4 - 2021 |
|---|---|---|---|---|---|---|---|---|
| P1 | 1144 | 2737 | 3545 | 3696 | 4279 | 4249 | 4167 | 4124 |
| P2 | 157 | 161 | 166 | 163 | 166 | 174 | 163 | 175 |
| P3 | 257 | 388 | 485 | 529 | 553 | 566 | 585 | 598 |
| P4 | 251 | 461 | 587 | 709 | 820 | 848 | 878 | 924 |
| P5 | 262 | 402 | 493 | 465 | 502 | 512 | 507 | 550 |
| P6 | 193 | 220 | 236 | 255 | 256 | 269 | 251 | 253 |
| P7 | 160 | 161 | 171 | 184 | 214 | 236 | 243 | 244 |
| P8 | 177 | 249 | 300 | 384 | 488 | 518 | 558 | 566 |
| P9 | 202 | 226 | 231 | 245 | 246 | 258 | 283 | 275 |
| P10 | 154 | 154 | 154 | 154 | 154 | 157 | 166 | 163 |
| P11 | 155 | 156 | 167 | 166 | 203 | 236 | 251 | 246 |
| P12 | 165 | 163 | 159 | 168 | 174 | 167 | 170 | 177 |
| P13 | 156 | 159 | 157 | 160 | 170 | 161 | 164 | 169 |
目标结果(各产品占对应周期列的百分比)
| Product | Q1 - 2020 | Q2 - 2020 | Q3 - 2020 | Q4 - 2020 | Q1 - 2021 | Q2 - 2021 | Q3 - 2021 | Q4 - 2021 |
|---|---|---|---|---|---|---|---|---|
| P1 | 33.3% | 48.6% | 51.7% | 50.8% | 52.0% | 50.9% | 49.7% | 48.7% |
| P2 | 4.6% | 2.9% | 2.4% | 2.2% | 2.0% | 2.1% | 1.9% | 2.1% |
| P3 | 7.5% | 6.9% | 7.1% | 7.3% | 6.7% | 6.8% | 7.0% | 7.1% |
| P4 | 7.3% | 8.2% | 8.6% | 9.7% | 10.0% | 10.2% | 10.5% | 10.9% |
| P5 | 7.6% | 7.1% | 7.2% | 6.4% | 6.1% | 6.1% | 6.0% | 6.5% |
| P6 | 5.6% | 3.9% | 3.4% | 3.5% | 3.1% | 3.2% | 3.0% | 3.0% |
| P7 | 4.7% | 2.9% | 2.5% | 2.5% | 2.6% | 2.8% | 2.9% | 2.9% |
| P8 | 5.2% | 4.4% | 4.4% | 5.3% | 5.9% | 6.2% | 6.7% | 6.7% |
| P9 | 5.9% | 4.0% | 3.4% | 3.4% | 3.0% | 3.1% | 3.4% | 3.2% |
| P10 | 4.5% | 2.7% | 2.2% | 2.1% | 1.9% | 1.9% | 2.0% | 1.9% |
| P11 | 4.5% | 2.8% | 2.4% | 2.3% | 2.5% | 2.8% | 3.0% | 2.9% |
| P12 | 4.8% | 2.9% | 2.3% | 2.3% | 2.1% | 2.0% | 2.0% | 2.1% |
| P13 | 4.5% | 2.8% | 2.3% | 2.2% | 2.1% | 1.9% | 2.0% | 2.0% |
现有Power Query代码
let Source = Excel.CurrentWorkbook(){[Name="Line1_Abs"]}[Content], //Organization will always be of type text. The others will be should be numbers, unless user error #"Changed Type" = Table.TransformColumnTypes(Source, {{"Product_Regimen", type text}}), //function to replace all values in all columns with percentages values MultiplyReplace = (DataTable as table, DataTableColumns as list) => let Counter = Table.ColumnCount(DataTable), ReplaceCol = (DataTableTemp, i) => let colName = DataTableColumns{i}, colTotal = List.Sum(Record.FieldValues(_, colName)), //Line not doing the trick ReplaceTable = Table.ReplaceValue(DataTableTemp,each Record.Field(_, colName), each if Record.Field(_, colName) is number then Record.Field(_, colName)/List.Sum(Record.FieldValues(_, colName)) else Record.Field(_, colName),Replacer.ReplaceValue,{colName}) in if i = Counter-1 then ReplaceTable else @ReplaceCol(ReplaceTable, i+1) in ReplaceCol(DataTable, 0), allColumns = Table.ColumnNames(#"Changed Type"), #"Multiplied Numerics" = MultiplyReplace(#"Changed Type", allColumns) in #"Multiplied Numerics"
问题分析与修正方案
核心问题
现有代码的错误在于:
List.Sum(Record.FieldValues(_, colName))误用了_,此处_指代单条记录,无法获取整列总和。- 递归循环处理列的逻辑冗余,可通过更简洁的批量处理方式替代。
修正后的代码
let Source = Excel.CurrentWorkbook(){[Name="Line1_Abs"]}[Content], // 转换Product列为文本,其余列自动识别数值类型 #"Changed Type" = Table.TransformColumnTypes(Source, {{"Product_Regimen", type text}}), // 动态获取所有非Product列(自动识别新增周期列) ValueColumns = List.RemoveItems(Table.ColumnNames(#"Changed Type"), {"Product_Regimen"}), // 计算每列总和,生成列名与总和的映射 ColumnTotals = List.Transform(ValueColumns, (col) => [Name=col, Total=List.Sum(Table.Column(#"Changed Type", col))]), // 批量转换数值列为百分比:值/对应列总和,保留1位小数并转为百分比格式 #"Calculated Percentages" = Table.TransformColumns(#"Changed Type", List.Transform(ColumnTotals, (item) => { item[Name], each if _ is number then Number.Round(_ / item[Total], 3) * 100 & "%" else _ }) ) in #"Calculated Percentages"
代码说明
- 动态列识别:通过
List.RemoveItems排除固定的Product_Regimen列,自动获取所有周期列,新增列无需修改代码。 - 列总和计算:用
Table.Column获取整列数据,再通过List.Sum计算总和,解决原代码中无法获取整列总和的问题。 - 百分比转换:使用
Table.TransformColumns批量处理所有数值列,将值除以对应列总和,保留3位小数后转为百分比格式。 - 鲁棒性:保留非数值类型判断,避免用户输入错误导致的报错。
内容的提问来源于stack exchange,提问作者Enrique Leon
相关产品推荐
相关产品推荐

