# 利息公式重叠检测方法 ## 问题描述 xlsx本息计算表中,同一列可能有多行利息公式。如果时间范围重叠,SUM汇总行会重复计算。 ## 检测步骤 1. 逐列提取所有利息公式行的时间范围: ```python # 伪代码 for col in interest_columns: periods = [] for row in data_rows: formula = ws.cell(row, col).value if formula and is_interest_formula(formula): start_date, end_date = parse_date_range(formula) periods.append((row, start_date, end_date)) # 检查重叠 for i, (r1, s1, e1) in enumerate(periods): for (r2, s2, e2) in periods[i+1:]: if s2 < e1: # 后一个的起始在前一个结束之前 print(f"OVERLAP: Row {r1} ({s1}-{e1}) and Row {r2} ({s2}-{e2})") ``` 2. 常见重叠模式: - **累计vs累计**:D13=(A13-A9)..., D15=(A15-A9)... → D15包含D13的全部期间 - **期间+累计混合**:某行用期间公式(A13-A11),另一行用累计(A15-A9) - **安全模式**:所有行用期间公式且首尾相连(如F列:F11从E3, F13从A11, F15从A13) ## 修复方法 ### 方案A:删除中间行,保留最后的累计公式 - 删除D13(中间累计行),D15覆盖全段 - 适用于:中间行无扣减动作依赖该数字 - 优点:简洁,公式少 - 缺点:中间节点的利息数字消失,docx中不能引用 ### 方案B:全部改为期间公式(推荐) - D13=(A13-A9)*rate*principal → 保留(2023-7-5到2025-1-23) - D15=(A15-**A13**)*rate*principal → 只算后半段(2025-1-23到2025-8-27) - 适用于:所有行都应保留(如docx需要引用中间节点的利息数字) - 优点:每个时间节点都有独立数字,SUM正确 ### 选择依据 - 如果docx正文中需要引用中间节点(如"截至2025年1月23日的利息为X元"),用方案B - 如果docx正文跳过中间节点直接算到暂计日,用方案A ## 2026-06-09 梁永案实例 ### 原始问题 ``` D9 = (A9-C3)*1%*12/365*C4 → 2019-1-13 到 2023-7-5 (1634天) ✓ D10 = -2,000,000 → 2023-7-5 还款 D13 = 933,698.63 (hardcoded) → 2023-7-5 到 2025-1-23 (568天) D15 = (A15-A9)*1%*12/365*C4 → 2023-7-5 到 2025-8-27 (784天) ← 包含D13! ``` D16=SUM(D4:D15) → D13和D15重叠568天,导致933,698.63元被重复计算。 ### 修复(Doro采用方案A) 删除D13,D15覆盖全段:D16 = D9(-2M) + D15 = 686,027.40 + 1,288,767.12 = 1,974,794.52 ✓ ### 对比:F列(无重叠,已是期间模式) ``` F11 = (A11-E3)... → 2019-10-15 到 2024-4-7 F12 = -1,000,000 F13 = (A13-A11)... → 2024-4-7 到 2025-1-23 ← 从A11开始,不从E3 F15 = (A15-A13)... → 2025-1-23 到 2025-8-27 ← 从A13开始 ``` 三段首尾相连,无重叠 ✓ ## docx联动注意 xlsx改了利息计算结构后,docx中利息累计的表述必须与xlsx结构一致: - xlsx用方案A(删中间行+全段累计)→ docx直接写"自X日起至Y日止利息Z元" - xlsx用方案B(期间公式)→ docx可分段写每期利息再合计 ⚠️ **表达清晰性**:如果某个数字已经是净额(如686,027.40 = 2,686,027.40 - 2,000,000),不要在同一句中同时出现被减数和减数,否则读者无法验证算术。详见 SKILL.md "表达清晰性要求"。