# 执行计划:部件数量核对功能 ## 一、需求概述 ### 1.1 功能描述 自动核对产品订单中"部件"类物料的库存情况,当库存不足时,按订单顺序将超出部分的订单的"部件优先"字段标记为"否"。 ### 1.2 数据源 #### [产品订单]工作表 - **表头位置**:第1行 - **数据起始行**:第2行 - **关键列**: - B列:产品型号 - C列:产品数量 - E列:部件优先(输出字段) #### [现存量]工作表 - **表头位置**:第3行 - **数据起始行**:第4行 - **关键列**: - B列:物料编码(对应BOM中的66代码) - J列:结存主数量(库存数量) --- ## 二、业务逻辑 ### 2.1 核心流程 ``` 1. 读取所有订单 → 2. 解析型号提取BOM → 3. 识别部件物料 ↓ 4. 统计部件总需求 → 5. 查询库存 → 6. 库存充足性检查 ↓ 7. 按订单顺序分配库存 → 8. 修改部件优先字段 ``` ### 2.2 计算规则 #### 部件总需求量 ``` 部件总需求 = Σ(订单i的BOM中部件数量 × 订单i的产品数量) ``` #### 示例 ``` 订单1:产品数量=2,部件A的BOM数量=1 → 需求 = 1 × 2 = 2 订单2:产品数量=2,部件A的BOM数量=1 → 需求 = 1 × 2 = 2 订单3:产品数量=2,部件A的BOM数量=1 → 需求 = 1 × 2 = 2 -------------------------------------------------------- 部件A总需求 = 2 + 2 + 2 = 6 部件A库存 = 5 库存不足 = 6 - 5 = 1 ``` ### 2.3 分配策略 **原则**:按订单自上而下的顺序分配库存 | 订单 | 需求量 | 分配前库存 | 分配后库存 | 部件优先 | |------|--------|-----------|-----------|---------| | 订单1 | 2 | 5 | 3 | 保持不变 | | 订单2 | 2 | 3 | 1 | 保持不变 | | 订单3 | 2 | 1 | -1(不足) | **改为"否"** | --- ## 三、处理规则 ### 3.1 正常情况 - 订单包含"部件"物料,库存充足 → 保持原值 - 订单包含"部件"物料,库存不足 → 改为"否" - 订单不包含"部件"物料 → **保持原值不变** ### 3.2 异常情况 - **部件在[现存量]中找不到** → 报错提示,终止处理 - **型号解析失败** → 跳过该订单,记录错误 - **未匹配到任何物料** → 跳过该订单(无部件) ### 3.3 字段修改规则 - **基于现有值进行修改**(不清空原有值) - **只修改E列"部件优先"字段** - 修改格式:`是`、`否`、`1`、`0`、`TRUE`、`FALSE` 均可识别 --- ## 四、数据结构设计 ### 4.1 订单数据结构 ```vba Type OrderInfo RowNumber As Long ' 行号 ProductModel As String ' 产品型号 Quantity As Long ' 产品数量 ComponentCode As String ' 部件66编码 ComponentQty As Double ' 部件BOM数量 HasComponent As Boolean ' 是否包含部件 ParseError As String ' 解析错误信息 End Type ``` ### 4.2 部件库存结构 ```vba Type ComponentInventory ComponentCode As String ' 部件66编码 TotalDemand As Double ' 总需求量 AvailableStock As Double ' 可用库存 IsShortage As Boolean ' 是否短缺 End Type ``` --- ## 五、实现方案 ### 5.1 新建模块 **文件名**:`ComponentInventoryCheckModule.bas` **主要过程**: ```vba Public Sub CheckComponentInventory() ' 主入口程序 End Sub ``` ### 5.2 核心函数 #### 5.2.1 读取订单数据 ```vba Private Function LoadOrderData(ws As Worksheet) As Collection ' 返回 Collection(Of OrderInfo) ' 读取[产品订单]的B、C列数据 End Function ``` #### 5.2.2 读取库存数据 ```vba Private Function LoadInventoryData(ws As Worksheet) As Object ' 返回 Dictionary(物料编码 -> 库存数量) ' 读取[现存量]的B、J列数据 End Function ``` #### 5.2.3 解析订单BOM ```vba Private Sub ParseOrderBOM(orderInfo As OrderInfo, _ bomExtractor As BomExtractor, _ parser As ProductModelParser) ' 解析型号,提取BOM ' 识别"部件"类别物料 ' 填充 orderInfo.ComponentCode 和 orderInfo.ComponentQty End Sub ``` #### 5.2.4 统计部件需求 ```vba Private Function CalculateComponentDemand( _ orders As Collection) As Object ' 返回 Dictionary(部件编码 -> ComponentInventory) ' 累加所有订单的部件需求量 End Function ``` #### 5.2.5 检查库存充足性 ```vba Private Sub ValidateInventory( _ componentDemands As Object, _ inventoryData As Object) ' 检查每个部件的库存是否充足 ' 如果找不到或不足,报错提示 End Sub ``` #### 5.2.6 分配库存并标记 ```vba Private Sub AllocateInventory( _ orders As Collection, _ componentDemands As Object, _ orderSheet As Worksheet) ' 按订单顺序分配库存 ' 库存不足时,修改E列"部件优先"为"否" End Sub ``` --- ## 六、详细实现步骤 ### 6.1 主流程(CheckComponentInventory) ``` 1. 获取工作表对象 ├─ [产品订单]工作表 ├─ [现存量]工作表 └─ [平台配置清单]工作表 2. 初始化BOM提取器 └─ 加载BOM数据 3. 读取库存数据到字典 └─ Dictionary(66编码 -> 库存数量) 4. 读取订单数据 └─ Collection(Of OrderInfo) 5. 解析所有订单的BOM └─ 识别部件,填充ComponentCode和ComponentQty 6. 统计部件总需求 └─ Dictionary(部件编码 -> ComponentInventory) 7. 验证库存 └─ 检查部件是否存在于[现存量]中 8. 按订单顺序分配库存 └─ 修改E列"部件优先"字段 9. 输出结果统计 └─ MsgBox显示处理结果 ``` ### 6.2 分配算法(伪代码) ```vba For Each order In orders If order.HasComponent Then Dim demand As ComponentInventory demand = componentDemands(order.ComponentCode) Dim requiredQty As Double requiredQty = order.ComponentQty * order.Quantity If demand.AvailableStock >= requiredQty Then ' 库存充足,保持原值 demand.AvailableStock = demand.AvailableStock - requiredQty Else ' 库存不足,标记为"否" orderSheet.Cells(order.RowNumber, 5).Value = "否" demand.AvailableStock = demand.AvailableStock - requiredQty End If End If Next order ``` --- ## 七、边界情况处理 ### 7.1 无部件的订单 ``` 条件:订单的BOM中没有"类别=部件"的物料 处理:跳过该订单,E列保持原值 ``` ### 7.2 多个订单使用不同部件 ``` 订单1:部件A 订单2:部件B 处理:分别统计A和B的需求,独立核算库存 ``` ### 7.3 库存为0的情况 ``` 条件:[现存量]中某部件的结存主数量 = 0 处理:所有需要该部件的订单都标记为"否" ``` ### 7.4 产品数量为0的情况 ``` 条件:订单的C列产品数量 = 0 处理:该订单的部件需求 = 0,不影响库存 ``` ### 7.5 部件优先字段原有值 ``` 可能的值:"是"、"否"、1、0、TRUE、FALSE、空 处理:基于现有值修改,不清空 ``` --- ## 八、测试用例 ### 8.1 基本功能测试 | 测试场景 | 订单数 | 部件 | 总需求 | 库存 | 预期结果 | |---------|--------|------|--------|------|---------| | 库存充足 | 3 | A(1) | 6 | 10 | 全部保持原值 | | 库存不足 | 3 | A(1) | 6 | 5 | 第3个订单改为"否" | | 库存刚好 | 3 | A(1) | 6 | 6 | 全部保持原值 | | 无部件订单 | 2 | - | - | - | 保持原值 | | 库存为0 | 2 | A(1) | 4 | 0 | 全部改为"否" | ### 8.2 异常情况测试 | 测试场景 | 预期行为 | |---------|---------| | 部件在[现存量]中不存在 | 报错提示,终止处理 | | 型号解析失败 | 跳过该订单,记录错误 | | [产品订单]为空 | 提示无数据,退出 | | [现存量]为空 | 报错提示,退出 | ### 8.3 边界值测试 | 测试场景 | 输入值 | 预期结果 | |---------|--------|---------| | 产品数量为1 | 所有订单数量=1 | 正常计算 | | 产品数量为大数 | 订单数量=1000 | 正常计算 | | 部件BOM数量为小数 | 0.5 | 正确计算总需求 | | 库存数量为小数 | 2.5 | 正确判断库存 | --- ## 九、用户界面设计 ### 9.1 执行入口 建议在主界面添加按钮: ``` [部件库存核对] ``` ### 9.2 结果提示 执行完成后显示: ``` ✓ 部件库存核对完成! 处理订单数:10 包含部件订单:8 库存充足订单:6 库存不足订单:2 耗时:0.50秒 ``` ### 9.3 错误提示 格式: ``` ✗ 部件库存核对失败! 错误信息: - 订单第5行:部件 '661234' 在[现存量]中未找到 请检查数据后重试。 ``` --- ## 十、实施步骤 1. **创建新模块** - 文件名:`ComponentInventoryCheckModule.bas` - 位置:`VBA/Modules/` 2. **实现核心函数** - LoadOrderData - LoadInventoryData - ParseOrderBOM - CalculateComponentDemand - ValidateInventory - AllocateInventory 3. **实现主流程** - CheckComponentInventory 4. **测试验证** - 基本功能测试 - 异常情况测试 - 边界值测试 5. **集成到主界面** - 添加按钮或菜单项 --- ## 十一、风险评估 | 风险 | 影响 | 缓解措施 | |------|------|---------| | 库存数据不准确 | 导致错误的分配结果 | 执行前提示用户确认库存数据 | | 订单量大导致性能问题 | 处理时间长 | 优化算法,使用批量操作 | | BOM解析失败 | 无法识别部件 | 记录错误日志,跳过该订单 | | 部件编码不一致 | 无法匹配库存 | 严格验证,报错提示 | --- **是否批准此执行计划?确认后我将开始代码实现。**