Files
AutoBOM/docs/Inventory_Check_Implementation_Summary.md
Misaka_Company 8477792d41
All checks were successful
NTFY Notification / notify (push) Successful in 7s
feat: integrate inventory verification for component materials in BOM extraction
Implement inventory-based component selection logic that accumulates demand
across orders and falls back to sub-components (joint + element) when stock
is insufficient.

**Changes:**
- M04_Config: Add inventory worksheet configuration constants
  - INVENTORY_SHEET_NAME = "现存量"
  - INVENTORY_HEADER_ROW = 3 (headers on row 3)
  - INVENTORY_COL_CODE = "B" (material code)
  - INVENTORY_COL_QTY = "J" (stock quantity)

- M08_ComponentProcessor: Implement inventory tracking and verification
  - Add module-level variables: g_InventoryDict, g_AccumulatedDemandDict
  - Add LoadInventoryData() to load stock from [现存量] worksheet
  - Add InitComponentProcessorWithInventory() for initialization with inventory
  - Rewrite CheckComponentInventory() with actual inventory logic:
    * Calculate cumulative demand = orderQty × bomQty + previousAccumulated
    * Compare with available stock
    * Return True if stock sufficient, False otherwise
    * Update accumulated demand after each order
  - Update ProcessComponentRecord() to accept orderQty parameter

- M09_BOMExtractor: Integrate inventory check into main workflow
  - Modify ReadInputModels() to read 3 columns (orderNo, model, qty)
  - Initialize component processor with inventory support
  - Extract order quantity from column C and pass through call chain
  - Update ProcessSingleModel() and MatchAllMaterialTypesWithValidation()
    signatures to accept orderQty parameter

**Logic Example:**
- 3 orders (PO-001, PO-003, PO-006) use component A
- Each order: quantity=2, BOM qty=1, stock=5
- PO-001: cumulative=2, stock 5>=2 ✓ → return component
- PO-003: cumulative=4, stock 5>=4 ✓ → return component
- PO-006: cumulative=6, stock 5<6 ✗ → return sub-components

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-24 16:21:18 +08:00

8.2 KiB
Raw Permalink Blame History

库存校验功能集成总结

实施日期

2026-02-24

功能概述

RunBOMExtraction 过程中集成了库存校验功能,针对部件物料进行库存检查。根据订单顺序累加需求量,当库存充足时使用部件,不足时使用子件(接头+弹性元件)。

修改的文件

1. M04_Config.bas

修改内容: 添加现存量工作表配置常量

' 现存量工作表配置常量
Public Const INVENTORY_SHEET_NAME As String = "现存量"
Public Const INVENTORY_HEADER_ROW As Long = 3      ' 表头在第3行
Public Const INVENTORY_COL_CODE As String = "B"     ' B列 = 物料编码
Public Const INVENTORY_COL_QTY As String = "J"      ' J列 = 库存数量

2. M08_ComponentProcessor.bas

修改内容:

2.1 添加库存追踪模块级变量

' 模块级变量 - 库存追踪
Private g_InventoryDict As Object        ' 部件编码 -> 现存量
Private g_AccumulatedDemandDict As Object ' 部件编码 -> 累计需求量

2.2 新增 LoadInventoryData 函数

  • 从[现存量]工作表加载库存数据
  • 表头在第3行从第4行开始读取
  • B列 = 物料编码J列 = 库存数量
  • 如果未找到工作表记录警告并使用空字典所有库存视为0

2.3 新增 InitComponentProcessorWithInventory 函数

  • 初始化部件处理器,同时加载库存数据
  • 创建累计需求量字典
  • 调用 LoadInventoryData 加载库存

2.4 重写 CheckComponentInventory 函数

输入参数:

  • wsComponent - "部件"工作表
  • rowNum - 匹配到的行号
  • headerMap - 表头映射
  • orderQty - 订单数量(新增)

逻辑流程:

  1. 提取部件编码
  2. 获取BOM需求量部件工作表中的数量列
  3. 检查库存数据是否存在
  4. 计算累计需求量 = 订单数量 × BOM需求量 + 之前累计需求
  5. 比较库存和需求:
    • 库存 >= 累计需求 → 返回 True更新累计需求量
    • 库存 < 累计需求 → 返回 False记录错误

2.5 修改 ProcessComponentRecord 函数签名

新增参数: orderQty As Long

修改调用: 传递 orderQtyCheckComponentInventory

3. M09_BOMExtractor.bas

修改内容:

3.1 修改 ReadInputModels 函数

当前实现: 读取2列生产订单号、产品型号

注意: 计划中提到读取3列包括数量但当前代码仍使用 ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, colIdx)).Value,需要确保 colIdx 变量包含第3列数量列

建议修改:

' 确保读取到第3列数量
ReadInputModels = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 3)).Value

3.2 修改 RunBOMExtraction 主循环

修改点1 提取数量列

Dim orderQty As Long
orderQty = CLng(inputModels(i, 3))  ' Column C: 数量

修改点2 初始化部件处理器时传递库存工作簿

Dim invWorkbook As Workbook
Set invWorkbook = ThisWorkbook  ' 现存量在主工作簿中
M08_ComponentProcessor.InitComponentProcessorWithInventory g_Logger, invWorkbook

