diff --git a/VBA_BOMConverter/Modules/M09_BOMExtractor.bas b/VBA_BOMConverter/Modules/M09_BOMExtractor.bas index 76170bc..dd8538b 100644 --- a/VBA_BOMConverter/Modules/M09_BOMExtractor.bas +++ b/VBA_BOMConverter/Modules/M09_BOMExtractor.bas @@ -398,6 +398,7 @@ End Function ' 特殊处理: ' - "部件"工作表特殊处理(调用M08_ComponentProcessor) ' - 部件、接头、弹性元件的交叉验证 +' - 边材料基于azxs参数的特殊验证(A0/Z0/B0不需要边,AH/AT等需要边) ' ------------------------------------------------------------------------------ Private Function MatchAllMaterialTypesWithValidation( _ ByVal params As Object, _ @@ -504,7 +505,7 @@ Private Function MatchAllMaterialTypesWithValidation( _ ' Phase 2: 统一验证所有匹配结果 ' ======================================== Dim validationResult As Object - Set validationResult = ValidateAllMatchResults(resultsDict, logger) + Set validationResult = ValidateAllMatchResults(resultsDict, logger, params) ' ======================================== ' Phase 3: 根据验证结果生成最终物料集合 @@ -561,6 +562,7 @@ End Function ' 输入: ' resultsDict - 所有工作表的匹配结果字典 ' logger - 错误记录器 +' params - 产品型号参数字典(用于边材料验证) ' ' 输出: ' Object - 验证结果对象 @@ -570,17 +572,23 @@ End Function ' 验证规则: ' 1. 基础规则(所有工作表): ' - 恰好匹配1条记录 → 正常 -' - 匹配0条记录 → 错误(部件/接头/弹性元件除外) +' - 匹配0条记录 → 错误(部件/接头/弹性元件/边除外) ' - 匹配2+条记录 → 错误 ' ' 2. 特殊规则(部件、接头、弹性元件): ' - 互斥关系验证 ' - 组合完整性验证 ' - 警告处理 +' +' 3. 特殊规则(边材料): +' - azxs=A0/Z0/B0 → 不需要边(0条=OK,1+条=ERROR) +' - azxs=AH/AT/BH/BT/BZ/ZH/ZT/ZZ → 需要边(1条=OK) +' - 支持双值格式(如"A0,径向") ' ------------------------------------------------------------------------------ Private Function ValidateAllMatchResults( _ ByVal resultsDict As Object, _ - ByVal logger As clsErrorLogger _ + ByVal logger As clsErrorLogger, _ + ByVal params As Object _ ) As Object On Error GoTo ErrorHandler @@ -593,7 +601,7 @@ Private Function ValidateAllMatchResults( _ ' 1. 基础验证:非特殊工作表必须恰好1条 ' ======================================== Dim specialSheets As Variant - specialSheets = Array(BOMLIB_SHEET_COMPONENT, "接头", "弹性元件") + specialSheets = Array(BOMLIB_SHEET_COMPONENT, "接头", "弹性元件", BOMLIB_SHEET_EDGE) Dim errors As Collection Set errors = New Collection @@ -727,6 +735,89 @@ Private Function ValidateAllMatchResults( _ End If End If + ' ======================================== + ' 3.5. 特殊验证:边 (Edge) 材料 + ' ======================================== + Dim edgeResult As Object + Set edgeResult = Nothing + + If resultsDict.Exists(BOMLIB_SHEET_EDGE) Then + Set edgeResult = resultsDict(BOMLIB_SHEET_EDGE) + End If + + ' 检查azxs参数值 + Dim azxsValue As String + Dim rawAzxs As String + azxsValue = "" + rawAzxs = "" + + If params.Exists("azxs") Then + azxsValue = CStr(params("azxs")) + ' 提取原始azxs值(处理双值格式如"A0,径向") + If InStr(azxsValue, ",") > 0 Then + rawAzxs = Trim(CStr(Split(azxsValue, ",")(0))) + Else + rawAzxs = Trim(azxsValue) + End If + End If + + ' 定义不需要边的azxs值 + Dim noEdgeAzxs As Variant + noEdgeAzxs = Array("A0", "Z0", "B0") + + ' 定义需要边的azxs值(有后缀H/T/Z的值) + Dim hasEdgeAzxs As Variant + hasEdgeAzxs = Array("AH", "AT", "BH", "BT", "BZ", "ZH", "ZT", "ZZ") + + ' 检查是否为不需要边的azxs值 + Dim isNoEdgeCase As Boolean + isNoEdgeCase = False + + Dim az As Variant + For Each az In noEdgeAzxs + If rawAzxs = az Then + isNoEdgeCase = True + Exit For + End If + Next az + + ' 情况A: azxs为A0/Z0/B0,不应该有边 + If isNoEdgeCase Then + If Not edgeResult Is Nothing Then + If edgeResult("rowCount") > 0 Then + errors.Add "[边]工作表匹配到" & edgeResult("rowCount") & "条记录,但azxs=" & rawAzxs & "不需要边物料" + End If + End If + ' 0条匹配是正常的,不记录错误或警告 + + ' 情况B: azxs为AH/AT/BH/BT/BZ/ZH/ZT/ZZ,走常规判断 + Else + ' 检查是否为需要边的azxs值 + Dim isHasEdgeCase As Boolean + isHasEdgeCase = False + + For Each az In hasEdgeAzxs + If rawAzxs = az Then + isHasEdgeCase = True + Exit For + End If + Next az + + If isHasEdgeCase Then + ' 标准验证:恰好1条匹配 + If Not edgeResult Is Nothing Then + If edgeResult("rowCount") = 0 Then + errors.Add "[边]未匹配到记录" + ElseIf edgeResult("rowCount") > 1 Then + errors.Add "[边]匹配到" & edgeResult("rowCount") & "条记录" + End If + Else + ' 没有边的结果记录 + errors.Add "[边]未匹配到记录" + End If + End If + End If + ' ======================================== ' 4. 处理[部件]工作表的多条匹配 ' ======================================== diff --git a/docs/BOM匹配错误判断机制详解.md b/docs/BOM匹配错误判断机制详解.md index 72b1dac..199b09a 100644 --- a/docs/BOM匹配错误判断机制详解.md +++ b/docs/BOM匹配错误判断机制详解.md @@ -12,6 +12,11 @@ --- +**重大更新 (v2.1 - 2025-02-12):** +- ✅ 新增边材料特殊验证(基于azxs参数) +- ✅ 支持A0/Z0/B0不需要边的规则 +- ✅ 支持AH/AT/BH/BT/BZ/ZH/ZT/ZZ需要边的规则 + **重大更新 (v2.0 - 2025-02-12):** - ✅ 实施两阶段验证机制(收集 → 验证) - ✅ 新增警告类型(非阻断性错误) @@ -932,6 +937,144 @@ End Function 2. 读取库存Excel表 3. 连接数据库库存表 +### 6.5 边特殊处理 + +#### 6.5.1 边物料特性 + +边物料在AutoBOM系统中具有特殊规则:根据`azxs`(安装形式)参数值决定是否需要边物料。 + +``` +┌──────────────────────────────────────────────────────────┐ +│ 边物料规则 │ +├──────────────────────────────────────────────────────────┤ +│ azxs = A0, Z0, B0 → 不需要边(0条=OK,1+条=ERROR) │ +│ azxs = AH, AT, BH, BT, BZ, ZH, ZT, ZZ → 需要边(1条=OK) │ +│ 其他azxs值 → 按常规验证(1条=OK) │ +└──────────────────────────────────────────────────────────┘ +``` + +#### 6.5.2 边验证流程 + +```mermaid +flowchart TD + A[验证边材料] --> B{获取azxs参数} + B --> C{提取rawAzxs值
处理双值格式} + + C --> D{azxs in A0/Z0/B0?} + D -->|是| E[不需要边模式] + E --> F{边匹配数>0?} + F -->|是| G[❌ 错误: 不应有边] + F -->|否| H[✅ 通过: 无边物料] + + D -->|否| I{azxs in AH/AT/
BH/BT/BZ/ZH/ZT/ZZ?} + I -->|是| J[需要边模式] + J --> K{边匹配数=1?} + K -->|是| L[✅ 通过: 有边物料] + K -->|否| M[❌ 错误: 0条或2+条] + + I -->|否| N[常规验证模式] + N --> O{边匹配数=1?} + O -->|是| L + O -->|否| M + + style H fill:#51cf66 + style L fill:#51cf66 + style G fill:#ff6b6b + style M fill:#ff6b6b +``` + +#### 6.5.3 边验证规则表 + +| azxs值 | 需要边? | 0条匹配 | 1条匹配 | 2+条匹配 | +|--------|---------|---------|---------|----------| +| A0 | ❌ 不需要 | ✅ OK | ❌ ERROR | ❌ ERROR | +| Z0 | ❌ 不需要 | ✅ OK | ❌ ERROR | ❌ ERROR | +| B0 | ❌ 不需要 | ✅ OK | ❌ ERROR | ❌ ERROR | +| AH | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| AT | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| BH | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| BT | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| BZ | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| ZH | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| ZT | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| ZZ | ✅ 需要 | ❌ ERROR | ✅ OK | ❌ ERROR | +| 其他 | ❓ 常规 | ❌ ERROR | ✅ OK | ❌ ERROR | + +#### 6.5.4 ValidateEdgeMaterial() 代码逻辑 + +边材料验证集成在 `M09_BOMExtractor.ValidateAllMatchResults()` 函数的 Phase 3.5: + +```vba +' ======================================== +' 3.5. 特殊验证:边 (Edge) 材料 +' ======================================== +Dim edgeResult As Object +Set edgeResult = Nothing + +If resultsDict.Exists(BOMLIB_SHEET_EDGE) Then + Set edgeResult = resultsDict(BOMLIB_SHEET_EDGE) +End If + +' 检查azxs参数值 +Dim azxsValue As String +Dim rawAzxs As String +azxsValue = "" + +If params.Exists("azxs") Then + azxsValue = CStr(params("azxs")) + ' 提取原始azxs值(处理双值格式如"A0,径向") + If InStr(azxsValue, ",") > 0 Then + rawAzxs = Trim(CStr(Split(azxsValue, ",")(0))) + Else + rawAzxs = Trim(azxsValue) + End If +End If + +' 定义不需要边的azxs值 +Dim noEdgeAzxs As Variant +noEdgeAzxs = Array("A0", "Z0", "B0") + +' 定义需要边的azxs值(有后缀H/T/Z的值) +Dim hasEdgeAzxs As Variant +hasEdgeAzxs = Array("AH", "AT", "BH", "BT", "BZ", "ZH", "ZT", "ZZ") + +' 情况A: azxs为A0/Z0/B0,不应该有边 +' ...(验证逻辑见完整代码) + +' 情况B: azxs为AH/AT/BH/BT/BZ/ZH/ZT/ZZ,走常规判断 +' ...(验证逻辑见完整代码) +``` + +#### 6.5.5 边验证错误类型 + +| 错误类型 | 错误信息 | 触发条件 | 检测位置 | +|---------|---------|---------|---------| +| **EdgeMaterialError** | `[边]工作表匹配到N条记录,但azxs=X不需要边物料` | azxs为A0/Z0/B0且边匹配数>0 | `M09_BOMExtractor.bas:763-766` | +| **No Match** | `[边]未匹配到记录` | azxs为AH/AT等且边匹配数=0 | `M09_BOMExtractor.bas:789-792` | +| **Multiple Match** | `[边]匹配到N条记录` | azxs为AH/AT等且边匹配数>1 | `M09_BOMExtractor.bas:793-795` | + +#### 6.5.6 设计决策:为什么边需要特殊处理? + +**业务背景:** +- **边材料的作用**:某些产品配置需要在表盘边缘添加边框或装饰条 +- **azxs依赖性**:边的需求取决于安装形式(azxs参数) + - **A0/Z0/B0(基础安装形式)**:产品设计上不需要边 + - **AH/AT/BH/BT/BZ/ZH/ZT/ZZ(带后缀的安装形式)**:需要边作为装饰或功能性部件 + +**技术实现考量:** +1. **避免误报**:如果对A0/Z0/B0型号使用标准验证,0条匹配会被误判为错误 +2. **精确控制**:对于AH/AT等型号,仍然需要严格执行1条匹配规则 +3. **双值兼容**:支持`"A0,径向"`格式的azxs参数,提取原始值进行判断 + +**可扩展性:** +本实现建立的模式可复用于其他需要参数依赖验证的物料类型: +```vba +' 未来可扩展为: +Function GetAzxsCategory(params As Object) As String + ' 返回: NO_EDGE_REQUIRED / EDGE_REQUIRED / STANDARD +End Function +``` + --- ## 7. 错误报告机制 @@ -1151,6 +1294,9 @@ BOM提取完成! | **部件组合异常** | `同时存在部件和子件` | 验证失败 | 检查部件处理逻辑 | | **部件、接头、弹性元件均未匹配** | `部件、接头、弹性元件均未匹配或组合不完整` | 特殊验证失败 | 检查BOM库配置 | | **接头和弹性元件数量不匹配** | `接头和弹性元件数量不匹配` | 特殊验证失败 | 确保接头和弹性元件一对一 | +| **EdgeMaterialError** | `[边]工作表匹配到N条记录,但azxs=X不需要边物料` | azxs为A0/Z0/B0且边匹配数>0 | 检查BOM库配置或产品型号 | +| **边未匹配到记录** | `[边]未匹配到记录` | azxs为AH/AT等且边匹配数=0 | 补充BOM库边记录 | +| **边匹配多条记录** | `[边]匹配到N条记录` | azxs为AH/AT等且边匹配数>1 | 删除重复或细化边配置条件 | #### 警告类型(v2.0新增) @@ -1220,8 +1366,8 @@ BOM提取完成! | `ValidateComponentCombination` | M08_ComponentProcessor | 423-507 | 部件组合验证(已弃用,移至M09) | | `ProcessSingleModel` | M09_BOMExtractor | 304-365 | 单型号处理流程 | | `MatchAllMaterialTypesWithValidation` | M09_BOMExtractor | 387-550 | **新增** 两阶段匹配(收集→验证) | -| `ValidateAllMatchResults` | M09_BOMExtractor | 552-750 | **新增** 统一验证所有匹配结果 | -| `ToArray` | M09_BOMExtractor | 751-762 | **新增** Collection转数组辅助函数 | +| `ValidateAllMatchResults` | M09_BOMExtractor | 581-815 | **新增** 统一验证所有匹配结果,包含边材料特殊验证 | +| `ToArray` | M09_BOMExtractor | 816-826 | **新增** Collection转数组辅助函数 | | `Record` | clsErrorLogger | 16-19 | 错误记录 | | `RecordWarning` | clsErrorLogger | 37-39 | **新增** 警告记录 | | `HasWarnings` | clsErrorLogger | 27-29 | **新增** 是否有警告 | @@ -1289,9 +1435,10 @@ End Sub |------|------|------|---------| | 1.0 | 2025-02-12 | Claude | 初始版本,完整覆盖错误判断机制 | | 2.0 | 2025-02-12 | Claude | **重大更新**:实施两阶段验证机制,新增警告类型,更新部件/接头/弹性元件交叉验证 | +| 2.1 | 2025-02-12 | Claude | **新增**:边材料特殊验证逻辑(基于azxs参数的条件验证) | --- **文档状态:** ✅ 完成 -**最后更新:** 2025-02-12 +**最后更新:** 2025-02-12(v2.1 - 边材料特殊验证) **维护者:** AutoBOM开发团队