docs: reorganize documentation structure and add analysis guidelines

- Move existing documentation files to reference_docs/ directory
- Add documentation guidelines section to CLAUDE.md
- Add clsBOMManager LoadData flow analysis with Mermaid diagrams

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-01-29 09:30:29 +08:00
parent 29fca561e8
commit fd414f7673
8 changed files with 451 additions and 0 deletions

View File

@@ -0,0 +1,464 @@
# Example1_GeneratePickingListByModel 过程时序图
## 过程说明
本时序图展示 `Example1_GeneratePickingListByModel` 过程的详细执行流程,该过程根据产品型号生成完整的领料清单。
---
## 1. 简略版时序图(概览)
此版本展示主要流程和关键交互,适合快速了解整体架构。
```mermaid
sequenceDiagram
autonumber
participant Main as Example1_Sub
participant BOMMgr as clsBOMManager
participant Excel as Excel工作表
participant PickList as 型号领料清单表
participant Parser as 型号解析组件
participant DataStore as 数据集合
%% ==================== 初始化 ====================
Note over Main: 1. 初始化与加载数据
Main->>BOMMgr: 创建并初始化 BOMManager
Main->>Excel: 获取配置工作表<br/>(领料配置、平台配置清单)
Main->>BOMMgr: LoadData(wsConfig, wsPlatform)
activate BOMMgr
BOMMgr->>Excel: 读取类别层级和物料数据
BOMMgr->>DataStore: 构建内存数据结构<br/>(dictCategories, dictAllMaterials)
deactivate BOMMgr
%% ==================== 创建输出表 ====================
Note over Main: 2. 创建输出工作表
Main->>Main: modelStr = "YTHN-100.A0.532.M203.M16.Y3|..."
Main->>Excel: 删除旧工作表(如存在)
Main->>Excel: 创建新工作表 "型号领料清单"
Excel-->>Main: PickList 工作表对象
%% ==================== 解析型号 ====================
Note over Main: 3. 解析型号并提取条件
Main->>PickList: 写入产品型号标题
Main->>Parser: ParseModelAndExtractConditions(modelStr)
activate Parser
Parser->>Parser: 解析表头型号(YTHN-100...)<br/>解析表盘型号(BP-095...)
Parser->>DataStore: 提取选择条件<br/>(gclj, jycz, lcfw)
Parser-->>Main: Conditions Dictionary
deactivate Parser
Main->>PickList: 写入提取条件到工作表
%% ==================== 写入表头 ====================
Note over Main: 4. 写入数据表头
Main->>PickList: 写入列标题<br/>(类别, 代号, 名称, 数量, 选择条件, 匹配状态)
%% ==================== 处理物料 ====================
Note over Main: 5. 遍历类别并匹配物料
Main->>BOMMgr: GetRootCategories()
BOMMgr-->>Main: 根类别集合
loop 每个根类别
Main->>BOMMgr: GetMaterialsByModel(modelStr, categoryName)
activate BOMMgr
BOMMgr->>DataStore: 获取类别对象
BOMMgr->>Parser: 匹配物料选择条件
Parser-->>BOMMgr: 匹配结果集合
BOMMgr-->>Main: Materials Collection
deactivate BOMMgr
Note over Main: 写入该类别的所有物料
loop 每个匹配的物料
Main->>PickList: 写入物料详细信息<br/>(代号, 名称, 数量, 条件)
end
end
%% ==================== 完成输出 ====================
Note over Main: 6. 格式化并完成
Main->>PickList: AutoFit 格式化
Main->>Main: 显示完成消息框
```
**简略版特点**
- **6个参与者**相比详细版的11个
- **6个主要阶段**相比详细版的14个步骤
- **合并了内部细节**:解析器、提取器、匹配器的内部操作合并为一个组件
- **简化循环展示**:不展示条件判断、分支逻辑等细节
- **适合**:快速理解整体流程和架构
---
## 2. 详细版时序图(完整流程)
此版本展示每个方法的调用细节、内部逻辑和数据流向,适合深入理解实现。
## 时序图
```mermaid
sequenceDiagram
autonumber
participant Main as Example1_Sub
participant BOMMgr as clsBOMManager
participant Workbooks as Excel.Worksheets
participant ConfigWS as 领料配置表
participant PlatformWS as 平台配置清单表
participant Parser as clsModelParser
participant Extractor as clsConditionExtractor
participant Matcher as clsConditionMatcher
participant PickListWS as 型号领料清单表
participant RootCats as 根类别Collection
participant Cat as clsCategory
participant Materials as 物料Collection
participant Conditions as 条件Dictionary
%% ==================== 初始化阶段 ====================
Note over Main: 1. 初始化 BOM 管理器
Main->>BOMMgr: New clsBOMManager
activate BOMMgr
BOMMgr->>BOMMgr: 初始化 dictCategories<br/>初始化 dictAllMaterials<br/>初始化 rootCategories
deactivate BOMMgr
%% ==================== 加载配置阶段 ====================
Note over Main: 2. 获取工作表对象
Main->>Workbooks: Worksheets("领料配置")
Workbooks-->>Main: ConfigWS
Main->>Workbooks: Worksheets("平台配置清单")
Workbooks-->>Main: PlatformWS
Note over Main: 3. 加载 BOM 数据
Main->>BOMMgr: LoadData(ConfigWS, PlatformWS)
activate BOMMgr
BOMMgr->>ConfigWS: 读取类别配置数据<br/>第2行起物料代号、类别名称、上层类别
ConfigWS-->>BOMMgr: 类别层级数据
BOMMgr->>BOMMgr: 构建类别树结构<br/>创建 clsCategory 对象<br/>建立父子关系
BOMMgr->>PlatformWS: 读取物料清单数据<br/>第4行起
PlatformWS-->>BOMMgr: 完整物料数据
BOMMgr->>BOMMgr: 创建 clsMaterialItem 对象<br/>填充 dictAllMaterials 字典
BOMMgr->>BOMMgr: 将物料分配到对应类别<br/>建立 rootCategories 集合
deactivate BOMMgr
%% ==================== 准备型号数据 ====================
Note over Main: 4. 定义产品型号
Main->>Main: modelStr = "YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3"
%% ==================== 创建输出工作表 ====================
Note over Main: 5. 删除旧的领料清单表
Main->>Workbooks: Worksheets("型号领料清单")
alt 工作表存在
Workbooks-->>Main: 工作表对象
Main->>PickListWS: Delete
else 工作表不存在
Workbooks-->>Main: 错误
Main->>Main: On Error Resume Next (忽略错误)
end
Note over Main: 6. 创建新工作表
Main->>Workbooks: Worksheets.Add()
Workbooks-->>Main: PickListWS
Main->>PickListWS: Name = "型号领料清单"
%% ==================== 写入标题行 ====================
Note over Main: 7. 写入产品型号
Main->>Main: row = 1
Main->>PickListWS: Cells(row, 1).value = "产品型号"
Main->>PickListWS: Cells(row, 2).value = modelStr
Main->>Main: row = row + 1
%% ==================== 解析型号并提取条件 ====================
Note over Main: 8. 解析型号提取条件
Main->>BOMMgr: ParseModelAndExtractConditions(modelStr)
activate BOMMgr
BOMMgr->>Parser: New clsModelParser
activate Parser
BOMMgr->>Parser: ParseModel(modelStr)
Note over Parser: 解析表头型号
Parser->>Parser: 提取型号前缀: "YTHN"
Parser->>Parser: 提取公称外径: "100"
Parser->>Parser: 提取安装形式: "A0"
Parser->>Parser: 提取壳体形式: "532"
Parser->>Parser: 提取过程连接: "M203"
Parser->>Parser: 提取量程范围: "M16"
Parser->>Parser: 提取仪表特性: "Y3"
Note over Parser: 解析表盘型号
Parser->>Parser: 提取表盘型号: "BP-095"
Parser->>Parser: 提取表盘规格: "2312"
Parser->>Parser: 提取表盘连接: "M16"
Parser->>Parser: 提取表盘特性: "PA3"
Parser-->>BOMMgr: True (解析成功)
deactivate Parser
BOMMgr->>Extractor: New clsConditionExtractor
activate Extractor
BOMMgr->>Extractor: ExtractConditions(Parser)
Note over Extractor: 应用提取规则
Extractor->>Extractor: 规则1: gclj = 过程连接 = "M203"
Extractor->>Extractor: 规则2: jycz = 接液材质 = "M16"
Extractor->>Extractor: 规则3: lcfw = 量程范围 = "M16"
Extractor->>Extractor: 创建条件字典
Extractor-->>BOMMgr: Conditions Dictionary
deactivate Extractor
BOMMgr-->>Main: Conditions Dictionary
deactivate BOMMgr
%% ==================== 写入提取条件 ====================
Note over Main: 9. 写入提取条件行
Main->>PickListWS: Cells(row, 1).value = "提取条件"
Note over Main: 遍历条件字典拼接字符串
Main->>Conditions: 遍历 Keys
loop 每个条件键值对
Conditions-->>Main: key, value
Main->>Main: 拼接条件字符串到 condStr
end
Main->>PickListWS: Cells(row, 2).value = condStr
Main->>Main: row = row + 2
%% ==================== 写入表头 ====================
Note over Main: 10. 写入数据表头
Main->>PickListWS: Cells(row, 1).value = "类别"
Main->>PickListWS: Cells(row, 2).value = "代号"
Main->>PickListWS: Cells(row, 3).value = "名称"
Main->>PickListWS: Cells(row, 4).value = "数量"
Main->>PickListWS: Cells(row, 5).value = "选择条件"
Main->>PickListWS: Cells(row, 6).value = "匹配状态"
Main->>PickListWS: 设置表头字体为粗体 (Range A-F)
Main->>Main: row = row + 1
%% ==================== 获取根类别 ====================
Note over Main: 11. 获取根类别集合
Main->>BOMMgr: GetRootCategories()
BOMMgr-->>Main: RootCats Collection
%% ==================== 外层循环:遍历根类别 ====================
Note over Main: 12. 遍历每个根类别
loop 每个根类别 i = 1 To RootCats.Count
Main->>RootCats: Item(i)
RootCats-->>Main: Cat
Note over Main: 获取类别名称
Main->>Cat: .categoryName
Cat-->>Main: categoryName
Note over Main: 获取该类别符合条件的物料
Main->>BOMMgr: GetMaterialsByModel(modelStr, categoryName)
activate BOMMgr
BOMMgr->>Matcher: New clsConditionMatcher
activate Matcher
Note over BOMMgr: 从 dictCategories 获取类别
BOMMgr->>BOMMgr: dictCategories(categoryName)
BOMMgr-->>BOMMgr: Category 对象
Note over BOMMgr: 遍历类别下的所有物料
BOMMgr->>Cat: .materials (Collection)
loop 每个物料
Cat-->>BOMMgr: MaterialItem
Note over BOMMgr: 检查物料选择条件
BOMMgr->>MaterialItem: .Condition
alt 物料有选择条件
MaterialItem-->>BOMMgr: conditionStr
Note over BOMMgr,Matcher: 匹配条件
BOMMgr->>Matcher: Match(conditionStr, Conditions)
Matcher->>Matcher: 解析条件表达式<br/>AND, OR, !=, 括号)
Matcher->>Conditions: 获取变量值
Conditions-->>Matcher: 变量值
Matcher->>Matcher: 评估逻辑表达式
Matcher-->>BOMMgr: True/False (匹配结果)
alt 匹配成功
BOMMgr->>BOMMgr: 添加到结果集合
end
else 物料无条件
MaterialItem-->>BOMMgr: ""
BOMMgr->>BOMMgr: 直接添加到结果集合
end
end
BOMMgr-->>Main: Materials Collection
deactivate Matcher
deactivate BOMMgr
%% ==================== 内层循环:遍历物料写入 ====================
Note over Main: 写入该类别的所有物料
loop 每个物料 j = 1 To Materials.Count
Main->>Materials: Item(j)
Materials-->>Main: mat (clsMaterialItem)
Note over Main: 写入物料详细信息
Main->>PickListWS: Cells(row, 1).value = categoryName
Main->>PickListWS: Cells(row, 2).value = mat.code
Main->>PickListWS: Cells(row, 3).value = mat.Name
Main->>PickListWS: Cells(row, 4).value = mat.Quantity
Main->>mat: .Condition
mat-->>Main: condition
alt condition = ""
Main->>PickListWS: Cells(row, 5).value = "(无条件)"
else condition <> ""
Main->>PickListWS: Cells(row, 5).value = condition
end
Main->>PickListWS: Cells(row, 6).value = "✓"
Main->>Main: row = row + 1
end
end
%% ==================== 格式化输出 ====================
Note over Main: 13. 格式化工作表
Main->>PickListWS: Columns("A:F").AutoFit
%% ==================== 显示完成消息 ====================
Note over Main: 14. 显示完成消息框
Main->>Main: MsgBox("领料清单生成完成!\n请查看工作表: 型号领料清单")
Note over Main: 过程结束
```
## 流程阶段说明
### 阶段 1: 初始化与数据加载 (步骤 1-3)
- 创建 BOM 管理器实例
- 从 Excel 获取配置工作表
- 加载类别层级和物料数据,构建内存数据结构
### 阶段 2: 工作表准备 (步骤 4-7)
- 定义产品型号字符串
- 删除旧的输出工作表(带错误处理)
- 创建新的"型号领料清单"工作表
- 写入产品型号标题
### 阶段 3: 型号解析与条件提取 (步骤 8-9)
- 使用 ModelParser 解析复杂型号字符串
- 表头型号YTHN-100.A0.532.M203.M16.Y3
- 表盘型号BP-095.2312.M16.PA3
- 使用 ConditionExtractor 提取物料选择条件
- 将条件字典写入输出表
### 阶段 4: 数据表头 (步骤 10-11)
- 写入数据列标题:类别、代号、名称、数量、选择条件、匹配状态
- 获取根类别集合
### 阶段 5: 物料匹配与写入 (步骤 12)
- **外层循环**:遍历每个根类别
- **物料匹配**:对每个类别调用 GetMaterialsByModel
- 遍历类别下所有物料
- 使用 ConditionMatcher 评估每个物料的选择条件
- 筛选符合条件的物料
- **内层循环**:遍历匹配的物料集合
- 写入物料的详细信息(代号、名称、数量等)
- 显示选择条件和匹配状态
### 阶段 6: 格式化与完成 (步骤 13-14)
- 自动调整列宽
- 显示完成消息框
## 关键数据结构
### 输入数据
- **产品型号**: "YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3"
- **配置工作表**: "领料配置"、"平台配置清单"
### 中间数据
- **Conditions Dictionary**: {gclj: "M203", jycz: "M16", lcfw: "M16"}
- **RootCategories Collection**: 所有顶层类别
- **Materials Collection**: 每个类别匹配的物料
### 输出数据
- **型号领料清单表**: 包含产品型号、提取条件、物料清单
## 性能考虑
- 使用 Dictionary 和 Collection 提高查找效率
- 嵌套循环结构:根类别 × 物料
- 大量 Excel 单元格写入操作(可考虑批量写入优化)
## 扩展建议
1. **批量写入优化**: 将数据先存入数组,一次性写入工作表
2. **进度显示**: 添加处理进度条
3. **错误处理**: 增强型号解析失败、数据缺失等异常处理
4. **参数化**: 将型号作为参数传入,增加灵活性
5. **日志记录**: 记录处理过程和匹配统计信息
---
## 3. 两个版本的对比
### 复杂度对比
| 特性 | 简略版 | 详细版 |
|------|--------|--------|
| **参与者数量** | 6个 | 11个 |
| **主要阶段** | 6个 | 14个步骤 |
| **交互步骤** | 约35步 | 约80步 |
| **循环展开** | 简化展示 | 完整展示内部逻辑 |
| **条件分支** | 隐藏 | 详细展示 (alt/opt/loop) |
| **内部方法调用** | 合并展示 | 逐个展开 |
### 适用场景
#### 简略版适用于:
- 📌 **初次了解**:快速掌握整体流程和架构
- 📌 **高层汇报**:向非技术人员展示系统工作原理
- 📌 **文档概览**:作为技术文档的目录或概述部分
- 📌 **快速参考**:复习主要步骤和组件关系
#### 详细版适用于:
- 🔍 **代码调试**:理解具体实现细节和数据流向
- 🔍 **代码审查**:检查逻辑错误和性能瓶颈
- 🔍 **新人培训**:深入讲解系统实现机制
- 🔍 **维护文档**:作为详细技术文档保存
### 组件对应关系
| 简略版组件 | 详细版组件 |
|------------|------------|
| Excel工作表 | Workbooks + ConfigWS + PlatformWS + PickListWS |
| 型号解析组件 | Parser + Extractor + Matcher |
| 数据集合 | RootCats + Cat + Materials + Conditions |
### 阶段对应关系
| 简略版阶段 | 详细版步骤 |
|------------|------------|
| 1. 初始化与加载数据 | 1-3: 初始化、获取工作表、加载数据 |
| 2. 创建输出工作表 | 4-7: 定义型号、删除旧表、创建新表、写入标题 |
| 3. 解析型号并提取条件 | 8-9: 解析型号、提取条件、写入条件行 |
| 4. 写入数据表头 | 10-11: 写入列标题、获取根类别 |
| 5. 遍历类别并匹配物料 | 12: 外层循环(类别)、内层循环(物料)、条件匹配 |
| 6. 格式化并完成 | 13-14: 格式化工作表、显示消息框 |
---
## 使用建议
1. **学习路径**:先看简略版建立整体概念,再看详细版理解实现细节
2. **文档组织**:简略版放在文档开头作为概述,详细版放在后面作为参考
3. **演示场景**简略版适合PPT演示详细版适合技术讲解
4. **版本维护**:代码变更时,优先更新详细版,然后同步更新简略版的主要流程

