Lazy loaded imageEP017:列表(List)函数族的统计运算

type
status
date
slug
summary
tags
category
icon
password
notion image

作为财务BP,你处理的报表往往涉及多维度的汇总、趋势分析以及异常值排查。Power Query 的列表(List)函数族正是解决“行内计算”和“整列统计”的神器。
为了确保你能够直接应用,我构建了一个“区域季度销售业绩表”作为基础数据源。这份数据模拟了财务分析中常见的几种情况:完整数据缺省数据(Null,模拟新业务)零值数据(Zero,模拟无业绩)

基础示例数据:Regional_Sales (区域销售表)

请将以下数据放入 Excel 并导入 Power Query,命名查询为 Source
区域
负责人
Q1_业绩
Q2_业绩
Q3_业绩
Q4_业绩
备注
华北区
张三
150000
180000
200000
210000
业务成熟
华东区
李四
250000
240000
260000
300000
核心市场
华南区
王五
null
null
120000
150000
下半年新开
西北区
赵六
80000
0
50000
60000
Q2停业整顿
西南区
张三
100000
110000
105000
120000
兼任

第一部分:列表求和 (List.Sum)

核心技术: 横向求和(行上下文)、构造总计行(表操作)

场景 1:计算全年总业绩(横向)

业务背景: 你需要计算每个区域的全年累计销售额 (YTD)。 M函数操作: 添加自定义列,名为“全年业绩”。
以下为该步骤完整函数:
注意视频演示的错误示范。
讲解:
  • 技术点:必须使用大括号 {} 将四个季度的字段包起来,构成一个 List,传给 List.Sum
  • 业务逻辑:注意看“华南区”,Q1和Q2是 null(空值)。List.Sum 会自动忽略 null,只计算 Q3+Q4,结果为 270,000。这符合财务逻辑:未开展业务期间不产生业绩,不影响求和。但如果中间是用“+”号,而不是用“,”号,那么有空值时会得出结果为空。

场景 2:构造“总计行”拼接在表底(纵向)

