EP032 List.Sort:财务BP与资产会计如何对工装模具执行内存级多字段复合排序

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

大家好,我是老汪。

在咱们汽车零部件制造企业(Tier 1 一级供应商),月末关账和资产盘点的时候,做工装模具核算、固定资产会计或产线财务 BP 的朋友,经常会遇到一个棘手的场景:

工厂为了给各大主机厂(比亚迪、吉利、特斯拉、蔚来等)承制核心零部件(底盘控制臂、制动盘、电池壳体托盘、副车架),投入了大量价值几十万甚至数百万元的专用工模夹具。这些工装模具的累计冲压次数(或加工工时)与单件摊销成本,直接关乎产品的量产降本指标与资产转固报废节奏。

月末关账前夕,设备工程部和工厂财务总监把各车间的模具台账扔给你:

“老汪,把全厂所有在产核心模具排个座次:第一看负荷,累计冲压冲次高的必须排在最前面,我们要查哪些模具快到疲劳报废线该补提折旧了;第二,如果有冲次一样的模具,单件摊销成本低的排在前面,我们要核定谁的性价比更高!别在界面上一步步手工点排序了,下个月改模更新数据,你能一键全自动刷新吗?”

很多初学 Power Query 的同学第一反应是去点界面上的【排序】按钮,或者只知道 Table.Sort。但在编写复杂的高级 M 函数、自定义批量清洗逻辑(比如按车间分组后,在内存中直接对每组内部进行动态打平排序)时,在内存里直接操作列表(List)或记录(Record)是性能最高、最优雅的极客打法!

今天老汪就带大家彻底吃透 M 语言里控制列表顺序的核心函数:List.Sort,手把手教你搞定内存级的多条件复合排序!


一、 为什么老汪说“学会 List.Sort 才算真正推开 M 语言高级算力的大门”?

很多朋友问:“老汪,界面上点一下排序不就完了吗?为什么要学 List.Sort?”

老汪跟你们说句大实话:界面的排序是针对‘二维表格’(Table)的笨重操作;而 List.Sort 是直接在内存管道里对‘列表(List)’和‘行记录(Record)’进行轻量级的高性能瞬时排序!

当你后面学会了 Table.Group(高级分组)或者写自定义递归函数时,分组内部嵌套的往往根本不是一张实体大表,而是一串纯净的记录集合。如果你还要把它转回 Table 排序再转回来,电脑内存直接卡死;而用 List.Sort,几毫秒内直接在内存核心搞定!

1. 函数基本语法拆解

List.Sort(list as list, optional comparisonCriteria as any) as list
  • 参数一(list):待排序的列表(可以是纯数字、纯文本列表,也可以是更高级的“列表套列表 List of Lists”或“记录列表 List of Records”);
  • 参数二(comparisonCriteria,可选):排序比较规则:
  • 默认缺省:升序(Order.Ascending,或简写为 0);
  • 降序:Order.Descending,在 M 语言中可以直接简写为数字 1!

2. 三大核心进阶语法(老汪亲测避坑)

  1. 单列纯值排序: – 升序:List.Sort({3, 1, 4, 2}) ➔ 返回 {1, 2, 3, 4} – 降序:List.Sort({3, 1, 4, 2}, Order.Descending) ➔ 返回 {4, 3, 2, 1}(也可以直接写 List.Sort({3, 1, 4, 2}, 1),极其干脆!)

  2. 嵌套子列表排序(List of Lists): – 如果一个大列表里面套着很多子列表(比如代表行数据):{{“A”, 30}, {“B”, 10}, {“C”, 20}} – 我们想按第 2 个元素(下标为 {1})降序排: powerquery List.Sort(大列表, {each _{1}, Order.Descending}) > ⚠️ 老汪敲黑板:注意看!只要带了 each 且需要降序,外层必须用大括号 {} 把 each 和 Order 包裹起来,这是 M 语言的固定语法!

  3. 记录列表排序(List of Records,★现代工程最推荐): – 当列表里包裹的是一条条 Record 记录时:{[零件="摆臂", 冲次=18], [零件="卡钳", 冲次=24]} – 我们不再用数字下标,而是直接用字段名(Key)提取: “`powerquery // 单字段降序 List.Sort(记录列表, {each [冲次], Order.Descending})

    // 多字段复合排序(冲次降序,冲次相同按摊销升序) List.Sort(记录列表, { {each [冲次], Order.Descending}, {each [摊销成本], Order.Ascending} }) “` 外层一个大列表,内层每一个条件都是一个小列表,逻辑严密,层级分明!


二、 走进车间:汽车零部件模具资产数据现场