View File

@@ -0,0 +1,439 @@
# clsBOMManager.LoadData 方法流程分析
## 方法概述
`LoadData``clsBOMManager` 类的核心方法,负责从 Excel 工作表加载 BOM 数据并构建完整的层级数据结构。
## 方法签名
```vba
Public Sub LoadData(wsConfig As Worksheet, wsPlatform As Worksheet)
```
### 参数说明
| 参数 | 类型 | 说明 |
|------|------|------|
| `wsConfig` | Worksheet | [领料配置]工作表,包含类别层级和需要领料的物料 |
| `wsPlatform` | Worksheet | [平台配置清单]工作表,包含完整的物料信息 |
## 整体流程图
```mermaid
flowchart TD
Start([开始 LoadData]) --> Step1[第一步: 加载物料基础信息]
Step1 --> Step2[第二步: 加载类别信息并关联物料]
Step2 --> Step3[第三步: 建立类别层级关系]
Step3 --> End([结束])
style Start fill:#e1f5e1
style End fill:#ffe1e1
style Step1 fill:#e1f0ff
style Step2 fill:#fff4e1
style Step3 fill:#f0e1ff
```
## 详细流程分析
### 第一步:从平台配置清单加载所有物料的基础信息
```mermaid
flowchart TD
S1_Start([开始第一步]) --> S1_Init[初始化: 获取最后一行行号]
S1_Init --> S1_Loop{循环 i = 4 到 lastRow}
S1_Loop -->|i += 1| S1_Read[读取第 i 行数据]
S1_Read --> S1_Create[创建 clsMaterialItem 对象]
S1_Create --> S1_Assign[赋值: code, Name, Quantity, Condition]
S1_Assign --> S1_Check{code 是否非空?}
S1_Check -->|是| S1_Add[添加到 dictAllMaterials<br/>键: code, 值: mat]
S1_Check -->|否| S1_Next[跳过]
S1_Add --> S1_Next
S1_Next --> S1_Loop
S1_Loop -->|i > lastRow| S1_End([第一步完成])
style S1_Start fill:#e1f5e1
style S1_End fill:#ffe1e1
style S1_Add fill:#c8e6c9
style S1_Check fill:#fff9c4
```
**数据来源**[平台配置清单] 工作表
| 列 | 字段 | 说明 |
|----|------|------|
| C | code | 物料代号 |
| D | Name | 物料名称 |
| E | Quantity | 物料数量 |
| F | Condition | 选择条件 |
**数据结构**
```
dictAllMaterials: Dictionary<String, clsMaterialItem>
├── "01011019001" → clsMaterialItem{code, Name, Quantity, Condition}
├── "01081013833" → clsMaterialItem{...}
└── ...
```
**关键代码**
```vba
lastRow = wsPlatform.Cells(wsPlatform.Rows.Count, "C").End(xlUp).row
For i = 4 To lastRow
Set mat = New clsMaterialItem
mat.code = Trim(wsPlatform.Cells(i, "C").value & "")
mat.Name = Trim(wsPlatform.Cells(i, "D").value & "")
mat.Quantity = CDbl(wsPlatform.Cells(i, "E").value)
mat.Condition = Trim(wsPlatform.Cells(i, "F").value & "")
If mat.code <> "" Then
Set dictAllMaterials(mat.code) = mat
End If
Next i
```
---
### 第二步:从领料配置加载类别信息并关联物料
```mermaid
flowchart TD
S2_Start([开始第二步]) --> S2_Init[初始化: 获取最后一行行号]
S2_Init --> S2_Loop{循环 i = 2 到 lastRow}
S2_Loop -->|i += 1| S2_Read[读取第 i 行数据<br/>code, catName, parentCatName]
S2_Read --> S2_CheckCode{code 是否为空?}
S2_CheckCode -->|是| S2_NextRow[跳到下一行]
S2_CheckCode -->|否| S2_CheckCat{类别是否已存在?}
S2_CheckCat -->|否| S2_CreateCat[创建新的 clsCategory 对象<br/>设置 categoryName 和 ParentCategoryName<br/>添加到 dictCategories]
S2_CheckCat -->|是| S2_Exists[类别已存在]
S2_CreateCat --> S2_CheckMat{物料在<br/>dictAllMaterials?}
S2_Exists --> S2_CheckMat
S2_CheckMat -->|是| S2_UpdateMat[更新物料信息:<br/>mat.Category = catName<br/>mat.ParentCategory = parentCatName<br/>添加到类别 materials 集合]
S2_CheckMat -->|否| S2_SkipMat[物料不在库中,跳过]
S2_UpdateMat --> S2_NextRow
S2_SkipMat --> S2_NextRow
S2_NextRow --> S2_Loop
S2_Loop -->|i > lastRow| S2_End([第二步完成])
style S2_Start fill:#e1f5e1
style S2_End fill:#ffe1e1
style S2_CreateCat fill:#bbdefb
style S2_UpdateMat fill:#c8e6c9
style S2_CheckCat fill:#fff9c4
style S2_CheckMat fill:#fff9c4
```
**数据来源**[领料配置] 工作表
| 列 | 字段 | 说明 |
|----|------|------|
| A | code | 物料代号 |
| C | catName | 类别名称 |
| D | parentCatName | 上层类别名称 |
**数据结构**
```
dictCategories: Dictionary<String, clsCategory>
├── "表壳" → clsCategory{categoryName, materials[], SubCategories[]}
├── "部件" → clsCategory{...}
└── ...
```
**关键代码**
```vba
lastRow = wsConfig.Cells(wsConfig.Rows.Count, "A").End(xlUp).row
For i = 2 To lastRow
code = Trim(wsConfig.Cells(i, "A").value & "")
catName = Trim(wsConfig.Cells(i, "C").value & "")
parentCatName = Trim(wsConfig.Cells(i, "D").value & "")
If code = "" Then GoTo NextRow
If Not dictCategories.Exists(catName) Then
Set cat = New clsCategory
cat.categoryName = catName
cat.ParentCategoryName = parentCatName
Set dictCategories(catName) = cat
End If
If dictAllMaterials.Exists(code) Then
Set mat = dictAllMaterials(code)
mat.Category = catName
mat.ParentCategory = parentCatName
dictCategories(catName).AddMaterial mat
End If
Next i
```
**业务逻辑说明**
- 只有出现在 [领料配置] 中的物料才会被添加到类别中
- 未在 [领料配置] 中的物料表示不需要领料
---
### 第三步:建立类别层级关系
```mermaid
flowchart TD
S3_Start([开始第三步]) --> S3_Loop{遍历 dictCategories<br/>所有键}
S3_Loop -->|下一个键| S3_GetCat[获取类别对象 cat]
S3_GetCat --> S3_CheckParent{ParentCategoryName<br/>是否为空?}
S3_CheckParent -->|否, 有父类别| S3_ParentExists{父类别<br/>存在?}
S3_CheckParent -->|是, 无父类别| S3_AddRoot[添加到 rootCategories<br/>作为根类别]
S3_ParentExists -->|是| S3_AddSub[添加到父类别的<br/>SubCategories 集合]
S3_ParentExists -->|否| S3_Orphan[父类别不存在<br/>跳过建立关系]
S3_AddRoot --> S3_Next
S3_AddSub --> S3_Next
S3_Orphan --> S3_Next
S3_Next --> S3_Loop
S3_Loop -->|遍历完成| S3_End([第三步完成])
style S3_Start fill:#e1f5e1
style S3_End fill:#ffe1e1
style S3_AddRoot fill:#ffccbc
style S3_AddSub fill:#b2dfdb
```
**数据结构**
```
rootCategories: Collection<clsCategory>
├── "表壳" (根类别)
├── "部件" (根类别)
│ └── SubCategories:
│ ├── "接头" (子类别)
│ └── "弹性元件" (子类别)
└── "机芯" (根类别)
```
**关键代码**
```vba
For Each key In dictCategories.Keys
Set cat = dictCategories(key)
If cat.ParentCategoryName <> "" Then
If dictCategories.Exists(cat.ParentCategoryName) Then
Set parentCat = dictCategories(cat.ParentCategoryName)
parentCat.AddSubCategory cat
End If
Else
rootCategories.Add cat, cat.categoryName
End If
Next key
```
**层级关系构建逻辑**
1. 遍历所有类别
2. 如果类别有父类别 → 建立父子关系(调用父类别的 `AddSubCategory` 方法)
3. 如果类别无父类别 → 作为根类别,添加到 `rootCategories`
---
## 数据结构总结
### 类的私有成员变量
```mermaid
classDiagram
class clsBOMManager {
-dictCategories: Dictionary
-dictAllMaterials: Dictionary
-rootCategories: Collection
+LoadData(wsConfig, wsPlatform)
+GetRootCategories() Collection
+GetCategory(categoryName) clsCategory
}
class clsCategory {
+categoryName: String
+ParentCategoryName: String
+materials: Collection
+SubCategories: Collection
+AddMaterial(mat)
+AddSubCategory(cat)
+HasSubCategories: Boolean
}
class clsMaterialItem {
+code: String
+Name: String
+Quantity: Double
+Condition: String
+Category: String
+ParentCategory: String
}
clsBOMManager "1" --> "*" clsCategory : 管理
clsCategory "1" --> "*" clsMaterialItem : 包含
clsCategory "1" --> "*" clsCategory : 父子关系
```
### 三个核心数据容器
| 数据容器 | 类型 | 键/索引 | 值 | 用途 |
|---------|------|---------|-----|------|
| `dictAllMaterials` | Dictionary | 物料代号 (String) | clsMaterialItem | 快速查找任意物料的完整信息 |
| `dictCategories` | Dictionary | 类别名称 (String) | clsCategory | 快速查找任意类别 |
| `rootCategories` | Collection | 索引 (Long) | clsCategory | 遍历完整的类别树结构 |
---
## 流程时序图
```mermaid
sequenceDiagram
participant Caller as 调用者
participant LoadData as LoadData方法
participant WSPlatform as [平台配置清单]
participant WSConfig as [领料配置]
participant DictMat as dictAllMaterials
participant DictCat as dictCategories
participant RootCats as rootCategories
Caller->>LoadData: LoadData(wsConfig, wsPlatform)
Note over LoadData, WSPlatform: 第一步: 加载物料库
LoadData->>WSPlatform: 读取第4-末行, C-F列
WSPlatform-->>LoadData: 返回物料数据
loop 每一行物料
LoadData->>DictMat: 添加物料 (代号→对象)
end
Note over LoadData, WSConfig: 第二步: 建立类别与物料关联
LoadData->>WSConfig: 读取第2-末行, A/C/D列
WSConfig-->>LoadData: 返回类别配置
loop 每一行配置
LoadData->>DictCat: 类别存在?
alt 类别不存在
LoadData->>DictCat: 创建新类别
end
LoadData->>DictMat: 查找物料信息
alt 物料存在
LoadData->>DictCat: 添加物料到类别
end
end
Note over LoadData, RootCats: 第三步: 构建层级树
loop 遍历所有类别
LoadData->>DictCat: 获取类别
alt 有父类别
LoadData->>DictCat: 添加到父类别的SubCategories
else 无父类别
LoadData->>RootCats: 添加为根类别
end
end
LoadData-->>Caller: 完成
```
---
## 重要业务规则
### 1. 物料筛选规则
- ✅ 在 [领料配置] 中的物料 → **需要领料**,会被添加到类别中
- ❌ 不在 [领料配置] 中的物料 → **不需要领料**,仅在 `dictAllMaterials`
### 2. 类别层级规则
- 根类别:`ParentCategoryName` 为空字符串 `""`
- 子类别:`ParentCategoryName` 指向父类别名称
- 层级深度:无限制(支持任意深度的树形结构)
### 3. 数据一致性
- 所有物料必须先在 [平台配置清单] 中定义
- [领料配置] 中的物料代号必须在 `dictAllMaterials` 中存在
- 如果不存在,该物料会被跳过(不会报错)
---
## 使用示例
### 调用 LoadData
```vba
Dim bomMgr As New clsBOMManager
Dim wsConfig As Worksheet
Dim wsPlatform As Worksheet
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
' 加载数据
Call bomMgr.LoadData(wsConfig, wsPlatform)
' 获取根类别
Dim rootCats As Collection
Set rootCats = bomMgr.GetRootCategories()
' 遍历所有根类别
Dim i As Long
For i = 1 To rootCats.Count
Debug.Print "根类别: " & rootCats(i).categoryName
Next i
```
---
## 执行后的数据结构示例
假设加载后的数据结构如下:
```
dictAllMaterials:
{
"01091004312" → {code: "01091004312", Name: "表壳(本色)", Quantity: 1, Condition: ""},
"01011019001" → {code: "01011019001", Name: "低压接头部件", Quantity: 1, Condition: "lcfw=M02"},
"01081013833" → {code: "01081013833", Name: "径向低压接头", Quantity: 1, Condition: "gclj=Z12"}
}
dictCategories:
{
"表壳" → {categoryName: "表壳", ParentCategoryName: "", materials: [01091004312], SubCategories: []},
"部件" → {categoryName: "部件", ParentCategoryName: "", materials: [01011019001], SubCategories: ["接头", "弹性元件"]},
"接头" → {categoryName: "接头", ParentCategoryName: "部件", materials: [01081013833], SubCategories: []}
}
rootCategories:
[
"表壳" (clsCategory),
"部件" (clsCategory),
"机芯" (clsCategory)
]
```
---
## 错误处理
LoadData 方法本身不包含显式的错误处理(`On Error`),依赖以下机制:
1. **空值处理**:使用 `& ""` 确保字符串转换不会失败
2. **类型转换**:使用 `CDbl()` 时没有错误处理,假设数据格式正确
3. **跳过机制**:物料代号为空时,使用 `GoTo NextRow` 跳过
4. **存在性检查**:使用 `Dictionary.Exists()` 避免键不存在错误
---
## 相关方法
LoadData 执行后,可以使用以下方法访问数据:
| 方法 | 说明 |
|------|------|
| `GetRootCategories()` | 获取所有顶层类别 |
| `GetCategory(categoryName)` | 根据名称获取类别对象 |
| `GetMaterialsByModel()` | 根据型号获取物料 |
| `GetValidMaterialsByModel()` | 获取物料并检查完整性 |
| `PrintCategoryTree()` | 打印类别树(调试用) |
---
## 总结
`LoadData` 方法通过三个阶段构建完整的 BOM 数据结构:
1. **数据收集**:从 [平台配置清单] 收集所有物料基础信息
2. **数据关联**:从 [领料配置] 建立类别与物料的关联
3. **结构构建**:构建类别的树形层级关系
最终形成的数据结构支持:
- 快速按代号查找物料
- 快速按类别查找物料
- 遍历完整的类别树
- 支持父类别/子类别的领料逻辑