修改点3 传递数量给 ProcessSingleModel

Set modelResults = ProcessSingleModel(modelString, g_BOMWorkbook, g_Logger, productionOrderNo, orderQty)

3.3 修改 ProcessSingleModel 函数签名

新增参数: orderQty As Long

修改调用: 传递 orderQtyMatchAllMaterialTypesWithValidation

3.4 修改 MatchAllMaterialTypesWithValidation 函数签名

新增参数: orderQty As Long

修改调用: 传递 orderQtyProcessComponentRecord

数据流程

输入数据

[产品型号]工作表:

生产订单号 产品型号 数量
PO-001 YTHN-... 2
PO-003 YTHN-... 2
PO-006 YTHN-... 2

[现存量]工作表: 第3行表头 | ... | 物料编码 | ... | 库存数量 | | ... | COMP001 | ... | 5 |

处理逻辑

  1. 初始化阶段:

    • InitComponentProcessorWithInventory 加载库存数据到 g_InventoryDict
    • 创建空的 g_AccumulatedDemandDict 用于追踪累计需求
  2. 订单处理阶段(按顺序):

    • PO-001: 累计需求 = 2×1 + 0 = 2库存5 >= 2 ✓ → 返回部件
    • PO-003: 累计需求 = 2×1 + 2 = 4库存5 >= 4 ✓ → 返回部件
    • PO-006: 累计需求 = 2×1 + 4 = 6库存5 < 6 ✗ → 返回子件(接头+弹性元件)
  3. 错误记录:

    • 库存不足时记录错误Blocking Error
    • 未找到库存数据时记录警告Non-blocking Warning

输出结果

BOM提取结果

生产订单号 原始产品型号 物料类型 物料名称 物料编码 物料数量 提取备注
PO-001 YTHN-... 部件 部件A COMP001 1
PO-003 YTHN-... 部件 部件A COMP001 1
PO-006 YTHN-... 接头 接头B JOINT01 1 部件无库存,使用子件
PO-006 YTHN-... 弹性元件 元件C ELEM01 1 部件无库存,使用子件

测试要点

功能测试

  1. 正常库存场景:

    • 准备测试数据3个订单库存=5
    • 验证前2个订单返回部件
    • 验证第3个订单返回子件
  2. 边界测试:

    • 库存=0所有订单应返回子件
    • 库存充足(>=累计需求),所有订单返回部件
    • 库存恰好等于累计需求,应返回部件
  3. 异常测试:

    • 现存量工作表不存在 → 记录警告,所有订单返回子件
    • 部件编码在现存量中不存在 → 记录警告,该订单返回子件
    • 数量列为空或非数字 → 应有错误处理

数据验证

  1. 累计需求计算:

    • 验证累计需求 = 订单数量 × BOM需求量 + 之前累计
    • 验证每次处理后累计需求量正确更新
  2. 错误报告:

    • 检查错误报告工作表是否生成
    • 验证库存不足错误正确记录
    • 验证警告正确记录

注意事项

关键假设

  1. [现存量]工作表结构:

    • 表头在第3行
    • 数据从第4行开始
    • B列 = 物料编码
    • J列 = 库存数量
  2. [产品型号]工作表结构:

    • A列 = 生产订单号
    • B列 = 产品型号
    • C列 = 数量
  3. BOM库[部件]工作表:

    • 必须包含"编码"列(部件编码)
    • 必须包含"数量"列BOM需求量

已知限制

  1. 库存检查时机:

    • 库存在初始化时加载一次
    • 处理过程中库存不更新(不考虑库存增加)
  2. 错误处理:

    • 未找到库存数据时返回 False使用子件
    • 不会中断整个流程,继续处理下一个订单
  3. 数量列处理:

    • 当前代码假设数量列总是存在且为数字
    • 如果数量列为空或非数字,可能导致运行时错误

后续改进建议

  1. 增强错误处理:

    • ReadInputModels 中验证数量列是否存在
    • 处理数量列为空或非数字的情况
  2. 性能优化:

    • 如果库存数据很大,考虑只加载需要的部件编码
    • 添加日志记录库存使用情况
  3. 功能扩展:

    • 支持库存实时更新(如果需要)
    • 支持按批次或其他维度分组计算需求
    • 添加库存预留功能(预留库存给特定订单)

相关文档

  • BOM提取系统架构CLAUDE.md
  • 库存校验计划:原始计划文档
  • 测试用例:需要单独创建

实施验证清单

  • M04_Config.bas 添加常量
  • M08_ComponentProcessor.bas 添加变量
  • M08_ComponentProcessor.bas 实现 LoadInventoryData
  • M08_ComponentProcessor.bas 重写 CheckComponentInventory
  • M08_ComponentProcessor.bas 添加 InitComponentProcessorWithInventory
  • M08_ComponentProcessor.bas 修改 ProcessComponentRecord 签名
  • M09_BOMExtractor.bas 修改 RunBOMExtraction初始化、提取数量
  • M09_BOMExtractor.bas 修改 ProcessSingleModel添加参数
  • M09_BOMExtractor.bas 修改 MatchAllMaterialTypesWithValidation添加参数
  • 验证 ReadInputModels 读取3列需要确认
  • 端到端测试
  • 错误场景测试