如何在Power Query(M语言)中实现带上下限的迭代累计计算?
在Power Query中实现带上下限的迭代累计计算(M语言)
针对你需要实现的带上下限迭代累计逻辑,这里提供两种M语言解决方案:适用于无类别分组的单序列计算,以及按类别分组的多序列计算(对应你提到的“每个类别对应从1开始的索引列”场景)。
方案1:无类别分组的单序列计算
如果你的数据是单一序列(无需按类别区分累计),可以直接遍历所有行进行迭代计算:
let // 替换为你的数据源(比如Excel表格或其他数据源) Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], // 将表格转换为记录列表,方便逐行处理 RecordList = Table.ToRecords(Source), // 使用List.Accumulate执行迭代计算 AccumulatedResult = List.Accumulate( RecordList, // 初始状态:保存上一次的计算值(初始为null)和结果列表 {null, {}}, (currentState, currentRow) => let PrevCalculatedValue = currentState{0}, ExistingResults = currentState{1}, // 按照规则计算当前行的累计值 CurrentValue = if currentRow[索引] = 1 then currentRow[Value] + 6.4 else let TempSum = currentRow[Value] + PrevCalculatedValue in if TempSum >= 12.8 then 12.8 else if TempSum <= 1.28 then 1.28 else TempSum in // 更新状态:当前计算值加入结果列表,同时保存当前值作为下一行的前置值 {CurrentValue, ExistingResults & {CurrentValue}} ), // 提取生成的累计值列表 CalculatedList = AccumulatedResult{1}, // 将累计值列表合并回原表格,生成新列 FinalTable = Table.FromColumns( Table.ToColumns(Source) & {CalculatedList}, Table.ColumnNames(Source) & {"累计值"} ) in FinalTable
方案2:按类别分组的多序列计算
如果数据是按类别分组,每个类别下的索引从1开始独立累计,需要先分组再计算:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], // 按类别分组,对每组数据独立执行累计计算 GroupedData = Table.Group(Source, {"类别"}, { {"ProcessedGroup", each let GroupRecords = Table.ToRecords(_), GroupAccumulate = List.Accumulate( GroupRecords, {null, {}}, (state, row) => let PrevVal = state{0}, Results = state{1}, CurrentCalc = if row[索引] = 1 then row[Value] + 6.4 else let Temp = row[Value] + PrevVal in if Temp >= 12.8 then 12.8 else if Temp <= 1.28 then 1.28 else Temp in {CurrentCalc, Results & {CurrentCalc}} ), GroupResults = GroupAccumulate{1}, // 为当前组添加累计值列 GroupWithCalc = Table.FromColumns( Table.ToColumns(_) & {GroupResults}, Table.ColumnNames(_) & {"累计值"} ) in GroupWithCalc, type table [类别=text, 索引=number, Value=number, 累计值=number] } }), // 展开分组后的结果表格 FinalTable = Table.ExpandTableColumn(GroupedData, "ProcessedGroup", Table.ColumnNames(GroupedData[ProcessedGroup]{0})) in FinalTable
关键说明
- List.Accumulate的使用:通过状态变量保存两个核心信息——上一行的计算结果、已生成的累计值列表,解决了你提到的“包含多列值记录”的问题,每次迭代只需读取当前行的
索引和Value列即可。 - 逻辑对应:代码中的计算逻辑完全匹配你给出的Excel公式,索引为1时直接计算
Value+6.4,否则先计算和再判断上下限。 - 自定义调整:请根据你的实际数据替换代码中的
Table1(数据源名称)、类别/索引/Value(列名),以及类型定义(如果你的列类型不同)。
内容的提问来源于stack exchange,提问作者Baris Esin
相关产品推荐
相关产品推荐

