All checks were successful
NTFY Notification / notify (push) Successful in 4s
Add a preprocessing step to the BOM Extraction System to enhance parameter extraction with mapping values from "对照表" worksheet. For azxs (安装形式) and lcfw (量程范围), the system now stores both the raw parsed value AND the mapped value from the lookup table, enabling flexible dual-value matching. Changes: - Create M06A_Mapper.bas: New module for value mapping - Load azxs/lcfw mappings from "对照表" worksheet - Return dual-value format "raw,mapped" (e.g., "A0,径向") - Support graceful degradation if "对照表" not found - Define constants locally to avoid VBA cross-module reference issues - Modify M06_ModelParser.bas: - Extract raw parameter values first - Apply mapping via M06A_Mapper if initialized - Store dual values for azxs and lcfw parameters - Modify M07_BOMMatcher.bas: - Update EvaluateCellCondition() to support dual-value matching - Split by comma and check if ANY value matches - Backward compatible with single-value parameters - Modify M09_BOMExtractor.bas: - Initialize M06A_Mapper during RunBOMExtraction() - Add WorksheetExists() helper function - Log warning if "对照表" worksheet not found - Define MAPPING_SHEET_NAME constant locally - Modify M04_Config.bas: - Add mapping table configuration constants - MAPPING_SHEET_NAME, MAPPING_COL_LCFW_KEY, etc. - Update CLAUDE.md: - Document new M06A_Mapper module - Update data flow diagram with mapping step - Document dual-value matching behavior - Update system architecture diagram - Update docs/RunBOMExtraction_运行机制详解.md: - Add M06A_Mapper to all diagrams and documentation - Add detailed value mapping section - Update sequence diagrams with mapping flow - Update parameter examples with dual-value format - Bump documentation version to 3.0 Example: Input: Product model "YTHN-100.A0.531.G123.M04.Y3" Parse: azxs="A0", lcfw="M04" Map: azxs="A0,径向", lcfw="M04,高压" Match: BOM库 with azxs="径向" OR "A0" → MATCH Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1255 lines
38 KiB
Markdown
1255 lines
38 KiB
Markdown
# RunBOMExtraction 运行机制详解
|
||
|
||
## 目录
|
||
|
||
1. [系统概述](#系统概述)
|
||
2. [系统架构](#系统架构)
|
||
3. [数据流图](#数据流图)
|
||
4. [核心流程](#核心流程)
|
||
5. [模块交互时序图](#模块交互时序图)
|
||
6. [关键模块详解](#关键模块详解)
|
||
7. [两阶段验证架构详解](#两阶段验证架构详解)
|
||
8. [数据结构](#数据结构)
|
||
9. [错误处理机制](#错误处理机制)
|
||
10. [使用示例](#使用示例)
|
||
|
||
---
|
||
|
||
## 系统概述
|
||
|
||
`RunBOMExtraction` 是BOM自动提取系统的入口函数,用于从产品型号中自动提取参数,匹配BOM库,输出标准BOM清单。
|
||
|
||
### 主要功能
|
||
|
||
- **参数提取**: 从复杂的产品型号字符串中解析出8个关键参数
|
||
- **智能匹配**: 根据参数在BOM库中查找对应的物料
|
||
- **特殊处理**: 针对"部件"类物料的特殊逻辑(组件与子组件的选择)
|
||
- **结果输出**: 生成格式化的BOM提取结果表
|
||
|
||
### 设计特点
|
||
|
||
- **模块化**: 各功能模块职责清晰,易于维护
|
||
- **两阶段验证**: 将匹配收集与验证分离,支持跨工作表验证规则
|
||
- **容错性**: 完善的错误处理机制,区分错误(阻塞)和警告(非阻塞)
|
||
- **灵活性**: 支持通配符匹配、负向匹配等多种匹配规则
|
||
- **可扩展**: 易于添加新的物料类型和匹配规则
|
||
|
||
---
|
||
|
||
## 系统架构
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "入口层"
|
||
M01[M01_Main.bas<br/>RunBOMExtraction]
|
||
end
|
||
|
||
subgraph "协调层"
|
||
M09[M09_BOMExtractor.bas<br/>主协调器]
|
||
end
|
||
|
||
subgraph "处理层"
|
||
M06[M06_ModelParser.bas<br/>型号解析器]
|
||
M06A[M06A_Mapper.bas<br/>值映射器]
|
||
M07[M07_BOMMatcher.bas<br/>BOM匹配器]
|
||
M08[M08_ComponentProcessor.bas<br/>部件处理器]
|
||
end
|
||
|
||
subgraph "配置层"
|
||
M04[M04_Config.bas<br/>配置管理]
|
||
Logger[clsErrorLogger.cls<br/>错误日志]
|
||
end
|
||
|
||
subgraph "数据源"
|
||
Input[产品型号工作表]
|
||
Mapping[对照表工作表]
|
||
BOMLib[BOM库.xlsx]
|
||
end
|
||
|
||
subgraph "输出"
|
||
Output[BOM提取结果工作表]
|
||
end
|
||
|
||
M01 --> M09
|
||
M09 --> M06
|
||
M09 --> M06A
|
||
M09 --> M07
|
||
M09 --> M08
|
||
M09 --> M04
|
||
M09 --> Logger
|
||
|
||
M06 --> Input
|
||
M06A --> Mapping
|
||
M06 --> M06A
|
||
M07 --> BOMLib
|
||
M08 --> BOMLib
|
||
|
||
M09 --> Output
|
||
|
||
style M01 fill:#e1f5ff
|
||
style M09 fill:#fff4e1
|
||
style M06 fill:#e8f5e9
|
||
style M06A fill:#f8bbd9
|
||
style M07 fill:#e8f5e9
|
||
style M08 fill:#e8f5e9
|
||
style Input fill:#f3e5f5
|
||
style Mapping fill:#fff9c4
|
||
style BOMLib fill:#f3e5f5
|
||
style Output fill:#f3e5f5
|
||
```
|
||
|
||
---
|
||
|
||
## 数据流图
|
||
|
||
**关键架构:两阶段验证(Two-Phase Validation)+ 值映射(Value Mapping)**
|
||
|
||
BOM提取系统采用**两阶段验证架构**,将匹配结果的收集与验证分离,并集成**值映射功能**以支持灵活的参数匹配:
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph "输入阶段"
|
||
A[产品型号<br/>YTHN-100.A0.531.G123.M04.Y3] --> B[M06_ModelParser<br/>型号解析]
|
||
end
|
||
|
||
subgraph "解析阶段"
|
||
B --> C0[提取表头<br/>去除管道符后内容]
|
||
C0 --> C1[按.分割成段]
|
||
C1 --> C2[xh: YTHN]
|
||
C1 --> C3[gcwj: 100]
|
||
C1 --> C4[azxs: A0]
|
||
C1 --> C5[bkxs: 531]
|
||
C1 --> C6[gclj: G12<br/>jycz: 3]
|
||
C1 --> C7[lcfw: M04]
|
||
C1 --> C8[fjgn: Y3]
|
||
end
|
||
|
||
subgraph "值映射阶段"
|
||
C4 --> M1[M06A_Mapper.MapAzxs<br/>A0 → A0,径向]
|
||
C7 --> M2[M06A_Mapper.MapLcfw<br/>M04 → M04,高压]
|
||
M1 --> P1[azxs: A0,径向<br/>双值格式]
|
||
M2 --> P2[lcfw: M04,高压<br/>双值格式]
|
||
end
|
||
|
||
subgraph "Phase 1: 收集阶段(不记录错误)"
|
||
C2 & C3 & P1 & C5 & C6 & P2 & C8 --> D[遍历所有BOM库工作表]
|
||
D --> E1[接头工作表<br/>MatchBOMRecord<br/>支持双值匹配]
|
||
D --> E2[弹性元件工作表<br/>MatchBOMRecord<br/>支持双值匹配]
|
||
D --> E3[机芯工作表<br/>MatchBOMRecord]
|
||
D --> E4[部件工作表<br/>MatchBOMRecord + M08_ComponentProcessor]
|
||
E1 --> F1[存储匹配结果<br/>不记录错误]
|
||
E2 --> F2[存储匹配结果<br/>不记录错误]
|
||
E3 --> F3[存储匹配结果<br/>不记录错误]
|
||
E4 --> F4[存储匹配结果<br/>不记录错误]
|
||
end
|
||
|
||
subgraph "Phase 2: 验证阶段(跨工作表验证)"
|
||
F1 & F2 & F3 & F4 --> G[ValidateAllMatchResults<br/>统一验证所有结果]
|
||
G --> G1{非特殊工作表<br/>必须恰好1条}
|
||
G --> G2{部件/接头/弹性元件<br/>特殊规则验证}
|
||
G1 --> H1[记录错误/警告]
|
||
G2 --> H1
|
||
end
|
||
|
||
subgraph "Phase 3: 生成输出"
|
||
H1 --> I[收集验证通过的物料]
|
||
I --> J[BOM提取结果表]
|
||
end
|
||
|
||
style A fill:#ffebee
|
||
style J fill:#e8f5e9
|
||
style D fill:#e3f2fd
|
||
style G fill:#fff3e0
|
||
style F1 fill:#e8f5e9
|
||
style F2 fill:#e8f5e9
|
||
style F3 fill:#e8f5e9
|
||
style F4 fill:#e8f5e9
|
||
style M1 fill:#f8bbd9
|
||
style M2 fill:#f8bbd9
|
||
style P1 fill:#fff9c4
|
||
style P2 fill:#fff9c4
|
||
```
|
||
|
||
---
|
||
|
||
## 核心流程
|
||
|
||
**关键架构:两阶段验证(Two-Phase Validation)+ 值映射(Value Mapping)**
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([开始: RunBOMExtraction]) --> Init[初始化<br/>创建错误日志记录器]
|
||
Init --> CheckInput{检查输入工作表}
|
||
|
||
CheckInput -->|不存在| Error1[返回错误:<br/>未找到产品型号工作表]
|
||
CheckInput -->|存在| ReadModels[读取产品型号数据]
|
||
|
||
ReadModels --> CheckBOM{检查BOM库}
|
||
CheckBOM -->|不存在| Error2[返回错误:<br/>未找到BOM库.xlsx]
|
||
CheckBOM -->|存在| OpenBOM[打开BOM库工作簿]
|
||
|
||
OpenBOM --> InitModules[初始化各模块<br/>M06_ModelParser<br/>M07_BOMMatcher<br/>M08_ComponentProcessor]
|
||
|
||
InitModules --> InitMapper{对照表存在?}
|
||
InitMapper -->|是| InitMapperYes[初始化M06A_Mapper<br/>加载映射数据]
|
||
InitMapper -->|否| InitMapperNo[记录警告<br/>仅使用原始值]
|
||
InitMapperYes --> LoopStart{遍历每个产品型号}
|
||
InitMapperNo --> LoopStart
|
||
|
||
LoopStart --> ParseModel[M06_ModelParser<br/>解析产品型号]
|
||
ParseModel --> ParseSuccess{解析成功?}
|
||
|
||
ParseSuccess -->|失败| LogParseError[记录解析错误<br/>继续下一个型号]
|
||
ParseSuccess -->|成功| ExtractParams[提取原始参数]
|
||
|
||
ExtractParams --> ApplyMapping{映射器已初始化?}
|
||
ApplyMapping -->|是| MapValues[M06A_Mapper<br/>应用值映射<br/>azxs, lcfw]
|
||
ApplyMapping -->|否| UseRawValues[使用原始值]
|
||
MapValues --> Phase1[Phase 1: 收集匹配结果]
|
||
UseRawValues --> Phase1
|
||
|
||
Phase1 --> CollectLoop[遍历所有BOM库工作表]
|
||
CollectLoop --> MatchBOM[M07_BOMMatcher<br/>匹配BOM记录<br/>支持双值匹配]
|
||
MatchBOM --> IsComponent{是部件工作表?}
|
||
|
||
IsComponent -->|是| ProcessComp[M08_ComponentProcessor<br/>处理部件特殊逻辑]
|
||
IsComponent -->|否| StoreResult[存储匹配结果<br/>不记录错误]
|
||
ProcessComp --> StoreCompResult[存储部件结果<br/>不记录错误]
|
||
|
||
StoreResult --> NextSheet{还有工作表?}
|
||
StoreCompResult --> NextSheet
|
||
|
||
NextSheet -->|是| CollectLoop
|
||
NextSheet -->|否| Phase2[Phase 2: 验证匹配结果]
|
||
|
||
Phase2 --> ValidateAll[ValidateAllMatchResults<br/>跨工作表验证]
|
||
ValidateAll --> NonSpecial{验证非特殊工作表}
|
||
NonSpecial --> Special{验证部件/接头/弹性元件}
|
||
|
||
Special --> HasErrors{有错误?}
|
||
HasErrors -->|是| RecordErrors[记录错误]
|
||
HasErrors -->|否| HasWarnings{有警告?}
|
||
|
||
HasWarnings -->|是| RecordWarnings[记录警告]
|
||
HasWarnings -->|否| Phase3[Phase 3: 生成物料集合]
|
||
RecordErrors --> Phase3
|
||
RecordWarnings --> Phase3
|
||
|
||
Phase3 --> CollectMaterials[收集所有物料]
|
||
CollectMaterials --> GenerateRows[生成输出行]
|
||
GenerateRows --> NextModel{还有型号?}
|
||
|
||
LogParseError --> NextModel
|
||
|
||
NextModel -->|是| LoopStart
|
||
NextModel -->|否| WriteOutput[M09_BOMExtractor<br/>写入结果]
|
||
|
||
WriteOutput --> CloseBOM[关闭BOM库工作簿]
|
||
CloseBOM --> GenReport{有错误?}
|
||
|
||
GenReport -->|是| ShowWarning[显示警告:<br/>完成但有错误]
|
||
GenReport -->|否| ShowSuccess[显示成功:<br/>提取完成]
|
||
|
||
Error1 & Error2 --> End([结束])
|
||
ShowWarning & ShowSuccess --> End
|
||
|
||
style Start fill:#c8e6c9
|
||
style End fill:#ffcdd2
|
||
style ParseModel fill:#e1f5fe
|
||
style MapValues fill:#f8bbd9
|
||
style MatchBOM fill:#fff9c4
|
||
style ProcessComp fill:#f8bbd9
|
||
style Phase1 fill:#e3f2fd
|
||
style Phase2 fill:#fff3e0
|
||
style Phase3 fill:#e8f5e9
|
||
style ValidateAll fill:#ffe082
|
||
style Error1 fill:#ffcdd2
|
||
style Error2 fill:#ffcdd2
|
||
style LogParseError fill:#ffebee
|
||
style RecordErrors fill:#ffcdd2
|
||
style RecordWarnings fill:#fff9c4
|
||
style InitMapperYes fill:#e8f5e9
|
||
style InitMapperNo fill:#fff9c4
|
||
```
|
||
|
||
---
|
||
|
||
## 模块交互时序图
|
||
|
||
**关键架构:两阶段验证(Two-Phase Validation)**
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant User as 用户
|
||
participant M01 as M01_Main
|
||
participant M09 as M09_BOMExtractor
|
||
participant M06 as M06_ModelParser
|
||
participant M06A as M06A_Mapper
|
||
participant M07 as M07_BOMMatcher
|
||
participant M08 as M08_ComponentProcessor
|
||
participant BOM as BOM库.xlsx
|
||
participant Mapping as 对照表.xlsx
|
||
participant Logger as clsErrorLogger
|
||
|
||
User->>M01: 调用 RunBOMExtraction()
|
||
M01->>M09: RunBOMExtraction()
|
||
|
||
M09->>Logger: 创建错误日志记录器
|
||
M09->>M09: 检查产品型号工作表
|
||
M09->>M09: 打开BOM库工作簿
|
||
|
||
M09->>M06: InitModelParser(logger)
|
||
M09->>M07: InitBOMMatcher(logger)
|
||
M09->>M08: InitComponentProcessor(logger)
|
||
|
||
alt 对照表存在
|
||
M09->>Mapping: 获取对照表工作表
|
||
M09->>M06A: InitMapper(logger, wsMapping)
|
||
M06A->>Mapping: 加载映射数据<br/>azxs: A0→径向, etc.<br/>lcfw: M01→低压, etc.
|
||
Mapping-->>M06A: 映射数据加载完成
|
||
M06A-->>M09: 映射器初始化完成
|
||
else 对照表不存在
|
||
M09->>Logger: 记录警告<br/>"未找到对照表工作表"
|
||
end
|
||
|
||
loop 遍历每个产品型号
|
||
M09->>M06: ParseProductModel(型号字符串)
|
||
M06->>M06: 提取原始参数<br/>azxs="A0", lcfw="M04"
|
||
|
||
alt 映射器已初始化
|
||
M06->>M06A: MapAzxs("A0")
|
||
M06A-->>M06: "A0,径向"
|
||
M06->>M06A: MapLcfw("M04")
|
||
M06A-->>M06: "M04,高压"
|
||
M06->>M06: 组装双值参数
|
||
end
|
||
|
||
M06-->>M09: 返回参数字典<br/>(含映射值)
|
||
|
||
alt 解析失败
|
||
M09->>Logger: 记录解析错误
|
||
else 解析成功
|
||
Note over M09: Phase 1: 收集匹配结果(不记录错误)
|
||
|
||
loop 遍历每个BOM库工作表
|
||
M09->>BOM: 读取工作表
|
||
|
||
alt 工作表 = "部件"
|
||
M09->>M07: MatchBOMRecord(工作表, 参数)
|
||
Note over M07: 支持双值匹配<br/>azxs="A0,径向" 可匹配 "A0" 或 "径向"
|
||
M07-->>M09: 返回匹配结果
|
||
|
||
alt 匹配成功
|
||
M09->>M08: ProcessComponentRecord(行数据)
|
||
M08-->>M09: 返回组件/子组件
|
||
M09->>M09: 存储匹配结果(不记录错误)
|
||
end
|
||
else 其他工作表
|
||
M09->>M07: MatchBOMRecord(工作表, 参数)
|
||
Note over M07: 支持双值匹配
|
||
M07-->>M09: 返回匹配结果
|
||
M09->>M09: 存储匹配结果(不记录错误)
|
||
end
|
||
end
|
||
|
||
Note over M09: Phase 2: 统一验证所有结果
|
||
|
||
M09->>M09: ValidateAllMatchResults(所有结果)
|
||
|
||
alt 验证非特殊工作表
|
||
M09->>M09: 检查rowCount = 1
|
||
alt rowCount != 1
|
||
M09->>Logger: 记录错误
|
||
end
|
||
end
|
||
|
||
alt 验证部件/接头/弹性元件
|
||
M09->>M09: 检查跨工作表冲突
|
||
alt 有冲突
|
||
M09->>Logger: 记录警告
|
||
end
|
||
alt 组合无效
|
||
M09->>Logger: 记录错误
|
||
end
|
||
end
|
||
|
||
Note over M09: Phase 3: 生成物料集合
|
||
|
||
M09->>M09: 收集所有验证通过的物料
|
||
end
|
||
end
|
||
|
||
M09->>M09: WriteExtractionResults(结果集)
|
||
M09->>BOM: 关闭BOM库工作簿
|
||
|
||
alt 有错误
|
||
M09-->>M01: 返回警告消息
|
||
else 无错误
|
||
M09-->>M01: 返回成功消息
|
||
end
|
||
|
||
M01-->>User: 显示结果消息框
|
||
```
|
||
|
||
---
|
||
|
||
## 关键模块详解
|
||
|
||
### 1. M01_Main.bas - 入口模块
|
||
|
||
**职责**: 系统入口,提供简洁的用户接口
|
||
|
||
```vba
|
||
Public Sub RunBOMExtraction()
|
||
Dim result As String
|
||
result = M09_BOMExtractor.RunBOMExtraction()
|
||
MsgBox result, vbInformation, "BOM提取"
|
||
End Sub
|
||
```
|
||
|
||
**特点**:
|
||
- 极简设计,仅作为调用入口
|
||
- 结果通过消息框返回
|
||
- 错误处理委托给下层模块
|
||
|
||
---
|
||
|
||
### 2. M09_BOMExtractor.bas - 主协调器
|
||
|
||
**职责**: 整体流程控制,模块调度,结果输出
|
||
|
||
**核心函数**:
|
||
|
||
| 函数名 | 职责 |
|
||
|--------|------|
|
||
| `RunBOMExtraction()` | 主流程控制函数 |
|
||
| `ProcessSingleModel()` | 处理单个产品型号 |
|
||
| `MatchAllMaterialTypesWithValidation()` | 匹配所有物料类型(两阶段验证) |
|
||
| `ValidateAllMatchResults()` | 统一验证所有匹配结果(跨工作表规则) |
|
||
| `WriteExtractionResults()` | 输出提取结果 |
|
||
|
||
**处理流程**:
|
||
```
|
||
初始化 → 验证输入 → 打开BOM库 → 循环处理型号(Phase 1收集→Phase 2验证→Phase 3生成) → 输出结果 → 清理资源
|
||
```
|
||
|
||
**两阶段验证架构**:
|
||
|
||
该模块实现了关键的**两阶段验证架构**,将匹配与验证分离:
|
||
|
||
1. **Phase 1 - 收集阶段** (`MatchAllMaterialTypesWithValidation`):
|
||
- 遍历所有BOM库工作表
|
||
- 调用 `M07_BOMMatcher.MatchBOMRecord()` 获取匹配结果
|
||
- 对于"部件"工作表,额外调用 `M08_ComponentProcessor.ProcessComponentRecord()`
|
||
- **关键点:不记录任何错误**,仅收集原始匹配结果
|
||
- 存储每个工作表的:success、rowCount、rowNums、materials
|
||
|
||
2. **Phase 2 - 验证阶段** (`ValidateAllMatchResults`):
|
||
- 统一验证所有收集到的匹配结果
|
||
- 应用跨工作表验证规则
|
||
- 区分错误(blocking)和警告(non-blocking)
|
||
- 记录所有错误和警告到Logger
|
||
|
||
3. **Phase 3 - 生成阶段**:
|
||
- 根据验证结果生成最终物料集合
|
||
- 即使验证失败,也返回物料用于错误显示
|
||
|
||
---
|
||
|
||
### 3. 两阶段验证架构详解
|
||
|
||
#### 为什么需要两阶段验证?
|
||
|
||
在BOM提取系统中,"部件"、"接头"、"弹性元件"三个工作表之间存在复杂的互斥和替代关系:
|
||
|
||
- **部件表**可能返回:1个组件 或 1个接头+1个弹性元件
|
||
- **接头表**可能返回:1个接头
|
||
- **弹性元件表**可能返回:1个弹性元件
|
||
|
||
如果立即记录错误,无法判断全局情况。例如:
|
||
- 部件表返回了组件,但接头表也匹配到接头 → 这是冲突,应该警告而非错误
|
||
- 部件表返回了接头+弹性元件,但独立表也匹配到 → 这是冲突,应该警告而非错误
|
||
|
||
#### Phase 1: 收集阶段(不记录错误)
|
||
|
||
**代码位置**: `M09_BOMExtractor.MatchAllMaterialTypesWithValidation()` (lines 387-541)
|
||
|
||
**流程**:
|
||
```vba
|
||
For Each ws In bomWb.Worksheets
|
||
If ws.Name = "部件" Then
|
||
' 1. 标准匹配
|
||
Set bomMatchResult = M07_BOMMatcher.MatchBOMRecord(ws, params)
|
||
' 2. 部件特殊处理
|
||
Set componentMaterials = M08_ComponentProcessor.ProcessComponentRecord(...)
|
||
' 3. 存储结果(不记录错误)
|
||
matchResult("success") = bomMatchResult("success")
|
||
matchResult("rowCount") = bomMatchResult("rowCount")
|
||
matchResult("materials") = componentMaterials
|
||
Else
|
||
' 标准匹配
|
||
Set bomMatchResult = M07_BOMMatcher.MatchBOMRecord(ws, params)
|
||
' 存储结果(不记录错误)
|
||
End If
|
||
resultsDict.Add ws.Name, matchResult
|
||
Next ws
|
||
```
|
||
|
||
**关键点**:
|
||
- 即使匹配失败(rowCount=0),也不记录错误
|
||
- 即使多重匹配(rowCount>1),也不记录错误
|
||
- 只存储原始数据供Phase 2使用
|
||
|
||
#### Phase 2: 验证阶段(跨工作表验证)
|
||
|
||
**代码位置**: `M09_BOMExtractor.ValidateAllMatchResults()` (lines 566-760)
|
||
|
||
**验证规则**:
|
||
|
||
##### 1. 基础规则(非特殊工作表)
|
||
|
||
```
|
||
非特殊工作表必须恰好匹配1条记录:
|
||
- rowCount = 0 → 错误
|
||
- rowCount = 1 → 正常
|
||
- rowCount > 1 → 错误
|
||
```
|
||
|
||
特殊工作表列表:`["部件", "接头", "弹性元件"]`
|
||
|
||
##### 2. 跨工作表规则(部件/接头/弹性元件)
|
||
|
||
**情况A**: 部件表返回了组件(1个部件物料)
|
||
```
|
||
如果部件表返回了组件:
|
||
接头表有匹配 → 警告:"存在[部件]物料,但[接头]工作表也匹配到X条记录,已忽略"
|
||
弹性元件表有匹配 → 警告:"存在[部件]物料,但[弹性元件]工作表也匹配到X条记录,已忽略"
|
||
```
|
||
|
||
**情况B**: 部件表返回了子件(接头+弹性元件)
|
||
```
|
||
如果部件表返回了接头+弹性元件:
|
||
接头表有匹配 → 警告:"[部件]工作表已返回接头,但[接头]工作表也匹配到X条记录,已忽略"
|
||
弹性元件表有匹配 → 警告:"[部件]工作表已返回弹性元件,但[弹性元件]工作表也匹配到X条记录,已忽略"
|
||
```
|
||
|
||
**情况C**: 部件表没有返回物料
|
||
```
|
||
如果部件表rowCount=0:
|
||
接头表=0 或 弹性元件表=0 → 错误:"部件、接头、弹性元件均未匹配或组合不完整"
|
||
接头表>1 → 错误:"[接头]工作表匹配到X条记录"
|
||
弹性元件表>1 → 错误:"[弹性元件]工作表匹配到X条记录"
|
||
```
|
||
|
||
**情况D**: 部件表多重匹配
|
||
```
|
||
部件表rowCount > 1 → 错误:"[部件]工作表匹配到X条记录"
|
||
```
|
||
|
||
##### 3. 错误与警告的区别
|
||
|
||
| 类型 | 是否阻塞 | Logger方法 | 颜色 |
|
||
|------|---------|-----------|------|
|
||
| 错误 | 是 | `logger.Record()` | 红色 |
|
||
| 警告 | 否 | `logger.RecordWarning()` | 黄色 |
|
||
|
||
#### Phase 3: 生成阶段
|
||
|
||
**代码位置**: `M09_BOMExtractor.MatchAllMaterialTypesWithValidation()` (lines 495-525)
|
||
|
||
**流程**:
|
||
```vba
|
||
If validationResult("valid") Then
|
||
' 验证通过:收集所有物料
|
||
For Each result In resultsDict
|
||
For Each mat In result("materials")
|
||
allMaterials.Add mat
|
||
Next mat
|
||
Next result
|
||
Else
|
||
' 验证失败:仍然收集物料(用于错误显示)
|
||
For Each result In resultsDict
|
||
For Each mat In result("materials")
|
||
allMaterials.Add mat
|
||
Next mat
|
||
Next result
|
||
End If
|
||
```
|
||
|
||
**关键点**:
|
||
- 即使验证失败,仍然返回所有物料
|
||
- 错误信息会显示在输出行的"提取备注"列
|
||
- 用户可以看到匹配到什么物料以及为什么出错
|
||
|
||
---
|
||
|
||
### 4. M06A_Mapper.bas - 值映射器
|
||
|
||
**职责**: 为参数值添加映射值,支持双值匹配
|
||
|
||
**映射表配置** (M04_Config):
|
||
|
||
| 配置项 | 值 | 说明 |
|
||
|--------|-----|------|
|
||
| `MAPPING_SHEET_NAME` | "对照表" | 映射表工作表名称 |
|
||
| `MAPPING_COL_LCFW_KEY` | 1 (A列) | lcfw原始值列 |
|
||
| `MAPPING_COL_LCFW_VAL` | 2 (B列) | lcfw映射值列 |
|
||
| `MAPPING_COL_AZXS_KEY` | 4 (D列) | azxs原始值列 |
|
||
| `MAPPING_COL_AZXS_VAL` | 5 (E列) | azxs映射值列 |
|
||
| `MAPPING_START_ROW` | 3 | 数据起始行 |
|
||
|
||
**映射数据结构**:
|
||
|
||
**对照表** 工作表格式:
|
||
|
||
| 行号 | A列 (lcfw key) | B列 (lcfw val) | D列 (azxs key) | E列 (azxs val) |
|
||
|------|----------------|----------------|----------------|----------------|
|
||
| 1-2 | (表头) | (表头) | (表头) | (表头) |
|
||
| 3 | M01 | 低压 | A0 | 径向 |
|
||
| 4 | M12 | 高压 | AT | 径向 |
|
||
| 5 | - | - | B0 | 下轴向 |
|
||
|
||
**核心功能**:
|
||
|
||
```vba
|
||
' 初始化映射器
|
||
Public Sub InitMapper(logger As clsErrorLogger, wsMapping As Worksheet)
|
||
|
||
' 映射azxs值
|
||
Public Function MapAzxs(ByVal rawValue As String) As String
|
||
' 输入: "A0"
|
||
' 输出: "A0,径向"
|
||
|
||
' 映射lcfw值
|
||
Public Function MapLcfw(ByVal rawValue As String) As String
|
||
' 输入: "M01"
|
||
' 输出: "M01,低压"
|
||
```
|
||
|
||
**双值格式匹配**:
|
||
|
||
参数存储为双值格式后,在BOM匹配时支持灵活匹配:
|
||
|
||
| 参数值 | BOM库值 | 匹配结果 | 原因 |
|
||
|--------|---------|----------|------|
|
||
| `azxs="A0,径向"` | `azxs=A0` | ✅ 匹配 | 参数包含"A0" |
|
||
| `azxs="A0,径向"` | `azxs=径向` | ✅ 匹配 | 参数包含"径向" |
|
||
| `azxs="A0,径向"` | `azxs=AT` | ❌ 不匹配 | 参数不包含"AT" |
|
||
|
||
**优雅降级**:
|
||
|
||
如果"对照表"工作表不存在:
|
||
- 系统记录警告(非阻塞)
|
||
- 继续使用原始值进行匹配
|
||
- 功能正常运行,仅失去映射增强
|
||
|
||
**未映射值处理**:
|
||
|
||
如果值在映射表中不存在:
|
||
- 仅返回原始值(无逗号)
|
||
- 匹配时退化为精确匹配
|
||
- 不影响其他参数的匹配
|
||
|
||
**示例流程**:
|
||
|
||
```
|
||
1. 产品型号: YTHN-100.A0.531.G123.M04.Y3
|
||
2. M06_ModelParser提取: azxs="A0", lcfw="M04"
|
||
3. M06A_Mapper映射:
|
||
- azxs: "A0" → "A0,径向"
|
||
- lcfw: "M04" → "M04,高压"
|
||
4. BOM库匹配:
|
||
- BOM库有azxs="径向" → 匹配成功
|
||
- BOM库有lcfw="高压" → 匹配成功
|
||
```
|
||
|
||
---
|
||
|
||
### 5. M06_ModelParser.bas - 型号解析器
|
||
|
||
**职责**: 从产品型号字符串中提取参数
|
||
|
||
**产品型号格式**:
|
||
```
|
||
[型号-公称外径].[安装形式].[表壳形式].[过程连接&接液材质].[量程范围].[附加功能]|[扩展信息]
|
||
```
|
||
|
||
**示例**: `YTHN-100.A0.531.G123.M04.Y3|BP-088.2312.B09.0A3`
|
||
|
||
**提取的参数**:
|
||
|
||
| 参数 | 描述 | 原始值 | 映射后值 | 转换规则 |
|
||
|------|------|--------|----------|----------|
|
||
| xh | 型号 | YTHN | YTHN | 从YTHN-100提取横线前部分(无映射) |
|
||
| gcwj | 公称外径 | 100 | 100 | 从YTHN-100提取横线后数字(无映射) |
|
||
| azxs | 安装形式 | A0 | A0,径向 | 直接提取,然后应用M06A_Mapper映射 |
|
||
| bkxs | 表壳形式 | 531 | 531 | 直接提取(无映射) |
|
||
| gclj | 过程连接 | G12 | G12 | 从G123去除末位(无映射) |
|
||
| jycz | 接液材质 | 3 | 3 | 从G123提取末位(无映射) |
|
||
| lcfw | 量程范围 | M04 | M04,高压 | 直接提取,然后应用M06A_Mapper映射 |
|
||
| fjgn | 附加功能 | Y3 | Y3 | 直接提取,多段用逗号连接(无映射) |
|
||
|
||
**值映射集成**:
|
||
|
||
```vba
|
||
' 1. 提取原始值
|
||
azxsRaw = ExtractAzxs(segments(1)) ' "A0"
|
||
lcfwRaw = ExtractLcfw(segments(4)) ' "M04"
|
||
|
||
' 2. 应用映射(如果映射器已初始化)
|
||
If M06A_Mapper.IsInitialized() Then
|
||
params("azxs") = M06A_Mapper.MapAzxs(azxsRaw) ' "A0,径向"
|
||
params("lcfw") = M06A_Mapper.MapLcfw(lcfwRaw) ' "M04,高压"
|
||
Else
|
||
' 映射器未初始化,使用原始值
|
||
params("azxs") = azxsRaw ' "A0"
|
||
params("lcfw") = lcfwRaw ' "M04"
|
||
End If
|
||
```
|
||
|
||
**核心函数**:
|
||
|
||
```vba
|
||
Public Function ParseProductModel(ByVal modelStr As String) As Object
|
||
' 返回包含8个参数的字典
|
||
' 如果M06A_Mapper已初始化,azxs和lcfw将包含映射值
|
||
End Function
|
||
```
|
||
|
||
---
|
||
|
||
### 6. M07_BOMMatcher.bas - BOM匹配器
|
||
|
||
**职责**: 根据参数在BOM库中查找匹配记录
|
||
|
||
**匹配规则**:
|
||
|
||
| 单元格值 | 匹配逻辑 |
|
||
|----------|----------|
|
||
| 空白 | 通配符,匹配所有 |
|
||
| `!value` | 负向匹配,不等于该值 |
|
||
| `value` | 精确匹配或双值匹配 |
|
||
| `fjgn`列 | 包含匹配,value包含在参数中 |
|
||
|
||
**双值匹配** (新增功能):
|
||
|
||
当参数包含映射值时(如`azxs="A0,径向"`),支持灵活匹配:
|
||
|
||
```
|
||
' EvaluateCellCondition函数逻辑
|
||
IF paramValue包含逗号 THEN
|
||
' 拆分为多个值
|
||
paramValues = Split(paramValue, ",")
|
||
|
||
' 只要任意一个值匹配单元格值,即认为匹配
|
||
FOR EACH pv IN paramValues
|
||
IF pv = cellStr THEN
|
||
RETURN True ' 匹配成功
|
||
END IF
|
||
NEXT
|
||
|
||
RETURN False ' 所有值都不匹配
|
||
ELSE
|
||
' 单值精确匹配
|
||
RETURN (paramValue = cellStr)
|
||
END IF
|
||
```
|
||
|
||
**双值匹配示例**:
|
||
|
||
| 参数值 | BOM库单元格值 | 匹配结果 | 说明 |
|
||
|--------|---------------|----------|------|
|
||
| `azxs="A0,径向"` | `azxs=A0` | ✅ 匹配 | 参数包含"A0" |
|
||
| `azxs="A0,径向"` | `azxs=径向` | ✅ 匹配 | 参数包含"径向" |
|
||
| `azxs="A0,径向"` | `azxs=AT` | ❌ 不匹配 | 参数不包含"AT" |
|
||
| `lcfw="M01,低压"` | `lcfw=M01` | ✅ 匹配 | 参数包含"M01" |
|
||
| `lcfw="M01,低压"` | `lcfw=低压` | ✅ 匹配 | 参数包含"低压" |
|
||
| `lcfw="M01,低压"` | `lcfw=高压` | ❌ 不匹配 | 参数不包含"高压" |
|
||
|
||
**匹配逻辑**:
|
||
|
||
```
|
||
对于每条记录:
|
||
对于每个参数:
|
||
IF 单元格为空 THEN 匹配成功
|
||
ELSE IF 单元格以"!"开头 THEN
|
||
IF 参数 != 去掉"!"的值 THEN 匹配成功
|
||
ELSE 匹配失败
|
||
ELSE IF 列名 = "fjgn" THEN
|
||
IF 参数包含单元格值 THEN 匹配成功
|
||
ELSE 匹配失败
|
||
ELSE IF 参数包含逗号 THEN
|
||
' 双值匹配:检查任意一个值是否匹配
|
||
FOR EACH pv IN Split(参数, ",")
|
||
IF pv = 单元格值 THEN 匹配成功
|
||
NEXT
|
||
匹配失败
|
||
ELSE
|
||
' 单值精确匹配
|
||
IF 参数 = 单元格值 THEN 匹配成功
|
||
ELSE 匹配失败
|
||
END IF
|
||
|
||
IF 所有参数都匹配成功 THEN 返回该记录
|
||
NEXT
|
||
```
|
||
|
||
**匹配要求**:
|
||
- 必须有且仅有1条匹配记录
|
||
- 0条 = 未找到匹配
|
||
- 多条 = 匹配不唯一
|
||
|
||
**向后兼容**:
|
||
- 单值参数(无逗号)退化为精确匹配
|
||
- 不影响现有的非映射参数
|
||
|
||
---
|
||
|
||
### 7. M08_ComponentProcessor.bas - 部件处理器
|
||
|
||
**职责**: 处理"部件"类物料的特殊逻辑
|
||
|
||
**部件结构**:
|
||
```
|
||
部件记录包含:
|
||
- 自身信息 (物料编码A, 数量A)
|
||
- 子组件1 - 接头 (物料编码B, 数量B)
|
||
- 子组件2 - 弹性元件 (物料编码C, 数量C)
|
||
```
|
||
|
||
**选择策略**:
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([匹配到部件记录]) --> CheckA{检查组件A}
|
||
|
||
CheckA -->|有库存| UseA[使用组件A]
|
||
CheckA -->|无库存| CheckB{检查子组件B+C}
|
||
|
||
CheckB -->|都有库存| UseBC[使用子组件B+C]
|
||
CheckB -->|任一无库存| Error[标记: 缺货]
|
||
|
||
UseA --> ValidateA{仅组件A?}
|
||
ValidateA -->|是| Valid[✓ 有效组合]
|
||
ValidateA -->|否| Error1[✗ 无效组合:<br/>不能同时使用组件和子组件]
|
||
|
||
UseBC --> ValidateBC{有组件A?}
|
||
ValidateBC -->|否| Valid
|
||
ValidateBC -->|是| Error1
|
||
|
||
Error & Error1 --> End([结束: 验证失败])
|
||
Valid --> End
|
||
|
||
style Start fill:#e1f5fe
|
||
style End fill:#ffebee
|
||
style Valid fill:#c8e6c9
|
||
style Error fill:#ffcdd2
|
||
style Error1 fill:#ffcdd2
|
||
```
|
||
|
||
**有效组合**:
|
||
1. ✅ 仅组件A (优先级1)
|
||
2. ✅ 仅子组件B + 子组件C (优先级2)
|
||
3. ❌ 组件A + 子组件 (无效)
|
||
4. ❌ 仅部分子组件 (无效)
|
||
|
||
---
|
||
|
||
## 数据结构
|
||
|
||
### 输入数据结构
|
||
|
||
**产品型号工作表**:
|
||
|
||
| 行号 | 列A (型号) | 列B (可选列) |
|
||
|------|------------|--------------|
|
||
| 1 | 型号 | (表头) |
|
||
| 2 | YTHN-100.A0.531.G123.M04.Y3 | ... |
|
||
| 3 | YTHN-150.B0.531.G456.M12.Y2 | ... |
|
||
|
||
---
|
||
|
||
### BOM库数据结构
|
||
|
||
**BOM库.xlsx** 包含多个工作表,每个工作表代表一种物料类型。
|
||
|
||
**通用列结构** (以"接头"为例):
|
||
|
||
| 列名 | 说明 | 示例值 |
|
||
|------|------|--------|
|
||
| azxs | 安装形式 | A0 |
|
||
| bkxs | 表壳形式 | 531 |
|
||
| gclj | 过程连接 | G12 |
|
||
| jycz | 接液材质 | 3 |
|
||
| lcfw | 量程范围 | M04 |
|
||
| fjgn | 附加功能 | Y3 |
|
||
| 物料编码 | 物料唯一标识 | JT-001 |
|
||
| 物料名称 | 物料描述名称 | 卡套式接头 |
|
||
| 数量 | 默认数量 | 1 |
|
||
|
||
**"部件"工作表特殊列**:
|
||
|
||
| 列名 | 说明 |
|
||
|------|------|
|
||
| 物料编码 | 组件A编码 |
|
||
| 数量A | 组件A数量 |
|
||
| 物料编码B | 子组件B(接头)编码 |
|
||
| 数量B | 子组件B数量 |
|
||
| 物料编码C | 子组件C(弹性元件)编码 |
|
||
| 数量C | 子组件C数量 |
|
||
|
||
---
|
||
|
||
### 输出数据结构
|
||
|
||
**BOM提取结果工作表** (12列):
|
||
|
||
| 列号 | 列名 | 说明 | 示例值 |
|
||
|------|------|------|--------|
|
||
| 1 | 原始产品型号 | 输入的完整型号 | YTHN-100...Y3 |
|
||
| 2 | azxs | 安装形式 | A0 |
|
||
| 3 | bkxs | 表壳形式 | 531 |
|
||
| 4 | gclj | 过程连接 | G12 |
|
||
| 5 | jycz | 接液材质 | 3 |
|
||
| 6 | lcfw | 量程范围 | M04 |
|
||
| 7 | fjgn | 附加功能 | Y3 |
|
||
| 8 | 物料类型 | 接头/弹性元件/机芯/部件/边 | 接头 |
|
||
| 9 | 物料名称 | 物料描述 | 卡套式接头 |
|
||
| 10 | 物料编码 | 唯一标识 | JT-001 |
|
||
| 11 | 物料数量 | 数量 | 1 |
|
||
| 12 | 提取备注 | 错误或警告信息 | (空/错误信息) |
|
||
|
||
**输出格式**:
|
||
- 每种物料占一行
|
||
- 一个产品型号可能对应多行输出
|
||
- 行按物料类型分组
|
||
|
||
---
|
||
|
||
### 内部数据结构
|
||
|
||
**参数字典** (M06_ModelParser输出):
|
||
```vba
|
||
Dictionary {
|
||
"xh": "YTHN",
|
||
"gcwj": "100",
|
||
"azxs": "A0,径向", // 双值格式(原始值,映射值)
|
||
"bkxs": "531",
|
||
"gclj": "G12",
|
||
"jycz": "3",
|
||
"lcfw": "M04,高压", // 双值格式(原始值,映射值)
|
||
"fjgn": "Y3"
|
||
}
|
||
```
|
||
|
||
**注意**: 如果M06A_Mapper未初始化或值未找到映射,则退化为单值格式。
|
||
|
||
**列映射字典** (M07_BOMMatcher):
|
||
```vba
|
||
Dictionary {
|
||
"azxs": 1,
|
||
"bkxs": 2,
|
||
"gclj": 3,
|
||
...
|
||
"物料编码": 10,
|
||
"物料名称": 11,
|
||
"数量": 12
|
||
}
|
||
```
|
||
|
||
**物料信息字典** (M07_BOMMatcher输出):
|
||
```vba
|
||
Dictionary {
|
||
"物料编码": "JT-001",
|
||
"物料名称": "卡套式接头",
|
||
"数量": 1,
|
||
"物料类型": "接头"
|
||
}
|
||
```
|
||
|
||
**结果集合** (M09_BOMExtractor汇总):
|
||
```vba
|
||
Collection {
|
||
Array(型号, azxs, bkxs, gclj, jycz, lcfw, fjgn, 物料类型, 物料名称, 物料编码, 数量, 备注),
|
||
Array(...), // 第二条物料
|
||
...
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误处理机制
|
||
|
||
### 错误分类
|
||
|
||
| 错误类型 | 级别 | 处理方式 | 示例 |
|
||
|----------|------|----------|------|
|
||
| 工作表不存在 | 致命 | 立即返回 | 未找到产品型号工作表 |
|
||
| BOM库不存在 | 致命 | 立即返回 | 未找到BOM库.xlsx |
|
||
| 型号解析失败 | 警告 | 记录错误,跳过 | 型号格式错误 |
|
||
| 无匹配记录 | 警告 | 记录错误,继续 | 未找到匹配物料 |
|
||
| 多重匹配 | 警告 | 记录错误,继续 | 找到多个匹配 |
|
||
| 组件组合无效 | 警告 | 记录错误,继续 | 组件与子组件混用 |
|
||
| 跨工作表冲突 | 警告 | 记录警告,继续 | 部件表与接头表同时匹配 |
|
||
|
||
---
|
||
|
||
### 两阶段验证错误处理
|
||
|
||
#### Phase 1: 收集阶段(不记录错误)
|
||
|
||
在收集阶段,系统**不记录任何错误**,原因如下:
|
||
|
||
1. **需要全局信息**: 判断是否为错误需要看所有工作表的匹配结果
|
||
2. **避免误报**: 部件表返回组件时,接头表也匹配是警告而非错误
|
||
3. **优先级处理**: 部件表的返回优先级高于独立表
|
||
|
||
示例:
|
||
```vba
|
||
' Phase 1 收集阶段 - 不记录错误
|
||
Set matchResult = M07_BOMMatcher.MatchBOMRecord(ws, params)
|
||
' 即使 matchResult("rowCount") = 0 或 > 1,也不记录错误
|
||
resultsDict.Add ws.Name, matchResult
|
||
```
|
||
|
||
#### Phase 2: 验证阶段(记录错误和警告)
|
||
|
||
在验证阶段,系统根据**跨工作表规则**统一验证:
|
||
|
||
**错误示例**(阻塞,红色):
|
||
```
|
||
[接头] 未匹配到记录
|
||
[机芯] 匹配到2条记录
|
||
部件、接头、弹性元件均未匹配或组合不完整
|
||
```
|
||
|
||
**警告示例**(非阻塞,黄色):
|
||
```
|
||
存在[部件]物料,但[接头]工作表也匹配到1条记录,已忽略
|
||
[部件]工作表已返回弹性元件,但[弹性元件]工作表也匹配到1条记录,已忽略
|
||
```
|
||
|
||
**Logger调用**:
|
||
```vba
|
||
' 记录错误(阻塞)
|
||
logger.Record 0, "M09.ValidateAllMatchResults", "BOMMatchError", errorMessage, ""
|
||
|
||
' 记录警告(非阻塞)
|
||
logger.RecordWarning 0, "M09.ValidateAllMatchResults", "ComponentConflict", warningMessage, ""
|
||
```
|
||
|
||
---
|
||
|
||
### 错误日志机制
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph "错误检测"
|
||
A[检测到错误/警告]
|
||
end
|
||
|
||
subgraph "两阶段验证"
|
||
B1[Phase 1: 收集<br/>不记录错误]
|
||
B2[Phase 2: 验证<br/>记录错误和警告]
|
||
end
|
||
|
||
subgraph "错误记录"
|
||
C[clsErrorLogger]
|
||
C1[logger.Record<br/>错误(红色)]
|
||
C2[logger.RecordWarning<br/>警告(黄色)]
|
||
end
|
||
|
||
subgraph "错误信息"
|
||
D[错误类型]
|
||
E[上下文信息]
|
||
F[时间戳]
|
||
end
|
||
|
||
subgraph "错误输出"
|
||
G[第12列: 提取备注]
|
||
H[红色高亮(错误)]
|
||
I[黄色高亮(警告)]
|
||
end
|
||
|
||
A --> B1
|
||
B1 --> B2
|
||
B2 --> C
|
||
C --> C1
|
||
C --> C2
|
||
C1 & C2 --> D & E & F
|
||
D & E & F --> G
|
||
G --> H
|
||
G --> I
|
||
|
||
style A fill:#ffebee
|
||
style B1 fill:#e3f2fd
|
||
style B2 fill:#fff3e0
|
||
style C fill:#fff9c4
|
||
style G fill:#e8f5e9
|
||
style H fill:#ffcdd2
|
||
style I fill:#fff59d
|
||
```
|
||
|
||
**clsErrorLogger方法**:
|
||
|
||
```vba
|
||
' 记录错误(阻塞)
|
||
logger.Record rowIndex, sourceModule, errorType, description, context
|
||
|
||
' 记录警告(非阻塞)
|
||
logger.RecordWarning rowIndex, sourceModule, warningType, description, context
|
||
```
|
||
|
||
**错误信息格式**:
|
||
```
|
||
[错误类型] 详细描述
|
||
- 行号: X
|
||
- 数据: [具体数据]
|
||
```
|
||
|
||
---
|
||
|
||
### 错误恢复策略
|
||
|
||
1. **继续处理**: 遇到非致命错误时继续处理下一条记录
|
||
2. **错误累积**: 所有错误都记录在日志中
|
||
3. **最终报告**: 处理完成后显示汇总报告
|
||
4. **部分成功**: 部分记录成功时仍然输出结果
|
||
5. **两阶段验证**: Phase 1不中断,Phase 2统一验证
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
### 示例1: 基本使用
|
||
|
||
```vba
|
||
' 在VBA编辑器中运行
|
||
Sub TestBOMExtraction()
|
||
Call RunBOMExtraction
|
||
End Sub
|
||
```
|
||
|
||
**输入数据**:
|
||
|
||
| 型号 |
|
||
|------|
|
||
| YTHN-100.A0.531.G123.M04.Y3 |
|
||
|
||
**输出结果**:
|
||
|
||
| 原始产品型号 | azxs | bkxs | gclj | jycz | lcfw | fjgn | 物料类型 | 物料名称 | 物料编码 | 数量 | 备注 |
|
||
|--------------|------|------|------|------|------|------|----------|----------|----------|------|------|
|
||
| YTHN-100...Y3 | A0 | 531 | G12 | 3 | M04 | Y3 | 接头 | 卡套式接头 | JT-001 | 1 | |
|
||
| YTHN-100...Y3 | A0 | 531 | G12 | 3 | M04 | Y3 | 弹性元件 | 膜片 | MH-002 | 1 | |
|
||
| YTHN-100...Y3 | A0 | 531 | G12 | 3 | M04 | Y3 | 机芯 | 齿轮机构 | JX-003 | 1 | |
|
||
|
||
---
|
||
|
||
### 示例2: 部件特殊处理
|
||
|
||
**场景**: 组件A缺货,使用子组件替代
|
||
|
||
**BOM库记录** ("部件"工作表):
|
||
|
||
| azxs | bkxs | ... | 物料编码 | 数量A | 物料编码B | 数量B | 物料编码C | 数量C |
|
||
|------|------|-----|----------|-------|-----------|-------|-----------|-------|
|
||
| A0 | 531 | ... | BJ-001 | 1 | JT-002 | 2 | MH-003 | 1 |
|
||
|
||
**假设**: 组件A (BJ-001) 缺货
|
||
|
||
**处理逻辑**:
|
||
1. 检测到组件A缺货
|
||
2. 检查子组件B (JT-002) 和C (MH-003) 库存
|
||
3. 如果都有库存,使用子组件替代
|
||
4. 验证组合: 只有子组件,无组件A ✓
|
||
|
||
**输出结果**:
|
||
|
||
| 物料类型 | 物料名称 | 物料编码 | 数量 | 备注 |
|
||
|----------|----------|----------|------|------|
|
||
| 接头 | 卡套式接头 | JT-002 | 2 | (子组件B) |
|
||
| 弹性元件 | 膜片 | MH-003 | 1 | (子组件C) |
|
||
|
||
---
|
||
|
||
### 示例3: 错误处理
|
||
|
||
**场景**: 型号解析失败
|
||
|
||
**输入**:
|
||
```
|
||
INVALID.MODEL.FORMAT
|
||
```
|
||
|
||
**处理流程**:
|
||
1. M06_ModelParser尝试解析
|
||
2. 检测到格式不匹配
|
||
3. 记录错误到Logger
|
||
4. 跳过该型号,继续下一个
|
||
|
||
**输出**:
|
||
|
||
| 原始产品型号 | 备注 |
|
||
|--------------|------|
|
||
| INVALID.MODEL.FORMAT | [解析错误] 型号格式不符合要求,无法提取参数 |
|
||
|
||
备注单元格会以红色高亮显示。
|
||
|
||
---
|
||
|
||
## 附录: 快速参考
|
||
|
||
### 常用函数速查
|
||
|
||
| 模块 | 函数 | 用途 |
|
||
|------|------|------|
|
||
| M01_Main | `RunBOMExtraction()` | 系统入口 |
|
||
| M09_BOMExtractor | `RunBOMExtraction()` | 主流程控制 |
|
||
| M09_BOMExtractor | `ProcessSingleModel()` | 处理单个型号 |
|
||
| M09_BOMExtractor | `MatchAllMaterialTypesWithValidation()` | 匹配所有物料类型(两阶段验证) |
|
||
| M09_BOMExtractor | `ValidateAllMatchResults()` | 统一验证所有匹配结果(跨工作表规则) |
|
||
| M06_ModelParser | `ParseProductModel()` | 解析型号参数 |
|
||
| M06A_Mapper | `InitMapper()` | 初始化值映射器 |
|
||
| M06A_Mapper | `MapAzxs()` | 映射azxs参数值 |
|
||
| M06A_Mapper | `MapLcfw()` | 映射lcfw参数值 |
|
||
| M07_BOMMatcher | `MatchBOMRecord()` | 匹配BOM记录(支持双值匹配) |
|
||
| M07_BOMMatcher | `EvaluateCellCondition()` | 评估单元格条件(支持双值匹配) |
|
||
| M07_BOMMatcher | `BuildHeaderMapping()` | 构建列映射 |
|
||
| M08_ComponentProcessor | `ProcessComponentRecord()` | 处理部件特殊逻辑 |
|
||
|
||
---
|
||
|
||
### 配置参数
|
||
|
||
| 配置项 | 值 | 说明 |
|
||
|--------|-----|------|
|
||
| 输入工作表名 | "产品型号" | 可含"型号"列 |
|
||
| 映射表工作表名 | "对照表" | 可选,用于值映射 |
|
||
| BOM库文件名 | "BOM库.xlsx" | 必须在同一目录 |
|
||
| 输出工作表名 | "BOM提取结果" | 自动创建/覆盖 |
|
||
| 数据起始行 | 2 | 行1为表头 |
|
||
| 映射表数据起始行 | 3 | 行1-2为表头 |
|
||
| 支持的物料类型 | 接头, 弹性元件, 机芯, 部件, 边 | 可扩展 |
|
||
| 支持的映射参数 | azxs, lcfw | 从对照表加载映射 |
|
||
|
||
---
|
||
|
||
### 相关文档
|
||
|
||
- [M03_Logic_Algorithm.md](./M03_Logic_Algorithm.md) - 条件解析算法详解
|
||
- [Test_PP_06_FullIntegration_流程详解.md](./Test_PP_06_FullIntegration_流程详解.md) - 预处理系统集成测试
|
||
- [CLAUDE.md](../CLAUDE.md) - 项目整体说明
|
||
|
||
---
|
||
|
||
**文档版本**: 3.0
|
||
**最后更新**: 2026-02-12
|
||
**作者**: Claude Code
|
||
**状态**: 更新完成 - 新增值映射功能文档
|
||
|
||
**版本历史**:
|
||
- v3.0 (2026-02-12): 重大更新 - 添加值映射(M06A_Mapper)功能文档,更新架构图、数据流图、核心流程图、模块交互时序图
|
||
- v2.0 (2026-02-12): 重大更新 - 添加两阶段验证架构详解,更新数据流图、核心流程图、模块交互时序图
|
||
- v1.0 (2026-02-12): 初稿完成
|