上一篇推文之后,我又给 Skill 加了一个"王炸级"的示例项目。不是那种花五分钟就能写完的 Demo——而是我花了多年时间,在一家大型集团公司的 SAP 项目中实战验证过的核心技术。今天,我要把一个真正的"工业级"案例拆给你看。
在这篇文章里,我会把三个东西放在一起给你看:
1. 一个全新的 Skill 示例项目——「wps-udf-tree-collections」
这是我刚刚做完、合并进 Skill 蓝图体系里的第八套蓝图。它的核心能力是用 Excel-DNA 的自定义函数,在 Excel 里直接操作父子维度的组织架构树、科目结构树,并基于树结构做事实指标的层级汇总。
2. 两个真实的生产级 SAP 项目
我在某大型制造集团做的两个 SAP BPC/BW 报表分析 Excel 插件——一个专注于财务报表工作台与审核流转,一个专注于多维即席分析与透视查询。这两个项目不是"做一个玩玩"的 Demo,而是真正的企业级生产系统,每天被几十个财务人员高强度使用。
3. 一个你听完会拍大腿的结论
Excel-DNA 的"内存对象跨公式共享"特性,和父子维度的树结构查询,是天作之合。
不是因为我把这两者放在一起所以它们是一对——而是我在 SAP 项目里踩了无数坑之后,才真切体会到:这才是 Excel 插件该有的样子。
在讲技术之前,我想先跟你聊点"道"层面的东西。
很多人提起 SAP,脑子里蹦出来的词是"贵""庞大""实施周期长""界面丑"。没错,这些都是真的。但你有没有想过一个问题——
为什么这么多世界五百强、这么多大型集团企业,哪怕被 SAP 虐得欲仙欲死,也不愿意换别的系统?
尤其在中国,用友、金蝶做了几十年了,产品也不差。为什么大集团该用 SAP 的还是用 SAP?
我的答案很简单:SAP 太懂财务用户了。
而这套"懂"的核心武器之一,就是 SAP BW(Business Warehouse)的多维数据分析能力。具体来说,SAP 有一整套极其成熟的父子维度(Parent-Child Hierarchy)建模体系,专门用来处理集团企业里最复杂的一件事——组织架构和财务科目分析。
让我用一个场景给你讲清楚。
你是一个集团财务分析师。你手里有一张 Excel 表,列 A 是"公司编码",列 B 是"公司名称",列 C 是"本期收入"。
看起来很简单对吧?三列数据,VLOOKUP 一下就能解决问题。
但实际的情况是这样的:
同一张"公司"维度的表里,有五个层级的数据同时在跑。
它们全放在同一列。你现在要做两件事:
1. 层级判断:南山区营业部到底是第几层?它的直属上级是谁?它的完整组织路径是什么?
2. 层级汇总:华南大区事业部的收入,等于它下面所有子孙公司的收入之和吗?
这还没完——在真实的 SAP 项目里,同一个维度可能不止一棵树。
什么意思?以"科目"维度为例。同一个科目编码"10010100",在管理口径的组织架构树里,它属于"管理费用-办公费";但在法人报表口径的组织架构树里,它可能属于"期间费用-管理费用-办公费"。
一棵树变成两棵树,甚至三四棵树。而且都是动态的——随着时间推移,组织架构在变,科目结构也在变。
这就是 SAP 的父子维度层级结构——也是我在这两个生产级项目中要解决的核心技术难题。
聊到 BI 工具,很多人第一个想到的是 Power BI。微软倾全力推广,学习资源铺天盖地,入门门槛极低,可视化效果惊艳——说它是"大众化的 BI 工具之王"毫不为过。
但如果你把上面那个"同一列不同层级 + 多棵树 + 时间版本"的父子维度场景扔给 Power BI,它会直接懵逼。
为什么?因为 Power BI 的数据模型内核,是一套围绕**星型模型(Star Schema)**设计的引擎。
在星型模型里,维度表的设计逻辑是:
看到了吗?Power BI 最擅长的是"把不同层级拆分到不同列、不同表"——比如地区一列、城市一列、门店一列,各列之间是平行展开、互不干扰的。这在零售、电商这些"层级结构扁平、稳定"的行业里,完全够用。
但在企业财务领域,维度结构天生就是"不平行"的。
Power BI 的 DAX 语言里确实提供了一组父-子函数:PATH()、PATHITEM()、PATHLENGTH()、PATHCONTAINS()。
表面上看,它们就是用来处理这种"同一张表内的 id/parentid 层级关系"的。但实际上,这组函数有几个致命短板:
第一,PATH 是扁平字符串,不是真正的树。
PATH 函数返回的是一个用"|"分隔的编码串,比如 "A|B|C|D"。这意味着:树结构被"拍扁"成了字符串,你失去了所有树结构的优势——没有层级索引、没有高效遍历、没有最近公共祖先查询。
你想知道"C"节点有多少个子孙?不好意思,PATH 不会直接告诉你。你得遍历整个表,用 PATHCONTAINS 一个一个判断。1000 个节点的维度,光这一个查询就要扫 1000 次。
第二,PATH 不支持动态多层级版本。
上一节的场景——同一个编码"10010100",在管理口径和法人口径下属于完全不同的路径。Power BI 怎么处理?你只能在 DAX 里写两套完全不同的计算列,或者用极其复杂的 SWITCH 逻辑。这在 Excel 里的财务用户根本不可能自己写出来。
第三,PATH 不支持跨树的分析操作。
"两个节点的最近公共祖先是什么?""当前节点在哪棵树上?""这棵树的根节点有几个?"——这些都是财务分析的日常操作。但在 PATH 的字符串世界里,这些操作要么极其昂贵,要么根本做不了。
**没有一个 DAX 函数能回答这个问题:**"华南大区"下面所有子孙节点(不管多少层),它们的本期收入加总是多少?
不是因为 DAX 不够好——而是因为 Power BI 的数据引擎从底层就不是为"父子维度"这种关系型层级结构设计的。 它擅长的是"每一列是一个独立的、无层级嵌套的维度属性"。
相比之下,SAP BW 里的父子维度(Parent-Child Hierarchy)是一个一等公民——从底层多维引擎到上层查询语言 MDX,全程原生支持。展开节点、层级汇总、祖先路径查询——这些在 SAP 里是基本操作,在 Power BI 里得绕一大圈。
Power BI 一个 Pro 账号一个月才几十块钱。SAP 一个 BW 模块的授权费可能是 Power BI 的几百倍甚至上千倍。
但从世界五百强到大型国有企业,它们在财务和供应链上的核心系统,仍然是 SAP。
原因非常直白:
企业级数据分析的真正分水岭,不是可视化好不好看,而是能不能准确处理"多层级、多版本、多口径"的复杂维度结构。
具体来说:
• 财务合并报表:母公司和子公司的交易要抵消、少数股东权益要拆分——这依赖于极其精准的组织架构树。差一个层级节点,整个集团的合并报表就错了。
• 管理口径 vs 法人口径:同一个部门,在管理会计的科目树里是一个"成本中心",在法定报表的科目树里可能被拆分到三个不同的"法人实体"。Power BI 需要你在 ETL 阶段做数据拆分和重建,而 SAP 的父子维度原生就支持"一套数据、多套层级"。
• 时间版本变化:2025 年 6 月之前,深圳分公司属于华南大区;7 月 1 号组织架构调整之后,它划归华东大区了。如果你要出一份跨半年的对比报表,6 月和 7 月的层级路径不同——Power BI 要处理这个,你得在数据加载时给每条打上时间标签然后写复杂的 DAX 过滤。SAP 呢?在 BW 里建维度的时候勾上"时间相关"就行了。
这就是为什么 SAP 配得上一个"贵"字。 它贵在底层数据建模的正确性和完整性,贵在面对真实企业复杂业务时不妥协。而"便宜的工具",往往是用"简化业务假设"来换取低成本的。
Power BI 很好——当你不需要处理这种量级的维度复杂度时,它是绝佳的选择。
但当你面对的是一个几十家子公司、几百个成本中心、每年变两三次组织架构、财务口径还有两三套并行的集团企业时——你需要的能力,Power BI 给不了,SAP 给得了,而现在,我的 Excel-DNA + TreeCollections 方案也给得了。
写到这里,我想顺带吐槽一个现象。
你打开任何一个国内 ToB 软件的产品发布会、融资新闻、公众号推文,不出三句话你一定能看到这些话术——
"彻底取代 Excel!""颠覆传统电子表格!""比 Excel 好用一百倍!"
说真的,这些口号我听了十几年了。从最早的 BI 工具到后来的低代码平台,从数据中台到 AI 报表——每一个都号称自己是"Excel 杀手"。
但结果呢?喊得最响的那几家,要么融完钱就销声匿迹了,要么产品做出来连一个集团级客户的财务月结都撑不过去,要么落地之后用户发现——脱离 Excel 根本没法干活,最后又偷偷加了一个"导出 Excel"的按钮。
而真正的赚钱王者、企业软件收割机 SAP,对 Excel 是什么态度?
人家没有喊过一个字"取代 Excel"。人家做的是:倾尽资源,做出 EPM 和 AO 这两个重量级 Excel 插件,把 SAP BW 的全部能力无缝嵌入到 Excel 里。 两个插件的说明书各有几百页,版本迭代几十年,投入的研发资源不知道能养活多少个国内的"Excel 杀手"创业公司。
SAP 比谁都清楚:你可以让用户不离开 Excel,但你可以让 Excel 离不开你。
财务用户打开 Excel,看到的是熟悉的单元格、熟悉的公式、熟悉的操作习惯。但背后跑的,是 SAP 的多维引擎、父子维度层级、时间版本管理。用户不需要学新工具,不需要迁移工作习惯——所有的能力长在了他们最熟悉的工具上。
这就是 SAP 的底层逻辑:不跟用户的习惯较劲,而是把能力做进用户的习惯里去。
反观国内那些天天喊"取代 Excel"的产品——他们真正想取代的不是 Excel,而是用户十几年积累的工作习惯和业务直觉。这件事,从来就没有成功过。而且我可以断言:未来也不会成功。
因为真正的企业级产品,不是做一个"看起来比 Excel 炫"的工具去跟 Excel 竞争——而是做一个"让 Excel 变得更强"的工具,让用户用了就回不去。
SAP 从来不喊口号。它只是年复一年地把产品做到极致,让你心甘情愿地为它买单——不管它多贵。
SAP 当然知道这个需求有多刚,所以他们自己做了两个 Excel 插件:
这两个插件的说明书,每一个都有几百页。版本迭代之频繁,功能之丰富,足以说明一个问题:
SAP 比任何人都清楚——财务用户的天堂,不是花里胡哨的可视化大屏,而是一个能跟 Excel 深度融合、能处理复杂维度层级的数据工具。
为什么是 Excel?因为有调研数据显示,全球超过 70% 的财务专业人员以 Excel 为核心工作工具。SAP 不会蠢到让财务用户离开 Excel,它选择的是:把能力做进 Excel,而不是把用户拉出 Excel。
这也正是我在该项目中走的路线——复刻并重新打造一套比 EPM 和 AO 更好用、更顺手的 Excel 插件。
现在来点实在的。让我告诉你我在那个大型制造集团的 SAP 项目里到底做了什么。
这是一个 VSTO + WPF 的 Excel 插件,功能深度远超你的想象:
插件有 8 个 Ribbon 功能区分组、几十个功能按钮。最大的 ViewModel 文件足足 507KB,可见其业务复杂度。
你看着我这个项目可能会想,"一个 Excel 插件为什么这么大?功能这么多?"
因为它不是在处理"一个简单的报表生成",它是在处理——
这些全部都是真实的 SAP 项目需求。不是功能堆砌——是真实的业务压力逼迫出来的复杂度。
第二个项目更聚焦——这是一套专门用来做 SAP BW 即席分析的 Excel 插件。
核心工作流是:选择模型 → 选择维度 → 把维度成员拖放到行轴/列轴/页轴 → 系统自动构建查询 → 返回数据填入 Excel。
听起来像一个"BI 工具"对吧?但它的精髓不在这个流程本身,而在对维度成员的处理上。
在这个插件里:
最核心的是——所有这些操作都依赖于一个预构建好、常驻内存的维度树结构。
好,关键的来了。
在上面两个 SAP 项目中,有一个技术组件贯穿始终——TreeCollections。
它是一个开源的 .NET 树集合库。我在两个生产级项目中,用它来构建和查询整个 SAP BPC 的所有维度树结构。
现在,我把这个库完整内嵌到了 Excel-DNA Skill 的新蓝图 wps-udf-tree-collections 里,并且做了两件非常"透彻"的事:
我的蓝图做的是一个完整的 BI 分析模型——维度表 + 事实表 + 层级汇总,全部在 Excel 单元格里完成。
具体来说:
=DIM_BUILD( 维度表区域,"id", "parentid", "name", "组织维度")这一条公式,把你工作表中写好的维度表区域(包含 id 和 parentid 两列),一次性构建成一棵完整的维度树快照,存进 Excel-DNA 的内存句柄。
然后,你可以用下面这些函数,基于这个句柄做各种查询:
=DIM_STATUS( 句柄 ) → 查看树的节点数、根数、叶子数=DIM_FIND( 句柄,"华南", 20 ) → 关键字搜索维度成员=DIM_PATH_NAMES( 句柄, "SZ001" ) → 返回完整层级路径=DIM_LEVEL( 句柄, "SZ001" ) → 返回节点的层级深度=DIM_PARENT( 句柄, "SZ001" ) → 返回父节点编码=DIM_CHILDREN( 句柄, "SZ001" ) → 返回直属子节点列表=DIM_DESCENDANTS( 句柄, "SZ001" ) → 返回全部子孙节点列表=DIM_LEAVES( 句柄, "SZ001" ) → 返回叶子节点列表=DIM_SIBLINGS( 句柄, "SZ001" ) → 返回兄弟节点列表=DIM_IS_ANCESTOR( 句柄, "HQ", "SZ001" ) → 判断 HQ 是否为 SZ001 的祖先=DIM_LCA( 句柄, "SZ001", "GZ001" ) → 返回两个节点的最近公共祖先=DIM_SCOPE_IDS( 句柄, "HQ", TRUE, TRUE, FALSE, "," ) → 返回节点作用域内的所有编码=DIM_ATTR( 句柄, "SZ001", "leader") → 读取节点属性但维度查询只是第一步。真正的王炸在后面——事实聚合。
在 BI 分析里,我们不光要知道"这个节点有几层、它的上级是谁",更要知道"这个节点 + 它的所有子孙节点,收入合起来是多少。"
这就是 FACT_AGG 做的事:
=FACT_BUILD( 维度句柄, 事实表区域,"id", "month='2026-07'", "", "总部")先根据维度句柄和事实表,构建一个事实缓存。你可以在 build 阶段就加上筛选条件——比如只保留 7 月的数据、只保留总部区域的记录。
然后用 FACT_AGG 做汇总:
=FACT_AGG( 事实句柄,"华南大区", "amount", "sum", TRUE, TRUE, FALSE, "", "")这一条公式的意思是:取"华南大区"这个节点(includeSelf=TRUE),加上它下面所有子孙节点(includeDescendants=TRUE),把它们的 amount 字段汇总(sum)。
你还可以追加运行时筛选条件。 比如上面用的是"全量句柄",后面想切到某一个月份或某一个场景(如 actual vs budget),直接在 FACT_AGG 里传 factWhere="month='2026-07' and category='actual'" 就行。
更进阶的用法: 如果某个月份或某个区域会被反复计算,推荐单独 build 一个预过滤句柄:
=FACT_BUILD( 维度句柄, 事实表,"id", "month='2026-07'", "", "总部")然后后面所有 FACT_AGG 都基于这个预过滤句柄——一次构建,多次复用。这就是内存对象的魅力。
看到这里,有些懂行的朋友会问:"递归遍历一棵树的子孙节点去做汇总,难道不慢吗?Excel 里每算一次公式都要遍历一遍整棵树,性能能看吗?"
这就是 Excel-DNA 内存对象特性的精髓所在:
1. DIM_BUILD 把维度表区域解析、构建成一棵完整的树结构——这是一次性的高开销操作
2. 构建完成后,整棵树作为一个对象常驻在 Excel-DNA 的内存句柄里
3. 之后所有的 DIM_* 查询和 FACT_AGG 汇总,都是直接操作内存中的同一个对象,不需要重新解析、重新建树
"一次性付出 O(n) 的构建成本,换来后续每一次查询 O(log n) 甚至 O(1) 的响应速度。"
在 SAP 的 EPM 和 AO 插件里,同样的操作依赖的是 SAP BPC 底层引擎的服务器端计算——每次展开一个节点、每次汇总一笔金额,都要走一次网络请求,等几十毫秒甚至几百毫秒。
而在 Excel-DNA 的方案下,所有这些计算都在本地内存完成。
对比一下:
不需要服务器,不需要网络,不需要数据库。所有计算在你的笔记本电脑上完成,速度比请求远程服务器快几个数量级。
到这里,我想请你停下来想一想:
你见过多少开源项目的示例,是用虚构的、三行数据的"Hello World"来演示的?
我的这个蓝图不是。
它是我在大型制造集团的 SAP 项目中用了真实企业数据、真实父子维度层级结构、真实财务报表分析场景反复验证过的模式。然后我把核心逻辑抽离出来——去掉项目特定的数据库连接、去掉 SAP BPC 的私有接口——变成了一套通用的、任何有父子维度分析需求的人都能直接用的 UDF 函数体系。
这套方案能解决的具体问题包括但不限于:
而且所有这些,都不需要用户在 Excel 外安装任何数据库、不需要学习 SQL、不需要打开 Power BI。
用户只需要在 Excel 单元格里输入
=DIM_BUILD(...),然后像用 VLOOKUP 一样去用这十几个维度函数和事实函数。
做 SAP BW 开发的人都知道——想在 BW 里玩转父子维度查询,你得会写 MDX。
MDX 是什么?它是 SAP BW 的查询语言,语法长这样:
SELECT{[Measures].[AMOUNT]}ONCOLUMNS,{DESCENDANTS([Z_ENTITY].[HIERARCHY1].&[E1001])}ONROWSFROM[BPC_MODEL/ZBUDGET]WHERE([Z_TIME].[2026.07],[Z_SCOPE].[ACTUAL])MDX 很强大,但它有几个让人头疼的问题:
1. 学习曲线陡峭:不是 SQL,不是 DAX,是一套独有的多维度查询语法
2. 调试困难:报错了不知道是哪一行的括号少了还是层级路径写错了
3. 和 Excel 脱节:你得把 MDX 写在一个配置表里,或者在代码里拼字符串,用户完全看不到这个查询在做什么
4. 依赖服务器:没有 SAP BW 服务器,MDX 跑不了
在我之前的 SAP 项目中,MDX 是实现维度层级查询的核心手段。它确实能干活——跨行成员查询、层级展开、成员属性获取——这些全都能用 MDX 表达出来。
但现在,我换了一种完全不同的实现方式:
[Dim].Levels(...) | DIM_LEVEL( 句柄, "SZ001" ) | |
DESCENDANTS( [Dim].&[ID] ) | DIM_DESCENDANTS( 句柄, "SZ001" ) | |
ANCESTOR( [Dim].&[ID] ) | DIM_IS_ANCESTOR( 句柄, "HQ", "SZ001" ) | |
[Dim].Properties(...) | DIM_ATTR( 句柄, "SZ001", "leader" ) | |
AGGREGATE( ... ) | FACT_AGG( 句柄, "SZ001", "amount", "sum" ) | |
同样的效果,零服务器依赖,零网络延迟,零 MDX 学习成本。
这就是我说的"降维打击"——不是技术上更高端,而是从"企业级重型武器"变成了"人人都能上手的 Excel 函数"。
让我把所有信息串起来,给你一个完整的视角:
┌─────────────────────────────┐ │ 我的 Skill 蓝图矩阵 │ │ │ │ 基础蓝图(7套) │ │ ├─ wps-udf-only │ │ ├─ wps-ribbon-ctp-webview │ │ ├─ wps-workbook-automation │ │ └─ ... │ │ │ │ NEW! 专项蓝图: │ │ ├─ wps-udf-tree-collections │ ← 本文主角 │ │ ├─ DIM_BUILD │ │ │ ├─ DIM_*(13个函数) │ │ │ ├─ FACT_BUILD │ │ │ ├─ FACT_AGG │ │ │ ├─ FACT_TABLE │ │ │ └─ TreeCollections 内嵌 │ │ │ │ │ └─ 组合使用 │ │ wps-ribbon-ctp-webview │ │ + wps-udf-tree-collections │ + wps-udf-live-cache │ │ = 全功能 BI 插件! │ └─────────────┬───────────────┘ │ ┌─────────────────┴─────────────────┐ │ │ ┌───────▼──────────────┐ ┌─────────────▼──────────────┐ │ 财务报表工作台插件 │ │ 多维即席分析插件 │ │ (SAP 报表分析) │ │ (SAP 即席查询) │ │ │ │ │ │ 大型制造集团生产级 │ │ 大型制造集团生产级 │ │ VSTO+WPF │ │ VSTO+WinForm │ │ 507KB ViewModel │ │ TreeCollections 核心 │ │ 8组 Ribbon │ │ 维度树展开/收缩/交换 │ │ TreeCollections │ │ 父子维度成员管理 │ │ 财务分析工作流 │ │ MDX 查询构造 │ │ OA 审批集成 │ │ 即席报表生成 │ └──────────────────┘ └────────────────────────┘ │ │ └──────────────┬────────────────────┘ │ ┌────────▼────────┐ │ 共同的灵魂 │ │ │ │ TreeCollections│ │ 父子维度树引擎 │ │ │ │ 提取共性 → │ │ 放回 Skill │ │ 赋能更多人 │ └─────────────────┘写到这里,我想回到一个更根本的话题。
我做这些 Skill、写这些推文,终极目的是什么?
不是炫技,不是卖课,不是割韭菜。
我想让看到这篇文章的你,认识到两件事:
Excel-DNA 不是我发明的,TreeCollections 不是我写的,SAP 也不是我开发的。
但是——
把 TreeCollections 内嵌进 Excel-DNA 的自定义函数里,让用户在 Excel 单元格里用 =DIM_BUILD(...) 就能完成父子维度的全部分析——这件事,是我做的。
在两个真实的生产级 SAP 项目里,用这套技术方案替代了 EPM 和 AO 几百页说明书的功能——这件事,是我做的。
把自己的实战经验提炼出来,做成一个可以一键生成的标准 Skill 蓝图,让 AI 帮你把项目脚手架搭好——这件事,也是我做的。
这不是"我懂某个技术"。这是"我从需求 → 方案设计 → 编码实现 → 生产验证 → 经验提炼 → 工具封装"的完整闭环。
如果你有类似的需求:
这些,我都能做。而且不仅仅是"能做"——我有生产级项目验证过的完整方案。
我不只是一个"Excel-DNA Skill 的制作者"。我是一个在数据领域——特别是 Excel 深度开发、BI 报表分析、企业级 Office 工具定制——有十几年经验的专业玩家。
这些是我打了十几年才集齐的"七龙珠"。而你现在看到的每一套 Skill,都是一颗龙珠的具象化。
文章到这里就写完了。
如果你耐心读到了这里,我想告诉你的是:
这篇推文不是结束,而是开始。
如果你正在面临类似的难题——父子维度分析、层级报表汇总、Excel 插件开发、SAP 报表定制——你可以直接来找我聊。
一个电话,一条微信,说说你的情况。聊完你至少会知道:
能做的直接做,不能做的直说,绝不兜圈子。
公众号:Excel催化剂 | 微信:190262897
承接:Excel/WPS 插件定制开发 · 数据报表解决方案 · AI 编程培训 · SAP BW/BPC 报表优化
如果你正在做 SAP BW 报表、财务分析工具、或有任何 Excel 深度开发需求——欢迎加好友,我们聊聊。
想体验全套 Skill(含本文的 wps-udf-tree-collections 蓝图)?加我微信进群自助申请即可。
