一页回答两件事:① 汇总大表的"生成计算"**参照了同事专项统计的哪些做法**;② 每次出表怎么验收(四层验收,已脚本化)。
来源:docs/汇总大表M0版式重建器规格_2026-10-06.md第十一节(2026-10-08 对齐表)、docs/汇总大表生成数据验证方法_2026-10-12.md、docs/要求与验收基线清单.mdR6、docs/确认回执汇总…_2026-09-07.md第八节。
| 同事专项统计的做法 | 他为什么能成立 | 汇总大表的对应做法 | 状态 |
|---|---|---|---|
一份母版(2026年十一数据.xlsx),**天为行、年为列** |
增长维度是「年」、天数固定 8 | 按 F10 按月按需扩列:读 N 月母版产出 N+1 月版式(不预留空列),母版只当版式来源 | ✅ 已实现(扩列器) |
| 母版**同时是数据容器**(历史年份值就在并排年列里) | 历史值随模板走 | 反过来做:历史参照值入库、母版只留版式、参照组由 DB 回填 | ⬜ 未实施(10-08 定方向) |
表头/行标签**语义定位**(findYearColumn/parseDayIndex) |
列序变了也能导 | 页规则表 SummarySheetRule:**按表头认月份组、按行标签认市州/指标,不硬编码列锚点** |
🚧 部分(月度块还依赖母版公式;2026-09 漏月即源于此) |
易漂移口径**外置成表**(holiday_calendar/passenger_coefficient/vehicle_adjustment) |
规则不散在代码与单元格里 | 外置:参照年保留组数、排名口径(全省不排名)、B=G+L/2+Q/10、缺数置空规则 |
🚧 部分 |
DECIMAL(30,15) + BigDecimal + 按 Excel 显示精度取值 |
精度口径统一、无浮点尾差 | 承接待办「16 张表 228 个 double 列改 DECIMAL+BigDecimal」;已做 F1 全精度存储+两位小数显示、母版文本数字归一 | 🚧 部分 |
| 导入两阶段确认 + 全程只读核对(历史数据不被误覆盖) | 先出差异清单、用户确认后才写 | 生成前先出缺数/差异清单、人工确认后再出表(B4 基数体检 + 《数据缺失清单》页) | ✅ 已实现 |
| 输出走模板文件(docx/PNG) | 版式来源单一 | 保留现有做法(快报改 word/document.xml、JFreeChart 出 PNG) |
— |
一句话:借的是**方法与纪律**(语义定位、口径外置、两阶段确认、精度统一),**不照搬**他"母版兼数据容器"的做法——我们反过来让历史值入库。
原则:**每一段都要有一个独立于该段的参照**;两边同源就验不出东西。
| 段 | 问题 | 参照 | 谁负责 | 程序能自证 |
|---|---|---|---|---|
| L0 源文件→库 | 源数据对不对 | 源文件/下发表模板 | 数据、业务 | 不能 |
| L1 库→口径值 | 算法口径对不对 | 手写 SQL 复算(不看母版/定稿) | 程序 | 能 |
| L2 口径值→单元格 | 写回对不对 | 上一期母版/生成件("不该动的格未变") | 程序 | 能 |
| L3 单元格→整本 | 与人工定稿一致吗 | 手工定稿(**记版本 + sha256**) | 双方复核 | 部分 |
| L4 跨页合成页 | 勾稽对不对 | 勾稽式本身(如 道路运输周转量 B=G+L/2+Q/10) |
程序 | 能 |
典型失败模式(原文):L0 漏导/列错位/单位差 10000/重复导入叠加;L1 规下倒减为负、Σ市州≠省行;L2 当月列没写、上期列被重算冲掉、公式断链;L3 把"定稿滞后"当"程序回归";L4 源页对而合成页引用错列。
工具:汇总表四层验收.py(L1–L4)+ 汇总表全盘体检.py(增量版,含 A/B/C/D)。命令: python 汇总表四层验收.py <生成表.xlsx> --源表 <当期源表.xlsx> --上期 <上期件.xlsx> --报告 验收报告.txt
| 层 | 查什么 | 真值/依据 | 通过标准 |
|---|---|---|---|
| 验收 L1 结构断言 | 全簿公式与表头 | 表头本身 | 累计=当年 1..M 月之和;累计同比分母=去年 1..M 月;**历史列零变化**;无月首日期串;#REF!=0 |
| 验收 L2 与源表 | 8 个可见台账页 | 当期业务源表 | 逐格 diff=0;差异须逐条结论并签核 |
| 验收 L3 内部勾稽 | 全簿 | 由 L2 推导 | 全省=Σ市州;累计=Σ各月;排名/占比自洽 |
| 验收 L4 跨期报警 | 全簿 | 上期件 | 同口径环比超阈值(默认 ±30%、基数≥100)即提示 |
白名单机制:已知且已解释的差异显式登记(轮渡块形态、母版模板遗留日期值、源表自带脏值被清空…);**白名单之外任何差异=不通过**,不再靠人工逐条解释。
两套切分的对应关系(重要):
| 验收四层 | 覆盖第二节的哪一段 |
|---|---|
| 验收 L1 结构断言 | 链条 L2(写回层)为主 |
| 验收 L2 与源表/定稿 | 链条 L3(出表层);源表可用时也覆盖 L0 的结果 |
| 验收 L3 内部勾稽 | 链条 L4(合成页) |
| 验收 L4 跨期报警 | 链条 L1 的"环比异常"体检 |
| 未覆盖 | 链条 L1 的"SQL 锚点复算"尚未脚本化(待办) |
| # | 约定可以参照的 | 做了吗 | 现在实际怎么做 |
|---|---|---|---|
| 1 | 按需增长列 → F10 按月按需扩列 | ✅ | 扩列器已实现;底稿取 _cache\summaryWorkbook_<期>_month_v*.xlsx;**未接主链**(resolveSummaryMother 只精确匹配)→ 每月仍需人工一步(扩列→确认落盘→生成) |
| 2 | 表头/行标签语义定位 | 🚧 | 已做:表头动态定位、按「A 市州名 + B 指标文案」定位行、扩列按基准月份列判表头、累计/累计同比按表头重建(2026-10-13 新增)。未做:页规则表 SummarySheetRule(用启发式替代) |
| 3 | 输出走模板文件 | ✅ | 复制母版 → 回填/还原 → 排名页按母版标题格对齐搬块 → 7 标题页按 period 现写 |
| 4 | 口径外置成表 | ⬜ | 写死在代码/母版:系数 2、10、排名口径、缺数置空规则 |
| 5 | 精度统一(DECIMAL+BigDecimal) | ⬜ | 仍走 double;已做 F1 全精度+两位小数显示、母版文本数字归一 |
| 6 | 两阶段确认+只读核对 | ✅(环节不同) | 同事在导入侧做;我们在**生成侧**做(缺数清单+货运体检+导出前弹窗+《数据缺失清单》页)。**导入侧仍是重复导入直接覆盖** |
| 7 | 二维表三层职责 | 🚧 | 原始值 ✅(导入表齐全);配置值、人工调整值**均无表**;**Excel 仍承担历史值存储**(2025 参照值在母版里) |
| 8 | 人工调整值单独建表(覆盖层) | ⬜ | 靠 _备份_/_bak_ 母版 + 人工改母版兜 |
不可照搬 3 条的执行:不把 Excel 当数据源 ✅(业务数据走 DB,但历史参照值仍在母版 ⚠️);母版只留版式 ⬜;独立「新年组」逻辑 ❌(跨年 month>=12 抛错)。
借同事的:① 语义定位(比对与定位都不硬编码列锚点);② 参照值入库、母版只留版式(阶段 2 核心);③ 口径与人工调整外置成表 + 覆盖层留痕(覆盖值+原因+时间)。
自建:④ SQL 锚点复算(链条 L1,唯一能发现"源表自身错"的层);⑤ L2 比对覆盖补齐(班线包车/网约车/货运,用语义映射);⑥ L4 跨期阈值报警(已实现)。
汇总表语义比对.py)按「行=市州+指标、列=年+月+类型」归位后比对 2026-09 生成件 与 桌面源表:
| 页签 | 可比行 | 差异 | 结论 |
|---|---|---|---|
| 班线包车 | 54 | 0 | ✅ 原被"表头布局不同"跳过,现可比且完全一致 |
| 公交 / 出租 / 城市客运 / 公路总客运 / 轨道、轮渡 | 72/69/36/36/10 | 0 | ✅ |
| 网约车 | 72 | 8 | ⚠️ 全省 4 个指标的 2026-09 当月值 = 生成 0、源表有值(4997.74 / 29166.70 / 4571.18 / 23367.09);同比 = -100%。属**库内 9 月网约车缺数**(订单/pin 未导),非算错 → 但"缺数期同比显示 -100%"应改为留空(待处理) |
| 中口径明细 / 中口径客运量 | 181 | 62 / 22 | 差异全为 生成=None / 源='#DIV/0!' → 源表脏值被清空(生成件更干净) |
结论:把语义比对补上后,班线包车 可证实一致;网约车 的差异可归因到"缺数",不属于算错。