- Introduced a comprehensive document detailing the project overview, goals, core functionalities, and technical architecture for the order material extraction feature. - Defined the product model coding rules and extraction logic for selection conditions. - Designed class structures for model parsing, condition evaluation, and order material list management. - Outlined implementation steps, testing plans, and risk assessments for the development process.
636 lines
16 KiB
Markdown
636 lines
16 KiB
Markdown
# 订单物料提取功能实现计划
|
||
|
||
## 一、项目概述
|
||
|
||
### 1.1 目标
|
||
实现从产品型号中提取选择条件,并根据条件匹配 BOM 库中对应的物料,生成订单物料清单。
|
||
|
||
### 1.2 核心功能
|
||
1. **型号解析**:从产品型号中提取选择条件变量
|
||
2. **条件匹配引擎**:解析并匹配物料的选择条件表达式
|
||
3. **物料清单生成**:整合上述功能,生成符合产品配置的物料清单
|
||
|
||
---
|
||
|
||
## 二、产品型号编码规则
|
||
|
||
### 2.1 型号结构
|
||
```
|
||
[型号] - [公称外径] . [安装形式] . [壳体形式] . [过程连接&接液材质] . [量程范围] . [仪表特性] | [表盘] | [附件] | [法兰隔膜]
|
||
```
|
||
|
||
### 2.2 示例分析
|
||
**输入**: `YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3`
|
||
|
||
**表头部分**: `YTHN-100.A0.532.M203.M16.Y3`
|
||
|
||
| 部位 | 代码 | 含义 |
|
||
|------|------|------|
|
||
| 型号 | YTHN | 不锈钢耐震压力表 |
|
||
| 公称外径 | 100 | 100mm |
|
||
| 安装形式 | A0 | 径向无边 |
|
||
| 壳体形式 | 532 | 532系列(304外壳、内卡式) |
|
||
| 过程连接&接液材质 | M203 | M20螺纹 + 3号材质(304) |
|
||
| 量程范围 | M16 | 0~60 MPa |
|
||
| 仪表特性 | Y3 | 硅油C充油 |
|
||
|
||
---
|
||
|
||
## 三、需求分析
|
||
|
||
### 3.1 提取的选择条件
|
||
|
||
| 变量名 | 变量标签 | 提取位置 | 提取规则 |
|
||
|--------|----------|----------|----------|
|
||
| gclj | 过程连接 | 过程连接&接液材质 | 除最后一位外的字符 |
|
||
| jycz | 接液材质 | 过程连接&接液材质 | 最后一位数字 |
|
||
| lcfw | 量程范围 | 量程范围 | 完整代码 |
|
||
|
||
### 3.2 提取示例
|
||
|
||
**输入**: `M203`
|
||
- 过程连接(gclj): `M20`
|
||
- 接液材质(jycz): `3`
|
||
|
||
**输入**: `M16`
|
||
- 量程范围(lcfw): `M16`
|
||
|
||
### 3.3 匹配逻辑
|
||
|
||
#### 物料选择条件类型
|
||
1. **无条件**:条件为空,表示该物料适用于所有配置
|
||
2. **简单条件**:单个条件判断
|
||
- 例: `lcfw=M01`
|
||
3. **AND 条件**:多个条件同时满足
|
||
- 例: `lcfw=M02 AND gclj=M20`
|
||
4. **OR 条件**:任一条件满足即可
|
||
- 例: `lcfw=M01 OR lcfw=M02 OR lcfw=M03`
|
||
5. **NOT 条件**:排除特定条件
|
||
- 例: `lcfw=M02 AND gclj!=M20`
|
||
6. **复杂条件**:AND、OR、NOT 混合
|
||
- 例: `gclj=Z12 AND (lcfw=M01 OR lcfw=M02 OR lcfw=M03)`
|
||
|
||
---
|
||
|
||
## 四、技术架构设计
|
||
|
||
### 4.1 模块结构
|
||
|
||
```
|
||
VBA/
|
||
├── ClassModules/
|
||
│ ├── clsBOMManager.cls # (已有)BOM管理器
|
||
│ ├── clsCategory.cls # (已有)类别类
|
||
│ ├── clsMaterialItem.cls # (已有)物料项类
|
||
│ ├── clsModelParser.cls # (新增)型号解析器
|
||
│ ├── clsConditionEvaluator.cls # (新增)条件表达式求值器
|
||
│ └── clsOrderMaterialList.cls # (新增)订单物料清单管理器
|
||
└── Modules/
|
||
└── modOrderProcessor.bas # (新增)订单处理模块
|
||
```
|
||
|
||
### 4.2 类设计
|
||
|
||
#### 4.2.1 clsModelParser(型号解析器)
|
||
|
||
**职责**: 解析产品型号,提取选择条件
|
||
|
||
**属性**:
|
||
```vba
|
||
Public ModelCode As String ' 完整型号代码
|
||
Public HeaderPart As String ' 表头部分
|
||
Public DialPart As String ' 表盘部分
|
||
Public AccessoryPart As String ' 附件部分
|
||
Public FlangePart As String ' 法兰隔膜部分
|
||
```
|
||
|
||
**方法**:
|
||
```vba
|
||
' 解析型号
|
||
Public Sub ParseModel(modelCode As String)
|
||
|
||
' 提取表头部分
|
||
Public Function ExtractHeader() As String
|
||
|
||
' 提取过程连接代码
|
||
Public Function GetProcessConnection() As String
|
||
|
||
' 提取接液材质代码
|
||
Public Function GetWettedMaterial() As String
|
||
|
||
' 提取量程范围代码
|
||
Public Function GetRangeCode() As String
|
||
|
||
' 获取所有选择条件
|
||
Public Function GetSelectionConditions() As Object
|
||
```
|
||
|
||
**示例数据结构**:
|
||
```vba
|
||
' 返回字典对象
|
||
' Key: 变量名 (如 "gclj", "jycz", "lcfw")
|
||
' Value: 变量值 (如 "M20", "3", "M16")
|
||
```
|
||
|
||
---
|
||
|
||
#### 4.2.2 clsConditionEvaluator(条件表达式求值器)
|
||
|
||
**职责**: 解析和求值物料选择条件表达式
|
||
|
||
**方法**:
|
||
```vba
|
||
' 求值条件表达式
|
||
' 参数:
|
||
' conditionExpr - 条件表达式 (如 "lcfw=M02 AND gclj=M20")
|
||
' conditionsDict - 从型号提取的条件字典
|
||
' 返回: Boolean - 是否匹配
|
||
Public Function Evaluate(conditionExpr As String, _
|
||
conditionsDict As Object) As Boolean
|
||
|
||
' 解析条件表达式为抽象语法树(AST)
|
||
Private Function ParseExpression(expr As String) As Object
|
||
|
||
' 求值单个条件
|
||
' 例: "lcfw=M02" -> True/False
|
||
Private Function EvaluateSingleCondition(condition As String, _
|
||
conditionsDict As Object) As Boolean
|
||
|
||
' 求值 AND 表达式
|
||
Private Function EvaluateAndExpression(conditions As Collection, _
|
||
conditionsDict As Object) As Boolean
|
||
|
||
' 求值 OR 表达式
|
||
Private Function EvaluateOrExpression(conditions As Collection, _
|
||
conditionsDict As Object) As Boolean
|
||
|
||
' 求值 NOT 表达式
|
||
Private Function EvaluateNotExpression(condition As String, _
|
||
conditionsDict As Object) As Boolean
|
||
```
|
||
|
||
**支持的运算符**:
|
||
- `=` : 等于
|
||
- `!=` 或 `<>` : 不等于
|
||
- `AND` : 逻辑与
|
||
- `OR` : 逻辑或
|
||
- `()` : 分组优先级
|
||
|
||
---
|
||
|
||
#### 4.2.3 clsOrderMaterialList(订单物料清单管理器)
|
||
|
||
**职责**: 管理单个订单的物料清单
|
||
|
||
**属性**:
|
||
```vba
|
||
Public OrderModel As String ' 订单型号
|
||
Public OrderConditions As Object ' 订单选择条件字典
|
||
Public SelectedMaterials As Collection ' 匹配的物料集合
|
||
```
|
||
|
||
**方法**:
|
||
```vba
|
||
' 根据订单型号生成物料清单
|
||
Public Sub GenerateMaterialList(modelCode As String, _
|
||
bomMgr As clsBOMManager)
|
||
|
||
' 筛选符合条件的物料
|
||
' 参数:
|
||
' categoryName - 类别名称
|
||
' bomMgr - BOM管理器
|
||
Private Function FilterMaterialsByCategory(categoryName As String, _
|
||
bomMgr As clsBOMManager) As Collection
|
||
|
||
' 获取物料汇总信息
|
||
Public Function GetMaterialSummary() As String
|
||
|
||
' 导出物料清单到工作表
|
||
Public Sub ExportToWorksheet(ws As Worksheet)
|
||
|
||
' 打印物料清单到立即窗口
|
||
Public Sub PrintToImmediateWindow()
|
||
```
|
||
|
||
---
|
||
|
||
#### 4.2.4 clsBOMManager 扩展
|
||
|
||
**新增方法**:
|
||
```vba
|
||
' 根据选择条件获取物料清单
|
||
' 参数:
|
||
' categoryName - 类别名称
|
||
' conditionsDict - 选择条件字典
|
||
' 返回: 匹配的物料集合
|
||
Public Function GetMaterialsByConditions(categoryName As String, _
|
||
conditionsDict As Object) As Collection
|
||
|
||
' 获取整个订单的物料清单
|
||
' 参数:
|
||
' conditionsDict - 从型号提取的选择条件字典
|
||
' useParent - 是否使用父类别领料方式
|
||
' 返回: 所有类别的匹配物料汇总
|
||
Public Function GetOrderMaterials(conditionsDict As Object, _
|
||
Optional useParent As Boolean = True) As Collection
|
||
```
|
||
|
||
---
|
||
|
||
## 五、实现步骤
|
||
|
||
### 阶段一:型号解析器(clsModelParser)
|
||
**优先级**: 高
|
||
|
||
**任务清单**:
|
||
1. 创建 `clsModelParser.cls` 类模块
|
||
2. 实现型号分段解析(表头、表盘、附件、法兰隔膜)
|
||
3. 实现表头部分的详细解析
|
||
4. 实现选择条件提取方法
|
||
5. 编写单元测试用例
|
||
|
||
**测试用例**:
|
||
```vba
|
||
Sub TestModelParser()
|
||
Dim parser As New clsModelParser
|
||
Dim conditions As Object
|
||
|
||
' 测试1: 标准型号
|
||
parser.ParseModel "YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3"
|
||
Set conditions = parser.GetSelectionConditions()
|
||
|
||
Debug.Assert conditions("gclj") = "M20"
|
||
Debug.Assert conditions("jycz") = "3"
|
||
Debug.Assert conditions("lcfw") = "M16"
|
||
|
||
' 测试2: 不同过程连接
|
||
parser.ParseModel "YTHN-100.A0.532.Z121.M06.Y3"
|
||
Set conditions = parser.GetSelectionConditions()
|
||
|
||
Debug.Assert conditions("gclj") = "Z12"
|
||
Debug.Assert conditions("jycz") = "1"
|
||
Debug.Assert conditions("lcfw") = "M06"
|
||
End Sub
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段二:条件表达式求值器(clsConditionEvaluator)
|
||
**优先级**: 高
|
||
|
||
**任务清单**:
|
||
1. 创建 `clsConditionEvaluator.cls` 类模块
|
||
2. 实现条件表达式词法分析(分词)
|
||
3. 实现条件表达式语法分析(构建 AST)
|
||
4. 实现各种运算符的求值逻辑
|
||
5. 处理括号优先级
|
||
6. 编写单元测试用例
|
||
|
||
**测试用例**:
|
||
```vba
|
||
Sub TestConditionEvaluator()
|
||
Dim evaluator As New clsConditionEvaluator
|
||
Dim conditions As Object
|
||
Set conditions = CreateObject("Scripting.Dictionary")
|
||
|
||
conditions("gclj") = "M20"
|
||
conditions("jycz") = "3"
|
||
conditions("lcfw") = "M16"
|
||
|
||
' 测试1: 简单条件
|
||
Debug.Assert evaluator.Evaluate("lcfw=M16", conditions) = True
|
||
Debug.Assert evaluator.Evaluate("lcfw=M02", conditions) = False
|
||
|
||
' 测试2: AND 条件
|
||
Debug.Assert evaluator.Evaluate("lcfw=M16 AND gclj=M20", conditions) = True
|
||
Debug.Assert evaluator.Evaluate("lcfw=M02 AND gclj=M20", conditions) = False
|
||
|
||
' 测试3: OR 条件
|
||
Debug.Assert evaluator.Evaluate("lcfw=M16 OR lcfw=M02", conditions) = True
|
||
Debug.Assert evaluator.Evaluate("lcfw=M01 OR lcfw=M02", conditions) = False
|
||
|
||
' 测试4: NOT 条件
|
||
Debug.Assert evaluator.Evaluate("lcfw=M16 AND gclj!=M20", conditions) = False
|
||
Debug.Assert evaluator.Evaluate("lcfw=M16 AND gclj!=Z12", conditions) = True
|
||
|
||
' 测试5: 复杂条件
|
||
Debug.Assert evaluator.Evaluate("gclj=Z12 AND (lcfw=M01 OR lcfw=M02 OR lcfw=M16)", conditions) = False
|
||
|
||
' 测试6: 空条件
|
||
Debug.Assert evaluator.Evaluate("", conditions) = True
|
||
End Sub
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段三:BOM管理器扩展
|
||
**优先级**: 中
|
||
|
||
**任务清单**:
|
||
1. 在 `clsBOMManager.cls` 中添加 `GetMaterialsByConditions()` 方法
|
||
2. 在 `clsBOMManager.cls` 中添加 `GetOrderMaterials()` 方法
|
||
3. 集成条件求值器
|
||
4. 编写单元测试用例
|
||
|
||
**测试用例**:
|
||
```vba
|
||
Sub TestBOMManagerConditions()
|
||
Dim bomMgr As New clsBOMManager
|
||
Dim conditions As Object
|
||
Dim materials As Collection
|
||
|
||
' 加载数据
|
||
bomMgr.LoadData _
|
||
ThisWorkbook.Worksheets("领料配置"), _
|
||
ThisWorkbook.Worksheets("平台配置清单")
|
||
|
||
' 准备条件
|
||
Set conditions = CreateObject("Scripting.Dictionary")
|
||
conditions("gclj") = "M20"
|
||
conditions("lcfw") = "M16"
|
||
|
||
' 测试: 获取部件类别的匹配物料
|
||
Set materials = bomMgr.GetMaterialsByConditions("部件", conditions)
|
||
|
||
' 验证结果
|
||
Debug.Print "匹配物料数量: " & materials.Count
|
||
' 应该只有 01011019018 (高压接头部件) 匹配
|
||
|
||
Dim mat As clsMaterialItem
|
||
For Each mat In materials
|
||
Debug.Print mat.code & " - " & mat.Name
|
||
Next mat
|
||
End Sub
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段四:订单物料清单管理器(clsOrderMaterialList)
|
||
**优先级**: 中
|
||
|
||
**任务清单**:
|
||
1. 创建 `clsOrderMaterialList.cls` 类模块
|
||
2. 实现物料清单生成逻辑
|
||
3. 实现物料汇总统计
|
||
4. 实现多种输出格式(工作表、立即窗口)
|
||
5. 编写单元测试用例
|
||
|
||
**测试用例**:
|
||
```vba
|
||
Sub TestOrderMaterialList()
|
||
Dim orderList As New clsOrderMaterialList
|
||
Dim bomMgr As New clsBOMManager
|
||
|
||
' 加载 BOM 数据
|
||
bomMgr.LoadData _
|
||
ThisWorkbook.Worksheets("领料配置"), _
|
||
ThisWorkbook.Worksheets("平台配置清单")
|
||
|
||
' 生成物料清单
|
||
orderList.GenerateMaterialList "YTHN-100.A0.532.M203.M16.Y3", bomMgr
|
||
|
||
' 打印到立即窗口
|
||
orderList.PrintToImmediateWindow
|
||
|
||
' 导出到工作表
|
||
Dim ws As Worksheet
|
||
Set ws = ThisWorkbook.Worksheets.Add
|
||
orderList.ExportToWorksheet ws
|
||
End Sub
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段五:订单处理模块(modOrderProcessor)
|
||
**优先级**: 低
|
||
|
||
**任务清单**:
|
||
1. 创建 `modOrderProcessor.bas` 模块
|
||
2. 实现批量订单处理过程
|
||
3. 实现单订单物料清单生成
|
||
4. 实现订单物料清单打印和导出
|
||
5. 编写用户界面宏
|
||
|
||
**示例宏**:
|
||
```vba
|
||
' 主入口:生成订单物料清单
|
||
Sub GenerateOrderMaterialList()
|
||
Dim modelCode As String
|
||
modelCode = InputBox("请输入产品型号:", "生成订单物料清单")
|
||
|
||
If modelCode = "" Then Exit Sub
|
||
|
||
Dim orderList As New clsOrderMaterialList
|
||
Dim bomMgr As New clsBOMManager
|
||
|
||
bomMgr.LoadData _
|
||
ThisWorkbook.Worksheets("领料配置"), _
|
||
ThisWorkbook.Worksheets("平台配置清单")
|
||
|
||
orderList.GenerateMaterialList modelCode, bomMgr
|
||
|
||
' 输出到工作表
|
||
Dim ws As Worksheet
|
||
Application.DisplayAlerts = False
|
||
On Error Resume Next
|
||
ThisWorkbook.Worksheets("订单物料清单").Delete
|
||
On Error GoTo 0
|
||
Application.DisplayAlerts = True
|
||
|
||
Set ws = ThisWorkbook.Worksheets.Add
|
||
ws.Name = "订单物料清单"
|
||
orderList.ExportToWorksheet ws
|
||
|
||
MsgBox "订单物料清单生成完成!", vbInformation
|
||
End Sub
|
||
|
||
' 快速打印到立即窗口
|
||
Sub QuickPrintOrderMaterials()
|
||
Dim modelCode As String
|
||
modelCode = InputBox("请输入产品型号:", "快速打印订单物料")
|
||
|
||
If modelCode = "" Then Exit Sub
|
||
|
||
' ... 实现逻辑
|
||
End Sub
|
||
```
|
||
|
||
---
|
||
|
||
## 六、数据流程图
|
||
|
||
```
|
||
用户输入产品型号
|
||
↓
|
||
[clsModelParser] 解析型号
|
||
↓
|
||
提取选择条件字典 {gclj: M20, jycz: 3, lcfw: M16}
|
||
↓
|
||
[clsOrderMaterialList] 生成物料清单
|
||
↓
|
||
遍历所有根类别
|
||
↓
|
||
对每个类别调用 [clsBOMManager.GetMaterialsByConditions()]
|
||
↓
|
||
遍历类别下的所有物料
|
||
↓
|
||
对每个物料使用 [clsConditionEvaluator.Evaluate()]
|
||
↓
|
||
匹配成功 → 添加到结果集合
|
||
匹配失败 → 跳过
|
||
↓
|
||
汇总所有匹配物料
|
||
↓
|
||
输出到工作表 / 立即窗口
|
||
```
|
||
|
||
---
|
||
|
||
## 七、关键技术难点
|
||
|
||
### 7.1 条件表达式解析
|
||
|
||
**难点**:
|
||
- 支持括号嵌套
|
||
- 运算符优先级处理
|
||
- 复杂逻辑组合
|
||
|
||
**解决方案**:
|
||
- 使用递归下降分析法
|
||
- 构建抽象语法树(AST)
|
||
- 后序遍历求值
|
||
|
||
### 7.2 型号格式多样性
|
||
|
||
**难点**:
|
||
- 部分型号可能缺少某些部分
|
||
- 附件和法兰隔膜数量不固定
|
||
- 过程连接代码长度不固定
|
||
|
||
**解决方案**:
|
||
- 使用正则表达式(如果 VBA 支持)
|
||
- 分段解析,容错处理
|
||
- 提供默认值
|
||
|
||
### 7.3 性能优化
|
||
|
||
**难点**:
|
||
- 大量物料匹配可能导致性能问题
|
||
- 复杂条件表达式求值耗时
|
||
|
||
**解决方案**:
|
||
- 缓存求值结果
|
||
- 优先筛选简单条件
|
||
- 减少不必要的条件求值
|
||
|
||
---
|
||
|
||
## 八、测试计划
|
||
|
||
### 8.1 单元测试
|
||
|
||
每个类都需要独立的单元测试模块:
|
||
|
||
1. **TestModelParser**: 测试型号解析功能
|
||
2. **TestConditionEvaluator**: 测试条件求值功能
|
||
3. **TestBOMManagerConditions**: 测试 BOM 管理器扩展功能
|
||
4. **TestOrderMaterialList**: 测试订单物料清单生成功能
|
||
|
||
### 8.2 集成测试
|
||
|
||
测试完整的订单物料生成流程:
|
||
|
||
1. 测试标准型号
|
||
2. 测试特殊配置型号
|
||
3. 测试边界条件
|
||
4. 测试异常输入
|
||
|
||
### 8.3 测试数据集
|
||
|
||
基于真实订单数据准备测试用例:
|
||
|
||
| 测试用例 | 型号 | 预期匹配物料数 |
|
||
|----------|------|----------------|
|
||
| 标准配置 | YTHN-100.A0.532.M203.M16.Y3 | 待定 |
|
||
| 不同螺纹 | YTHN-100.A0.532.Z121.M06.Y3 | 待定 |
|
||
| 小量程 | YTHN-100.A0.532.M201.M02.Y3 | 待定 |
|
||
| 大量程 | YTHN-100.A0.532.M201.M16.Y3 | 待定 |
|
||
|
||
---
|
||
|
||
## 九、文档需求
|
||
|
||
### 9.1 代码注释
|
||
- 所有类模块需要详细的中文注释
|
||
- 关键算法需要解释说明
|
||
- 复杂逻辑需要举例说明
|
||
|
||
### 9.2 使用说明
|
||
创建 `订单物料清单使用说明.md`,包括:
|
||
- 功能概述
|
||
- 使用方法
|
||
- API 文档
|
||
- 常见问题
|
||
|
||
### 9.3 开发文档
|
||
- 类设计文档
|
||
- 接口定义文档
|
||
- 测试报告
|
||
|
||
---
|
||
|
||
## 十、实施时间表
|
||
|
||
| 阶段 | 任务 | 预计工作量 |
|
||
|------|------|------------|
|
||
| 1 | 型号解析器 | 2-3 天 |
|
||
| 2 | 条件表达式求值器 | 3-4 天 |
|
||
| 3 | BOM管理器扩展 | 1-2 天 |
|
||
| 4 | 订单物料清单管理器 | 2-3 天 |
|
||
| 5 | 订单处理模块 | 1-2 天 |
|
||
| 6 | 测试与调试 | 2-3 天 |
|
||
| 7 | 文档编写 | 1-2 天 |
|
||
|
||
**总计**: 约 12-19 天
|
||
|
||
---
|
||
|
||
## 十一、风险评估
|
||
|
||
### 11.1 技术风险
|
||
- **风险**: VBA 不支持复杂的字符串处理
|
||
- **应对**: 使用 VBScript Regular Expression 对象
|
||
|
||
### 11.2 数据风险
|
||
- **风险**: BOM 数据不完整或格式错误
|
||
- **应对**: 增加数据验证和容错处理
|
||
|
||
### 11.3 性能风险
|
||
- **风险**: 大量物料匹配导致响应缓慢
|
||
- **应对**: 优化算法,增加缓存机制
|
||
|
||
---
|
||
|
||
## 十二、后续扩展方向
|
||
|
||
1. **批量订单处理**: 支持从 Excel 列表批量生成物料清单
|
||
2. **条件配置化**: 将提取规则配置化,支持动态调整
|
||
3. **物料替代方案**: 支持物料替代品推荐
|
||
4. **库存集成**: 与库存系统集成,实时查询可用库存
|
||
5. **成本计算**: 根据物料清单计算订单成本
|
||
|
||
---
|
||
|
||
## 附录:参考资料
|
||
|
||
- 布莱迪公司压力表产品选型大表.md
|
||
- clsBOMManager使用说明.md
|
||
- VBA 编程规范
|
||
|
||
---
|
||
|
||
**文档版本**: 1.0
|
||
**创建日期**: 2025-01-20
|
||
**编制人**: Claude Code
|
||
**审核状态**: 待审核
|