refactor: integrate [领料配置] into [平台配置清单] and add category selection conditions

Major changes:
- Remove dependency on separate [领料配置] sheet
- Load all data from [平台配置清单] in a single pass
- Add "类别选用条件" (CategorySelectCondition) field to support dynamic category filtering
- Add "66代码" (Code66) field for 66-system integration
- Refactor completeness check logic to only verify required categories

Data model changes:
- clsMaterialItem: Add CategorySelectCondition and Code66 properties
- clsCategory: Add CategorySelectCondition property and IsRequiredForModel() method
- clsBOMManager: Refactor LoadData() to use single data source
- clsBOMManager: Add GetRequiredCategories() method
- clsBOMManager: Update GetValidMaterialsByModel() to use category selection conditions

New workflow:
- LoadData() now takes only wsPlatform parameter (removed wsConfig)
- Categories are filtered by "类别选用条件" before completeness check
- Categories with empty selection condition are always required
- Categories with non-empty condition are checked against model specifications

Documentation:
- Update CLAUDE.md with new sheet structure
- Add comprehensive refactoring plan document
- Add v2.0 LoadData flow analysis with Mermaid diagrams
- Add platform configuration sheet reference

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-01-29 10:25:28 +08:00
parent fd414f7673
commit a9b3188d23
7 changed files with 1419 additions and 88 deletions

View File

