feat(clsBOMManager): add optional autoFallback param
Added the `autoFallback` optional parameter to `GetMaterialsByModel`. This flag controls whether the search automatically descends to subcategories when no matches are found in the target category. - Defaults to True to maintain previous recursive behavior. - When False, the search is restricted strictly to the specified category. - Updated documentation with usage examples and logic explanations.
This commit is contained in:
@@ -377,6 +377,15 @@ End Sub
|
|||||||
' 指定类别名: 仅返回该类别下的符合条件物料
|
' 指定类别名: 仅返回该类别下的符合条件物料
|
||||||
' 示例: "部件"、"表壳"、"接头"、"机芯"
|
' 示例: "部件"、"表壳"、"接头"、"机芯"
|
||||||
'
|
'
|
||||||
|
' autoFallback - 是否自动降级到子类别(可选参数,默认为True)
|
||||||
|
' True (默认): 当某个类别无匹配物料时,自动降级到其子类别继续查找
|
||||||
|
' False: 仅在当前类别查找,不降级到子类别
|
||||||
|
' 示例场景:
|
||||||
|
' 型号 "YTHN-100.A0.532.M203.M17.Y3" 的量程是M17
|
||||||
|
' 类别"部件"下的物料条件是 "lcfw=M02"
|
||||||
|
' autoFallback=True: 自动降级到子类别"接头"、"弹性元件"等查找
|
||||||
|
' autoFallback=False: "部件"类别返回空集合
|
||||||
|
'
|
||||||
' 【返回值】
|
' 【返回值】
|
||||||
' 返回类型: Collection对象
|
' 返回类型: Collection对象
|
||||||
' 元素类型: Collection中的每个元素都是 clsMaterialItem 对象
|
' 元素类型: Collection中的每个元素都是 clsMaterialItem 对象
|
||||||
@@ -395,6 +404,9 @@ End Sub
|
|||||||
' 3. 返回的Collection可能为空(没有符合条件的物料),需要判断Count属性
|
' 3. 返回的Collection可能为空(没有符合条件的物料),需要判断Count属性
|
||||||
' 4. 调试信息会输出到VBA的"立即窗口"(Ctrl+G查看)
|
' 4. 调试信息会输出到VBA的"立即窗口"(Ctrl+G查看)
|
||||||
' 5. 物料的Condition属性为空表示该物料无条件限制(所有型号都使用)
|
' 5. 物料的Condition属性为空表示该物料无条件限制(所有型号都使用)
|
||||||
|
' 6. autoFallback 参数影响查找范围:
|
||||||
|
' - True (默认): 会返回父类别和子类别的物料,更全面但可能包含不需要的物料
|
||||||
|
' - False: 仅返回指定类别的物料,更精确但可能遗漏子类别的替代物料
|
||||||
'
|
'
|
||||||
' 【相关方法】
|
' 【相关方法】
|
||||||
' - GetMaterialsByCategoryAndModel: 结合了类别层级逻辑的物料获取
|
' - GetMaterialsByCategoryAndModel: 结合了类别层级逻辑的物料获取
|
||||||
@@ -402,7 +414,8 @@ End Sub
|
|||||||
' - ParseModelAndExtractConditions: 仅解析型号并返回条件字典
|
' - ParseModelAndExtractConditions: 仅解析型号并返回条件字典
|
||||||
' ========================================
|
' ========================================
|
||||||
Public Function GetMaterialsByModel(modelStr As String, _
|
Public Function GetMaterialsByModel(modelStr As String, _
|
||||||
Optional categoryName As String = "") As collection
|
Optional categoryName As String = "", _
|
||||||
|
Optional autoFallback As Boolean = True) As collection
|
||||||
Dim result As collection
|
Dim result As collection
|
||||||
Set result = New collection
|
Set result = New collection
|
||||||
|
|
||||||
@@ -430,7 +443,7 @@ Public Function GetMaterialsByModel(modelStr As String, _
|
|||||||
Debug.Print ""
|
Debug.Print ""
|
||||||
|
|
||||||
' ========================================
|
' ========================================
|
||||||
' 第2步: 按类别筛选物料(自动降级到子类别)
|
' 第2步: 按类别筛选物料(根据参数决定是否自动降级到子类别)
|
||||||
' ========================================
|
' ========================================
|
||||||
Dim matcher As New clsConditionMatcher
|
Dim matcher As New clsConditionMatcher
|
||||||
Dim totalMatchCount As Long
|
Dim totalMatchCount As Long
|
||||||
@@ -440,6 +453,13 @@ Public Function GetMaterialsByModel(modelStr As String, _
|
|||||||
Dim i As Long, j As Long
|
Dim i As Long, j As Long
|
||||||
totalMatchCount = 0
|
totalMatchCount = 0
|
||||||
|
|
||||||
|
If autoFallback Then
|
||||||
|
Debug.Print "【降级模式】启用自动降级到子类别"
|
||||||
|
Else
|
||||||
|
Debug.Print "【降级模式】禁用自动降级,仅查找当前类别"
|
||||||
|
End If
|
||||||
|
Debug.Print ""
|
||||||
|
|
||||||
If categoryName <> "" Then
|
If categoryName <> "" Then
|
||||||
' ========================================
|
' ========================================
|
||||||
' 情况A: 指定了类别名称
|
' 情况A: 指定了类别名称
|
||||||
@@ -448,8 +468,8 @@ Public Function GetMaterialsByModel(modelStr As String, _
|
|||||||
Set cat = GetCategory(categoryName)
|
Set cat = GetCategory(categoryName)
|
||||||
|
|
||||||
If Not cat Is Nothing Then
|
If Not cat Is Nothing Then
|
||||||
' 从该类别开始查找(包含子类别降级逻辑)
|
' 从该类别开始查找(根据参数决定是否启用子类别降级逻辑)
|
||||||
Set catResult = FilterCategoryWithSubcategories(cat, matcher, conditions)
|
Set catResult = FilterCategoryWithSubcategories(cat, matcher, conditions, autoFallback)
|
||||||
|
|
||||||
' 合并结果
|
' 合并结果
|
||||||
For i = 1 To catResult.Count
|
For i = 1 To catResult.Count
|
||||||
@@ -465,8 +485,8 @@ Public Function GetMaterialsByModel(modelStr As String, _
|
|||||||
For j = 1 To rootCategories.Count
|
For j = 1 To rootCategories.Count
|
||||||
Set rootCat = rootCategories(j)
|
Set rootCat = rootCategories(j)
|
||||||
|
|
||||||
' 对每个根类别应用筛选(包含子类别降级逻辑)
|
' 对每个根类别应用筛选(根据参数决定是否启用子类别降级逻辑)
|
||||||
Set catResult = FilterCategoryWithSubcategories(rootCat, matcher, conditions)
|
Set catResult = FilterCategoryWithSubcategories(rootCat, matcher, conditions, autoFallback)
|
||||||
|
|
||||||
' 合并结果
|
' 合并结果
|
||||||
For i = 1 To catResult.Count
|
For i = 1 To catResult.Count
|
||||||
@@ -484,29 +504,34 @@ End Function
|
|||||||
|
|
||||||
' ========================================
|
' ========================================
|
||||||
' FilterCategoryWithSubcategories 方法 (私有)
|
' FilterCategoryWithSubcategories 方法 (私有)
|
||||||
' 功能: 对指定类别进行筛选,如果无匹配则自动降级到子类别
|
' 功能: 对指定类别进行筛选,根据参数决定是否自动降级到子类别
|
||||||
' 参数:
|
' 参数:
|
||||||
' cat - 类别对象
|
' cat - 类别对象
|
||||||
' matcher - 条件匹配器对象
|
' matcher - 条件匹配器对象
|
||||||
' conditions - 提取的条件字典
|
' conditions - 提取的条件字典
|
||||||
|
' autoFallback - 是否自动降级到子类别(默认True)
|
||||||
|
' True: 当前类别无匹配时,自动降级到子类别查找
|
||||||
|
' False: 仅在当前类别查找,不降级到子类别
|
||||||
' 返回: Collection对象,包含匹配的物料
|
' 返回: Collection对象,包含匹配的物料
|
||||||
'
|
'
|
||||||
' 工作逻辑:
|
' 工作逻辑:
|
||||||
' 1. 先尝试在当前类别下筛选物料
|
' 1. 先尝试在当前类别下筛选物料
|
||||||
' 2. 如果当前类别有匹配结果,直接返回
|
' 2. 如果当前类别有匹配结果,直接返回
|
||||||
' 3. 如果当前类别无匹配结果,检查是否有子类别
|
' 3. 如果当前类别无匹配结果且 autoFallback=True,检查是否有子类别
|
||||||
' 4. 如果有子类别,递归对所有子类别进行筛选
|
' 4. 如果有子类别且允许降级,递归对所有子类别进行筛选
|
||||||
' 5. 如果无子类别,返回空集合
|
' 5. 如果无子类别或不允许降级,返回当前结果
|
||||||
'
|
'
|
||||||
' 示例场景:
|
' 示例场景:
|
||||||
' 型号: "YTHN-100.A0.532.M203.M16.Y3"
|
' 型号: "YTHN-100.A0.532.M203.M16.Y3"
|
||||||
' 类别"部件"下有物料"低压接头部件"(条件: lcfw=M02)
|
' 类别"部件"下有物料"低压接头部件"(条件: lcfw=M02)
|
||||||
' 如果该型号的量程不是M02,则"部件"类别无匹配
|
' 如果该型号的量程不是M02,则"部件"类别无匹配
|
||||||
' 此时自动降级到子类别"接头"、"弹性元件"等查找
|
' 当 autoFallback=True 时,自动降级到子类别"接头"、"弹性元件"等查找
|
||||||
|
' 当 autoFallback=False 时,返回空集合,不查找子类别
|
||||||
' ========================================
|
' ========================================
|
||||||
Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
|
Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
|
||||||
ByVal matcher As clsConditionMatcher, _
|
ByVal matcher As clsConditionMatcher, _
|
||||||
ByVal conditions As Object) As collection
|
ByVal conditions As Object, _
|
||||||
|
ByVal autoFallback As Boolean) As collection
|
||||||
Dim result As collection
|
Dim result As collection
|
||||||
Set result = New collection
|
Set result = New collection
|
||||||
|
|
||||||
@@ -539,9 +564,9 @@ Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
|
|||||||
Next i
|
Next i
|
||||||
|
|
||||||
' ========================================
|
' ========================================
|
||||||
' 第二阶段: 如果当前类别无匹配,检查子类别
|
' 第二阶段: 如果当前类别无匹配且允许降级,检查子类别
|
||||||
' ========================================
|
' ========================================
|
||||||
If matchCount = 0 And cat.HasSubCategories Then
|
If matchCount = 0 And cat.HasSubCategories And autoFallback Then
|
||||||
Debug.Print "【降级】类别 """ & cat.categoryName & """ 无匹配物料,降级到子类别查找..."
|
Debug.Print "【降级】类别 """ & cat.categoryName & """ 无匹配物料,降级到子类别查找..."
|
||||||
|
|
||||||
' 递归处理所有子类别
|
' 递归处理所有子类别
|
||||||
@@ -550,9 +575,9 @@ Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
|
|||||||
For j = 1 To cat.SubCategories.Count
|
For j = 1 To cat.SubCategories.Count
|
||||||
Set subCat = cat.SubCategories(j)
|
Set subCat = cat.SubCategories(j)
|
||||||
|
|
||||||
' 递归调用,获取子类别的匹配结果
|
' 递归调用,获取子类别的匹配结果(传递相同的 autoFallback 参数)
|
||||||
Dim subResult As collection
|
Dim subResult As collection
|
||||||
Set subResult = FilterCategoryWithSubcategories(subCat, matcher, conditions)
|
Set subResult = FilterCategoryWithSubcategories(subCat, matcher, conditions, autoFallback)
|
||||||
|
|
||||||
' 合并子类别的结果
|
' 合并子类别的结果
|
||||||
Dim k As Long
|
Dim k As Long
|
||||||
@@ -560,6 +585,8 @@ Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
|
|||||||
result.Add subResult(k)
|
result.Add subResult(k)
|
||||||
Next k
|
Next k
|
||||||
Next j
|
Next j
|
||||||
|
ElseIf matchCount = 0 And cat.HasSubCategories And Not autoFallback Then
|
||||||
|
Debug.Print "【跳过】类别 """ & cat.categoryName & """ 无匹配物料,但降级已禁用,不查找子类别"
|
||||||
ElseIf matchCount > 0 Then
|
ElseIf matchCount > 0 Then
|
||||||
Debug.Print "【成功】类别 """ & cat.categoryName & """ 匹配 " & matchCount & " 个物料"
|
Debug.Print "【成功】类别 """ & cat.categoryName & """ 匹配 " & matchCount & " 个物料"
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -375,3 +375,128 @@ Sub Example5_ValidateMaterialConditions()
|
|||||||
|
|
||||||
MsgBox "条件验证完成!", vbInformation
|
MsgBox "条件验证完成!", vbInformation
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
' ========================================
|
||||||
|
' 示例6: 对比启用/禁用自动降级的效果
|
||||||
|
' ========================================
|
||||||
|
Sub Example6_CompareAutoFallback()
|
||||||
|
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
|
||||||
|
|
||||||
|
' 产品型号(使用可能导致类别缺失的型号)
|
||||||
|
Dim modelStr As String
|
||||||
|
modelStr = "YTHN-100.A0.532.M203.M17.Y3|BP-095.2312.M16.PA3"
|
||||||
|
|
||||||
|
' 创建对比结果表
|
||||||
|
Dim wsCompare As Worksheet
|
||||||
|
On Error Resume Next
|
||||||
|
Application.DisplayAlerts = False
|
||||||
|
ThisWorkbook.Worksheets("降级模式对比").Delete
|
||||||
|
Application.DisplayAlerts = True
|
||||||
|
On Error GoTo 0
|
||||||
|
|
||||||
|
Set wsCompare = ThisWorkbook.Worksheets.Add
|
||||||
|
wsCompare.Name = "降级模式对比"
|
||||||
|
|
||||||
|
' 表头
|
||||||
|
Dim row As Long
|
||||||
|
row = 1
|
||||||
|
wsCompare.Cells(row, 1).value = "型号"
|
||||||
|
wsCompare.Cells(row, 2).value = modelStr
|
||||||
|
row = row + 2
|
||||||
|
|
||||||
|
' 测试1: 启用自动降级
|
||||||
|
wsCompare.Cells(row, 1).value = "模式1: 启用自动降级 (autoFallback=True)"
|
||||||
|
wsCompare.Cells(row, 1).Font.Bold = True
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
wsCompare.Cells(row, 1).value = "类别"
|
||||||
|
wsCompare.Cells(row, 2).value = "代号"
|
||||||
|
wsCompare.Cells(row, 3).value = "名称"
|
||||||
|
wsCompare.Cells(row, 4).value = "数量"
|
||||||
|
wsCompare.Cells(row, 5).value = "选择条件"
|
||||||
|
wsCompare.Range("A" & row & ":E" & row).Font.Bold = True
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
Dim materials As collection
|
||||||
|
Dim mat As clsMaterialItem
|
||||||
|
Dim i As Long
|
||||||
|
|
||||||
|
' 获取启用自动降级的物料
|
||||||
|
Set materials = bomMgr.GetMaterialsByModel(modelStr, "部件", True)
|
||||||
|
|
||||||
|
If materials.Count = 0 Then
|
||||||
|
wsCompare.Cells(row, 1).value = "(无物料)"
|
||||||
|
row = row + 1
|
||||||
|
Else
|
||||||
|
For i = 1 To materials.Count
|
||||||
|
Set mat = materials(i)
|
||||||
|
wsCompare.Cells(row, 1).value = mat.Category
|
||||||
|
wsCompare.Cells(row, 2).value = mat.code
|
||||||
|
wsCompare.Cells(row, 3).value = mat.Name
|
||||||
|
wsCompare.Cells(row, 4).value = mat.Quantity
|
||||||
|
wsCompare.Cells(row, 5).value = IIf(mat.Condition = "", "(无)", mat.Condition)
|
||||||
|
row = row + 1
|
||||||
|
Next i
|
||||||
|
End If
|
||||||
|
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
' 测试2: 禁用自动降级
|
||||||
|
wsCompare.Cells(row, 1).value = "模式2: 禁用自动降级 (autoFallback=False)"
|
||||||
|
wsCompare.Cells(row, 1).Font.Bold = True
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
wsCompare.Cells(row, 1).value = "类别"
|
||||||
|
wsCompare.Cells(row, 2).value = "代号"
|
||||||
|
wsCompare.Cells(row, 3).value = "名称"
|
||||||
|
wsCompare.Cells(row, 4).value = "数量"
|
||||||
|
wsCompare.Cells(row, 5).value = "选择条件"
|
||||||
|
wsCompare.Range("A" & row & ":E" & row).Font.Bold = True
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
' 获取禁用自动降级的物料
|
||||||
|
Set materials = bomMgr.GetMaterialsByModel(modelStr, "部件", False)
|
||||||
|
|
||||||
|
If materials.Count = 0 Then
|
||||||
|
wsCompare.Cells(row, 1).value = "(无物料 - 因为禁用降级)"
|
||||||
|
wsCompare.Cells(row, 2).value = "说明"
|
||||||
|
wsCompare.Cells(row, 3).value = "当父类别无匹配物料时,不会降级到子类别查找"
|
||||||
|
row = row + 1
|
||||||
|
Else
|
||||||
|
For i = 1 To materials.Count
|
||||||
|
Set mat = materials(i)
|
||||||
|
wsCompare.Cells(row, 1).value = mat.Category
|
||||||
|
wsCompare.Cells(row, 2).value = mat.code
|
||||||
|
wsCompare.Cells(row, 3).value = mat.Name
|
||||||
|
wsCompare.Cells(row, 4).value = mat.Quantity
|
||||||
|
wsCompare.Cells(row, 5).value = IIf(mat.Condition = "", "(无)", mat.Condition)
|
||||||
|
row = row + 1
|
||||||
|
Next i
|
||||||
|
End If
|
||||||
|
|
||||||
|
' 添加说明
|
||||||
|
row = row + 1
|
||||||
|
wsCompare.Cells(row, 1).value = "说明:"
|
||||||
|
wsCompare.Cells(row, 1).Font.Bold = True
|
||||||
|
row = row + 1
|
||||||
|
wsCompare.Cells(row, 1).value = "• autoFallback=True (默认): 当""部件""类别无匹配物料时,自动降级到子类别""接头""、""弹性元件""等查找"
|
||||||
|
row = row + 1
|
||||||
|
wsCompare.Cells(row, 1).value = "• autoFallback=False: 仅在""部件""类别查找,即使有子类别也不降级,可能返回空集合"
|
||||||
|
|
||||||
|
' 格式化
|
||||||
|
wsCompare.Columns("A:E").AutoFit
|
||||||
|
wsCompare.Range("A1").Font.Bold = True
|
||||||
|
|
||||||
|
MsgBox "降级模式对比完成!" & vbCrLf & _
|
||||||
|
"请查看工作表: 降级模式对比" & vbCrLf & vbCrLf & _
|
||||||
|
"启用降级: " & bomMgr.GetMaterialsByModel(modelStr, "部件", True).Count & " 个物料" & vbCrLf & _
|
||||||
|
"禁用降级: " & bomMgr.GetMaterialsByModel(modelStr, "部件", False).Count & " 个物料", _
|
||||||
|
vbInformation
|
||||||
|
End Sub
|
||||||
Reference in New Issue
Block a user