# 订单物料提取功能实现计划 ## 一、项目概述 ### 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 **审核状态**: 待审核