EP035 Record.ToList:将单行记录值转为列表(内存级横向行聚合与多字段遍历)

文 / 老汪(汽车零部件财务与商业智能实战派)

“老汪,我把 6 个车间料工费字段用加号相加算总成本:[材料] + [人工] + [电耗] + ...,为什么只要某个零件没有发生外协表面处理(值为 null),加出来的总成本整格全变成 null 了?难道我还得写一串又臭又长的判断公式吗?”
月末成本结账时,成本会计小陈抓着头发跑来诉苦。在 Excel BI 财务建模中,多列横向汇总(Row-Level Horizontal Aggregation)是一个极高频的刚需。很多初学者习惯用 Excel 的加号思维,结果在 Power Query 里被 null 空值撞得头破血流。今天老汪就带大家拆解一把行级横向计算的瑞士军刀 —— Record.ToList!


一、 为什么老汪说“横向多列计算,必用 Record.ToList”?

在 Power Query 的底层对象模型中: – 一张表(Table)是由一行一行的记录(Record)组成的; – 每一条记录本质上是一个键值对(Key-Value Pair),比如:[零件="控制臂", 材料=125, 人工=28.5]。

很多时候,我们不需要关心左边的“字段名(Key)”,我们只想把右边的“具体数值(Values)”抓取出来进行求和、求最大值、求平均值或者统计非空个数。

这时候,核心神器就是 Record.ToList。

1. 函数基本语法拆解

Record.ToList(record as record) as list
  • 参数(record):目标行记录;
  • 返回值(list):由该记录中所有字段值组成的纯净列表!
  • 等价函数:M 语言里还有一个叫 Record.FieldValues 的函数,功能与 Record.ToList 完全等价,但从语义直观度和书写简短度来看,老汪强烈推荐直接使用 Record.ToList,简单好记!

2. 白话工作原理演示

假设有一行成本记录:

记录 = [主材=125, 人工=28.5, 动力=12, 外协=null]

直接调用函数:

Record.ToList(记录)

返回的结果就是一个纯粹的 M 语言列表:

{ 125, 28.5, 12, null }

有了这个列表,外层直接套上列表家族的强大函数,战斗力瞬间爆表: – 横向求和(免疫 null):List.Sum(Record.ToList(...)) ➔ 结果是 165.5(自动忽略 null 空值,绝不报错!) – 求单行最大支出项:List.Max(Record.ToList(...)) ➔ 结果是 125 – 统计有效发生项数:List.NonNullCount(Record.ToList(...)) ➔ 结果是 3 项


二、 走进车间:汽车零部件单件料工费横向成本核算现场

拿老汪经手的一家知名汽车底盘与动力总成零部件制造企业(Tier 1)为例。厂里生产比亚迪、特斯拉、吉利极氪等明星车型的核心总成。

财务部月末从 ERP 导出的《产品成本横向明细表》如下(包含 9 列大宽表,文末可免费下载随堂 Excel 课件):

零件图号 核心零部件名称 主机厂客户 主材铝锭成本(元) CNC加工人工(元) 产线动力电耗(元) 专用工装模具摊销(元) 表面阳极钝化外协(元) 包装与辅材消耗(元)
P-812-ARM 铝合金底盘下控制臂 比亚迪海豹 125.00 28.50 12.00 15.00 18.00 6.50
P-605-CAL 双活塞制动卡钳体 蔚来ES6总成 95.00 32.00 14.50 12.00 null 5.00
P-901-TRAY 电池包下托盘托架 吉利极氪001 380.00 65.00 35.00 45.00 52.00 18.00
P-302-ROTOR 轻量化通风制动盘 特斯拉Model Y 85.00 22.00 11.00 9.50 null 4.50
P-408-SUB 高强前悬架副车架 理想L7底盘 260.00 55.00 28.00 30.00 36.00 12.00
P-510-COV 驱动电机前置端盖 小鹏G6三电 145.00 36.00 16.00 18.00 null 7.00
P-715-ARM 后悬架双球节摆臂 小米SU7总成 110.00 26.00 10.50 14.00 15.50 6.00
P-204-STEER 高精度转向节臂管 广汽埃安Hyper 75.00 18.50 8.00 8.00 null 3.50

📱 移动端排版体验:上方表格已配置横向平滑滚动容器,在手机端手指左右滑动即可舒展查看完整 9 列数据,单元格字距舒展绝不挤爆!

大家注意看:制动卡钳体、通风制动盘、电机端盖等零件是不需要外协阳极钝化的,所以【表面阳极钝化外协(元)】列存在真实的 null 空值。如果直接用 + 加号相加,这些零件的单件总成本将全部阵亡变成 null!


三、 高级编辑器手把手实操代码

在随堂 Excel 课件中,老汪已将 Q001 动态相对路径标准置入【配置】表。进入 Power Query 高级编辑器,贴入老汪的标准自适应代码:

