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:
Misaka_Company
2026-01-20 16:24:49 +08:00
parent 388ccc4e7a
commit f3fc5b4cbd
2 changed files with 171 additions and 19 deletions

View File

@@ -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中的每个元素都是 clsMaterialItem 对象
@@ -395,6 +404,9 @@ End Sub
' 3. 返回的Collection可能为空(没有符合条件的物料),需要判断Count属性
' 4. VBA"立即窗口"(Ctrl+G)
' 5. 物料的Condition属性为空表示该物料无条件限制(所有型号都使用)
' 6. autoFallback 参数影响查找范围:
' - True (默认): 会返回父类别和子类别的物料,更全面但可能包含不需要的物料
' - False: 仅返回指定类别的物料,更精确但可能遗漏子类别的替代物料
'
' 【相关方法】
' - GetMaterialsByCategoryAndModel: 结合了类别层级逻辑的物料获取
@@ -402,7 +414,8 @@ End Sub
' - ParseModelAndExtractConditions: 仅解析型号并返回条件字典
' ========================================
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
Set result = New collection
@@ -430,7 +443,7 @@ Public Function GetMaterialsByModel(modelStr As String, _
Debug.Print ""
' ========================================
' 第2步: 按类别筛选物料(自动降级到子类别)
' 第2步: 按类别筛选物料(根据参数决定是否自动降级到子类别)
' ========================================
Dim matcher As New clsConditionMatcher
Dim totalMatchCount As Long
@@ -440,6 +453,13 @@ Public Function GetMaterialsByModel(modelStr As String, _
Dim i As Long, j As Long
totalMatchCount = 0
If autoFallback Then
Debug.Print "【降级模式】启用自动降级到子类别"
Else
Debug.Print "【降级模式】禁用自动降级,仅查找当前类别"
End If
Debug.Print ""
If categoryName <> "" Then
' ========================================
' 情况A: 指定了类别名称
@@ -448,8 +468,8 @@ Public Function GetMaterialsByModel(modelStr As String, _
Set cat = GetCategory(categoryName)
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
@@ -465,8 +485,8 @@ Public Function GetMaterialsByModel(modelStr As String, _
For j = 1 To rootCategories.Count
Set rootCat = rootCategories(j)
' 对每个根类别应用筛选(包含子类别降级逻辑)
Set catResult = FilterCategoryWithSubcategories(rootCat, matcher, conditions)
' 对每个根类别应用筛选(根据参数决定是否启用子类别降级逻辑)
Set catResult = FilterCategoryWithSubcategories(rootCat, matcher, conditions, autoFallback)
'
For i = 1 To catResult.Count
@@ -484,29 +504,34 @@ End Function
' ========================================
' FilterCategoryWithSubcategories 方法 (私有)
' 功能: 对指定类别进行筛选,如果无匹配则自动降级到子类别
' 功能: 对指定类别进行筛选,根据参数决定是否自动降级到子类别
' 参数:
' cat - 类别对象
' matcher - 条件匹配器对象
' conditions - 提取的条件字典
' cat - 类别对象
' matcher - 条件匹配器对象
' conditions - 提取的条件字典
' autoFallback - 是否自动降级到子类别默认True
' True: 当前类别无匹配时,自动降级到子类别查找
' False: 仅在当前类别查找,不降级到子类别
' 返回: Collection对象包含匹配的物料
'
' 工作逻辑:
' 1. 先尝试在当前类别下筛选物料
' 2. 如果当前类别有匹配结果,直接返回
' 3. 如果当前类别无匹配结果,检查是否有子类别
' 4. 如果有子类别,递归对所有子类别进行筛选
' 5. 如果无子类别,返回空集合
' 3. 如果当前类别无匹配结果且 autoFallback=True,检查是否有子类别
' 4. 如果有子类别且允许降级,递归对所有子类别进行筛选
' 5. 如果无子类别或不允许降级,返回当前结果
'
' 示例场景:
' : "YTHN-100.A0.532.M203.M16.Y3"
' "部件""低压接头部件": lcfw=M02
' M02"部件"
' "接头""弹性元件"
' autoFallback=True "接头""弹性元件"
' 当 autoFallback=False 时,返回空集合,不查找子类别
' ========================================
Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
ByVal matcher As clsConditionMatcher, _
ByVal conditions As Object) As collection
ByVal conditions As Object, _
ByVal autoFallback As Boolean) As collection
Dim result As collection
Set result = New collection
@@ -539,9 +564,9 @@ Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
Next i
' ========================================
' 第二阶段: 如果当前类别无匹配,检查子类别
' 第二阶段: 如果当前类别无匹配且允许降级,检查子类别
' ========================================
If matchCount = 0 And cat.HasSubCategories Then
If matchCount = 0 And cat.HasSubCategories And autoFallback Then
Debug.Print "【降级】类别 """ & cat.categoryName & """ 无匹配物料,降级到子类别查找..."
' 递归处理所有子类别
@@ -550,9 +575,9 @@ Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
For j = 1 To cat.SubCategories.Count
Set subCat = cat.SubCategories(j)
' 递归调用,获取子类别的匹配结果
' 递归调用,获取子类别的匹配结果(传递相同的 autoFallback 参数)
Dim subResult As collection
Set subResult = FilterCategoryWithSubcategories(subCat, matcher, conditions)
Set subResult = FilterCategoryWithSubcategories(subCat, matcher, conditions, autoFallback)
'
Dim k As Long
@@ -560,6 +585,8 @@ Private Function FilterCategoryWithSubcategories(ByVal cat As clsCategory, _
result.Add subResult(k)
Next k
Next j
ElseIf matchCount = 0 And cat.HasSubCategories And Not autoFallback Then
Debug.Print "【跳过】类别 """ & cat.categoryName & """ 无匹配物料,但降级已禁用,不查找子类别"
ElseIf matchCount > 0 Then
Debug.Print "【成功】类别 """ & cat.categoryName & """ 匹配 " & matchCount & " 个物料"
End If