Power Query中替代嵌套IF函数实现多条件按产品类型提取最大日期的方案咨询
替代Power Query嵌套IF的多规则日期提取方案
嘿,这个场景我太熟了——7种产品类型各有专属规则,用嵌套IF写出来不仅代码冗长到爆炸,以后改个规则都得扒拉半天代码,简直头疼。好在Power Query里有俩更优雅的方案,都是我平时处理这类多规则逻辑常用的,分享给你:
方案1:规则表+合并查询(最推荐,可维护性拉满)
这个方法把规则和数据彻底分离,以后改规则直接改表格就行,不用碰M代码,适合规则可能变动的场景:
第一步:创建规则映射表
新建一个空白查询(或者直接在Excel里做表再导入),把每种产品类型对应的状态键组合列出来,比如:产品类型 状态键1 状态键2 Type A S1 S3 Type B S2 S4 Type C S5 S1 ... ... ... 如果有规则优先级(比如某个物料可能匹配多个规则),可以再加一列
优先级,数值越小优先级越高。第二步:合并主数据与规则表
回到你的主数据表,点击「合并查询」,选择按产品类型做左外连接,关联刚才的规则表。合并后会生成一个包含规则表数据的列。第三步:筛选符合规则的行
添加一个自定义列,判断当前行的状态键是否匹配规则里的组合:= if [状态键1] = [规则表.状态键1] and [状态键2] = [规则表.状态键2] then [日期] else null如果有优先级,先按
物料+优先级分组,保留每组优先级最高的行,再做上面的判断。第四步:分组取最大日期
按物料分组,对刚才的自定义列取最大值:= Table.Group(上一步的表, {"物料"}, {{"目标最大日期", each List.Max([自定义列]), type date}})
方案2:用M代码定义规则列表(适合不想额外建表的场景)
如果不想单独维护规则表,直接在M代码里把规则写成列表,配合函数匹配:
let // 先把所有规则定义成列表,每个元素是包含产品类型和匹配逻辑的记录 规则列表 = { [产品类型="Type A", 状态键1="S1", 状态键2="S3"], [产品类型="Type B", 状态键1="S2", 状态键2="S4"], [产品类型="Type C", 状态键1="S5", 状态键2="S1"], // 剩下4种产品类型的规则依次补充 }, // 加载你的主数据表 主数据 = 你的主数据表名称, // 添加列:判断当前行是否匹配对应产品类型的规则 添加匹配标记 = Table.AddColumn(主数据, "是否符合规则", each let 当前产品类型 = [产品类型], // 找到当前产品类型对应的规则 对应规则 = List.FindValue(规则列表, 当前产品类型, (r)=>r[产品类型]), // 判断状态键是否匹配 匹配结果 = if 对应规则 <> null then ([状态键1] = 对应规则[状态键1] and [状态键2] = 对应规则[状态键2]) else false in if 匹配结果 then [日期] else null ), // 按物料分组取最大日期 分组计算 = Table.Group(添加匹配标记, {"物料"}, {{"目标最大日期", each List.Max([是否符合规则]), type date}}) in 分组计算
如果你的规则逻辑更复杂(比如状态键是“或”关系、多条件组合),可以把规则里的匹配逻辑改成自定义函数,比如:
规则列表 = { [产品类型="Type A", 匹配逻辑=(row)=> row[状态键1]="S1" or row[状态键2]="S3"], [产品类型="Type B", 匹配逻辑=(row)=> row[状态键1]="S2" and row[状态键2]="S4"] }
然后在添加列的时候调用这个函数:
添加匹配标记 = Table.AddColumn(主数据, "是否符合规则", each let 当前行 = _, 对应规则 = List.FindValue(规则列表, 当前行[产品类型], (r)=>r[产品类型]) in if 对应规则 <> null and 对应规则[匹配逻辑](当前行) then [日期] else null )
最后小提示
优先选方案1,因为规则表可视化程度高,后续维护、修改规则都不用碰代码,团队协作也更方便。如果只是临时用一下,方案2会更快捷。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

