# 错误处理机制详解 ## 目录 1. [系统概述](#系统概述) 2. [错误处理架构](#错误处理架构) 3. [错误类型与分类](#错误类型与分类) 4. [错误处理流程](#错误处理流程) 5. [模块错误处理详解](#模块错误处理详解) 6. [错误恢复策略](#错误恢复策略) 7. [错误报告生成](#错误报告生成) 8. [最佳实践](#最佳实践) 9. [测试覆盖](#测试覆盖) 10. [快速参考](#快速参考) --- ## 系统概述 AutoBOM系统采用**集中式日志记录 + 持续处理**的错误处理策略,确保在批量处理BOM数据时,单个记录的错误不会中断整个处理流程。 ### 核心设计原则 1. **错误隔离**: 单个记录错误不影响其他记录处理 2. **错误累积**: 所有错误统一收集,集中展示 3. **上下文保留**: 记录完整的错误上下文信息 4. **用户友好**: 提供清晰的错误描述和定位信息 ### 设计优势 ```mermaid graph LR subgraph "传统错误处理" A1[遇到错误] --> B1[停止处理] B1 --> C1[用户修复] C1 --> D1[重新运行] D1 --> E1[下一个错误
再次停止] end subgraph "AutoBOM错误处理" A2[遇到错误] --> B2[记录错误] B2 --> C2[继续处理] C2 --> D2[处理完成] D2 --> E2[一次性查看
所有错误] end style A2 fill:#c8e6c9 style B2 fill:#c8e6c9 style C2 fill:#c8e6c9 style D2 fill:#c8e6c9 style E2 fill:#c8e6c9 style A1 fill:#ffcdd2 style E1 fill:#ffcdd2 ``` --- ## 错误处理架构 ### 类层次结构 ```mermaid classDiagram class clsErrorLogger { -Collection pErrors +Record(rowIdx, sourceFunc, errorType, desc, context) +HasErrors() Boolean +PrintReport(targetWb) +Class_Initialize() } class M01_Main { +RunBOMConversion() +GeneratePreprocessingReport() } class M03_Logic { -clsErrorLogger g_Logger +InitLogic(logger) +ParseRule(strRule, rowIdx) -ConflictDetection() } class M05_PreProcessor { -clsErrorLogger g_Logger +InitPreProcessor(logger, wsMapping) +PreprocessCondition(strCond, strCat, rowIdx) } class M06_ModelParser { -clsErrorLogger g_Logger +InitModelParser(logger) +ParseProductModel(modelString) } class M07_BOMMatcher { -clsErrorLogger g_Logger +InitBOMMatcher(logger) +MatchBOMRecord(ws, params) } class M08_ComponentProcessor { -clsErrorLogger g_Logger +InitComponentProcessor(logger) +ProcessComponentRecord(row) } class M09_BOMExtractor { -clsErrorLogger g_Logger +RunBOMExtraction() +ProcessSingleModel(modelString) } clsErrorLogger <-- M01_Main : uses clsErrorLogger <-- M03_Logic : uses clsErrorLogger <-- M05_PreProcessor : uses clsErrorLogger <-- M06_ModelParser : uses clsErrorLogger <-- M07_BOMMatcher : uses clsErrorLogger <-- M08_ComponentProcessor : uses clsErrorLogger <-- M09_BOMExtractor : uses ``` ### 模块依赖关系 ```mermaid graph TB Logger[clsErrorLogger.cls
错误日志记录器] M01[M01_Main.bas
主入口] M03[M03_Logic.bas
条件解析] M05[M05_PreProcessor.bas
预处理] M06[M06_ModelParser.bas
型号解析] M07[M07_BOMMatcher.bas
BOM匹配] M08[M08_ComponentProcessor.bas
部件处理] M09[M09_BOMExtractor.bas
BOM提取] M01 --> Logger M01 --> M03 M01 --> M05 M09 --> Logger M09 --> M06 M09 --> M07 M09 --> M08 M03 -.记录错误.-> Logger M05 -.记录错误.-> Logger M06 -.记录错误.-> Logger M07 -.记录错误.-> Logger M08 -.记录错误.-> Logger Logger -.生成报告.-> M01 Logger -.生成报告.-> M09 style Logger fill:#e1f5fe style M01 fill:#fff4e1 style M09 fill:#fff4e1 ``` --- ## 错误类型与分类 ### 错误分类体系 ```mermaid graph TD Root[错误类型] Root --> Sys[系统错误
SystemError] Root --> Syn[语法错误
SyntaxError] Root --> Log[逻辑冲突
LogicConflict] Root --> Map[映射警告
MappingWarning] Root --> Mod[型号解析错误
ModelParseError] Root --> Mat[BOM匹配错误
BOMMatchError] Root --> Val[验证错误
ValidationError] Sys --> Sys1[运行时异常] Sys --> Sys2[空引用错误] Sys --> Sys3[类型转换错误] Syn --> Syn1[缺少运算符] Syn --> Syn2[括号不匹配] Syn --> Syn3[非法字符] Log --> Log1[相等与不等冲突] Log --> Log2[互斥值冲突] Map --> Map1[azxs映射缺失] Map --> Map2[lcfw映射缺失] Mod --> Mod1[表头为空] Mod --> Mod2[格式不匹配] Mat --> Mat1[无匹配记录] Mat --> Mat2[多重匹配] Val --> Val1[组件组合无效] Val --> Val2[数据不完整] style Root fill:#e1f5fe style Sys fill:#ffcdd2 style Syn fill:#fff9c4 style Log fill:#ffe0b2 style Map fill:#c8e6c9 style Mod fill:#c8e6c9 style Mat fill:#c8e6c9 style Val fill:#c8e6c9 ``` ### 错误类型详细说明 | 错误类型 | 英文标识 | 严重级别 | 处理策略 | 示例 | |----------|----------|----------|----------|------| | 系统错误 | SystemError / System Error | 🔴 高 | 记录并跳过 | 运行时异常、对象为空 | | 语法错误 | SyntaxError | 🔴 高 | 记录并跳过 | 条件缺少"="或"!=" | | 逻辑冲突 | LogicConflict | 🟡 中 | 记录并跳过 | `azxs=1 AND azxs=2` | | 映射警告 | MappingWarning | 🟢 低 | 记录并继续 | 值未在映射表中找到 | | 型号解析错误 | ModelParseError | 🔴 高 | 记录并跳过 | 型号格式不匹配 | | BOM匹配错误 | BOMMatchError | 🟡 中 | 记录并继续 | 无匹配/多重匹配 | | 验证错误 | ValidationError | 🟡 中 | 记录并继续 | 组件与子组件混用 | --- ## 错误处理流程 ### 完整错误处理生命周期 ```mermaid sequenceDiagram participant User as 用户 participant Main as M01/M09 participant Logger as clsErrorLogger participant Module as 业务模块 participant Excel as Excel工作表 User->>Main: 启动处理 Main->>Logger: 创建错误日志记录器 Main->>Main: 初始化各模块 loop 遍历数据行 Main->>Module: 处理单条记录 Module->>Module: 执行业务逻辑 alt 处理成功 Module-->>Main: 返回成功结果 else 发生错误 Module->>Logger: Record(rowIdx, source, type, desc, context) Logger->>Logger: 存储错误信息到集合 Logger-->>Module: 确认记录 Module-->>Main: 返回Nothing/空结果 Main->>Main: 继续处理下一条记录 end end Main->>Logger: HasErrors? alt 有错误 Logger-->>Main: True Main->>Logger: PrintReport(targetWb) Logger->>Excel: 创建"错误报告_hhmmss"工作表 Logger->>Excel: 写入表头(红色背景) Logger->>Excel: 批量写入错误数据 Logger->>Excel: 自动调整列宽 Main->>User: 显示警告消息框 else 无错误 Logger-->>Main: False Main->>User: 显示成功消息 end User-->>Main: 查看错误报告 ``` ### 错误记录数据结构 ```mermaid graph LR subgraph "错误记录数组" A[0: 行号
RowIndex] B[1: 来源模块
SourceFunc] C[2: 错误类型
ErrorType] D[3: 详细描述
Description] E[4: 原始数据
Context] end subgraph "示例" F[
125
M03.ParseAtom
SyntaxError
No = or != found
azxsA0
] end A & B & C & D & E --> F style A fill:#e1f5fe style B fill:#fff4e1 style C fill:#ffe0b2 style D fill:#c8e6c9 style E fill:#f3e5f5 style F fill:#fafafa ``` --- ## 模块错误处理详解 ### M03_Logic.bas - 条件解析模块 #### 错误场景 ```mermaid flowchart TD Start[M03_Logic.ParseRule] --> CheckSyntax{检查语法} CheckSyntax -->|无效| SyntaxErr[语法错误] CheckSyntax -->|有效| ProcessLogic[处理逻辑] ProcessLogic --> CheckConflict{检测冲突} CheckConflict -->|冲突| ConflictErr[逻辑冲突] CheckConflict -->|无冲突| SystemCheck{系统检查} SystemCheck -->|异常| SystemErr[系统错误] SystemCheck -->|正常| Success[解析成功] SyntaxErr --> LogSyntax[记录: SyntaxError] ConflictErr --> LogConflict[记录: LogicConflict] SystemErr --> LogSystem[记录: System Error] LogSyntax --> Return[返回Nothing] LogConflict --> Return LogSystem --> Return Success --> ReturnResult[返回结果集] style SyntaxErr fill:#ffcdd2 style ConflictErr fill:#ffe0b2 style SystemErr fill:#ffcdd2 style LogSyntax fill:#fff9c4 style LogConflict fill:#ffe0b2 style LogSystem fill:#ffe0b2 style Return fill:#ffebee ``` #### 错误处理代码 **1. 系统错误处理** ```vba ErrorHandler: g_Logger.Record rowIdx, "M03.ParseRule", "System Error", Err.Description, strRule Set ParseRule = Nothing ``` **2. 语法错误处理** ```vba Else ' 无法解析的格式 If Len(strAtom) > 0 Then g_Logger.Record rowIdx, "M03.ParseAtom", "Syntax Error", _ "No = or != found", strAtom End If End If ``` **3. 逻辑冲突检测** ```vba If v1 = Mid(v2, 3) Then ' 等于一个不允许的值 g_Logger.Record rowIdx, "M03.Conflict", "Logic Conflict", _ "Equals disallowed value", k & ": " & v1 & " AND " & v2 Set MergeDictionaries = Nothing: Exit Function ElseIf v1 = v2 Then ' 相同,无视 ElseIf Left(v1, 2) = "!=" And Left(v2, 2) = "!=" Then ' 都是不等于,合并 res(k) = v1 & "," & v2 Else ' 都是等于,但值不同 → 互斥 g_Logger.Record rowIdx, "M03.Conflict", "Logic Conflict", _ "Mutually Exclusive", k & "=" & v1 & " AND " & v2 Set MergeDictionaries = Nothing: Exit Function End If ``` --- ### M05_PreProcessor.bas - 预处理模块 #### 错误处理流程 ```mermaid flowchart TD Start[PreprocessCondition] --> CheckCategory{检查类别} CheckCategory -->|接头/部件| LoadMapping[加载映射表] CheckCategory -->|其他| Bypass[跳过预处理] LoadMapping --> CheckMapping{检查映射} CheckMapping -->|找到映射| ApplyMapping[应用映射] CheckMapping -->|未找到| LogWarning[记录映射警告] ApplyMapping --> MergeOR[合并OR条件] LogWarning --> MergeOR MergeOR --> Simplify[简化括号] Simplify --> Success[返回转换结果] style CheckMapping fill:#fff9c4 style LogWarning fill:#c8e6c9 style Success fill:#e8f5e9 ``` #### 错误处理代码 **映射警告处理** ```vba Else ' 记录警告但不中断处理 g_Logger.Record rowIdx, "M05.PreProcessor", "Mapping Warning", _ "Value not found in mapping table: " & keyName & "=" & originalValue, match.Value End If ``` --- ### M06_ModelParser.bas - 型号解析模块 #### 错误处理流程 ```mermaid flowchart TD Start[ParseProductModel] --> ExtractHeader[提取表头部分] ExtractHeader --> CheckEmpty{检查是否为空} CheckEmpty -->|为空| ParseError[解析错误] CheckEmpty -->|有值| ParseParams[解析参数] ParseError --> LogError1[记录: ModelParseError] LogError1 --> ReturnEmpty[返回空字典] ParseParams --> SystemCheck{系统检查} SystemCheck -->|异常| SysError[系统错误] SystemCheck -->|正常| Success[解析成功] SysError --> LogError2[记录: SystemError] LogError2 --> ReturnEmpty2[返回空字典] Success --> ReturnParams[返回参数字典] style ParseError fill:#ffcdd2 style SysError fill:#ffcdd2 style LogError1 fill:#ffe0b2 style LogError2 fill:#ffe0b2 style ReturnEmpty fill:#ffebee style ReturnEmpty2 fill:#ffebee ``` #### 错误处理代码 **1. 解析错误处理** ```vba If Len(headerPart) = 0 Then If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "ModelParseError", _ "无法提取表头部分,型号可能为空或格式错误", modelString End If Set ParseProductModel = params Exit Function End If ``` **2. 系统错误处理** ```vba ErrorHandler: If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "SystemError", _ "解析过程发生错误: " & Err.Description, modelString End If Set ParseProductModel = CreateObject("Scripting.Dictionary") ``` --- ### M07_BOMMatcher.bas - BOM匹配模块 #### 错误处理流程 ```mermaid flowchart TD Start[MatchBOMRecord] --> BuildMapping[构建列映射] BuildMapping --> LoopRows[遍历行] LoopRows --> Evaluate{评估匹配} Evaluate -->|匹配| CheckCount{检查数量} Evaluate -->|不匹配| NextRow[下一行] CheckCount -->|0条| NoMatch[无匹配] CheckCount -->|1条| Success[唯一匹配] CheckCount -->|多条| MultiMatch[多重匹配] NoMatch --> LogNoMatch[记录: BOMMatchError
未找到匹配] MultiMatch --> LogMulti[记录: BOMMatchError
多重匹配] LogNoMatch --> ReturnFail[返回失败结果] LogMulti --> ReturnFail Success --> ExtractInfo[提取物料信息] ExtractInfo --> ExtractErr{提取异常?} ExtractErr -->|是| LogSysError[记录: SystemError] ExtractErr -->|否| ReturnSuccess[返回物料信息] LogSysError --> ReturnEmptyDict[返回空字典] style NoMatch fill:#ffe0b2 style MultiMatch fill:#ffe0b2 style ExtractErr fill:#ffcdd2 style LogNoMatch fill:#fff9c4 style LogMulti fill:#fff9c4 style LogSysError fill:#ffe0b2 style ReturnFail fill:#ffebee ``` #### 错误处理代码 **1. 匹配结果处理** ```vba If matchResult("rowCount") = 0 Then logger.Record 0, "M09.MatchAllMaterialTypes", "BOMMatchError", _ sheetName & " " & matchResult("message"), "" End If ``` **2. 系统错误处理** ```vba ErrorHandler: If Not g_Logger Is Nothing Then g_Logger.Record 0, "M07.MatchBOMRecord", "SystemError", _ "匹配过程发生错误: " & Err.Description, ws.Name End If result("success") = False result("rowCount") = 0 Set result("rowNums") = New Collection result("message") = "系统错误: " & Err.Description Set MatchBOMRecord = result ``` --- ### M08_ComponentProcessor.bas - 部件处理模块 #### 错误处理流程 ```mermaid flowchart TD Start[ProcessComponentRecord] --> ValidateCombination[验证组件组合] ValidateCombination --> CheckValid{验证结果} CheckValid -->|无效| ValidationError[验证错误] CheckValid -->|有效| ExtractComponent[提取组件信息] ValidationError --> LogError[记录: ValidationError
无效组合] LogError --> ReturnError[返回错误物料] ExtractComponent --> ExtractErr{提取异常?} ExtractErr -->|是| SystemError[系统错误] ExtractErr -->|否| ReturnSuccess[返回组件信息] SystemError --> LogSysError[记录: SystemError] LogSysError --> ReturnError2[返回错误物料] style ValidationError fill:#ffe0b2 style SystemError fill:#ffcdd2 style LogError fill:#fff9c4 style LogSysError fill:#ffe0b2 style ReturnError fill:#ffebee style ReturnError2 fill:#ffebee ``` #### 错误处理代码 **系统错误处理** ```vba ErrorHandler: If Not logger Is Nothing Then logger.Record 0, "M08.ProcessComponentRecord", "SystemError", _ "处理部件记录失败: " & Err.Description, "" End If ' 返回错误物料信息 Dim errorMat As Object Set errorMat = CreateObject("Scripting.Dictionary") errorMat("materialType") = "部件" errorMat("materialName") = "" errorMat("materialCode") = "" errorMat("materialQty") = 0 errorMat("remarks") = "系统错误: " & Err.Description ``` --- ### M09_BOMExtractor.bas - BOM提取模块 #### 错误处理流程 ```mermaid flowchart TD Start[ProcessSingleModel] --> ParseModel[解析型号] ParseModel --> ParseOK{解析成功?} ParseOK -->|失败| LogParseError[记录: ModelParseError] ParseOK -->|成功| MatchLoop[匹配所有物料类型] LogParseError --> GenerateErrorRow[生成错误行] GenerateErrorRow --> Continue[继续下一个型号] MatchLoop --> MatchCheck{匹配检查} MatchCheck -->|匹配失败| LogMatchError[记录: BOMMatchError] MatchCheck -->|匹配成功| SaveResult[保存结果] LogMatchError --> Continue SaveResult --> Continue Continue --> End[结束] style LogParseError fill:#ffe0b2 style LogMatchError fill:#ffe0b2 style GenerateErrorRow fill:#ffebee ``` #### 错误处理代码 **1. 单型号处理错误** ```vba ErrorHandler: If Not logger Is Nothing Then logger.Record 0, "M09.ProcessSingleModel", "SystemError", _ "处理型号[" & modelString & "]失败: " & Err.Description, "" End If results.Add GenerateErrorRow(modelString, "系统错误: " & Err.Description) Set ProcessSingleModel = results ``` **2. 匹配错误处理** ```vba If matchResult("rowCount") = 0 Then logger.Record 0, "M09.MatchAllMaterialTypes", "BOMMatchError", _ sheetName & " " & matchResult("message"), "" End If ``` --- ## 错误恢复策略 ### 策略分类 ```mermaid graph TD subgraph "错误恢复策略" A[策略选择] A --> B[继续处理
Continue Processing] A --> C[优雅降级
Graceful Degradation] A --> D[仅警告
Warning Only] end subgraph "继续处理" B1[记录错误] B2[返回Nothing/空值] B3[处理下一条记录] end subgraph "优雅降级" C1[检测组件失败] C2[返回错误物料] C3[保存部分结果] end subgraph "仅警告" D1[记录警告信息] D2[继续正常流程] D3[不中断处理] end B --> B1 --> B2 --> B3 C --> C1 --> C2 --> C3 D --> D1 --> D2 --> D3 style B fill:#c8e6c9 style C fill:#fff9c4 style D fill:#e1f5fe style B3 fill:#e8f5e9 style C3 fill:#ffe0b2 style D3 fill:#e8f5e9 ``` ### 策略详解 #### 1. 继续处理 (Continue Processing) **适用场景**: 语法错误、系统错误、解析错误 ```vba ' M03_Logic.bas ErrorHandler: g_Logger.Record rowIdx, "M03.ParseRule", "System Error", Err.Description, strRule Set ParseRule = Nothing ' 返回Nothing表示失败 ' 调用方检测到Nothing后继续处理下一条记录 ``` **流程**: ``` 错误发生 → 记录错误 → 返回Nothing → 调用方跳过 → 处理下一条记录 ``` --- #### 2. 优雅降级 (Graceful Degradation) **适用场景**: 组件处理失败、物料提取失败 ```vba ' M08_ComponentProcessor.bas ErrorHandler: ' 返回错误物料信息而不是崩溃 Dim errorMat As Object Set errorMat = CreateObject("Scripting.Dictionary") errorMat("materialType") = "部件" errorMat("materialName") = "" errorMat("materialCode") = "" errorMat("materialQty") = 0 errorMat("remarks") = "系统错误: " & Err.Description ``` **流程**: ``` 错误发生 → 构造错误对象 → 返回部分信息 → 用户看到部分结果 ``` --- #### 3. 仅警告 (Warning Only) **适用场景**: 映射值缺失、预处理警告 ```vba ' M05_PreProcessor.bas Else ' 记录警告但继续使用原始值 g_Logger.Record rowIdx, "M05.PreProcessor", "Mapping Warning", _ "Value not found in mapping table: " & keyName & "=" & originalValue, match.Value End If ' 继续处理,使用原始值 ``` **流程**: ``` 检测问题 → 记录警告 → 使用原始值 → 继续正常流程 ``` --- ### 策略对比 | 策略 | 严重级别 | 结果处理 | 用户体验 | 适用场景 | |------|----------|----------|----------|----------| | 继续处理 | 🔴 高 | 跳过当前记录 | 部分数据缺失 | 语法/系统/解析错误 | | 优雅降级 | 🟡 中 | 返回部分数据 | 看到错误标记 | 组件/物料提取失败 | | 仅警告 | 🟢 低 | 使用原始值 | 无明显影响 | 映射值缺失 | --- ## 错误报告生成 ### clsErrorLogger.PrintReport 方法 ```mermaid flowchart TD Start[PrintReport] --> CheckCount{检查错误数量} CheckCount -->|0个错误| Exit[退出, 不生成报告] CheckCount -->|有错误| CreateSheet[创建新工作表] CreateSheet --> SetName[设置名称:
错误报告_hhmmss] SetName --> WriteHeader[写入表头] WriteHeader --> FormatHeader[格式化表头:
粗体+红色背景] FormatHeader --> PrepareArray[准备输出数组] PrepareArray --> LoopErrors[遍历错误集合] LoopErrors --> PopulateArray[填充数组数据] PopulateArray --> CheckEnd{还有错误?} CheckEnd -->|是| LoopErrors CheckEnd -->|否| WriteData[批量写入数据] WriteData --> AutoFit[自动调整列宽] AutoFit --> End[结束] style CheckCount fill:#fff9c4 style Exit fill:#c8e6c9 style FormatHeader fill:#ffe0b2 style End fill:#e8f5e9 ``` ### 错误报告结构 ```mermaid graph TB subgraph "错误报告工作表" Header[第1行: 表头
红色背景+粗体] Data[第2行-N: 数据] end subgraph "列结构" ColA[列A: 原表行号] ColB[列B: 来源模块] ColC[列C: 错误类型] ColD[列D: 详细描述] ColE[列E: 原始数据] end subgraph "示例数据" Row2[
125M03.ParseAtomSyntaxErrorNo = or != foundazxsA0
] Row3[
138M03.ConflictLogicConflictMutually Exclusiveazxs=径向 AND azxs=下轴向
] end Header --> ColA & ColB & ColC & ColD & ColE Data --> Row2 & Row3 style Header fill:#ffcdd2 style Row2 fill:#fafafa style Row3 fill:#fafafa ``` ### 代码实现 ```vba Public Sub PrintReport(targetWb As Workbook) If pErrors.count = 0 Then Exit Sub ' 1. 创建新工作表 Dim ws As Worksheet Set ws = targetWb.Worksheets.Add(After:=targetWb.Worksheets(targetWb.Worksheets.count)) ws.Name = "错误报告_" & Format(Now, "hhmmss") ' 2. 写入表头(红色背景,粗体) ws.Range("A1:E1").Value = Array("原表行号", "来源模块", "错误类型", "详细描述", "原始数据") ws.Range("A1:E1").Font.Bold = True ws.Range("A1:E1").Interior.Color = RGB(255, 200, 200) ' 3. 准备输出数组(批量写入提高性能) Dim arrOutput() As Variant ReDim arrOutput(1 To pErrors.count, 1 To 5) Dim i As Long Dim vItem As Variant For i = 1 To pErrors.count vItem = pErrors(i) arrOutput(i, 1) = vItem(0) ' 行号 arrOutput(i, 2) = vItem(1) ' 来源模块 arrOutput(i, 3) = vItem(2) ' 错误类型 arrOutput(i, 4) = vItem(3) ' 描述 arrOutput(i, 5) = vItem(4) ' 上下文 Next i ' 4. 批量写入数据 ws.Range("A2").Resize(UBound(arrOutput, 1), 5).Value = arrOutput ' 5. 自动调整列宽 ws.Columns.AutoFit End Sub ``` ### 报告生成调用 ```vba ' M01_Main.bas - BOM转换系统 If logger.HasErrors Then logger.PrintReport ActiveWorkbook MsgBox "转换完成,但发现部分数据存在逻辑冲突,已生成错误报告。", vbExclamation End If ' M09_BOMExtractor.bas - BOM提取系统 If g_Logger.HasErrors Then g_Logger.PrintReport ActiveWorkbook result = "BOM提取完成,但发现部分错误,已生成错误报告。" Else result = "BOM提取成功完成!" End If ``` --- ## 最佳实践 ### 1. 一致的日志记录器初始化 所有可能产生错误的模块都遵循相同的初始化模式: ```vba ' 模块级别声明 Private g_Logger As clsErrorLogger ' 公共初始化方法 Public Sub Init[ModuleName](logger As clsErrorLogger) Set g_Logger = logger End Sub ``` **优点**: - 统一的接口 - 依赖注入模式 - 易于测试和维护 --- ### 2. 结构化的错误信息 每条错误记录都包含5个关键信息: | 字段 | 类型 | 用途 | 示例 | |------|------|------|------| | 行号 | Long | 定位Excel行 | 125 | | 来源模块 | String | 定位代码位置 | "M03.ParseAtom" | | 错误类型 | String | 错误分类 | "SyntaxError" | | 详细描述 | String | 人类可读的描述 | "No = or != found" | | 原始数据 | String | 调试上下文 | "azxsA0" | --- ### 3. 防御性编程 **使用 `Nothing` 检查**: ```vba If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "SystemError", _ "解析过程发生错误: " & Err.Description, modelString End If ``` **优点**: 即使日志记录器未初始化也不会崩溃 --- ### 4. 延迟绑定避免依赖 ```vba ' 使用 CreateObject 而不是 New Set params = CreateObject("Scripting.Dictionary") Set errorMat = CreateObject("Scripting.Dictionary") ``` **优点**: - 无需添加外部引用 - 提高兼容性 - 减少部署问题 --- ### 5. 批量操作优化 错误报告使用数组批量写入: ```vba ' 准备数组 ReDim arrOutput(1 To pErrors.count, 1 To 5) ' 填充数组 For i = 1 To pErrors.count arrOutput(i, 1) = ... Next i ' 一次性写入 ws.Range("A2").Resize(UBound(arrOutput, 1), 5).Value = arrOutput ``` **优点**: 比逐单元格写入快10-100倍 --- ### 6. 用户友好的错误通知 ```vba If logger.HasErrors Then logger.PrintReport ActiveWorkbook MsgBox "转换完成,但发现部分数据存在逻辑冲突,已生成错误报告。", _ vbExclamation, "处理完成" End If ``` **要点**: - 明确告知有错误 - 说明已生成报告 - 使用合适的图标类型 --- ### 7. 错误级别分类 使用统一的错误类型标识: ```vba ' 致命错误 - 红色 "SystemError" "SyntaxError" "ModelParseError" ' 警告 - 黄色 "LogicConflict" "BOMMatchError" "ValidationError" ' 信息 - 绿色 "MappingWarning" ``` --- ### 8. 上下文信息保留 始终记录导致错误的原始数据: ```vba g_Logger.Record rowIdx, "M03.ParseAtom", "Syntax Error", _ "No = or != found", strAtom ' 保留原始数据 ``` **优点**: 便于后续调试和修复 --- ## 测试覆盖 ### M99_TestRunner.bas 中的错误测试 ```mermaid graph TD subgraph "错误测试用例" T1[Test_LogicConflict01
相等与不等冲突] T2[Test_LogicConflict02
互斥值冲突] T3[Test_SysError01
空条件处理] T4[Test_PP_MissingValue
映射值缺失] end subgraph "验证内容" V1[错误被正确记录] V2[返回Nothing/空值] V3[处理继续不中断] V4[错误报告正确生成] end T1 --> V1 & V2 & V3 T2 --> V1 & V2 & V3 T3 --> V1 & V2 & V3 T4 --> V1 & V3 & V4 style T1 fill:#ffe0b2 style T2 fill:#ffe0b2 style T3 fill:#ffcdd2 style T4 fill:#c8e6c9 ``` ### 测试示例 **逻辑冲突测试** ```vba Public Sub Test_LogicConflict01() ' 测试: azxs=1 AND azxs!=1 Dim result As Collection Set result = M03_Logic.ParseRule("azxs=1 AND azxs!=1", 10) ' 验证: 应该返回Nothing并记录错误 Assert result Is Nothing, "应该检测到相等与不等冲突" End Sub ``` **映射值缺失测试** ```vba Public Sub Test_PP_MissingValue() ' 测试: azxs值未在映射表中 Dim result As String result = M05_PreProcessor.PreprocessCondition("azxs=INVALID", "接头", 10) ' 验证: 应该记录警告但继续处理 Assert result <> "", "即使映射缺失也应返回结果" End Sub ``` --- ## 快速参考 ### 错误处理常用代码片段 #### 1. 初始化日志记录器 ```vba ' 在主模块中 Dim logger As New clsErrorLogger ' 传递给子模块 M03_Logic.InitLogic logger M05_PreProcessor.InitPreProcessor logger, wsMapping ``` #### 2. 记录错误 ```vba ' 完整格式 g_Logger.Record rowIdx, "Module.Function", "ErrorType", "Description", "Context" ' 示例 g_Logger.Record 125, "M03.ParseAtom", "Syntax Error", _ "No = or != found", "azxsA0" ``` #### 3. 检查并报告错误 ```vba If logger.HasErrors Then logger.PrintReport ActiveWorkbook MsgBox "处理完成,但发现错误。", vbExclamation End If ``` #### 4. 标准错误处理器 ```vba ErrorHandler: If Not g_Logger Is Nothing Then g_Logger.Record rowIdx, "Module.Function", "SystemError", _ Err.Description, contextData End If Set FunctionResult = Nothing ``` --- ### 错误类型速查表 | 类型标识 | 显示名称 | 严重级别 | 通用模块 | |----------|----------|----------|----------| | `SystemError` | System Error | 🔴 高 | 所有模块 | | `System Error` | System Error | 🔴 高 | M03_Logic | | `SyntaxError` | Syntax Error | 🔴 高 | M03_Logic | | `LogicConflict` | Logic Conflict | 🟡 中 | M03_Logic | | `MappingWarning` | Mapping Warning | 🟢 低 | M05_PreProcessor | | `ModelParseError` | Model Parse Error | 🔴 高 | M06_ModelParser | | `BOMMatchError` | BOM Match Error | 🟡 中 | M07_BOMMatcher, M09_BOMExtractor | | `ValidationError` | Validation Error | 🟡 中 | M08_ComponentProcessor | --- ### 错误报告格式 **工作表名称**: `错误报告_hhmmss` (例如: `错误报告_143025`) **列结构**: | 列 | 宽度 | 对齐 | 说明 | |----|------|------|------| | A | 自动 | 左对齐 | 原表行号 | | B | 自动 | 左对齐 | 来源模块 | | C | 自动 | 左对齐 | 错误类型 | | D | 自动 | 左对齐 | 详细描述 | | E | 自动 | 左对齐 | 原始数据 | **格式**: - 第1行: 粗体 + 红色背景 (RGB 255, 200, 200) - 数据行: 默认格式 - 列宽: 自动调整 --- ### 相关文档 - [RunBOMExtraction_运行机制详解.md](./RunBOMExtraction_运行机制详解.md) - BOM提取系统文档 - [M03_Logic_Algorithm.md](./M03_Logic_Algorithm.md) - 条件解析算法详解 - [Test_PP_06_FullIntegration_流程详解.md](./Test_PP_06_FullIntegration_流程详解.md) - 预处理系统集成测试 - [CLAUDE.md](../CLAUDE.md) - 项目整体说明 --- **文档版本**: 1.0 **最后更新**: 2026-02-12 **作者**: Claude Code **状态**: 初稿完成 **审核**: 待审核