View File

@@ -0,0 +1,545 @@
# clsBOMManager 类使用说明
## 概述
`clsBOMManager` 是 AutoBOM 系统的核心控制器类,负责管理整个 BOM物料清单数据结构。它从 Excel 工作表加载数据,构建层级化的类别树,并提供物料查询和领料逻辑处理功能。
---
## 类初始化
```vba
Dim bomMgr As New clsBOMManager
```
创建实例时,会自动初始化以下内部数据结构:
- `dictCategories` - 类别字典(类别名称 → clsCategory 对象)
- `dictAllMaterials` - 物料字典(物料代号 → clsMaterialItem 对象)
- `rootCategories` - 根类别集合(顶层类别)
---
## 公开方法
### 1. LoadData 方法
**功能**:从 Excel 工作表加载 BOM 数据并构建数据结构
**语法**
```vba
Public Sub LoadData(wsConfig As Worksheet, wsPlatform As Worksheet)
```
**参数**
| 参数 | 类型 | 说明 |
|------|------|------|
| wsConfig | Worksheet | 领料配置工作表,定义类别层级和需要领料的物料 |
| wsPlatform | Worksheet | 平台配置清单工作表,包含完整的物料信息 |
**数据要求**
**领料配置** 工作表格式:
- **第 1 行**:标题行
- **第 2 行起**:数据行
- A 列:物料代号
- C 列:类别名称
- D 列:上层类别名称
**平台配置清单** 工作表格式:
- **第 1-3 行**:标题行
- **第 4 行起**:数据行
- C 列:物料代号
- D 列:物料名称
- E 列:物料数量
- F 列:选择条件
**处理逻辑**
1. 从"平台配置清单"加载所有物料的基础信息到 `dictAllMaterials`
2. 从"领料配置"加载类别信息,筛选需要领料的物料
3. 建立类别的父子关系,构建层级树
**重要说明**
- 只有出现在"领料配置"中的物料才会被添加到类别中
- 未在"领料配置"中的物料表示不需要领料,但仍存在于物料字典中
**使用示例**
```vba
Dim bomMgr As New clsBOMManager
Dim wsConfig As Worksheet
Dim wsPlatform As Worksheet
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
bomMgr.LoadData wsConfig, wsPlatform
```
---
### 2. GetRootCategories 方法
**功能**:获取所有顶层类别的集合
**语法**
```vba
Public Function GetRootCategories() As Collection
```
**返回值**
- `Collection` 对象,包含所有无父类别的 `clsCategory` 对象
**用途**
- 遍历整个 BOM 结构时的入口点
- 生成领料清单时遍历所有根类别
**使用示例**
```vba
Dim rootCats As Collection
Dim cat As clsCategory
Dim i As Long
Set rootCats = bomMgr.GetRootCategories()
For i = 1 To rootCats.Count
Set cat = rootCats(i)
Debug.Print "根类别: " & cat.categoryName
Debug.Print " 物料数: " & cat.Materials.Count
Debug.Print " 子类别数: " & cat.SubCategories.Count
Next i
```
---
### 3. GetCategory 方法
**功能**:根据类别名称获取类别对象
**语法**
```vba
Public Function GetCategory(categoryName As String) As clsCategory
```
**参数**
| 参数 | 类型 | 说明 |
|------|------|------|
| categoryName | String | 要查询的类别名称 |
**返回值**
- 找到时:返回 `clsCategory` 对象
- 未找到时:返回 `Nothing`
**用途**:快速查找特定类别及其下的物料
**使用示例**
```vba
Dim cat As clsCategory
Set cat = bomMgr.GetCategory("部件")
If Not cat Is Nothing Then
Debug.Print "类别: " & cat.categoryName
Debug.Print "父类别: " & cat.ParentCategoryName
Debug.Print "物料数: " & cat.Materials.Count
Debug.Print "是否叶子类别: " & cat.IsLeafCategory
End If
```
---
### 4. GetMaterialsForPicking 方法
**功能**:获取某类别下需要领料的物料清单(支持层级逻辑)
**语法**
```vba
Public Function GetMaterialsForPicking(categoryName As String, _
Optional useParent As Boolean = True) As Collection
```
**参数**
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| categoryName | String | - | 类别名称 |
| useParent | Boolean | True | 领料方式True=父类别物料False=子类别物料 |
**返回值**
- `Collection` 对象,包含 `clsMaterialItem` 对象
**业务逻辑说明**
#### 父类别模式 (useParent=True)
- 这是**默认的领料方式**
- 直接返回当前类别下的所有物料
- 即使该类别有子类别,也仍然返回父类别物料
- 用于领取组装好的部件
**示例**
```vba
' 获取"部件"类别的父类别物料
Set materials = bomMgr.GetMaterialsForPicking("部件", True)
' 返回:低压接头部件、高压接头部件等组装好的部件
```
#### 子类别模式 (useParent=False)
- 这是**库存不足时的替代方案**
- 如果当前类别有子类别,递归获取所有子类别的物料
- 如果当前类别是叶子类别(无子类别),返回本类别物料
- 用于父类别库存不足,需要领取零件自行组装的情况
**示例**
```vba
' 获取"部件"类别的子类别展开物料
Set materials = bomMgr.GetMaterialsForPicking("部件", False)
' 返回:径向低压接头、弹簧管、螺旋管等零件
```
**层级结构示例**
```
部件 (父类别)
├── 低压接头部件 (物料)
├── 高压接头部件 (物料)
└── 接头 (子类别)
├── 径向低压接头 (物料)
├── 轴向高压接头 (物料)
└── 弹性元件 (孙类别)
└── 弹簧管 (物料)
```
**使用示例**
```vba
Dim materials As Collection
Dim mat As clsMaterialItem
Dim i As Long
' 默认使用父类别物料
Set materials = bomMgr.GetMaterialsForPicking("部件", True)
Debug.Print "父类别物料数: " & materials.Count
For i = 1 To materials.Count
Set mat = materials(i)
Debug.Print mat.code & " - " & mat.Name & _
" | 数量:" & mat.Quantity & _
" | 条件:" & mat.Condition
Next i
' 库存不足时,使用子类别物料
Set materials = bomMgr.GetMaterialsForPicking("部件", False)
Debug.Print "子类别展开物料数: " & materials.Count
```
---
### 5. PrintCategoryTree 方法
**功能**:将类别树结构打印到工作表(用于调试和查看)
**语法**
```vba
Public Sub PrintCategoryTree(ws As Worksheet)
```
**参数**
| 参数 | 类型 | 说明 |
|------|------|------|
| ws | Worksheet | 输出的目标工作表对象 |
**输出格式**
- 第 1 列:类别名称(带缩进显示层级)
- 第 2 列:物料数量信息
- 第 3 列:选择条件
**缩进规则**:每层级 2 个空格
**输出示例**
```
表壳 (物料数:1)
- 01091004312 表壳(本色) 数量:1 条件:
部件 (物料数:20)
- 01011019001 低压接头部件 数量:1 条件:lcfw=M02...
接头 (物料数:18)
- 01081013833 径向低压接头 数量:1 条件:gclj=Z12...
```
**使用示例**
```vba
Dim wsOutput As Worksheet
' 创建新工作表
On Error Resume Next
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("BOM结构").Delete
Application.DisplayAlerts = True
On Error GoTo 0
Set wsOutput = ThisWorkbook.Worksheets.Add
wsOutput.Name = "BOM结构"
' 打印类别树
bomMgr.PrintCategoryTree wsOutput
```
---
## 典型使用场景
### 场景 1生成领料清单
```vba
Sub GeneratePickingList()
Dim bomMgr As New clsBOMManager
Dim wsConfig As Worksheet, wsPlatform As Worksheet
Dim wsPickList As Worksheet
Dim rootCats As Collection
Dim cat As clsCategory
Dim materials As Collection
Dim mat As clsMaterialItem
Dim row As Long
Dim i As Long, j As Long
' 1. 加载数据
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
bomMgr.LoadData wsConfig, wsPlatform
' 2. 创建输出工作表
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Worksheets("领料清单").Delete
On Error GoTo 0
Application.DisplayAlerts = True
Set wsPickList = ThisWorkbook.Worksheets.Add
wsPickList.Name = "领料清单"
' 3. 写入表头
row = 1
wsPickList.Cells(row, 1).Value = "代号"
wsPickList.Cells(row, 2).Value = "名称"
wsPickList.Cells(row, 3).Value = "类别"
wsPickList.Cells(row, 4).Value = "数量"
wsPickList.Cells(row, 5).Value = "选择条件"
wsPickList.Cells(row, 6).Value = "领料方式"
row = row + 1
' 4. 遍历所有根类别并生成清单
Set rootCats = bomMgr.GetRootCategories
For i = 1 To rootCats.Count
Set cat = rootCats(i)
' 默认使用父类别物料
Set materials = bomMgr.GetMaterialsForPicking(cat.categoryName, True)
For j = 1 To materials.Count
Set mat = materials(j)
wsPickList.Cells(row, 1).Value = mat.code
wsPickList.Cells(row, 2).Value = mat.Name
wsPickList.Cells(row, 3).Value = mat.Category
wsPickList.Cells(row, 4).Value = mat.Quantity
wsPickList.Cells(row, 5).Value = mat.Condition
wsPickList.Cells(row, 6).Value = "父类别"
row = row + 1
Next j
Next i
' 5. 格式化表格
wsPickList.Range("A1:F1").Font.Bold = True
wsPickList.Columns("A:F").AutoFit
MsgBox "领料清单生成完成!", vbInformation
End Sub
```
### 场景 2查询特定类别信息
```vba
Sub QueryCategoryInfo()
Dim bomMgr As New clsBOMManager
Dim wsConfig As Worksheet, wsPlatform As Worksheet
Dim cat As clsCategory
Dim mat As clsMaterialItem
Dim subCat As clsCategory
Dim i As Long
' 加载数据
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
bomMgr.LoadData wsConfig, wsPlatform
' 查询特定类别
Set cat = bomMgr.GetCategory("部件")
If Not cat Is Nothing Then
Debug.Print "========== 类别信息 =========="
Debug.Print "类别名称: " & cat.categoryName
Debug.Print "父类别: " & cat.ParentCategoryName
Debug.Print "物料数量: " & cat.Materials.Count
Debug.Print "子类别数量: " & cat.SubCategories.Count
Debug.Print "是否叶子类别: " & cat.IsLeafCategory
Debug.Print ""
' 列出所有物料
Debug.Print "---------- 物料列表 ----------"
For i = 1 To cat.Materials.Count
Set mat = cat.Materials(i)
Debug.Print " " & mat.code & ": " & mat.Name & _
" (数量:" & mat.Quantity & _
", 条件:" & mat.Condition & ")"
Next i
Debug.Print ""
' 列出所有子类别
Debug.Print "---------- 子类别列表 ----------"
For i = 1 To cat.SubCategories.Count
Set subCat = cat.SubCategories(i)
Debug.Print " " & subCat.categoryName & _
" (物料数:" & subCat.Materials.Count & ")"
Next i
Else
Debug.Print "类别不存在"
End If
End Sub
```
### 场景 3根据库存情况选择领料方式
```vba
Sub SmartPicking()
Dim bomMgr As New clsBOMManager
Dim materials As Collection
Dim mat As clsMaterialItem
Dim categoryName As String
Dim i As Long
' 加载数据
bomMgr.LoadData _
ThisWorkbook.Worksheets("领料配置"), _
ThisWorkbook.Worksheets("平台配置清单")
categoryName = "部件"
' 尝试获取父类别物料
Set materials = bomMgr.GetMaterialsForPicking(categoryName, True)
' 检查库存是否充足(这里需要连接实际的库存系统)
Dim isStockSufficient As Boolean
isStockSufficient = CheckStock(materials) ' 假设的库存检查函数
If isStockSufficient Then
Debug.Print "使用父类别领料方式"
Else
Debug.Print "父类别库存不足,改用子类别领料方式"
Set materials = bomMgr.GetMaterialsForPicking(categoryName, False)
End If
' 输出物料清单
For i = 1 To materials.Count
Set mat = materials(i)
Debug.Print mat.code & " " & mat.Name
Next i
End Sub
```
---
## 辅助类说明
### clsCategory 类
表示物料类别及其层级关系。
**公共属性**
| 属性 | 类型 | 说明 |
|------|------|------|
| categoryName | String | 类别名称 |
| ParentCategoryName | String | 父类别名称 |
| Materials | Collection | 该类别下的物料集合 |
| SubCategories | Collection | 子类别集合 |
| IsLeafCategory | Boolean | 是否为叶子类别(无子类别) |
**公共方法**
- `AddMaterial(mat As clsMaterialItem)` - 添加物料
- `AddSubCategory(cat As clsCategory)` - 添加子类别
- `GetMaterial(code As String) As clsMaterialItem` - 获取指定代号的物料
- `HasSubCategories() As Boolean` - 检查是否有子类别
### clsMaterialItem 类
表示单个物料项。
**公共属性**
| 属性 | 类型 | 说明 |
|------|------|------|
| code | String | 物料代号 |
| Name | String | 物料名称 |
| Quantity | Double | 物料数量 |
| Condition | String | 选择条件 |
| Category | String | 所属类别 |
| ParentCategory | String | 上层类别 |
---
## 注意事项
1. **数据加载顺序**:必须先调用 `LoadData()` 方法,才能使用其他查询方法
2. **工作表名称**:确保工作表名称与代码中的名称一致:
- "领料配置"
- "平台配置清单"
3. **空值处理**:使用 `GetCategory()` 方法时,务必检查返回值是否为 `Nothing`
4. **领料方式选择**
- 正常情况使用 `useParent=True`(领取组装好的部件)
- 仅在库存不足时使用 `useParent=False`(领取零件自行组装)
5. **数据一致性**:修改 Excel 数据后,需要重新调用 `LoadData()` 重新加载数据
6. **内存管理**使用完毕后VBA 会自动清理对象,无需手动释放
---
## 常见问题
### Q1: 如何判断某个类别是否存在?
```vba
Dim cat As clsCategory
Set cat = bomMgr.GetCategory("类别名")
If Not cat Is Nothing Then
' 类别存在
Else
' 类别不存在
End If
```
### Q2: 如何获取所有类别的名称?
```vba
Sub ListAllCategories()
' 需要递归遍历所有类别
' 可以使用 PrintCategoryTree 方法输出到工作表查看
End Sub
```
### Q3: 父类别和子类别物料有什么区别?
- **父类别物料**:组装好的成品部件,如"低压接头部件"
- **子类别物料**:组成部件的零件,如"径向低压接头"、"弹簧管"等
### Q4: 如何处理物料选择条件?
```vba
Dim mat As clsMaterialItem
' ...
If mat.Condition <> "" Then
' 根据条件选择合适的物料
' 条件格式如lcfw=M02;gclj=Z12
' 需要根据产品配置解析这些条件
End If
```
---
## 版本信息
- **类名称**clsBOMManager
- **版本**1.0
- **最后更新**2025
- **依赖类**clsCategory, clsMaterialItem

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,428 @@
# 型号解析与物料匹配系统 - 使用说明
## 📋 目录
1. [系统概述](#系统概述)
2. [安装部署](#安装部署)
3. [快速开始](#快速开始)
4. [详细使用](#详细使用)
5. [API参考](#api参考)
6. [扩展指南](#扩展指南)
7. [常见问题](#常见问题)
---
## 系统概述
### 功能简介
本系统实现了从产品型号中自动提取物料选择条件并根据这些条件从BOM库中筛选出符合要求的物料清单。
### 核心功能
-**型号解析**: 自动解析产品型号的各个组成部分
-**条件提取**: 按规则提取物料选择条件(过程连接、接液材质、量程范围等)
-**条件匹配**: 支持复杂的逻辑表达式(AND/OR/NOT/括号)
-**物料筛选**: 自动筛选符合条件的物料
-**批量处理**: 支持批量处理多个型号
-**可扩展性**: 便于添加新的提取条件和匹配规则
### 示例
**输入型号**: `YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3`
**提取条件**:
- `gclj` (过程连接) = `M20`
- `jycz` (接液材质) = `3`
- `lcfw` (量程范围) = `M16`
**匹配结果**: `01011019018 - 高压接头部件`
---
## 安装部署
### 1. 导入类模块
将以下4个类模块文件导入到VBA项目中:
1. **clsModelParser.cls** - 型号解析器
2. **clsConditionExtractor.cls** - 条件提取器
3. **clsConditionMatcher.cls** - 条件匹配器
4. **clsBOMManager.cls** - BOM管理器(扩展版本)
### 2. 导入标准模块
将以下2个标准模块导入到VBA项目中:
1. **modModelParserTest.bas** - 测试模块
2. **modModelParserExamples.bas** - 应用示例模块
### 3. 验证安装
运行测试过程验证安装是否成功:
```vba
' 在立即窗口或通过运行按钮执行
RunAllTests
```
如果所有测试通过,说明安装成功!
---
## 快速开始
### 最简单的使用方式
```vba
Sub QuickStart()
' 1. 创建BOM管理器并加载数据
Dim bomMgr As New clsBOMManager
bomMgr.LoadData ThisWorkbook.Worksheets("领料配置"), _
ThisWorkbook.Worksheets("平台配置清单")
' 2. 根据型号获取物料
Dim modelStr As String
modelStr = "YTHN-100.A0.532.M203.M16.Y3"
Dim materials As Collection
Set materials = bomMgr.GetMaterialsByModel(modelStr, "部件")
' 3. 查看结果
Dim mat As clsMaterialItem
For Each mat In materials
Debug.Print mat.Code & " - " & mat.Name
Next mat
End Sub
```
### 生成领料清单
运行以下示例生成完整的领料清单:
```vba
Example1_GeneratePickingListByModel
```
这将创建一个新工作表,包含完整的领料清单。
---
## 详细使用
### 1. 型号解析
#### 基础解析
```vba
Dim parser As New clsModelParser
Dim modelStr As String
modelStr = "YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3"
If parser.ParseModel(modelStr) Then
' 解析成功
Debug.Print "型号: " & parser.ModelType ' YTHN
Debug.Print "外径: " & parser.Diameter ' 100
Debug.Print "过程连接: " & parser.ConnectionCode ' M203
Debug.Print "量程: " & parser.RangeCode ' M16
Else
' 解析失败
Debug.Print "错误: " & parser.ErrorMessage
End If
```
#### 获取提取的代码
```vba
Debug.Print "螺纹代码: " & parser.GetThreadCode() ' M20
Debug.Print "材质代码: " & parser.GetMaterialCode() ' 3
Debug.Print "量程代码: " & parser.GetRangeCode() ' M16
```
### 2. 条件提取
```vba
Dim parser As New clsModelParser
parser.ParseModel "YTHN-100.A0.532.M203.M16.Y3"
Dim extractor As New clsConditionExtractor
Dim conditions As Object
Set conditions = extractor.ExtractConditions(parser)
' 获取单个条件
Debug.Print "过程连接: " & extractor.GetConditionValue("gclj") ' M20
Debug.Print "接液材质: " & extractor.GetConditionValue("jycz") ' 3
Debug.Print "量程范围: " & extractor.GetConditionValue("lcfw") ' M16
' 遍历所有条件
Dim key As Variant
For Each key In conditions.Keys
Debug.Print key & " = " & conditions(key)
Next key
```
### 3. 条件匹配
#### 简单条件
```vba
Dim matcher As New clsConditionMatcher
Dim conditions As Object
Set conditions = CreateObject("Scripting.Dictionary")
conditions("gclj") = "M20"
conditions("lcfw") = "M16"
' 等于
Debug.Print matcher.IsMatch("lcfw=M16", conditions) ' True
' 不等于
Debug.Print matcher.IsMatch("gclj!=M10", conditions) ' True
```
#### 复合条件
```vba
' AND 运算
Debug.Print matcher.IsMatch("lcfw=M16 AND gclj=M20", conditions) ' True
' OR 运算
Debug.Print matcher.IsMatch("lcfw=M16 OR lcfw=M17", conditions) ' True
' 括号优先级
Debug.Print matcher.IsMatch("gclj=M20 AND (lcfw=M16 OR lcfw=M17)", conditions) ' True
```
### 4. 获取物料清单
#### 指定类别
```vba
Dim bomMgr As New clsBOMManager
bomMgr.LoadData wsConfig, wsPlatform
' 获取"部件"类别的符合条件的物料
Dim materials As Collection
Set materials = bomMgr.GetMaterialsByModel("YTHN-100.A0.532.M203.M16.Y3", "部件")
```
#### 所有类别
```vba
' 获取所有类别的符合条件的物料
Set materials = bomMgr.GetMaterialsByModel("YTHN-100.A0.532.M203.M16.Y3")
```
#### 使用父类别/子类别逻辑
```vba
' 使用父类别物料(默认)
Set materials = bomMgr.GetMaterialsByCategoryAndModel( _
"YTHN-100.A0.532.M203.M16.Y3", "部件", True)
' 使用子类别物料(库存不足时)
Set materials = bomMgr.GetMaterialsByCategoryAndModel( _
"YTHN-100.A0.532.M203.M16.Y3", "部件", False)
```
---
## API参考
### clsModelParser
| 方法/属性 | 说明 | 返回类型 |
|---------|------|---------|
| `ParseModel(modelStr)` | 解析型号字符串 | Boolean |
| `GetThreadCode()` | 获取螺纹代码 | String |
| `GetMaterialCode()` | 获取材质代码 | String |
| `GetRangeCode()` | 获取量程代码 | String |
| `IsValid` | 解析是否成功 | Boolean |
| `ErrorMessage` | 错误信息 | String |
| `ToString()` | 返回解析结果(调试用) | String |
### clsConditionExtractor
| 方法/属性 | 说明 | 返回类型 |
|---------|------|---------|
| `ExtractConditions(parser)` | 提取所有条件 | Dictionary |
| `GetConditionValue(varName)` | 获取单个条件值 | String |
| `AddCondition(varName, value)` | 手动添加条件 | - |
| `AddExtractionRule(...)` | 添加提取规则 | - |
| `ToString()` | 返回条件字符串(调试用) | String |
### clsConditionMatcher
| 方法 | 说明 | 返回类型 |
|-----|------|---------|
| `IsMatch(expr, conditions)` | 判断条件是否匹配 | Boolean |
| `TestExpression(expr)` | 测试表达式有效性 | String |
### clsBOMManager (新增方法)
| 方法 | 说明 | 返回类型 |
|-----|------|---------|
| `GetMaterialsByModel(modelStr, [categoryName])` | 根据型号获取物料 | Collection |
| `GetMaterialsByCategoryAndModel(...)` | 根据类别和型号获取物料 | Collection |
| `ParseModelAndExtractConditions(modelStr)` | 解析型号并返回条件 | Dictionary |
---
## 扩展指南
### 添加新的提取条件
假设需要添加"表盘类型"条件:
```vba
' 在 clsConditionExtractor.InitializeRules 方法中添加:
m_ExtractionRules("bplx") = Array("DialCode", "Direct")
```
### 添加新的提取方法
如果需要特殊的提取逻辑:
```vba
' 在 clsConditionExtractor.ExtractValue 方法中添加:
Case "GetMiddleChars"
' 提取中间几位字符
If Len(sourceValue) > 4 Then
ExtractValue = Mid(sourceValue, 2, 3)
Else
ExtractValue = sourceValue
End If
```
### 扩展条件匹配运算符
`clsConditionMatcher.EvaluateSimpleCondition` 中添加新运算符:
```vba
' 示例: 添加 > 运算符
ElseIf InStr(cond, ">") > 0 Then
' ... 实现大于比较
```
---
## 常见问题
### Q1: 型号解析失败怎么办?
**A**: 检查型号格式是否正确:
- 表头部分必须包含: `型号-外径.安装.壳体.连接.量程.[特性]`
- 各部分用 `.` 分隔
- 表头和表盘用 `|` 分隔
### Q2: 条件匹配不准确?
**A**:
1. 检查物料的选择条件表达式是否正确
2. 运行 `Test3_ConditionMatcher` 验证匹配器功能
3. 使用 `TestExpression` 方法测试具体表达式
### Q3: 如何调试条件提取?
**A**: 使用以下代码查看提取结果:
```vba
Dim conditions As Object
Set conditions = bomMgr.ParseModelAndExtractConditions(modelStr)
Dim key As Variant
For Each key In conditions.Keys
Debug.Print key & " = " & conditions(key)
Next key
```
### Q4: 批量处理速度慢?
**A**:
1. 避免在循环中重复加载BOM数据
2. 使用 `GetMaterialsByModel` 一次性获取所有类别
3. 考虑添加缓存机制
### Q5: 如何验证物料条件表达式?
**A**: 运行示例:
```vba
Example5_ValidateMaterialConditions
```
这将生成一个验证报告,显示所有物料条件的有效性。
---
## 测试用例
### 运行所有测试
```vba
RunAllTests
```
### 单独测试
```vba
' 测试型号解析
Test1_ModelParser
' 测试条件提取
Test2_ConditionExtractor
' 测试条件匹配
Test3_ConditionMatcher
' 测试完整流程
Test4_GetMaterialsByModel
```
---
## 应用示例
### 示例1: 生成领料清单
```vba
Example1_GeneratePickingListByModel
```
### 示例2: 批量处理型号
```vba
Example2_BatchProcessModels
```
### 示例3: 查询型号详情
```vba
Example3_ShowModelDetails
```
### 示例4: 对比两个型号
```vba
Example4_CompareModels
```
### 示例5: 验证条件表达式
```vba
Example5_ValidateMaterialConditions
```
---
## 技术支持
如有问题,请:
1. 查看测试结果和调试信息
2. 运行相关示例程序
3. 检查条件表达式语法
---
**文档版本**: v1.0
**最后更新**: 2026-01-19

View File

@@ -0,0 +1,716 @@
# 布莱迪公司压力表产品选型大表
**版本**: 20250806 版
**说明**: 公司内部资料不得外传
---
## 目录
1. [型号](#型号)
2. [公称外径](#公称外径)
3. [安装形式](#安装形式)
4. [壳体形式](#壳体形式)
5. [过程连接&接液材质](#过程连接&接液材质)
6. [量程范围](#量程范围)
7. [仪表特性](#仪表特性)
8. [表盘](#表盘)
9. [附件](#附件)
10. [法兰隔膜](#法兰隔膜)
---
## 型号
### 基础压力表系列
| 型号 | 说明 |
|------|------|
| Y | 压力表 |
| YY | (乙炔)压力表 |
| YA | (氨)压力表 |
| YR | (耐热)压力表 |
| YTF | (防溅)压力表 |
| YTN | (防溅)耐震压力表 |
| YTH | (不锈钢)压力表 |
| YTHN | (不锈钢)耐震压力表 |
### 精密压力表系列
| 型号 | 说明 |
| ---- | ------------ |
| YB | 精密压力表 |
| YBH | (不锈钢)精密压力表 |
| YBHN | (不锈钢)耐震精密压力表 |
### 膜盒压力表系列
| 型号 | 说明 |
|------|------|
| YE | 膜盒压力表 |
| YEF | (不锈钢)膜盒压力表 |
| YEFN | (不锈钢耐震)膜盒压力表 |
| YEY | (医用)膜盒压力表 |
### 安全型压力表系列
| 型号 | 说明 |
|------|------|
| YQHB | (不锈钢安全)型压力表 |
| YQHBN | (不锈钢安全型)耐震压力表 |
| YQ | (铸铝外壳安全型)压力表 |
| YQF | (不锈钢铸铝外壳安全型)压力表 |
### 酚醛系列
| 型号 | 说明 |
|------|------|
| YSH | (不锈钢酚醛)压力表 |
| YSHN | (不锈钢酚醛)耐震压力表 |
| YQS | (酚醛安全型)压力表 |
| YQSN | (酚醛安全型)耐震压力表 |
| YQSH | (不锈钢酚醛安全型)压力表 |
| YQSHN | (不锈钢酚醛安全型)耐震压力表 |
### 差压表系列
| 型号 | 说明 |
|------|------|
| YCA | (不锈钢双膜片)差压表 |
| YCAN | (不锈钢双膜片)耐震差压表 |
| YCS | (双针双管)差压表 |
| YCSH | (不锈钢双针双管)差压表 |
| YCSHN | (不锈钢双针双管)耐震差压表 |
| YCC | (磁)差压表 |
| YCB | (泳池)差压表 |
| YCBF | (不锈钢单膜片)差压表 |
| YCBFN | (不锈钢单膜片)耐震差压表 |
| YCWF | (不锈钢波纹管)差压表 |
| YCWFN | (不锈钢波纹管)耐震差压表 |
### 电接点压力表系列
| 型号 | 说明 |
|------|------|
| YX | 电接点压力表 |
| YXFB | (防爆)电接点压力表 |
| YXA | (氨用)电接点压力表 |
| YXH | (不锈钢)电接点压力表(注:坚固型) |
| YXHN | (不锈钢)耐震电接点压力表(注:坚固型) |
| YXGC | (感应式)电接点差压表 |
| YXK | 位式控制压力表 |
| YXGH | (不锈钢防爆感应式)电接点压力表 |
| YXGHN | (不锈钢防爆感应式)耐震电接点压力表 |
| YCAXF | (不锈钢双膜片)电接点差压表 |
| YCBXF | (不锈钢单膜片)电接点差压表 |
### 其他特殊系列
| 型号 | 说明 |
|------|------|
| YSZ | (两线)压力变送器 |
| YTZ | (电阻)远传压力表 |
| YTJA | (A级洁净型)压力表 |
| YTJB | (BA级洁净型)压力表 |
| YTJE | (EP级洁净型)压力表 |
| BF | (不锈钢)膜片压力表 |
| BFN | (不锈钢耐震)膜片压力表 |
| JBH | (不锈纲膜片)绝压表 |
| YTU | (不锈钢耐硫)压力表 |
| YTC | (不锈钢船用)压力表 |
### 特殊型号前缀
- **B前缀**: 膜片压力表 - 在基本型号前加"B",例如: BYX = 膜片电接点压力表
- **P前缀**: 隔膜压力表 - 在基本型号前加"P",例如: PYTHN = (不锈钢)耐震隔膜压力表
---
## 公称外径
| 代码 | 外径尺寸 |
|------|----------|
| 036 | 36mm |
| 040 | 40mm |
| 043 | 43mm |
| 046 | 46mm |
| 050 | 50mm |
| 053 | 53mm |
| 060 | 60mm |
| 063 | 63mm |
| 070 | 70mm |
| 075 | 75mm |
| 080 | 80mm |
| 090 | 90mm |
| 098 | 98mm |
| 100 | 100mm |
| 107 | 107mm |
| 120 | 120mm |
| 150 | 150mm |
| 160 | 160mm |
| 200 | 200mm |
| 250 | 250mm |
| 330 | 330mm |
**代码格式**: 3或4位数码
---
## 安装形式
### 径向安装
| 代码 | 说明 |
|------|------|
| A0 | 径向无边 |
| AT | 径向前边 |
| AH | 径向后边 |
| AM | 膜片式径向 |
### 轴向安装
#### 中轴向
| 代码 | 说明 |
|------|------|
| Z0 | 中轴向无边 |
| ZT | 中轴向前边 |
| ZZ | 中轴向中边 |
| ZH | 中轴向后边 |
| ZK | 中轴向卡子 |
#### 下轴向
| 代码 | 说明 |
|------|------|
| B0 | 下轴向无边 |
| BT | 下轴向前边 |
| BZ | 下轴向中边 |
| BH | 下轴向后边 |
| BK | 下轴向卡子 |
### 其他安装形式
| 代码 | 说明 |
|------|------|
| C0 | 八字无边 |
| CT | 八字前边 |
| CH | 八字后边 |
| JG | 接杆安装 |
| GS | 挂式 |
| FG | 矩形挂式 |
| GK | 2〞安装支架安装 |
| 00 | 特定型 |
---
## 壳体形式
### 表壳类型
| 代码 | 说明 |
|------|------|
| 00 | 特殊型 |
| 10 | 塑料表壳(非安全型) |
| 20 | 碳钢喷塑外壳 |
| 21 | 碳钢喷塑外壳、镀铬罩 |
| 22 | 碳钢喷塑外壳、安装式 |
| 23 | 碳钢喷塑外壳、焊接式 |
| 24 | 碳钢喷塑外壳,反装机芯,普通压力表 |
| 25 | 碳钢喷塑外壳、有机玻璃罩 |
| 30 | 坚固安全型压力表 |
| 40 | 压铸铝喷塑外壳压力表 |
#### 304外壳系列
| 代码 | 说明 |
|------|------|
| 50 | 304外壳不可充油 |
| 51 | 304外壳、2件式 |
| 52 | 304外壳、安装式、可充油 |
| 53 | 304外壳、焊接式 |
| 54 | 304外壳、焊接式、防爆孔 |
| 55 | 304外壳有机玻璃罩 |
#### 316L外壳系列
| 代码 | 说明 |
|------|------|
| 60 | 316L外壳 |
| 61 | 316L外壳、2件式 |
| 62 | 316L外壳、安装式 |
| 63 | 316L外壳、焊接式 |
| 64 | 316L外壳、焊接式、防爆孔 |
| 65 | 316L外壳有机玻璃罩 |
#### 其他材质
| 代码 | 说明 |
|------|------|
| 70 | 铜外壳 |
### 罩壳类型
| 代码 | 说明 |
|------|------|
| 0 | 螺钉上紧式 |
| 1 | 内卡式 |
| 2 | 外卡式 |
| 3 | 滚边式 |
| 4 | 旋紧式 |
| 5 | 压紧式 |
| 6 | 卡圈式 |
| 7 | 合页边式 |
| 8 | 外卡锁式 |
| 9 | 特定型 |
---
## 过程连接&接液材质
### 过程连接
| 代码 | 规格 |
|------|------|
| M08 | M 8×1 |
| M10 | M 10×1 |
| M12 | M 12×1 |
| M14 | M 14×1.5 |
| M16 | M 16×1.5 |
| M20 | M 20×1.5 |
| G18 | G 1/8″ |
| G14 | G 1/4″ |
| G38 | G 3/8″ |
| G12 | G 1/2″ |
| G34 | G 3/4″ |
| G10 | G 1″ |
| R18 | ZG 1/8″ |
| R14 | ZG 1/4″ |
| R38 | ZG 3/8″ |
| R12 | ZG 1/2″ |
| R34 | ZG 3/4″ |
| Z18 | NPT1/8″ |
| Z14 | NPT1/4″ |
| Z38 | NPT3/8″ |
| Z12 | NPT1/2″ |
| Z34 | NPT3/4″ |
| V20 | 1/4VCR(M) |
| V30 | 1/4VCR(F) |
| V40 | 1/2VCR(M) |
| V50 | 1/2VCR(F) |
| U38 | 3/8-24 UNF |
| U10 | 9/16-18 UNF |
| U78 | 7/8-14 UNF |
| K00 | 快装连接 |
| K05 | 0.5″快装 |
| K10 | 1″快装 |
| K15 | 1.5″快装 |
| K20 | 2″快装 |
| K25 | 2.5″快装 |
| KT06 | Φ6 卡套连接 |
**注意**: 阴螺纹在螺纹符号后标记字母"F"
### 接液材质
| 代码 | 材质 |
| --- | ------- |
| 1 | 316L |
| 2 | 316 |
| 3 | 304 |
| 4 | HPb59-1 |
| 5 | 蒙乃尔 |
| 6 | 碳钢 |
| 7 | HC276 |
**注**: 其他材质代码参考选型软件
---
## 量程范围
### 常用计量单位
| 代码 | 单位 |
|------|------|
| M | MPa |
| K | kPa |
| A | Pa |
| B | bar |
| L | mbar |
| P | psi |
| G | kgf/cm² |
| g | inHg |
| e | mmHg |
| i | inH2O |
| C | cmH2O |
| 0 | mmH2O |
| t | atm |
| M0XA | MPa abs |
### MPa量程代码
#### 正压量程
| 代码 | 量程范围 |
|------|----------|
| M01 | 00.06 MPa |
| M02 | 00.1 MPa |
| M03 | 00.16 MPa |
| M04 | 00.25 MPa |
| M05 | 00.4 MPa |
| M06 | 00.6 MPa |
| M07 | 01 MPa |
| M08 | 01.6 MPa |
| M09 | 02.5 MPa |
| M10 | 04 MPa |
| M11 | 06 MPa |
| M12 | 010 MPa |
| M13 | 016 MPa |
| M14 | 025 MPa |
| M15 | 040 MPa |
| M16 | 060 MPa |
| M17 | 0100 MPa |
| M18 | 0160 MPa |
| M19 | 0250 MPa |
#### 负压及复合量程
| 代码 | 量程范围 |
|------|----------|
| M30 | -0.10 MPa |
| M31 | -0.10.06 MPa |
| M32 | -0.10.15 MPa |
| M33 | -0.10.3 MPa |
#### 绝对压力量程
| 代码 | 量程范围 |
|------|----------|
| M02A | 00.1 MPa abs |
| M03A | 00.16 MPa abs |
| M04A | 00.25 MPa abs |
| M05A | 00.4 MPa abs |
| M06A | 00.6 MPa abs |
### kPa量程代码
#### 正压量程
| 代码 | 量程范围 |
|------|----------|
| K10 | 00.06 kPa |
| K11 | 00.1 kPa |
| K12 | 00.16 kPa |
| K13 | 00.25 kPa |
| K14 | 00.4 kPa |
| K15 | 00.6 kPa |
| K16 | 01 kPa |
| K17 | 01.6 kPa |
| K18 | 02.5 kPa |
| K19 | 04 kPa |
| K20 | 06 kPa |
| K21 | 010 kPa |
| K22 | 016 kPa |
| K23 | 025 kPa |
| K24 | 040 kPa |
| K25 | 060 kPa |
| K26 | 0100 kPa |
| K27 | 0160 kPa |
| K28 | 0250 kPa |
| K29 | 0400 kPa |
| K30 | 0600 kPa |
#### 负压量程
| 代码 | 量程范围 |
|------|----------|
| K50 | -0.060 kPa |
| K51 | -0.10 kPa |
| K52 | -0.160 kPa |
| K53 | -0.40 kPa |
| K54 | -0.60 kPa |
| K55 | -10 kPa |
| K56 | -1.60 kPa |
**代码格式**: 8位以内数码
**注**: 其它量程代码参见选型软件
---
## 仪表特性
### 表头充油
| 代码 | 充油类型及温度范围 |
|------|-------------------|
| Y1 | 硅油A-60℃70℃(低温专用) |
| Y2 | 硅油B-40℃70℃(膜盒表专用) |
| Y3 | 硅油C-40℃70℃(压力表常规) |
| Y4 | 甘油水,-40℃70℃ |
| Y5 | 无油耐震(阻尼机芯) |
| Y6 | 防静电油(电接点专用) |
| Y7 | 甘油0℃70℃ |
| Y8 | 氟油R-50℃70℃ |
| Y0 | 表头其他 |
### 附加功能
| 代码 | 功能说明 |
|------|----------|
| N1 | 内置指针装置 |
| N2 | 外置指针装置 |
| N3 | 调零指针 |
| N4 | 机芯限位 |
| N5 | 记忆装置 |
| N0 | 其他(备注内文字说明) |
### 电接点类型
**格式**: 接点型式(1位) + 开关信号(1位)
#### 接点型式
| 代码 | 说明 |
|------|------|
| C | 磁助电接点 |
| D | 普通电接点 |
| E | 镀金磁助电接点 |
| F | 镀金普通电接点 |
| G | 感应电接点 |
| H | 干簧管电接点 |
#### 开关信号
| 代码 | 说明 |
|------|------|
| 1 | 单下限 |
| 2 | 单上限 |
| 3 | 双下限 |
| 4 | 常开上下限 |
| 5 | 常闭上下限 |
| 6 | 双上限 |
| 0 | 其他多接点信号(备注内文字说明) |
**代码格式**: 2位数码
---
## 表盘
### 单双刻度
| 代码 | 说明 |
|------|------|
| 0 | 单刻度 |
| M | 双刻度内圈MPa |
| K | 双刻度内圈kPa |
| P | 双刻度内圈psi |
| G | 双刻度内圈kgf/cm² |
| X00 | 双刻度,内圈量程无要求,按标配 |
**注**: 其他量程代码参见选型软件
### 表盘特性
| 代码 | 说明 |
|------|------|
| A | 标准盘 |
| B | 英文盘 |
| C | 中性无标 |
| D | Wonder标 |
| E | FW标 |
**注**: 其他用户代码参见选型软件
### 仪表精度
| 代码 | 精度等级 |
|------|----------|
| 1 | 4.0级 |
| 2 | 2.5级 |
| 3 | 1.6(1.5)级 |
| 4 | 1.0级 |
| 5 | 0.4级 |
| 6 | 0.25级 |
| 0 | 无精度等级 |
### 特殊介质和特殊要求
| 代码 | 介质/要求 |
|------|----------|
| TA | 氨 |
| TO | 氧气 |
| TH | 氢气 |
| TY | 乙炔 |
| TQ | 其他可燃气体 |
| TB | 禁油 |
| TI | 氮气 |
### 表盘套色
**注**: 表盘套色(选型软件手动输入数值)
表盘套色主要分三色:黄色(Y)、绿色(G)、红色(R)
#### 套单色
格式: `RXXX`
示例: `R0.81` 代表0.81区域套红色
#### 套双色
格式: `GXXX.RXXX`
示例: `G00.7.R0.71` 代表00.7区域绿色0.71区域红色
#### 套三色
格式: `YXXX.GXXX.RXXX`
示例: `Y00.2.G0.20.8.R0.81` 代表:
- 00.2区域套黄色
- 0.20.8区域套绿色
- 0.81区域套红色
### 双刻度盘刻度线颜色
| 代码 | 说明 |
|------|------|
| nr | 标配,内红外黑 |
| wr | 内黑外红 |
### 刻度线红色标记
格式: `rxxx`
示例: `r0.35` 代表0.35刻度线为红色刻度线
---
### 附件
**示例格式**:
* `R3.M20F.M20.1`
说明:
- **R3**: 散热器
- **M20F**: 仪表接口(M20×1.5内螺纹)
- **M20**: 过程接口(M20×1.5外螺纹)
- **1**: 接液材质(316L)
* `WHP.70X20X1.3`
说明:
- **WHP**: 位号牌
- **70X20X1.3**: 长度X高度X厚度
---
## 法兰隔膜
### 隔膜化学密封附件型号
| 代码 | 说明 |
|------|------|
| F0 | 螺纹隔膜 |
| F1 | 焊接式螺纹隔膜 |
| F5 | 探入式螺纹隔膜 |
| F6A | 卫生型隔膜 |
| F6B | 散热卫生型隔膜 |
| F7A | 内螺纹螺母式卫生型隔膜 |
| F7B | 外螺纹螺母式卫生型隔膜 |
| F9 | 管道型隔膜化学密封 |
| F10 | 在线式隔膜化学密封 |
| FA | 螺纹压紧式法兰隔膜 |
| FB | 膜片整体平铺式法兰隔膜 |
| FC | 缩颈式法兰隔膜 |
| FD | 膜片中心内嵌式法兰隔膜 |
| FG | 探入式法兰隔膜 |
| FK | 安装空法兰 |
| FM | 工字式法兰隔膜 |
#### 特殊处理标记
- **P为喷涂式**: 例如 `FBP` = 膜片整体平铺式法兰隔膜喷涂PTFE
- **C为衬套式**: 例如 `FAC` = 螺纹压紧式法兰隔膜衬套PTFE
### 隔膜充油
| 代码 | 充油类型及温度范围 |
|------|-------------------|
| A | 硅油A-55℃220℃(低温专用) |
| B | 硅油B-40℃220℃(常规) |
| F | 硅油F-30℃200℃(食品级) |
| G | 硅油G-10℃300℃(高温) |
| J | 硅油J-10℃360℃(超高温) |
| N | 乙二醇,-50℃100℃ |
| P | 甘油0℃95℃ |
| Q | 甘油水,-30℃95℃ |
| R | 氟油R-50℃150℃ |
| 0 | 其他(其他油脂特殊说明) |
**注**: 高温硅油价格高,报价时提前咨询。
---
## 选型代码格式说明
完整的产品选型代码由以下部分组成:
```
[型号] - [公称外径] . [安装形式] . [壳体形式] . [过程连接&接液材质] . [量程范围] . [仪表特性] | [表盘] | [附件] | [法兰隔膜]
```
例子:
* 表头 | 表盘 | 附件(多个) | 法兰隔膜
```
PYTHN-100.A0.541.M201.M06.N2,N3.Y3|BP-088.2312.M06.0A3|WHP.70X20X1.3^GYBHQ-FW.M20F.M20.3.M06|FB-5020.RF3.049.1.M20F.B
```
* 表头 | 表盘 | 附件 | 法兰隔膜
```
PYTHN-100.A0.541.M201.M06.N2,N3.Y3|BP-088.2312.M06.0A3|GYBHQ-FW.M20F.M20.3.M06|FB-5020.RF3.049.1.M20F.B
```
* 表头 | 表盘 | 附件
```
PYTHN-100.A0.541.M201.M06.N2,N3.Y3|BP-088.2312.M06.0A3|GYBHQ-FW.M20F.M20.3.M06
```
* 表头 | 表盘 | 法兰隔膜
```
PYTHN-100.A0.541.M201.M06.N2,N3.Y3|BP-088.2312.M06.0A3|FB-5020.RF3.049.1.M20F.B
```
* 表头 | 表盘
```
PYTHN-100.A0.541.M201.M06.N2,N3.Y3|BP-088.2312.M06.0A3
```
### 代码位数说明
- **型号**: 字母组合
- **公称外径**: 3或4位数码
- **安装形式**: 2位字母/数字组合
- **壳体形式**: 2位数码(表壳) + 1位数码(罩壳)
- **过程连接**: 3位数码
- **量程范围**: 8位以内数码
- **仪表特性**: 2位数码或3位数码
- **表盘**: n位数码
- **附件**: n位数码
---
## 版本信息
**文档版本**: 20250806
**文档性质**: 公司内部资料,严禁外传
**编制单位**: 布莱迪公司
---
*注: 本文档中未详细列出的代码和规格请参考选型软件获取完整信息。*

View File

@@ -0,0 +1,276 @@
# 新增条件提取功能实现计划
## 一、需求概述
需要向 `clsConditionExtractor.cls` 类增加两个新的条件提取:
1. **安装形式 (azxs)** - 从型号中提取安装形式代码
2. **表壳形式 (bkxs)** - 从型号中提取表壳形式代码
### 示例说明
以型号 `YTHN-100.A0.532.M203.M17.Y3|BP-095.2312.M17.P3` 为例:
- **A0** = 安装形式代码(径向无边)
- **532** = 表壳形式代码,其中:
- `53` = 表壳类型304外壳、安装式、可充油
- `2` = 罩壳类型(外卡式)
---
## 二、参考文档依据
根据 `布莱迪公司压力表产品选型大表.md` 文档:
### 2.1 安装形式代码第159-204行
| 代码 | 说明 |
|------|------|
| A0 | 径向无边 |
| AT | 径向前边 |
| AH | 径向后边 |
| AM | 膜片式径向 |
| Z0 | 中轴向无边 |
| B0 | 下轴向无边 |
| ... | 共20多种安装形式 |
**提取规则**直接提取2位代码字母+数字组合)
### 2.2 表壳形式代码第207-266行
表壳形式由两部分组成:**表壳类型(2位) + 罩壳类型(1位)**
#### 表壳类型示例:
| 代码 | 说明 |
|------|------|
| 00 | 特殊型 |
| 10 | 塑料表壳 |
| 20-24 | 碳钢喷塑外壳系列 |
| 30 | 坚固安全型 |
| 40 | 压铸铝喷塑外壳 |
| 50-55 | 304外壳系列 |
| 60-65 | 316L外壳系列 |
#### 罩壳类型示例:
| 代码 | 说明 |
|------|------|
| 0 | 螺钉上紧式 |
| 1 | 内卡式 |
| 2 | 外卡式 |
| 3 | 滚边式 |
| 4-9 | 其他6种罩壳类型 |
**提取规则**
- 整体提取3位代码532
- 如果需要细分,可以拆分为:
- 前2位表壳类型53
- 后1位罩壳类型2
---
## 三、技术实现方案
### 3.1 代码检查
检查 `clsModelParser` 类是否已包含以下属性:
-`InstallForm` - 安装形式代码
-`ShellForm` - 表壳形式代码
**说明**:根据 `clsConditionExtractor.cls` 第113-116行显示解析器已经支持这些字段。
### 3.2 提取规则设计
#### 规则1安装形式 (azxs)
```vba
m_ExtractionRules("azxs") = Array("InstallForm", "Direct")
```
- **源字段**`InstallForm`
- **提取方法**`Direct`(直接使用)
#### 规则2表壳形式 (bkxs)
```vba
m_ExtractionRules("bkxs") = Array("ShellForm", "Direct")
```
- **源字段**`ShellForm`
- **提取方法**`Direct`(直接使用)
### 3.3 修改位置
`clsConditionExtractor.cls``InitializeRules()` 方法中添加上述两条规则。
**修改位置**第29-47行InitializeRules 方法内部)
---
## 四、实现步骤
### 步骤1修改 clsConditionExtractor.cls
`InitializeRules()` 方法中添加两个新的提取规则:
```vba
Private Sub InitializeRules()
' 规则格式: Dictionary(变量名) = Array(源字段, 提取方法)
' 规则1: 过程连接 (gclj)
m_ExtractionRules("gclj") = Array("ConnectionCode", "RemoveLastDigit")
' 规则2: 接液材质 (jycz)
m_ExtractionRules("jycz") = Array("ConnectionCode", "GetLastDigit")
' 规则3: 量程范围 (lcfw)
m_ExtractionRules("lcfw") = Array("RangeCode", "Direct")
' === 新增规则 ===
' 规则4: 安装形式 (azxs)
m_ExtractionRules("azxs") = Array("InstallForm", "Direct")
' 规则5: 表壳形式 (bkxs)
m_ExtractionRules("bkxs") = Array("ShellForm", "Direct")
End Sub
```
### 步骤2验证 ExtractValue 方法
检查 `ExtractValue` 方法第98-157行是否已支持 `InstallForm``ShellForm` 源字段。
**确认点**
- 第113-114行`Case "InstallForm"` ✅ 已存在
- 第115-116行`Case "ShellForm"` ✅ 已存在
**结论**:无需修改 `ExtractValue` 方法,它已经支持所需的源字段。
### 步骤3测试验证
创建或更新测试用例,验证提取功能:
```vba
' 测试用例
Dim parser As New clsModelParser
Dim extractor As New clsConditionExtractor
Dim conditions As Object
' 解析型号
parser.Parse "YTHN-100.A0.532.M203.M17.Y3|BP-095.2312.M17.P3"
' 提取条件
Set conditions = extractor.ExtractConditions(parser)
' 验证结果
Debug.Print "安装形式(azxs): " & conditions("azxs") ' 应输出: A0
Debug.Print "表壳形式(bkxs): " & conditions("bkxs") ' 应输出: 532
```
---
## 五、影响范围评估
### 5.1 影响的文件
| 文件 | 修改类型 | 说明 |
|------|----------|------|
| `VBA/ClassModules/clsConditionExtractor.cls` | 修改 | 添加2条提取规则 |
### 5.2 兼容性
-**向后兼容**新增规则不影响现有条件gclj、jycz、lcfw的提取
-**现有测试**:无需修改现有测试用例
- ⚠️ **物料匹配**如需在物料选择条件中使用这些新条件需在Excel表格的"选择条件"列中使用新变量名azxs、bkxs
### 5.3 使用场景
新增的条件可以在以下场景中使用:
1. **物料选择条件表达式**
```
azxs=A0 AND bkxs=532
```
2. **BOM完整性检查**
- 检查是否缺少特定安装形式的物料
- 检查是否缺少特定表壳形式的物料
3. **数据分析和统计**
- 按安装形式统计物料需求
- 按表壳形式统计物料需求
---
## 六、可选增强功能(未来扩展)
### 6.1 表壳形式细分提取
如果需要将表壳形式细分为表壳类型和罩壳类型,可以添加:
```vba
' 表壳类型前2位
m_ExtractionRules("bklx") = Array("ShellForm", "GetFirstTwoDigits")
' 罩壳类型后1位
m_ExtractionRules("zklx") = Array("ShellForm", "GetLastDigit")
```
同时需要在 `ExtractValue` 方法中添加新的提取方法:
- `GetFirstTwoDigits`取前2位字符
- `GetLastDigit`:已存在,直接复用
### 6.2 条件验证
可以添加条件值验证功能,确保提取的值在合法范围内:
```vba
Public Function ValidateCondition(varName As String, value As String) As Boolean
' 验证安装形式是否合法
' 验证表壳形式是否合法
End Function
```
---
## 七、实施清单
- [ ] 1. 备份 `clsConditionExtractor.cls` 文件
- [ ] 2. 在 `InitializeRules()` 方法中添加 azxs 提取规则
- [ ] 3. 在 `InitializeRules()` 方法中添加 bkxs 提取规则
- [ ] 4. 更新代码注释,说明新增规则的用途
- [ ] 5. 创建测试用例验证提取功能
- [ ] 6. 运行现有测试套件,确保无回归问题
- [ ] 7. 更新相关文档(如需要)
- [ ] 8. 提交代码变更
---
## 八、预期结果
实现完成后,系统将能够:
1. ✅ 从产品型号中自动提取安装形式代码azxs
2. ✅ 从产品型号中自动提取表壳形式代码bkxs
3. ✅ 在物料选择条件表达式中使用这两个新变量
4. ✅ 保持向后兼容,不影响现有功能
**测试验证示例**
输入型号:`YTHN-100.A0.532.M203.M17.Y3`
提取结果:
- `gclj` = M20
- `jycz` = 3
- `lcfw` = M17
- **`azxs` = A0** ⬅️ 新增
- **`bkxs` = 532** ⬅️ 新增
---
## 九、备注
1. 本计划遵循现有代码的设计模式和命名规范
2. 所有新增代码将包含中文注释,便于维护
3. 修改完成后将更新 VBA 模块元数据(如需要)
4. 建议在Excel开发环境中先进行手动测试确保功能正常
---
**文档版本**: 1.0
**创建日期**: 2026-01-27
**作者**: Claude Code