let
    // 💡 老汪敲黑板(免改路径直接刷新秘籍):换电脑解压后直接点【全部刷新】永不报红字!
    当前路径 = try 
        let 
            raw = Text.From(Excel.CurrentWorkbook(){[Name="当前路径"]}[Content]{0}[Column1]),
            clean = Text.Trim(raw)
        in 
            if Text.EndsWith(clean, "\") then clean else clean & "\"
    otherwise 
        "./",

    // 1. 读取原始业务数据源
    数据源路径 = 当前路径 & "原始业务数据表.xlsx",
    源 = Excel.Workbook(File.Contents(数据源路径), null, true),
    成本原始表 = 源{[Item="产品成本横向明细表", Kind="Sheet"]}[Data],
    提升标题 = Table.PromoteHeaders(成本原始表, [PromoteAllScalars=true]),
    更改类型 = Table.TransformColumnTypes(提升标题, {
        {"零件图号", type text},
        {"核心零部件名称", type text},
        {"主机厂客户", type text},
        {"主材铝锭成本(元)", type number},
        {"CNC加工人工(元)", type number},
        {"产线动力电耗(元)", type number},
        {"专用工装模具摊销(元)", type number},
        {"表面阳极钝化外协(元)", type number},
        {"包装与辅材消耗(元)", type number}
    }),

    // 2. 统一定义需要横向计算的成本科目清单
    成本科目列表 = {
        "主材铝锭成本(元)",
        "CNC加工人工(元)",
        "产线动力电耗(元)",
        "专用工装模具摊销(元)",
        "表面阳极钝化外协(元)",
        "包装与辅材消耗(元)"
    },

    // 3. 核心大招:Record.SelectFields 截取数值记录,配合 Record.ToList 转列表后求和
    // 💡 自动忽略 null,彻底根除普通加号报空崩溃的顽疾!
    添加单台总成本 = Table.AddColumn(更改类型, "单台全制造成本(元)", each 
        List.Sum(Record.ToList(Record.SelectFields(_, 成本科目列表))), type number),

    // 4. 横向求单项最大成本金额(List.Max)
    添加单项最高成本 = Table.AddColumn(添加单台总成本, "单项最高成本项金额(元)", each 
        List.Max(Record.ToList(Record.SelectFields(_, 成本科目列表))), type number),

    // 5. 统计有效发生费用的科目数量(剔除 null)
    添加有效科目数 = Table.AddColumn(添加单项最高成本, "发生费用项目数(项)", each 
        List.Count(List.RemoveNulls(Record.ToList(Record.SelectFields(_, 成本科目列表)))), Int64.Type),

    // 6. 注入财务结构诊断建议
    添加管理建议 = Table.AddColumn(添加有效科目数, "成本结构诊断建议", each 
        if [#"单台全制造成本(元)"] >= 300 then "🚨 高价值重载件,重点稽核主材铝锭利用率"
        else if [#"单台全制造成本(元)"] >= 150 then "🟡 骨干中型总成,强化CNC机加工时管控"
        else "🟢 紧凑型零部件,成本构成稳健受控", type text),

    // 整理最终呈现报表
    整理输出字段 = Table.SelectColumns(添加管理建议, {
        "零件图号", "核心零部件名称", "主机厂客户", 
        "单台全制造成本(元)", "单项最高成本项金额(元)", "发生费用项目数(项)", "成本结构诊断建议"
    })
in
    整理输出字段

四、 最终清洗效果与车间管理看板

运行上述 M 脚本后,我们在 Excel 中得到的标准化分析看板如下(支持移动端自由横向滑动):

零件图号 核心零部件名称 主机厂客户 单台全制造成本(元) 单项最高成本项金额(元) 发生费用项目数(项) 成本结构诊断建议
P-812-ARM 铝合金底盘下控制臂 比亚迪海豹 205.00 125.00 6 🟡 骨干中型总成,强化CNC机加工时管控
P-605-CAL 双活塞制动卡钳体 蔚来ES6总成 158.50 95.00 5 🟡 骨干中型总成,强化CNC机加工时管控
P-901-TRAY 电池包下托盘托架 吉利极氪001 595.00 380.00 6 🚨 高价值重载件,重点稽核主材铝锭利用率
P-302-ROTOR 轻量化通风制动盘 特斯拉Model Y 132.00 85.00 5 🟢 紧凑型零部件,成本构成稳健受控
P-408-SUB 高强前悬架副车架 理想L7底盘 421.00 260.00 6 🚨 高价值重载件,重点稽核主材铝锭利用率
P-510-COV 驱动电机前置端盖 小鹏G6三电 222.00 145.00 5 🟡 骨干中型总成,强化CNC机加工时管控
P-715-ARM 后悬架双球节摆臂 小米SU7总成 182.00 110.00 6 🟡 骨干中型总成,强化CNC机加工时管控
P-204-STEER 高精度转向节臂管 广汽埃安Hyper 113.00 75.00 5 🟢 紧凑型零部件,成本构成稳健受控

大家仔细观察第二行制动卡钳体(P-605-CAL):即使它缺少外协钝化费用,全制造成本依然精准算出了 158.50 元,有效项目数准确识别为 5 项,整张表没有任何一行因 null 崩溃!


五、 老汪从业多年总结的 2 个避坑指南

  1. 务必先用 Record.SelectFields 过滤非数值列: – 很多同学直接写 Record.ToList(_),把整行的所有字段都转成了列表。结果列表中混入了【零件图号】、【核心零部件名称】等文本,传给 List.Sum 时就会直接报“类型不匹配”错误! – 牢记老汪的标准套路:Record.ToList(Record.SelectFields(_, {"科目1", "科目2"...})),先圈定数值科目,再转列表求和,百发百中!
  2. 动态获取所有数值列(高阶免维护秘籍): – 如果表里有 30 个费用科目,连科目名字都不想手写怎么办? – 我们可以先用 Table.ColumnNames 获取所有列名,用 List.RemoveMatchingItems 剔除掉前 3 个文本列,剩下的动态传给 Record.SelectFields,以后哪怕财务加了新科目,公式一行都不用改!

大家赶紧在文末免费下载随堂实操课件包,打开 PQ 高级编辑器跟老汪同步动手操练起来!

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

请登录后发表评论

    暂无评论内容