@@ -31,33 +31,44 @@ End Sub
' ========================================
' LoadData 方法
' 功能: 从Excel工作表加载BOM数据并构建数据结构
' 功能: 从[平台配置清单]工作表加载BOM数据并构建数据结构
' 参数:
' wsConfig - [领料配置]工作表对象,包含类别层级和需要领料的物料
' wsPlatform - [平台配置清单]工作表对象,包含完整的物料信息(代号/名称/数量/条件)
' wsPlatform - [平台配置清单]工作表对象,包含完整的物料信息和类别配置
' 表结构: 行号|模块|代号|名称|数量|选择条件|备注|类别|上层类别|类别选用条件|66代码
' 数据从第4行开始(前3行是标题)
' 处理步骤:
' 1. 从[平台配置清单]加载所有物料的基础信息到dictAllMaterials
' 2. 从[领料配置]加载类别信息,筛选需要领料的物料
' 3. 建立类别的父子关系,构建层级树
' 注意:
' - 只有出现在[领料配置]中的物料才会被添加到类别中
' - 未在[领料配置]中的物料表示不需要领料
' 1. 从[平台配置清单]一次性加载所有物料信息和类别信息
' 2. 建立类别的父子关系,构建层级树
'
' 重要说明:
' - 所有数据都从[平台配置清单]读取,不再需要[领料配置]表
' - "类别"
' - "类别选用条件"()
' - "66代码"66使
' ========================================
Public Sub LoadData(wsConfig As Worksheet, wsPlatform As Worksheet)
Public Sub LoadData(wsPlatform As Worksheet)
Dim i As Long, lastRow As Long
Dim mat As clsMaterialItem
Dim cat As clsCategory
' ========================================
' 第一步: 从平台配置清单加载所有物料的基础信息
' 第一步: 从平台配置清单加载所有物料和类别信息
' 说明:
' - 读取C列(代号)、D列(名称)、E列(数量)、F列(选择条件)
' 读取列说明:
' - C列(代号)、D列(名称)、E列(数量)、F列(选择条件)
' - H列(类别)、I列(上层类别)、J列(类别选用条件)、K列(66代码)
' - 从第4行开始读取(前3行是标题)
' - 所有物料存入dictAllMaterials字典,以代号为键
' 目的: 建立完整的物料信息库,供后续按代号查询
'
' 处理逻辑:
' 1. 所有物料都存入dictAllMaterials字典(包括无类别的物料)
' 2. "类别"
' 3. 类别对象保存CategorySelectCondition属性
' 4. 物料对象保存CategorySelectCondition和Code66属性
' ========================================
lastRow = wsPlatform.Cells(wsPlatform.Rows.Count, "C").End(xlUp).row
For i = 4 To lastRow ' 从第4行开始(跳过标题)
' 1.
Set mat = New clsMaterialItem
mat.code = Trim(wsPlatform.Cells(i, "C").value & "") ' 物料代号
mat.Name = Trim(wsPlatform.Cells(i, "D").value & "") ' 物料名称
@@ -66,55 +77,46 @@ Public Sub LoadData(wsConfig As Worksheet, wsPlatform As Worksheet)
On Error GoTo 0
mat.Condition = Trim(wsPlatform.Cells(i, "F").value & "") ' 选择条件
'
' 2.
Dim catName As String
Dim parentCatName As String
Dim catSelectCond As String
Dim code66 As String
catName = Trim(wsPlatform.Cells(i, "H").value & "") ' 类别
parentCatName = Trim(wsPlatform.Cells(i, "I").value & "") ' 上层类别
catSelectCond = Trim(wsPlatform.Cells(i, "J").value & "") ' 类别选用条件
code66 = Trim(wsPlatform.Cells(i, "K").value & "") ' 66代码
' 3. 保存类别相关属性到物料对象
mat.Category = catName
mat.ParentCategory = parentCatName
mat.CategorySelectCondition = catSelectCond
mat.Code66 = code66
' 4. (,)
If mat.code <> "" Then
Set dictAllMaterials(mat.code) = mat
End If
' 5. ,,
If catName <> "" Then
' 确保类别对象存在(如果类别不存在则创建)
If Not dictCategories.Exists(catName) Then
Set cat = New clsCategory
cat.categoryName = catName
cat.ParentCategoryName = parentCatName
cat.CategorySelectCondition = catSelectCond ' ⭐ 设置类别选用条件
Set dictCategories(catName) = cat
End If
' 将物料添加到类别
dictCategories(catName).AddMaterial mat
End If
Next i
' ========================================
' 第二步: 从领料配置加载类别信息并建立层级
' 说明:
' - 读取A列(代号)、C列(类别)、D列(上层类别)
' - 从第2行开始读取(第1行是标题)
' - 只有出现在此表中的物料才需要领料
' 处理逻辑:
' 1. 为每个类别创建clsCategory对象
' 2. 从dictAllMaterials中查找对应的物料信息
' 3. 将物料添加到对应的类别中
' ========================================
lastRow = wsConfig.Cells(wsConfig.Rows.Count, "A").End(xlUp).row
For i = 2 To lastRow ' 2
Dim code As String, catName As String, parentCatName As String
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
' 将物料添加到类别
' 注意: 必须先在dictAllMaterials中查找到完整的物料信息
If dictAllMaterials.Exists(code) Then
Set mat = dictAllMaterials(code)
mat.Category = catName ' 设置物料所属类别
mat.ParentCategory = parentCatName ' 设置物料的上层类别
dictCategories(catName).AddMaterial mat ' 将物料添加到类别对象中
End If
NextRow:
Next i
' ========================================
' 第三步: 建立类别层级关系
' 第二步: 建立类别层级关系
' 说明:
' - 遍历所有类别,根据ParentCategoryName建立父子关系
' - 如果类别有父类别,将自己添加到父类别的SubCategories中
@@ -662,6 +664,56 @@ Public Function GetMaterialsByCategoryAndModel(modelStr As String, _
Set GetMaterialsByCategoryAndModel = result
End Function
' ========================================
' GetRequiredCategories 方法 (私有)
' 功能: 根据型号条件确定哪些类别是需要的
' 参数:
' conditions - 从型号提取的条件字典 (Dictionary对象)
' 包含如 lcfw, gclj, jycz 等条件变量
' 返回: Collection对象, 包含所有需要的 clsCategory 对象
'
' 判断逻辑:
' 遍历所有类别,对每个类别调用 IsRequiredForModel(conditions) 方法:
' - 如果类别选用条件为空 → 该类别总是需要,添加到结果集
' - 如果类别选用条件不为空 → 用 conditions 匹配
' - 匹配成功 → 添加到结果集
' - 匹配失败 → 不添加
'
' 示例:
' 假设型号条件为: lcfw=M16, gclj=M20
'
' 1: CategorySelectCondition = ""
' → IsRequiredForModel = True → 添加到结果集
'
' 2: CategorySelectCondition = "lcfw=M02"
' → IsRequiredForModel = False → 不添加
'
' 3: CategorySelectCondition = "gclj=M20"
' → IsRequiredForModel = True → 添加到结果集
'
' 用途:
' 在 GetValidMaterialsByModel 中,只检查需要的类别是否有物料匹配
' 不需要的类别不参与完整性检查
' ========================================
Private Function GetRequiredCategories(conditions As Object) As collection
Dim result As collection
Set result = New collection
' 遍历所有类别
Dim key As Variant
For Each key In dictCategories.Keys
Dim cat As clsCategory
Set cat = dictCategories(key)
' 检查该类别是否需要
If cat.IsRequiredForModel(conditions) Then
result.Add cat
End If
Next key
Set GetRequiredCategories = result
End Function
' ========================================
' ParseModelAndExtractConditions 方法
' 功能: 解析型号并返回条件字典(工具方法)
@@ -689,23 +741,41 @@ End Function
' 参数:
' modelStr - 产品型号字符串
' 返回: Collection对象
' Collection中包含个元素:
' Collection中包含个元素:
' (1) "Materials" - Collection, clsMaterialItem
' (2) "IsComplete" - Boolean,
' (3) "MissingCategories" - Collection,
'
' 完整性判断规则:
' - 对于每个需要领料的类别(顶层类别或其需要领取的子类别)
' - 必须有且仅有一个物料被匹配
' - 如果某个类别有0个或多于1个物料,则视为不完整
' 完整性判断规则(重构后):
' 第一步: 确定哪些类别是该型号需要的
' - ,"类别选用条件"
' - 类别选用条件为空 → 该类别总是需要
' - 类别选用条件不为空 → 用型号条件匹配,匹配成功才需要
'
' 第二步: 只检查需要的类别的完整性
' - 对于每个需要的类别(顶层类别或其需要领取的子类别)
' - 必须有且仅有一个物料被匹配
' - 如果某个需要的类别有0个或多于1个物料,则视为不完整
' - 不需要的类别不参与完整性检查
'
' 示例:
' "YTHN-100.A0.532.M203.M16.Y3" (M16, M20)
'
' 1: CategorySelectCondition = ""
' 2: CategorySelectCondition = "lcfw=M02" (M16)
' 3: CategorySelectCondition = "gclj=M20" ()
'
' 只有类别1和类别3需要检查完整性,类别2不检查
'
' 调用示例:
' Dim result As Collection
' Set result = bomMgr.GetValidMaterialsByModel("YTHN-100.A0.532.M203.M16.Y3")
' Dim materials As Collection
' Dim isComplete As Boolean
' Dim missingCats As Collection
' Set materials = result("Materials")
' isComplete = result("IsComplete")
' Set missingCats = result("MissingCategories")
' ========================================
Public Function GetValidMaterialsByModel(modelStr As String) As collection
Dim result As New collection
@@ -732,17 +802,21 @@ Public Function GetValidMaterialsByModel(modelStr As String) As collection
' 条件匹配器
Dim matcher As New clsConditionMatcher
' 遍历所有根类别,检查完整性
' ⭐ 第一步: 获取需要的类别列表
Dim requiredCats As collection
Set requiredCats = GetRequiredCategories(conditions)
' ⭐ 第二步: 只检查需要的类别的完整性
isComplete = True
Dim rootCat As clsCategory
Dim reqCat As clsCategory
Dim i As Long
For i = 1 To rootCategories.Count
Set rootCat = rootCategories(i)
For i = 1 To requiredCats.Count
Set reqCat = requiredCats(i)
' 检查该类别及其子类别的完整性
Dim catResult As Object
Set catResult = CheckCategoryCompleteness(rootCat, matcher, conditions)
Set catResult = CheckCategoryCompleteness(reqCat, matcher, conditions)
' 1.
Dim mat As clsMaterialItem
@@ -752,7 +826,7 @@ Public Function GetValidMaterialsByModel(modelStr As String) As collection
allMaterials.Add mat
Next mat
' 2. ()
' 2.
Dim missingCollection As collection
Set missingCollection = catResult("Missing")
Dim missingCatName As Variant
@@ -769,7 +843,7 @@ Public Function GetValidMaterialsByModel(modelStr As String) As collection
'
result.Add allMaterials, "Materials"
result.Add isComplete, "IsComplete"
result.Add allMissingCats, "MissingCategories" ' 新增返回项
result.Add allMissingCats, "MissingCategories"
Set GetValidMaterialsByModel = result
End Function