Refine project overview to include specific business context (Blaidy Company) and the main workbook file. Restructure the architecture section into a layered object-oriented design (Data, Processing, Application layers) and define the responsibilities of core VBA classes. Add new technical documentation sections covering: - Model number format parsing structure - Condition expression language syntax - Category hierarchy logic and picking strategies - Material matching pipeline flow Include VBA code examples for key methods such as CollectAllMaterials and GetMaterialsByCategoryAndModel to illustrate recursive traversal and material retrieval logic. Clarify the structure of key Excel configuration sheets.
465 lines
17 KiB
Markdown
465 lines
17 KiB
Markdown
# 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. **版本维护**:代码变更时,优先更新详细版,然后同步更新简略版的主要流程
|