# 利息公式重叠检测方法

## 问题描述

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 "表达清晰性要求"。