拿老汪经手的一家知名汽车底盘与动力总成零部件制造企业(Tier 1)为例。厂里冲压、压铸和机加车间共有 8 套骨干模具工装,承接各主机厂明星车型的关键部件。

老汪从设备管理系统里导出的原始明细台账如下(大家可以在文末下载随堂课件跟老汪同步动手):

模具工装编号 工装类型 配套核心零部件 主机厂配套项目 累计使用冲次(次) 单件摊销成本(元/件) 资产原值(万元) 业务背景与关注点
MOLD-DC-01 高压压铸双腔模 铝合金底盘下控制臂 比亚迪海豹项目 185,000 28.50 160.0 骨干稳产模具
MOLD-ST-01 伺服连续冲压模 电池包下壳体托盘 吉利极氪001 240,000 32.00 220.0 冲次并列第一,摊销高
MOLD-DC-02 高压重力铸造模 轻量化通风制动盘 特斯拉Model Y 240,000 18.50 195.0 冲次并列第一,摊销低(优先排前)
TOOL-CNC-01 四轴数控精密夹具 双活塞制动卡钳体 蔚来ES6总成 95,000 14.20 65.0 爬坡期优良工装
MOLD-ST-02 机器人多工位冲模 前悬架减震器支架 长安深蓝SL03 150,000 22.00 110.0 冲次并列第二档
TOOL-WLD-01 底盘副车架焊接夹具 高强度轻量副车架 理想L7底盘 150,000 15.80 85.0 冲次并列,摊销更优
MOLD-DC-03 精密压铸成型模 驱动电机端盖总成 小鹏G6三电 210,000 26.00 145.0 高负荷运转模具
TOOL-CNC-02 高速加工中心专用刀架 转向节转向节臂 广汽埃安Hyper 120,000 12.00 55.0 经济实用工装

大家注意看:这里面有两对典型的“冲次并列”: 1. MOLD-ST-01 与 MOLD-DC-02 的累计冲次都是 240,000 次; 2. MOLD-ST-02 与 TOOL-WLD-01 的累计冲次都是 150,000 次。

按照设备与财务考核要求:冲次高的排前面;若冲次并列,单件摊销成本低的排前面!


三、 老汪手把手带你在高级编辑器中实操

💡 老汪敲黑板(免改路径直接刷新秘籍):
平时做财务分析最怕换台电脑一刷新就蹦出一堆刺眼的红色报错:“找不到文件路径”。老汪在给你们配套的随堂 Excel 课件里,特意放了免改路径自适应刷新代码。在【配置】表的 A1 预置公式 =LEFT(CELL("filename",$A$1), FIND("[", CELL("filename",$A$1))-1) 并命名为【当前路径】。不管你解压到哪个文件夹,打开直接点击【全部刷新】即可秒出结果,绝不报红字!大家可以直接抄走用在自己的日常工作中!

打开 Power Query 编辑器,新建空查询,进入【高级编辑器】,直接看老汪调校的生产级 M 代码:

