这一节课,主要讲解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(_)(调用数字函数,挑出偶数)。
- 单个条件:
- 参数1
具体案例
与 Table.SelectRows(筛选表中的行)对应,List.Select 是用来筛选 列表 (List) 中的元素的。
- 基础语法:
List.Select( 列表, 筛选条件 ) - 核心逻辑:它会遍历列表中的每一个元素(用
each _代表),符合条件的留下,不符合的踢掉,最后返回一个新的列表。
常见的筛选条件写法:
- 单条件:
List.Select({1, 99, 8, 98, 5}, each _ < 50)-> 返回{1, 8, 5} - 多条件 (或 – or):满足其一即可
List.Select({1, 99, 8, 98, 5}, each _ < 50 or _ > 98) - 多条件 (且 – and):必须同时满足
List.Select({1, 30, 25, 18, 100}, each _ > 25 and _ < 100) - 嵌套判断函数(极简写法):
筛选偶数:List.Select({1, 2, 3, 4}, Number.IsEven)-> 返回{2, 4}
(注:这里连each _都省了,直接把判断函数传进去,非常优雅) - 文本筛选:
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 | 差旅费 | 1500 | 2000 | 1800 |
| 销售部 | P-002 | 业务招待费 | 5000 | 8000 | 6000 |
| 研发部 | R-105 | 测试材料费 | 12000 | 0 | 15000 |
| 研发部 | R-105 | 专家咨询费 | 0 | 5000 | 5000 |
| 行政部 | A-001 | 办公耗材 | 800 | 900 | 850 |
🚀 Power Query 实操步骤 (手把手教学)
第一步:将数据加载到 Power Query
选中上面的表格,点击 【数据】 -> 【来自表格/区域】。进入 PQ 编辑器。
第二步:添加自定义列 (输入魔法代码)
- 点击顶部菜单栏的 【添加列】 -> 【自定义列】。
- 新列名:输入
累计总费用。 - 自定义列公式:请直接复制粘贴下面这行代码(注意不要多写
each):
List.Sum(List.Skip(Record.ToList(_), 3))
- 点击 【确定】。
见证奇迹!
你会发现,所有的金额都被完美地加总在了一起。销售部差旅费变成了 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 的高光时刻 (动态测试)
为什么说这个技巧是“神技”?你可以做一个测试来验证它的威力。
测试步骤:
- 把刚才 PQ 里的数据 【关闭并上载】 到 Excel。
- 回到你的原始数据表(源数据)。
- 在“3月发生额”的右边,手动加上一列“4月发生额”,随便填几个数字(比如第一行填个 1000)。
- 右键点击你用 PQ 生成的结果表,点击 【刷新】。
你会看到什么?
你不需要去 PQ 里修改任何代码,也不需要把“4月”加进公式里。
结果表里的“累计总费用”瞬间自动把 4 月的金额也加进去了(变成了 6300)!
这就是数据建模中的“防呆”与“自动化扩展”。
只要你的报表规则是“前 N 列是文本,后面的全加起来”,这段代码就能保你一劳永逸。下个月业务部就算发来一个横跨 24 个月的表格,你也能在一秒钟内完成汇总!










暂无评论内容