Tableau 本身没有杜邦分析功能,我们为此开发了杜邦分析可视化扩展,把 ROE 的拆解做成了能在 Tableau 里直接用的图表。
扩展文件和示例数据都放在我们的扩展网站( https://vizwise.cn/pages/tableau-viz-extensions )。去那里下载杜邦分析的> TREX 文件和示例数据文件,第一次用建议连示例数据一起下,照着填更快上手。
截至目前,我们这套 Tableau 扩展里,其他十个都是一个套路:拖一个维度、拖一个度量,图就出来了。换一份数据、换一张表,字段类型对得上就能画。玫瑰图、漏斗图、蜂群图、河流图都这样。
杜邦分析不是。
它是唯一一个对数据源有硬要求的组件,得先按我们的格式把数据备好,才画得出图。除了这棵固定的树,它还带一个 ROE 变动归因的抽屉,把 ROE 的涨跌拆到三个因子上看(见第七节)。
一、它跟别的扩展差在哪
其他扩展是字段驱动的:给什么字段,画什么图。
杜邦分析是模型驱动的。扩展内部有一棵写死的树,根是 ROE,往下拆销售净利率、资产周转率、权益乘数,再往下拆到净利润、营业收入、总资产、净资产,一路拆到你填进去的原始科目。父子关系、加减乘除、哪个节点显示成百分比,都在代码里定死了。数据只负责往 18 个固定格子里填数字。
所以数据源必须满足:行号用模板里的 1 到 18,或者科目名用我们的标准名("主营业务收入""流动资产"这类)。
这跟其他扩展不是一个体验,但不是偷懒,是杜邦分析这个东西本身决定的。
二、杜邦分析为什么没法做成通用组件
杜邦分析从来没有统一标准。
常见的有两因素(总资产收益率 × 权益乘数)、三因素(销售净利率 × 资产周转率 × 权益乘数),往下还有五因素,把净利率再拆成税盾和利息负担。这还只是最粗的分法,真正麻烦的是细节口径:
- 资产周转率的分母用期末总资产,还是期初期末平均?
- 净利润取净利润,还是归母净利润?
- 有息负债的利息要不要从净利率里加回来、单列一项?
- 少数股东权益摆在哪?
- 收入用营业收入,还是主营业务收入?
这些不是学术争论。同一家公司同一年的数据,换一套口径,ROE 能差出几个百分点,而每个平台、每个财务系统的默认选法都不一样。
所以只有两条路:要么做一个配置项多到没人愿意打开的怪物,要么把口径定死,做透一个版本。
我们选了后者,三因素。
三、三因素,公式是这样
ROE = 销售净利率 × 资产周转率 × 权益乘数
销售净利率 = 净利润 ÷ 营业收入
资产周转率 = 营业收入 ÷ 总资产
权益乘数 = 总资产 ÷ 净资产净利润走的是完整三阶:
营业收入 = 主营业务收入 + 其他业务收入
毛利 = 营业收入 − 营业成本
期间费用 = 销售费用 + 管理费用 + 研发费用 + 财务费用
营业利润 = 毛利 − 期间费用 − 税金及附加 + 其他收益 + 投资收益 + 其他收支
利润总额 = 营业利润 + 营业外收入 − 营业外支出
净利润 = 利润总额 − 所得税费用三个口径提前说清楚,免得你填完发现对不上。
两处收入是同一个数,都是营业收入。 净利率的分母和周转率的分子,用的都是营业收入(主营业务收入 + 其他业务收入)。这不是巧合:三因子相乘要严格还原 ROE = 净利润 ÷ 净资产,中间那个收入项必须约得掉。两边口径一旦不同就约不掉,树上算出来的 ROE 会偏离真实值,偏多少取决于其他业务收入的占比。
营业收入在树上左右各出现一次。资产周转率下面那个不再展开明细,主营和其他业务收入的拆解,统一在左边「销售净利率 → 营业收入」下看。
总资产和净资产用你填进去的数,扩展不区分期末还是平均。 多数场景填期末数。但资产周转率、权益乘数常用期初期末平均来算,单文件模板里直接把平均值填进第 15–18 行就行,总资产、净资产随之变成平均口径——扩展不设开关,它只认你给的数字。一张图呈现一个口径的切片,跨期对比靠期间列做期间对比,不靠平均。
净利润是全部股东口径,不是归母净利润。 合并报表里有少数股东权益的公司,这个 ROE 会比归母 ROE 高。目前没有开关,这是已知边界。
四、要填的就是 18 个格子
利润表:14 项(行号 1–14)
| 行号 | 科目 | 说明 |
|---|---|---|
| 1 | 主营业务收入 | 主营口径的收入 |
| 2 | 其他业务收入 | 副业、废料、租赁等 |
| 3 | 营业成本 | |
| 4 | 税金及附加 | 城建税、教育费附加等 |
| 5 | 销售费用 | |
| 6 | 管理费用 | |
| 7 | 研发费用 | |
| 8 | 财务费用 | |
| 9 | 其他收益 | 政府补助等 |
| 10 | 投资收益 | 投资净收益 |
| 11 | 其他收支 | 非经常性损益,自己填一个汇总值 |
| 12 | 营业外收入 | |
| 13 | 营业外支出 | |
| 14 | 所得税费用 |
行号 11 是个杂项口子。公允价值变动收益、资产减值损失、资产处置收益,各家差别大,我们不做细分,算个净额填进来就行。
资产负债表:4 项(行号 15–18)
| 行号 | 科目 | 说明 |
|---|---|---|
| 15 | 流动资产 | 直接填流动资产合计 |
| 16 | 非流动资产 | 直接填非流动资产合计 |
| 17 | 流动负债 | 直接填流动负债合计 |
| 18 | 非流动负债 | 直接填非流动负债合计 |
四个格子,全是合计行。货币资金、应收账款、存货、长短期借款这些明细一概不进这张表。
模板里没有的行,你也不用造。总资产、总负债、净资产这几个上层节点,扩展自己算。
为什么利润表细、资产负债表粗
利润表科目相对标准化。营业利润以上这一串,A 股报表里几乎固定,个别公司多一个少一个,填 0 就行。展开得细,分析才有用,你能在树上直接点开,看管理费用涨了多少、吃掉了几个点的净利率。
资产负债表不一样。不同行业、不同公司的科目千差万别,而且大量科目对多数公司常年是零。明细全列进来,等于每次填表都面对一张几十行的空表,填的人先崩溃。
代价也明确:这个扩展偏利润表。ROE 的变动是从利润率、周转率还是杠杆来的,它答得上来;资产结构健不健康、应收账款周转几天,它答不了,得配别的图,堆叠柱、瀑布图、趋势线都比杜邦树合适。
五、两种数据载入方式
示例文件 杜邦分析示例数据.xlsx 有三个 sheet:数据模板、映射表、填写说明。前两个对应两种用法。
单文件模板,最快
数据模板是一张扁平表:行号、科目名称、科目英文名称、数值、年份、填写说明、报表来源。
一年 18 行。填完这 18 行的数值,一年的杜邦分析就出来了。
想要多年,把 18 行整段复制一遍,改年份列(这一列拖进扩展的期间槽)。想分析多家公司,加一列"公司",然后在 Tableau 里给公司加筛选器。
这一步有个坑:加了公司列不加筛选器,扩展不报错,它把各家公司的金额加总,算出一个合并口径的 ROE。数字看着合理,几家的钱已经混在一起算了。多公司场景,筛选器不是可选项。
数据从哪来,两条路:
- Tableau Prep 加工,把财务系统导出的表处理成这个格式;
- 数据不多的话,把财报丢给 AI,让它把数字摘进模板。一年 18 行,这活儿 AI 干得比手抄快,也不容易看错行。
映射表,接自己的报表
报表定期更新、公司多、频次高,每次手填不现实,这时候用映射表。
映射表的结构:行号 + 标准科目名 + 科目英文名 + 映射列。前三个不动,你只改映射列,写成你单位报表里的实际科目名。比如标准名是"主营业务收入",你利润表上那一行写的是"其中:营业收入",映射列就填后者。
配好之后,拿映射列跟你财务报表里的科目字段做关联,财务表本身不用动,也不用给它加行号列。关联完,扩展拖映射表带过来的"行号"和财务表的"数值"两个字段就行。
关联怎么做都行:Tableau 里建关系、Prep 里做 join、Excel 里先查一次表把行号带出来,没有限制。
映射支持一对多。行号 11「其他收支」在示例映射表里挂了三个来源科目:公允价值变动收益、资产减值损失、资产处置收益。财务系统导出的表里这几项通常是分开的,一并归到行号 11。
怎么选
| 单文件 | 映射表 | |
|---|---|---|
| 适用场景 | 一次性分析、公司少、年份少 | 定期更新、多公司、接财务系统 |
| 准备工作 | 填 18 行/年 | 配一次映射表,做一次关联 |
| 后续维护 | 每次重填 | 数据刷新即可 |
| 上手难度 | 十分钟 | 看你的数据结构 |
一句话:看一次就用单文件,要长期用就上映射表。
平均口径怎么填
资产周转率、权益乘数常用期初期末平均,但平均要你自己先算好填进去,扩展不替你求平均。单文件模板最省事:第 15–18 行直接填平均总资产、平均净资产,图出来就是平均口径,一步到位。
映射表方式处理平均就别扭了。源报表里利润表、资产负债表往往同时带着期初、期末,要靠筛选或自定义计算字段把两期并成一期再求平均,步骤多、易错,一般人很难掌握。所以平均口径优先走单文件直接填报;如果非接财务系统,就把求平均放在 Tableau Prep 里预处理,或者把原始数字丢给 AI 整理成平均值模板——比在扩展里现算快得多。
六、拖字段,和几个会让你怀疑人生的坑
三个编码槽:
- 行号(必填,维度):拖行号列或科目名称列都认,拖一个即可。
- 数值(必填,度量):拖金额列。
- 期间(选填,维度或连续度量都吃):把年份(或月份、季度)字段拖进来,才开启期间对比。期间可以是离散文本(2024、2024年)、连续数字(2024.0),也可以是日期字段,粒度由 Tableau 决定。默认显示期取最新、基准期取次新,也就是自动对比最近两个期间;两个下拉各自独立,可以手动覆盖,选成一样就不显示对比。
拖完一片空白的话,按下面挨个查。
行号对不上,扩展静默丢弃。 它只认 1 到 18 这 18 个字符串,以及标准科目名。行号列在 Tableau 里被识别成带小数的度量(1.0、1.00),或者格式化成 01、混了全角字符,就匹配不上,那一格直接当 0。最稳的做法是把行号列设成文本类型。
科目名写错,同样静默丢弃。 不报错,那一格当 0。症状是 ROE 明显偏小,图照样画得出来,很容易误判成数据填错了。
同一期间、同一行号的多条记录,扩展是累加的。 前面几家被合并成一家,就是这个机制。反过来,行号不在 1 到 18 里的科目(比如你把"货币资金"这种明细行塞进数据源)会被忽略,不污染结果,但也白填了。
金额单位必须统一。 扩展不做换算。元就全是元,万元就全是万元,混着填比率就错。
排查先做减法。 只拖行号和数值,不拖期间,看 ROE 出不出来。出来了再逐年加复杂度。
还有一句:期间对比只在你把字段拖进期间槽时开启。字段拖到详细信息架不会触发对比,这是故意的,免得别的字段误带出对比、把图弄乱。
七、ROE 变动归因
光看 ROE 从 15% 变到 18%,看不出是哪使劲。归因抽屉就是把这一变动拆到三个因子上:销售净利率、资产周转率、权益乘数各自贡献了多少个百分点(pp)。
归因比较的是两个期间之间的差异(ΔROE = 报告期 ROE − 基期 ROE),所以它有个前提:期间字段必须拖进期间槽,且数据里至少有两个不同期间。没有期间、只有一个期间、或基准期和显示期选成同一个,就没有 ROE 变动可归,归因抽屉不会出现,树上的贡献胶囊也不画。
方法用顺序替代法(连环替代法),替代顺序固定为 净利率 → 周转率 → 权益乘数。顺序不能配:顺序一变,三个因子的贡献额会同时变,同一份数据就出现两个答案。好处是三个贡献额加起来严格等于 ROE 的变动(ΔROE),链条闭合,没有残差。
图表右边有个抽屉把手,点开:
- 收起时是一行摘要,告诉你 ROE 比基准期变了多少 pp;
- 展开是瀑布图加明细表。瀑布图首末两根是总量,必须从 0 画起,截断轴会夸大变动幅度;中间三根各因子的增量,虚线串起累积高度,一眼看出是谁拉着 ROE 走。
树上每个节点右侧还有个贡献胶囊,直接标这个节点对 ROE 变动的贡献(pp)。胶囊内容可在配置页选:只显示 pp、只显示占比、或者两者都显示。
占比口径解释一下:单个因子的贡献额除以 ΔROE 得到一个占比,但 ΔROE 接近 0 时这个占比会失真(分母太小,正负被放大)。所以:
- 占比含正负:正贡献为正、负贡献为负,正常情况用它;
- 占比取绝对值:所有因子按绝对值算占比,适合某因子贡献极小、正负占比失去意义时;
- 自动:默认占比含正负,只有 |ΔROE| 小于 0.01pp 时才自动降级成绝对值。
三个比率前提会挡住归因:净资产小于等于 0、营业收入等于 0、或总资产等于 0 时,归因停用并提示,不会静默显示 0,因为这时候比率本身没意义。
八、什么时候不该用它
适用面窄。下面这几种,它现在给不了答案:
- 五因素杜邦分析;
- 归母净利润口径;
- 把资产负债表拆到明细科目做结构分析;
- 自定义归因顺序(归因固定三因素,顺序不可改)。
它只解决一件事:ROE 的变动到底从哪个口子来。利润率、周转率、杠杆,是单独一项还是几项合力,一层层点开能追到原始科目;配合归因抽屉,还能直接看到每个因子贡献了多少个百分点。
No comments yet