let
    // 1. 【动态相对路径】:读取老汪预设的当前工作簿目录,换电脑绝不报错
    当前路径 = 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 
        "./", // 兜底相对路径

    源数据文件 = 当前路径 & "原始业务数据表.xlsx",

    // 2. 加载工作簿并读取「工装模具台账表」
    源工作簿 = Excel.Workbook(File.Contents(源数据文件), null, true),
    模具表_Sheet = 源工作簿{[Item="工装模具台账表", Kind="Sheet"]}[Data],
    提升标题 = Table.PromoteHeaders(模具表_Sheet, [PromoteAllScalars=true]),
    更改类型 = Table.TransformColumnTypes(提升标题, {
        {"模具工装编号", type text}, {"工装类型", type text}, {"配套核心零部件", type text},
        {"主机厂配套项目", type text}, {"累计使用冲次(次)", Int64.Type}, 
        {"单件摊销成本(元/件)", type number}, {"资产原值(万元)", type number}
    }),

    // =========================================================================
    // 🚀【核心实战技巧】:利用 Record 记录列表执行极速多字段复合排序
    // =========================================================================
    // 3. 将二维表格化为“记录列表”(进入极致轻量的内存管道)
    模具记录列表 = Table.ToRecords(更改类型),

    // 4. 调用 List.Sort 双条件复合排序:
    //    第一条件:累计使用冲次(次) 降序排列 (Order.Descending)
    //    第二条件:单件摊销成本(元/件) 升序排列 (Order.Ascending)
    记录复合排序 = List.Sort(模具记录列表, {
        {each [#"累计使用冲次(次)"], Order.Descending},
        {each [#"单件摊销成本(元/件)"], Order.Ascending}
    }),

    // 5. 瞬间将排好序的纯净内存结构还原为标准数据表
    还原表 = Table.FromRecords(记录复合排序),

    // 6. 追加序号与财务资产管控建议
    添加序号 = Table.AddIndexColumn(还原表, "排序序号", 1, 1, Int64.Type),
    添加评估建议 = Table.AddColumn(添加序号, "资产评估建议", each 
        if [#"累计使用冲次(次)"] >= 200000 then "临近报废大修线,优先安排转固复核"
        else if [#"累计使用冲次(次)"] >= 150000 then "骨干模具稳定期,重点管控分摊单价"
        else "新品量产爬坡期,设备工况优良", 
        type text
    ),

    // 7. 整理列顺序,整洁呈现给管理层看板
    最终呈现 = Table.ReorderColumns(添加评估建议, {
        "排序序号", "模具工装编号", "工装类型", "配套核心零部件", "主机厂配套项目",
        "累计使用冲次(次)", "单件摊销成本(元/件)", "资产原值(万元)", "资产评估建议"
    })
in
    最终呈现

四、 最终清洗效果与管理层看板对照

代码运行后,出来的最终财务看板表格如下:

排序序号 模具工装编号 工装类型 配套核心零部件 主机厂配套项目 累计使用冲次(次) 单件摊销成本(元/件) 资产原值(万元) 资产评估建议
1 MOLD-DC-02 高压重力铸造模 轻量化通风制动盘 特斯拉Model Y 240,000 18.50 195.0 临近报废大修线,优先安排转固复核
2 MOLD-ST-01 伺服连续冲压模 电池包下壳体托盘 吉利极氪001 240,000 32.00 220.0 临近报废大修线,优先安排转固复核
3 MOLD-DC-03 精密压铸成型模 驱动电机端盖总成 小鹏G6三电 210,000 26.00 145.0 临近报废大修线,优先安排转固复核
4 MOLD-DC-01 高压压铸双腔模 铝合金底盘下控制臂 比亚迪海豹项目 185,000 28.50 160.0 骨干模具稳定期,重点管控分摊单价
5 TOOL-WLD-01 底盘副车架焊接夹具 高强度轻量副车架 理想L7底盘 150,000 15.80 85.0 骨干模具稳定期,重点管控分摊单价
6 MOLD-ST-02 机器人多工位冲模 前悬架减震器支架 长安深蓝SL03 150,000 22.00 110.0 骨干模具稳定期,重点管控分摊单价
7 TOOL-CNC-02 高速加工中心专用刀架 转向节转向节臂 广汽埃安Hyper 120,000 12.00 55.0 新品量产爬坡期,设备工况优良
8 TOOL-CNC-01 四轴数控精密夹具 双活塞制动卡钳体 蔚来ES6总成 95,000 14.20 65.0 新品量产爬坡期,设备工况优良

大家仔细看: – 第 1 名和第 2 名的冲次都是 240,000 次,但因为制动盘模具单件摊销成本只有 18.50 元,低于冲压模的 32.00 元,稳稳排在前面; – 第 5 名和第 6 名同样是 150,000 次冲次,焊接夹具摊销 15.80 元低于冲模的 22.00 元,同样精准排在前列!

这就是标准的多条件复合排序,整洁严密,毫厘不差!


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

  1. 大括号嵌套规则(很多人写漏报错):
    单条件排序时,如果只需要升序,写 each [字段] 就行;但只要加上降序或写了多条件,每一个排序规则都必须封装为一个子列表 {each [字段], 排序方向},而且外层还要再套一个大列表 {...}!写的时候务必检查括号是否成对配齐。

  2. 为什么推荐 Table.ToRecords 而不是 Table.ToRows?
    用 Table.ToRows 得到的是数字下标(如 _{4}、_{5})。如果车间下个月在中间插了一列,索引全部错位崩溃;而用 Table.ToRecords 是通过字段名(Key)寻找数据,不管列顺序怎么换,代码坚如磐石!


六、 随堂课件下载与动手实操

光看不练假把式。老汪已经把本节课涉及的完整练习题做成了一个标准课件包,内含: – 📂 原始业务数据表.xlsx(包含 8 套工装模具台账明细,供你亲手演练) – 📂 最终完成版_带PQ查询.xlsx(内嵌完整自适应 M 查询与配置表,解压即用) – 📂 M_动态自适应脚本.m(可直接用记事本打开复制的纯净代码)

大家下载后解压,亲自把老汪这套流水线跑一遍。如果在实操中遇到任何问题,欢迎在评论区留言交流!

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

请登录后发表评论

    暂无评论内容