EP024 列表(List)数据结构的处理技巧: List.Select(筛选)、List.Skip(跳过)以及结合 Record.ToList(记录转列表)的动态求和综合实战案例

这一节课,主要讲解M语言中列表(List)数据结构的处理技巧,涉及到的核心知识点包括 List.Select(筛选)、List.Skip(跳过)以及一个结合了 Record.ToList(记录转列表)的动态求和综合实战案例。


🎯 知识点一:List.Select —— 提取列表中的“目标分子”

知识点讲解与“剥洋葱”式参数拆解

  • 这是什么: List.Select 是M语言中用于对列表(List)内部的元素进行条件筛选的函数。它会遍历列表中的每一个元素,判断是否符合设定的条件,把符合条件的元素挑出来,组成一个新的列表。
  • 应用场景: 当你需要对一维数据(而不是整个二维表格)进行清洗、提取特定数值(如极值、异常值)或特定文本时使用。
  • 剥洋葱式参数拆解:公式语法:List.Select( list as list, selection as function )
    • 参数1 list:你要处理的那个“数据包”(列表),比如 {10, 25, 50, 98, 100}
    • 参数2 selection:你的“筛选规则”(函数)。这里通常会搭配两个重要的符号:
      • each:代表“对于列表中的每一个元素”进行后续判断。
      • _(下划线):代表当前正在被判断的那个元素本身(因为列表没有列名/字段名,只能用下划线做代词)。
    • 逻辑关系组合
      • 单个条件each _ < 50 (挑出小于50的数)。
      • 或(OR)关系each _ < 50 or _ > 98(挑出两头的数据:小于50 或 大于98,两个条件满足其一即可)。
      • 且(AND)关系each _ > 25 and _ < 100(挑出中间的数据:必须同时大于25 并且 小于100)。
      • 嵌套函数each Number.IsEven(_)(调用数字函数,挑出偶数)。

具体案例

Table.SelectRows(筛选表中的行)对应,List.Select 是用来筛选 列表 (List) 中的元素的。

  • 基础语法List.Select( 列表, 筛选条件 )
  • 核心逻辑:它会遍历列表中的每一个元素(用 each _ 代表),符合条件的留下,不符合的踢掉,最后返回一个新的列表

常见的筛选条件写法:

  1. 单条件
    List.Select({1, 99, 8, 98, 5}, each _ < 50) -> 返回 {1, 8, 5}
  2. 多条件 (或 – or):满足其一即可
    List.Select({1, 99, 8, 98, 5}, each _ < 50 or _ > 98)
  3. 多条件 (且 – and):必须同时满足
    List.Select({1, 30, 25, 18, 100}, each _ > 25 and _ < 100)
  4. 嵌套判断函数(极简写法):
    筛选偶数:List.Select({1, 2, 3, 4}, Number.IsEven) -> 返回 {2, 4}
    (注:这里连 each _ 都省了,直接把判断函数传进去,非常优雅)
  5. 文本筛选
    List.Select({"老汪洞察", "猪八戒"}, each Text.Contains(_, "汪")) -> 返回 {"老汪洞察"}

🎯 知识点二、 列表元素的跳过:List.Skip

这个函数非常简单,但在后面的实战中起到了决定性的作用。

  • 基础语法List.Skip( 列表, N )
  • 功能:从列表的开头,跳过(舍弃)前 N 个元素,保留剩下的所有元素。
  • 示例
    List.Skip({1, 2, 3, 4, 5}, 3)
    逻辑:跳过前面的 1, 2, 3。
    *结果:返回 {4, 5}

🎯 知识点三:综合实战案例

这个“宽表动态横向求和”的技巧,是很多财务打工人的“保命神技”

在实际工作中,我们经常会遇到那种“横向无限延伸”的表格。比如每个月都会往右边新增一列“X月实际发生额”,或者做滚动预测时,右边会跟着 12 个月甚至 18 个月的预测数据。

如果用笨办法 [1月] +[2月] + [3月]...,下个月多了一个“4月”,你的公式就得重写,否则数据就漏了。

