扫码入库记录 → 客户箱数汇总
这个 Skill 解决什么
把厂商系统导出的「扫码入库记录」宽表(70 列、数万行)整理成一份可直接给业务看的客户箱数汇总表。全过程是确定性脚本,口径集中在配置里,任何数字都能回溯到原始行数漏斗。
核心难点已经沉淀在脚本与 references/口径与字段说明.md 中,尤其是:
- 不能用「规格」列判断件数,必须按「物流码类型」折算
- 入库数量=0 是重复扫码/冲销,必须剔除
- 「盖内码装」不等于「五码装」,容易被 contains('五码装') 误判
- 同一客户可能由多家经销商供货,行数≠客户数
第一步:先看清源文件
运行前先确认三件事,避免拿错窗口的数据:
python3 -c "
import pandas as pd
d = pd.read_excel('<源文件>.xlsx', sheet_name=0)
print(len(d), d['入库时间'].min(), '~', d['入库时间'].max())
print(d['扫码类型'].value_counts())
print(d['客户类型'].value_counts())
"
重点看:入库时间范围(不同导出窗口不可直接相加或算增长,有的导出含「退货入库」)、扫码类型分布、列数是否 70 列。列数不符说明不是同一张导出。
第二步:预览漏斗(不写文件)
python3 scripts/build_summary.py --src "<源文件>.xlsx" --preview
会打印逐级过滤的漏斗表、总箱数、年度拆分、折算部分、待确认量、TOP10 客户。先核对漏斗:如果「④-1 纳入主表」为 0 或明显偏小,说明产品关键词配置与本次产品不符,调整后再生成。
第三步:生成成品
python3 scripts/build_summary.py --src "<源文件>.xlsx"
默认输出到源文件同目录:客户入库箱数汇总_<label>_<YYYYMMDD-HHMM>.xlsx。用 --out 指定路径。
参数
| 参数 | 默认 | 说明 |
|---|---|---|
--src |
必填 | 扫码入库记录 xlsx |
--out |
自动 | 输出路径 |
--customer-type |
终端 |
传 "" 表示不过滤 |
--scan-type |
采购入库 |
传 "" 表示不过滤 |
--product-all |
30年\|60年 / 2017版 / 500ml\*6 |
用 \| 分隔多个正则,必须全部命中 |
--pack-include |
五码装 |
包装版本必须命中 |
--pack-exclude |
盖内码装 |
明确排除,优先于 include 判定 |
--label |
2017版五码装500ml*6 |
产品简称括注,同时用于输出文件名 |
--coef |
箱码=1,瓶码=0.166,盒码=0.166 |
折算系数(箱) |
--keep-zero-qty |
关 | 保留入库数量=0 的记录 |
--config |
— | JSON 文件,批量覆盖以上口径 |
--preview |
— | 只打印漏斗,不写文件 |
换产品线的例子
# 只看 60年
python3 scripts/build_summary.py --src x.xlsx --product-all "60年"
# 换成盖内码装(并把排除项清空)
python3 scripts/build_summary.py --src x.xlsx --pack-include 盖内码装 --pack-exclude "" \
--label "2017版盖内码装500ml*6"
# 换系数(如按 1/6 精确折算)
python3 scripts/build_summary.py --src x.xlsx --coef "箱码=1,瓶码=0.1667,盒码=0.1667"
第四步:自检并交付
生成后必须核对,全部通过才能交付:
python3 -c "
import pandas as pd
f = '<输出>.xlsx'
m = pd.read_excel(f, '01_客户箱数汇总', header=3)
m = m[m['序号'].apply(lambda x: str(x).isdigit())]
t = m['合计箱数'].sum()
print('总箱数', round(t, 3), '行', len(m), '客户', m['客户编码'].nunique())
print('年度相加=合计:', (abs(m.filter(like='年箱数').sum(axis=1) - m['合计箱数']) < 0.002).all())
for s, c in [('02_客户产品明细','合计箱数'),('03_经销商汇总','箱数'),('04_区县汇总','箱数'),('05_产品汇总','箱数')]:
d = pd.read_excel(f, s, header=3); d = d[d['序号'].apply(lambda x: str(x).isdigit())]
print(s, round(d[c].sum(), 3))
"
四个表的总计必须与表01一致。然后向用户汇报,必须包含:
1. 漏斗(每步剩余行数,尤其剔除了多少退货入库、多少入库数量=0)
2. 总箱数与年度拆分占比、度数拆分
3. 经销商与区县 Top、集中度
4. 待确认量(表06)+ 异常状态条数
5. 若与历史文件对比,先说明两个文件的时间窗口是否一致
输出结构(8 个工作表)
| Sheet | 内容 |
|---|---|
| 00_说明与口径 | 数据源、统计范围、折算规则、逐级漏斗、结果核对、待确认项 |
| 01_客户箱数汇总 | 基础信息(经销商/区县/编码/名称/跟进人)+ 各年度箱数 + 合计 + 占比 + 记录数 + 异常状态数 |
| 02_客户产品明细 | 客户 × 产品简称(年度·度数)交叉,横向合计=表01 |
| 03_经销商汇总 | 客户数、各年度箱数、占比 |
| 04_区县汇总 | 同上 |
| 05_产品汇总 | 产品 × 物流码类型,可核对瓶/盒折算来源 |
| 06_待确认_无包装标注 | 命中产品关键词但未标注 pack_include 的,未计入主表 |
| 07_图形 | 经销商、区县 年度堆叠柱状图 |
格式已固化:泸州老窖红表头、隔行浅底、冻结窗格、筛选、合计行、千分位三位小数、xxx占比 百分比。
口径默认值的来历
默认值来自 2026-11 与业务确认过的需求,改动前先问清楚:
- 客户类型=终端、扫码类型=采购入库(退货入库不计入库量)
- 产品范围=30年/60年 + 2017版 + 五码装 + 500ml*6;38度/52度分列,不做合并
- 箱码=1箱,瓶码/盒码=0.166箱(业务给定系数,注意 6 瓶=0.996 箱≠1 箱,属系数本身特性)
- 汇总粒度=来源经销商+区县+客户编码+客户名称;主要跟进人取记录数最多者,其余进「协同跟进人」
字段含义、决策依据、踩过的坑见 references/口径与字段说明.md。
环境依赖
pandas、numpy、openpyxl。无需其他第三方库。本机无 LibreOffice,xlsx 版式只能通过 openpyxl 断言校验,不要承诺截图核验效果。