业务背景: 财务报表通常需要在最后一行显示“所有区域的总计”,Power Query 默认不带汇总行,我们需要手动造一个。 M函数代码 (高级编辑器):
notion image
讲解:
  • 技术点:这里演示了如何利用 List.Sum(#"源"[列名])整列求和,然后放入 Record,最后拼回原表。
  • 业务逻辑:这是自动化财务报表的关键一步,省去了导出 Excel 后再手动添加求和公式的步骤。

了解PowerQuery里面的let…in骨架

宏观上来说,对于绝大多数你在 Power Query 编辑器里看到的查询(Query),它的标准骨架就是一个巨大的 let ... in 包裹着所有的步骤。
  • let:大喊一声“我要开始定义步骤啦!”
  • 中间的步骤:一步接一步,用英文状态逗号隔开。
  • in:大喊一声“搞定,我要输出结果啦!”

但是进阶情况下存在嵌套

虽然“一个查询通常只有一个外壳”,但在 M 语言中,let ... in 其实是一个“表达式”。这意味着,它是可以嵌套的(像俄罗斯套娃一样)。
以后咱们进阶了,可能会遇到一种“局部的 let ... in ”。

场景举例:

假设你在计算某一列时,逻辑特别复杂,你想在这一步内部先定义几个临时变量,算完后再把结果给这一步。
代码可能会长这样:

如何理解这种嵌套?

我们可以用 “房子”和“抽屉” 来打比方:
  1. 最外层的 let ... in(查询本身)
      • 这是整个房子
      • 步骤A步骤B 是房子里的房间
      • 你在任何一个房间里,只要喊一声“源!”,都能找得到它(全局可见)。
  1. 内层的 let ... in(步骤B 里面的)
      • 这是一个上锁的抽屉
      • 里面的 税前税后 是抽屉里的私人物品
      • 关键点:出了这个 let ... in(出了抽屉),外面的步骤(比如“结果”)是看不到也不认识 税前税后 的。它们只在那个小小的逻辑里存活。
现阶段作为新手,我们可以暂时忽略嵌套的情况。你只需要死死记住这条铁律: 一个查询文件,就是一个大的 let 开始,一堆步骤在中间(英文逗号隔开),最后用 in 结束。这个认知足够你解决 99% 的工作问题了!
如果你很好学,那么可以看看这篇文章,这里有详细的讲解以及配套的操作案例,便于加深理解。➡️➡️➡️ 《一个案例学习理解let...in骨架函数的嵌套逻辑》

第二部分:列表元素计数与判断 (List.Count, IsDistinct)

核心技术: 计数(含空/不含空)、判重

场景 1:统计“活跃经营季度”数

业务背景: 计算每个区域实际经营了几个季度。对于“华南区”,因为上半年未开业,分母应该是2;而“西北区”虽然Q2是0(停业),但属于经营期间,分母应该是4。 M函数操作: 添加自定义列,名为“经营季度数”。
该步骤完整函数:
具体操作步骤如下:

第一步:打开自定义列窗口

  1. 在 Power Query 编辑器中,点击顶部菜单栏的 【添加列】选项卡。
  1. 点击 【自定义列】按钮。

第二步:编写公式

在弹出的对话框中,进行如下设置:
  1. 新列名:输入 经营季度数
  1. 自定义列公式
      • 手写部分:输入 = List.NonNullCount({
      • 选列部分:在右侧“可用列”列表中,依次双击 Q1_业绩,输入逗号,双击 Q2_业绩,输入逗号... 直到选完四个季度。
      • 补全括号:最后输入 })
      最终公式应该是这样的(注意标点符号):

第三步:确认并完成

  1. 检查底部显示“未检测到语法错误”。
  1. 点击 【确定】

结果验证

操作完成后,你会看到新的一列:
  • 华南区(王五):结果应该是 2。(因为前两个季度是 null,不计入)
  • 西北区(赵六):结果应该是 4。(因为 Q2 虽然是 0,但 0 也是数值,不是空,所以计入)
讲解:
  • 技术点List.NonNullCount 只统计非空数值。
    • 华南区 (null, null, 12w, 15w) -> 结果 2
    • 西北区 (8w, 0, 5w, 6w) -> 结果 4 (0也是数值,不是空)。
  • 业务逻辑:准确区分“无数据”(没开业)和“零业绩”(经营不善)。

场景 2:审计检查——负责人是否兼任(判重)

业务背景: 检查是否有区域负责人存在兼任情况(即列表中是否有重复名字)。 M函数操作: (通常用于整列检查,这里演示逻辑)
  1. 定位:确保你现在停留在数据表的最后一步(比如步骤名叫 已添加自定义 )。
  1. 点击 fx:点击公式栏左侧的小图标 fx(这会添加一个新的步骤)。
  1. 输入公式
    1. = List.IsDistinct( #"已添加自定义"[负责人] )
  1. 查看结果
      • 按下回车后,原本的表格会消失,屏幕中间只会显示一个值。
      • 如果显示 TRUE:恭喜,数据很干净,没有重复(全是唯一的)。
      • 如果显示 FALSE:警告,数据有重复值(有人兼任)。
(看完后,如果还要继续处理表格,把这个步骤右键删除即可)

第三部分:列表求平均 (List.Average)

核心技术: 忽略空值的平均 vs 包含0的平均

场景:计算“季度平均产出”

业务背景: 评估各区域的平均盈利能力。
  • 华南区:只开了两个季度,赚了27万。它的平均水平应该是 27万/2 = 13.5万。
  • 西北区:开了四个季度,赚了19万(含Q2的0)。它的平均水平应该是 19万/4 = 4.75万。
M函数操作: 添加自定义列,名为“季度平均”。
该自定义列步骤的完整函数:
 
讲解:
  • 技术点List.Average 自动忽略 null
    • 华南区:(120000 + 150000) / 2 = 135,000(正确,符合新店评估逻辑)。
    • 西北区:(80000 + 0 + 50000 + 60000) / 4 = 47,500(正确,0拉低了平均分)。
  • 业务陷阱:如果你在上一部操作中,错误地将所有 null 替换成了 0,那么华南区的平均分就会变成 270000 / 4 = 67,500,这会严重低估新店的潜力。保留 null 在财务分析中往往是有意义的。

第四部分:最大和最小值 (List.Max, List.Min)

核心技术: 极值查找、默认值处理

场景 1:查找“峰值业绩”和“最低值业绩”

业务背景: 找出每个区域表现最好的那个季度的金额,用于设定明年的激励上限。 M函数操作: 添加自定义列,名为“最佳季度业绩”。
该自定义列步骤的完整函数:

场景 2:查找“最低值业绩”时(防止报错的高级用法)

业务背景: 假设有一个新建的“大上海区”,四个季度全是 null。你希望计算最小值时,如果全是空值,不要报错或返回空,而是返回 0 ,表示“无保底”。 M函数操作: 添加自定义列,名为“最低季度业绩”。
该自定义列步骤的完整函数:
讲解:
  • 技术点List.Min(列表, 默认值)。第二个参数 0 只有在列表为空(或全为null被忽略后视为空)时才会生效。
  • 业务逻辑:确保数据模型的健壮性(Robustness)。在自动化报表中,防止因为某个新部门没有任何数据而导致整张报表刷新失败。

总结:财务BP视角的知识点匹配

知识点
对应 M 函数
财务BP实战意义
横向求和
List.Sum({[Col1], [Col2]...})
计算 YTD (Year-To-Date)、总成本、总费用。
纵向汇总
Table.Combine + List.Sum(列)
自动化生成报表的“总计行”,无需手工加工。
非空计数
List.NonNullCount
准确统计“实际运营月份/季度”,作为平均值分母。
平均逻辑
List.Average
核心! 区分“未发生业务(Null)”和“业绩为零(0)”,避免KPI计算失真。
合规审计
List.IsDistinct
检查发票号重复、人员重复、供应商重复。
极值与容错
List.Max/Min(..., 0)
寻找季节性波动峰值;处理空数据异常,防止模型崩溃。

 
【扫码识别下发二维码,获取本文使用到的及历史以来提及、发布的相关精选和原创资料,和我们一起充电,加入后可享受每月6次免费咨询提问,帮助解决您的特定问题!】

如果本篇文章对您有帮助或启发,请帮我们点赞、转发、推荐、关注,让更多想转型财务BP、锻造数据分析和可视化洞察能力的财务同行们看到,关注【老汪洞察】,不迷路!
notion image
notion image
 
温馨提示
🙏🏻
如果您不想错过【老汪洞察】的文章,请将我们设为"星标",这样每次最新文章推送才会第一时间出现在您的订阅列表里。 方法:点击文章页面左上角蓝色文字“老汪洞察”进入主页,点击关注后,再点主页右上角"...",然后选择"设为星标",即可完成,感谢您的支持。
 
上一篇
EP018:理解上下文(each)和((x)=>)嵌套,解决国际标准排名问题
下一篇
EP016:筛选表、删除重复项、行列数计算
Loading...
文章列表
让财税成为经营的力量
管理报表
从Power Query到Power BI,入门到精通
699课程讲义
VBA小工具
电脑与网络
知识运用