今天,我们就用 List.Sum(List.Skip(Record.ToList(_), N)) 这个组合拳,彻底把这个计算做成“全自动挡”


💼 业务场景:各部门多期费用横向汇总

痛点:
你拿到了一份《各部门项目费用明细表》。
3 列 是文本信息(部门、项目编号、费用类型)。
从第 4 列 开始,全是每个月的金额。
现在老板要求:在最后一列加一个“累计总费用”。并且,以后不管业务部门在后面加上多少个月的数据,你的汇总公式都不能报错,也不能漏算。

📊 模拟数据源 (请复制到 Excel 并创建为表)

部门项目编号费用类型1月发生额2月发生额3月发生额
销售部P-001差旅费150020001800
销售部P-002业务招待费500080006000
研发部R-105测试材料费12000015000
研发部R-105专家咨询费050005000
行政部A-001办公耗材800900850

🚀 Power Query 实操步骤 (手把手教学)

第一步:将数据加载到 Power Query

选中上面的表格,点击 【数据】 -> 【来自表格/区域】。进入 PQ 编辑器。

第二步:添加自定义列 (输入魔法代码)

  1. 点击顶部菜单栏的 【添加列】 -> 【自定义列】
  2. 新列名:输入 累计总费用
  3. 自定义列公式请直接复制粘贴下面这行代码(注意不要多写 each):
List.Sum(List.Skip(Record.ToList(_), 3))
  1. 点击 【确定】

见证奇迹!
你会发现,所有的金额都被完美地加总在了一起。销售部差旅费变成了 5300 (1500+2000+1800)。


🧠 核心原理解析:为什么是跳过 3?(剥洋葱解密)

这段短短的代码里,包含了 4 层嵌套。我们以第一行(销售部、P-001、差旅费、1500、2000、1800)为例,由内向外剥开它:

🧅 第一层:_ (下划线)

  • 它是谁:代表当前这一整行的数据。
  • 它的样子:它是一个 Record (记录)
    [部门="销售部", 项目编号="P-001", 费用类型="差旅费", 1月发生额=1500, 2月发生额=2000, 3月发生额=1800]

🧅 第二层:Record.ToList( _ )

  • 它的动作:把上面那个记录里所有的“值”抽出来,排成一个清单。
  • 它的样子:变成了一个 List (列表)
    {"销售部", "P-001", "差旅费", 1500, 2000, 1800}
  • 潜在危机:如果这时候直接用 List.Sum 求和,机器会崩溃报错,因为汉字和字母不能参与加法计算

🧅 第三层:List.Skip( ..., 3 ) (最关键的护城河)

  • 它的动作:对着刚才那个列表说,“从左边开始数,把前 3 个元素给我扔掉!”
  • 为什么是 3? 因为我们观察了表结构,前 3 列(部门、编号、类型)是不能相加的文本。
  • 它的样子:列表被切掉了头,只剩下了纯数字。
    {1500, 2000, 1800}

🧅 第四层:List.Sum( ... )

  • 它的动作:对这个干净的、全是数字的列表进行求和。
  • 最终结果5300

🌟 财务 BP 的高光时刻 (动态测试)

为什么说这个技巧是“神技”?你可以做一个测试来验证它的威力。

测试步骤:

  1. 把刚才 PQ 里的数据 【关闭并上载】 到 Excel。
  2. 回到你的原始数据表(源数据)。
  3. 在“3月发生额”的右边,手动加上一列“4月发生额”,随便填几个数字(比如第一行填个 1000)。
  4. 右键点击你用 PQ 生成的结果表,点击 【刷新】

你会看到什么?
不需要去 PQ 里修改任何代码,也不需要把“4月”加进公式里。
结果表里的“累计总费用”瞬间自动把 4 月的金额也加进去了(变成了 6300)!

这就是数据建模中的“防呆”与“自动化扩展”。

只要你的报表规则是“前 N 列是文本,后面的全加起来”,这段代码就能保你一劳永逸。下个月业务部就算发来一个横跨 24 个月的表格,你也能在一秒钟内完成汇总!

© 版权声明
THE END
喜欢就支持一下吧
点赞119 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容