本文简介:
每月从系统导出一张销售订单明细,几千行、几百家门店,老板问「这个月卖得怎么样」,只能临时拉透视表——每次拉的口径还不一样,数字对不上就得重来。
这篇文章借一个手机厂商国别经销团队的真实需求(数据已脱敏,地名与机型均为替换后的示例),把一条完整路径讲透:两张 Excel 怎么洗成一张能反复用的一维明细表、净销量与退货率口径怎么定、分州地图怎么画、为什么「州」要按收货地址而不是销售区域、机型与门店怎么联动下钻,以及怎么看穿地图上看不见的客单价差异。
文内嵌了一套可以直接点击的分州地图看板 Demo:点州、点机型,全页图表跟着联动;文末附数据接入方法、常见坑清单与 FAQ。
核心结论速览:销售看板要看哪些指标、口径怎么定?
先把整套方法的口径浓缩成一张表,后文逐条展开:
| 环节 | 口径 / 做法 |
|---|---|
| 数据源 | 销售订单明细 + 退货订单明细(两张 Excel,结构固定,月月导出) |
| 清洗 | Power Query 建固定管线 → 一张一维明细表,一行 = 一张订单的一个机型 |
| 净销量 | 销售数量 − 退货数量(退货行以负数入表,求和即净值) |
| 净销售额 | 销售金额 − 退货金额 |
| 退货率 | 退货台数 ÷ 销售台数 |
| 客单价 | 净销售额 ÷ 净销量 |
| 地理口径 | 分州地图按收货地址所在州,不按销售区域(管理口径会变) |
| 地图实现 | ECharts registerMap + 州级 GeoJSON(ADM1 级),抽稀后约 100 KB |
| 交互联动 | 点州 / 点机型 → KPI 与全部图表一起筛选 |
| 数据链路 | Power Query 清洗 → 一维表 → 看板整文件替换 data.js |
说明:本文所有数据均为脱敏演示数据(客户名称、机型、门店、仓库与地理信息均已替换,金额按令吉计)。数量、日期与单据结构未作改动,因此集中度、退货率、机型结构这类结构性结论依然成立;口径与真实交付完全一致,方法可以直接复用到你家数据上。
客户是谁?这个案例要解决什么痛点?
答案先行:一家手机厂商的国别经销团队(也是我们的一对一陪跑客户),每月从商家后台导出两张 Excel——销售订单详情和退货订单详情,要一张销售看板,点名要有全国分省的地图。
先澄清一个容易搞错的认知:这不是连锁零售的门店 POS 数据。卖方固定(品牌方),买方是各地独立的手机店——本例 676 家,绝大多数是独立小店。所以这份数据看的是经销商进货(订货),不是终端零售。口径搞错,后面所有分析都是错的。
痛点集中在三条:
| # | 痛点(客户原话归纳) | 后果 |
|---|---|---|
| 1 | 每月导出几千行,临时拉透视表 | 每次口径不同,数字对不上 |
| 2 | 老板要看「哪个州卖得好」 | 表格说不清,缺地图 |
| 3 | 想知道哪个机型、哪个仓在跑量 | 每次都要重做一遍筛选 |
结构化之后其实是四件事:把两张表洗成一张 → 定净销量口径 → 画分州地图 → 让机型 / 仓库 / 门店能联动下钻。
两张 Excel 怎么洗成一张能反复用的明细表?
答案先行:Power Query 建一条固定管线,两张源表进去、一张一维明细表出来,一行 = 一张订单的一个机型。数据每月结构固定,所以管线建一次,之后就是「替换源文件 → 刷新」。
| 层 | 内容 |
|---|---|
| 源 | 销售订单详情(8,021 行)+ 退货订单详情(14 行),列结构固定 |
| 清洗 | 统一列名、规范日期、拆出门店代码、补州字段 |
| 一维表 | 期间 / 类型 / 单号 / 日期 / 店铺 / 区域 / 州 / 地图 / 仓库 / 机型 / 数量 / 金额 |
| 输出 | 一张 xlsx,8,035 行 |
两个关键决定:
其一,退货行以负数入表。 退货数量与金额直接取负,这样任何维度求和都是「净值」,不用在每个度量值里再写一次「销售 − 退货」。本例 3,122 张销售单、6 张退货单,求和后:销售 58,809 台、退货 164 台、净销量 58,645 台。
其二,州字段要单独判定。 原始导出只有「销售区域」(城市名),没有州。清洗时按城市名建一张映射表判定所属州——本例 22 个城市 → 15 个州,判定不出来的落「未识别」,清洗完必须检查它是 0。这一步偷懒,地图就会缺一大块,而且各州金额加总对不上总数。
净销量、退货率、客单价,口径到底怎么定?
答案先行:净销量 = 销售 − 退货;退货率 = 退货台数 ÷ 销售台数;客单价 = 净销售额 ÷ 净销量。三个数各有各的用处,别混着用。
2026 年 6 月这批数据(脱敏演示)跑出来是这样:
| 指标 | 数值 |
|---|---|
| 销售订单 / 退货单 | 3,122 张 / 6 张 |
| 销售台数 / 退货台数 | 58,809 / 164 |
| 净销量 | 58,645 台 |
| 退货率 | 0.28% |
| 净销售额 | 5,278.3 万令吉 |
| 客单价 | 900 令吉/台 |
| 覆盖 | 676 家门店 · 42 款机型 · 22 个城市 · 15 个州 · 7 个仓库 |
| 有效销售日 | 24 天,日均 2,444 台 |
退货率 0.28% 这个数本身是「没问题」的信号——说明这批货在渠道里没有系统性质量或错发问题。但真正要盯的是它的单量结构:6 张退货单相对 3,122 张销售单,一旦某个月退货单张数跳到几十张,即便退货率还只有 1%,也意味着某个州或某个机型出了批次问题。所以看板把「退货单张数」和 KPI 放在一起,就是这个原因——比率会稀释问题,单量不会。
分州地图怎么画?为什么「州」要按收货地址而不是销售区域?
答案先行:ECharts 用 registerMap 注册一份州级 GeoJSON(ADM1 级),再用 series.type = "map" 渲染;地图填色用的是收货地址所在州,不是销售区域。
为什么非要用收货地址?因为「销售区域」是管理口径——业务团队怎么划分大区、怎么归属门店,是可以人为调整的;今天归在吉隆坡的店,下季度可能被划到雪兰莪。而收货地址是物理事实,货发到哪个州就是哪个州。要做产能规划、仓配布局、物流成本分析,只能用物理口径;用管理口径画地图,地图会跟着组织架构调整而变形,同比环比全乱。
地图边界取自 geoBoundaries 的开放数据(ODbL 1.0,数据源 OpenStreetMap),授权干净可商用;原始 2.95 MB 经 Douglas-Peucker 抽稀 + 坐标取整去重压到约 100 KB,加载无压力。
15 个州的分布(脱敏演示):
| 州 | 净销量 | 销量占比 | 净销售额 | 金额占比 | 客单价 |
|---|---|---|---|---|---|
| 雪兰莪 | 16,554 台 | 28.2% | 1,414.1 万 | 26.8% | 854 |
| 吉隆坡 | 7,826 台 | 13.3% | 774.7 万 | 14.7% | 990 |
| 柔佛 | 7,280 台 | 12.4% | 600.5 万 | 11.4% | 825 |
| 沙巴 | 4,823 台 | 8.2% | 449.0 万 | 8.5% | 931 |
| 霹雳 | 4,119 台 | 7.0% | 329.3 万 | 6.2% | 799 |
| 槟城 | 3,651 台 | 6.2% | 369.3 万 | 7.0% | 1,011 |
| 砂拉越 | 3,343 台 | 5.7% | 365.0 万 | 6.9% | 1,092 |
| 马六甲 | 1,876 台 | 3.2% | 210.0 万 | 4.0% | 1,120 |
| 其余 7 州 | 9,173 台 | 15.6% | 766.4 万 | 14.5% | 835 |
前三州(雪兰莪 + 吉隆坡 + 柔佛)合计 52.9%,正好卡在「半壁江山」上;要覆盖 80% 的销售额需要 7 个州。
客单价的州际差异怎么看?为什么地图上看不见?
答案先行:把「销量占比」和「客单价」两张图叠着看,才能看出每个州在卖什么价位的货。地图只能告诉你谁卖得多,不能告诉你谁卖得贵。
同一批数据里,客单价最高的马六甲是 1,120 令吉/台,最低的布城只有 348 令吉/台,差了 3.2 倍。这不是定价错了,是产品结构差异:
- 高客单州(马六甲 1,120 / 砂拉越 1,092 / 槟城 1,011 / 吉隆坡 990):中高端机型占比高。槟城、吉隆坡是成熟城市市场,消费者认机型、愿意为影像和屏幕加钱。
- 低客单州(彭亨 776 / 霹雳 799 / 柔佛 825):走量机型为主。柔佛销量 7,280 台排第三,金额却只排第三——卖得多、卖得便宜。
- 布城 348 令吉/台(285 台):典型的异常值。285 台的体量对全盘没有影响,但它往往意味着某个渠道在清仓,或者录入口径有问题。
这一层只看地图颜色深浅是永远看不到的:雪兰莪颜色最深(销量第一 28.2%),但客单价 854 低于全国 900 的平均线。所以看板把「州排名」放在地图旁边,而且可以点——点一个州,全页切过去。
机型结构的集中度比州更高:42 款机型里,前 5 款就占了净销量的 77.2%(M3c-4+64 单款 31.6%),30 款机型的占比不足 0.5%。这意味着两件事:主力机型的备货不能断,长尾机型的库存周转要单独盯。
发货仓库则高度集中——巴生港中心仓一家发出 80.2% 的货,槟城分仓 8.1%、新山分仓 6.6%、古晋分仓 4.6%。东马(沙巴、砂拉越)合计占 13.9% 的销量,却只有一个古晋分仓在支撑,这个错配就是下一步要算的物流账。
看板最终长什么样?(文内可直接点)
答案先行:纯展示层的 HTML 看板——顶部 4 个 KPI,中间「分州地图 + 州排名」双图,下方每日趋势、机型、销售区域、发货仓库四图,最下面是门店订货前 20 名表;点地图上的任意州、或点任意机型,全页 KPI 与所有图表一起联动。
下面的就是活的 Demo(脱敏演示数据),不是截图——你可以直接点:
页面结构从上到下:
| 区块 | 内容 | 交互 |
|---|---|---|
| 期间切换 | 全部 / 2026-06 | 点击切换,全页联动 |
| KPI 行 | 净销量、净销售额、销售订单、退货率 | 净销量含销售 / 退货拆分;退货率含单量 |
| 分州地图 | 15 州填色(净销量),可滚轮缩放 | 点州 → 全页筛选;再点一次取消 |
| 州排名 | 15 州横向条形 | 点州条 → 与地图同步 |
| 每日净销量 | 24 天折线(销售 − 当天退货) | 看峰谷节奏 |
| 机型 | TOP12 机型横向条形 | 点机型 → 全页筛选 |
| 销售区域 | TOP12 城市 | 按净销量排序 |
| 发货仓库 | 7 仓占比环形图 | 按销售数量(不含退货) |
| 门店订货 | 净销量前 20 家门店明细表 | 跟随州 / 机型筛选 |
实测出来的节奏也很说明问题:24 个有效销售日里,峰值在 6 月 10 日(7,001 台),谷值在 6 月 22 日(257 台),峰谷差 27 倍;周日普遍无单。这种波动不是数据错了,是订货节奏本身——经销商集中下单,看日均 2,444 台反而是被平滑掉的假象。看板保留逐日折线,就是不让你被平均数骗。
数据从哪来?清洗管线跑完怎么接进看板?
答案先行:Power Query 负责洗,看板只负责展示。 展示层零写死、只吃一份数据文件;清洗管线跑完按约定格式整文件替换,页面脚本一行都不用改。
接入只要四步:
- Power Query 建管线:两张源表 → 一张一维明细表(列结构见上文表格);
- 跑清洗,检查「未识别州 = 0」;
- 按
data.js的 schema 拼装(一行一条,字段名保持一致); - 整文件替换,刷新页面,核对 KPI 与 Excel 透视结果一致。
三条必须满足的校验:
- 净销量 = 销售台数 − 退货台数(用 Excel 透视交叉验一遍);
- 各州净额合计 = 全盘净额(州的判定不能有漏、不能有重);
- 未识别州 = 0。
这个「洗显分离」的分工还有个好处:客户自己每月跑清洗(已购课程,陪跑教到会),展示模板由我们交付——同一套模板换一份数据文件,就是下一个客户的新看板。
上手这套方法,最容易踩的坑有哪些?
答案先行:五个坑,每一个都在这个案例里真实出现过。
| 坑 | 后果 | 正确做法 |
|---|---|---|
| 地图按「销售区域」填色 | 组织一调整,同比环比全乱 | 按收货地址所在州(物理口径) |
| 退货另开一张表单独算 | 每个度量值都要减一次退货,容易漏 | 退货行取负数入一维表,求和即净值 |
| 州字段靠人填、不建映射表 | 漏判 / 重判,地图缺块、金额对不上 | 城市→州映射表 + 「未识别 = 0」硬校验 |
| 只看销量排名 | 看不出「卖得多但卖得便宜」 | 销量占比与客单价叠着看 |
| 用日均销量做判断 | 订货是脉冲式的,均值掩盖峰谷 | 保留逐日折线,看峰值与节奏 |
另有一个地图的正常形态别当 bug:面积大的州颜色未必深。沙巴、砂拉越在地图上占了东马一大片,销量却只有 8.2% 和 5.7%——choropleth 地图填色看的是数值不是面积,这是它最经典的误读,汇报时最好口头补一句。
FAQ:关于销售看板,读者最常问的五个问题
销售看板应该看哪些核心指标?
第一类看规模:净销量、净销售额、订单数;第二类看质量:退货率、客单价;第三类看结构:分州、分城市、分机型、分仓库的占比与集中度。规模指标回答「卖了多少」,质量指标回答「卖得好不好」,结构指标回答「是谁在卖、卖的什么」——三类缺一不可。
退货数据怎么处理才最不容易出错?
把退货行的数量与金额取负数,和销售行放在同一张一维明细表里。这样任何维度直接求和就是净值,不需要在每个度量值里重复写「销售 − 退货」,从根上避免漏减。退货率单独定义为「退货台数 ÷ 销售台数」,同时把退货单张数放在 KPI 上——比率会稀释问题,单量不会。
分省 / 分州地图的数据从哪来,会不会有版权风险?
用公开地理数据,推荐 geoBoundaries(ODbL 1.0,数据源 OpenStreetMap),授权干净可商用;在 ECharts 里用 registerMap 注册 GeoJSON 后即可渲染。注意两点:一是行政层级要取对(省级即 ADM1),二是原始边界文件往往几 MB,需要用 Douglas-Peucker 抽稀并压缩坐标精度,压到 100 KB 级才适合网页加载。
几百家门店,看板怎么展示才不乱?
不要试图在一张图上铺满所有门店。做法是:主图只显示 TOP10–TOP20,下方配一张可排序的明细表,并让它们跟随州 / 机型筛选联动。长尾门店的价值在于「能被查到」,不在于「被画出来」。本例 676 家门店中,TOP10 只占 14.9%,贡献 80% 销售额需要 277 家——这种极度长尾的结构,画全反而什么都看不清。
每月数据更新麻烦吗?
不麻烦。看板是纯展示层,只吃一份数据文件;清洗管线(Power Query 或脚本)每月跑一次,按 schema 整文件替换,刷新页面即可,页面与脚本无需任何改动。月度更新就是「跑清洗 → 校验三条 → 替换 → 核对 KPI」四步。
作者与更新说明
我是汪斌(老汪),制造业财务出身,专注成本核算、业财融合与 Excel BI / Power BI 落地,运营「老汪洞察」。本文来自一个真实的一对一陪跑案例,客户与产品信息已脱敏;文中数据均为脱敏演示数据,口径与真实交付一致。更新于 2026-09。
汪斌带你开公司 | 老汪洞察 | 小微之家会计服务 · www.accunion.cn
想让你家的销售数据也变成一张能点的看板?
如果你手头也有一堆每月导出的订单明细,却说不清「哪个区域卖得好、哪个机型在跑量、哪个仓扛着货」,可以像这位客户一样从一份需求清单开始:一对一陪跑覆盖需求梳理 → 口径确认 → 清洗管线 → 看板交付。想自己动手做的,Excel BI 财务建模实战课从 Power Query 清洗一路讲到看板发布。

添加老汪微信(xiaoweihome_ah),聊聊你家的销售看板












暂无评论内容