本工具用于把 立讯未立账明细表(SAP 导出)与 客户对账单(客户发来的账单文件) 自动进行金额/数量匹配,找出「客户已确认、但 SAP 尚未立账」的差异,输出规范化的对账结果 Excel。
工具在选中的文件夹里扫描所有 Excel 文件,完全按文件名关键字自动分类,不需要手动选择哪份是 SAP 表、哪份是对账单:
| 表类型 | 识别规则(代码中的判断条件) | 示例文件名 |
|---|---|---|
| SAP 未立账表 (我们的表) | 文件名包含以下任一关键字:未立账 或 未对账 或 SAP | 立讯未立账明细.xlsx联想SAP.xlsx未对账清单.xls |
| 客户对账单 (需求方) | 文件名以 「立讯」开头,且其后紧跟数字 (允许中间有空格或下划线) | 立讯 2033579_联想对账单.xls立讯2033580_对账明细.xlsx |
~$ 开头)会被自动排除,不会误参与匹配。.xlsx.xls(旧版 .xls 通过 xlrd 读取)。一个文件夹可放多张客户对账单,工具逐一处理。
联想对账工具V2.exe(无需安装 Python 或任何依赖,纯本地运行)。立讯对账匹配结果.xlsx,打开即见 6 个 Sheet(见第 5 节)。匹配的目标:对于客户对账单里的每一笔「需求数量 D」,在 SAP 未立账表里找到一组整行, 使其数量之和恰好等于 D;找不到整组时,才允许在某一行「拆单」。
X。对一个需求 D,在候选行中用「折半搜索(meet-in-the-middle)」寻找一组行使其数量和 恰好 = D:
exact_subset(候选行, D): 把候选行分成两半,分别枚举「所有可能的子集和」 在两侧找:左和 + 右和 = D 的组合 返回能凑齐 D 的一组整行(否则返回 None,退化拆单)
候选优选规则(当多个组合都能整组凑齐 D 时):优先选「扣账时间早的行尽量都被选中」的那组, 即把最晚的 SAP 行留作未匹配(N),从而让尽可能多的早日期扣账行被匹配掉。
这是工具最关键、也最容易误解的一步:
对排序后的未立账行逐行累加数量,设累加到第 k 行时首次 ≥ 需求 D(即「溢出」):
❌ 错误做法:把前 1..k-1 行「锁定」为已匹配,再从第 k 行往后找。
问题:可能后面所有行都凑不齐,但其实把 1..k 里的某行替换掉就能凑齐。
✅ 本工具做法:前 1..k-1 行不锁定。
从范围 m = k 起向后逐范围扩大(1..k, 1..k+1, … 1..N),
在每个范围 1..m 内用 exact_subset 找「整行恰好 = D」的组合:
· 找到 → 该组合全部标记 Y(可能替换前缀中的某些早行,仍零拆单),结束。
· 所有范围都凑不齐 → 前 1..k-1 行 Y,第 k 行拆单(标 X,取剩余量),其余 N。
| 标记 | 含义 | 说明 |
|---|---|---|
| Y已匹配 | 该行作为整行被某笔需求完整匹配 | 零拆单,最理想状态 |
| X拆单 | 该行被「拆开」只取其中一部分数量 | 仅当所有整行组合都凑不齐时才发生 |
| N未匹配 | 该行未被任何需求匹配 | 通常为最晚的溢出行,留作后续处理 |
| 忽略负数应收 | 未立账数量为负(应收)的行 | 单独归类,不参与正向匹配 |
| Sheet | 内容 |
|---|---|
| SAP原表(标注) | 原始 SAP 未立账数据,每行附加「匹配标记」列(Y/X/N/忽略)。 |
| 匹配结果 | 按客户凭证展开的 12 列明细,记录每笔需求由哪些 SAP 行凑齐。 |
| 客户未消耗明细 | 客户对账单中未能被 SAP 未立账覆盖的部分。 |
| 已忽略(负数应收) | 未立账数量为负的行,单独列出便于核对。 |
| 客户未识别料号 | 对账单中出现、但 SAP 未立账里找不到对应物料编号的料号。 |
| 汇总 | 各类标记的数量与金额统计,一眼看清整体对账进度。 |
通常是该物料下所有「整行组合」都无法恰好凑齐某笔需求,工具把最晚的溢出行留作 N(等后续需求或人工处理)。 若想让更早的行优先被匹配,工具已在算法层面做了「早行优先」处理(见 4.3 / 4.4)。
正常,但应较少。仅当某个物料无论如何都无法用整行凑齐时才拆单。如拆单较多,建议检查对账单数量是否有误或存在未提供的未立账行。
支持。同一文件夹放多张客户对账单(文件名含各自客户标识 + 「对账单」),工具按表分别匹配。 若对账单文件名未含「对账单」关键字,请补充后重跑。
不会。工具在本地离线运行,数据不出本机。
SAP 与 对账单 关键字。