docs: expand AutoBOM architecture and implementation details
Refine project overview to include specific business context (Blaidy Company) and the main workbook file. Restructure the architecture section into a layered object-oriented design (Data, Processing, Application layers) and define the responsibilities of core VBA classes. Add new technical documentation sections covering: - Model number format parsing structure - Condition expression language syntax - Category hierarchy logic and picking strategies - Material matching pipeline flow Include VBA code examples for key methods such as CollectAllMaterials and GetMaterialsByCategoryAndModel to illustrate recursive traversal and material retrieval logic. Clarify the structure of key Excel configuration sheets.
This commit is contained in:
250
VBA/ClassModules/clsConditionMatcher.cls
Normal file
250
VBA/ClassModules/clsConditionMatcher.cls
Normal file
@@ -0,0 +1,250 @@
|
||||
' ========================================
|
||||
' 类模块: clsConditionMatcher
|
||||
' 用途: 解析物料的选择条件表达式,并判断是否匹配
|
||||
' 支持: AND, OR, NOT(!=), 括号优先级
|
||||
' ========================================
|
||||
Option Explicit
|
||||
|
||||
' ========================================
|
||||
' IsMatch 方法
|
||||
' 功能: 判断条件表达式是否匹配
|
||||
' 参数:
|
||||
' conditionExpr - 条件表达式字符串
|
||||
' conditions - Dictionary对象,包含变量名->值的映射
|
||||
' 返回: Boolean - 是否匹配
|
||||
' 示例:
|
||||
' IsMatch("lcfw=M16 AND gclj=M20", conditions) -> True/False
|
||||
' ========================================
|
||||
Public Function IsMatch(conditionExpr As String, conditions As Object) As Boolean
|
||||
On Error GoTo ErrorHandler
|
||||
|
||||
' 空条件表示无条件,始终匹配
|
||||
If Trim(conditionExpr) = "" Then
|
||||
IsMatch = True
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
' 解析并计算表达式
|
||||
IsMatch = EvaluateExpression(Trim(conditionExpr), conditions)
|
||||
Exit Function
|
||||
|
||||
ErrorHandler:
|
||||
' 出错时返回False(保守处理)
|
||||
Debug.Print "条件匹配出错: " & conditionExpr & " - " & Err.description
|
||||
IsMatch = False
|
||||
End Function
|
||||
|
||||
' ========================================
|
||||
' EvaluateExpression 方法 (私有)
|
||||
' 功能: 递归计算逻辑表达式
|
||||
' 优先级: 括号 > NOT(!=) > AND > OR
|
||||
' ========================================
|
||||
Private Function EvaluateExpression(expr As String, conditions As Object) As Boolean
|
||||
expr = Trim(expr)
|
||||
|
||||
' 处理括号 (最高优先级)
|
||||
If InStr(expr, "(") > 0 Then
|
||||
EvaluateExpression = EvaluateWithParentheses(expr, conditions)
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
' 处理 OR (最低优先级)
|
||||
If InStr(expr, " OR ") > 0 Then
|
||||
EvaluateExpression = EvaluateOR(expr, conditions)
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
' 处理 AND (中等优先级)
|
||||
If InStr(expr, " AND ") > 0 Then
|
||||
EvaluateExpression = EvaluateAND(expr, conditions)
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
' 处理单个条件 (最高优先级)
|
||||
EvaluateExpression = EvaluateSimpleCondition(expr, conditions)
|
||||
End Function
|
||||
|
||||
' ========================================
|
||||
' EvaluateWithParentheses 方法 (私有)
|
||||
' 功能: 处理包含括号的表达式
|
||||
' 策略: 找到最内层括号,递归计算,然后替换为结果
|
||||
' ========================================
|
||||
Private Function EvaluateWithParentheses(expr As String, conditions As Object) As Boolean
|
||||
Dim pos As Long, level As Long, startPos As Long
|
||||
Dim i As Long
|
||||
Dim innerExpr As String
|
||||
Dim innerResult As Boolean
|
||||
Dim newExpr As String
|
||||
|
||||
' 查找最内层的括号对
|
||||
startPos = 0
|
||||
level = 0
|
||||
|
||||
For i = 1 To Len(expr)
|
||||
If Mid(expr, i, 1) = "(" Then
|
||||
If level = 0 Then startPos = i
|
||||
level = level + 1
|
||||
ElseIf Mid(expr, i, 1) = ")" Then
|
||||
level = level - 1
|
||||
If level = 0 And startPos > 0 Then
|
||||
' 找到一对括号
|
||||
innerExpr = Mid(expr, startPos + 1, i - startPos - 1)
|
||||
innerResult = EvaluateExpression(innerExpr, conditions)
|
||||
|
||||
' 替换括号部分为结果
|
||||
newExpr = Left(expr, startPos - 1) & _
|
||||
IIf(innerResult, "TRUE", "FALSE") & _
|
||||
Mid(expr, i + 1)
|
||||
|
||||
' 递归处理剩余部分
|
||||
EvaluateWithParentheses = EvaluateExpression(newExpr, conditions)
|
||||
Exit Function
|
||||
End If
|
||||
End If
|
||||
Next i
|
||||
|
||||
' 如果没有找到有效括号,直接计算
|
||||
EvaluateWithParentheses = EvaluateExpression(expr, conditions)
|
||||
End Function
|
||||
|
||||
' ========================================
|
||||
' EvaluateOR 方法 (私有)
|
||||
' 功能: 处理 OR 逻辑运算
|
||||
' 规则: 任一为真则为真
|
||||
' ========================================
|
||||
Private Function EvaluateOR(expr As String, conditions As Object) As Boolean
|
||||
Dim parts() As String
|
||||
Dim part As Variant
|
||||
|
||||
' 按 OR 分割
|
||||
parts = Split(expr, " OR ")
|
||||
|
||||
' 任一部分为真则返回真
|
||||
For Each part In parts
|
||||
If EvaluateExpression(Trim(CStr(part)), conditions) Then
|
||||
EvaluateOR = True
|
||||
Exit Function
|
||||
End If
|
||||
Next part
|
||||
|
||||
EvaluateOR = False
|
||||
End Function
|
||||
|
||||
' ========================================
|
||||
' EvaluateAND 方法 (私有)
|
||||
' 功能: 处理 AND 逻辑运算
|
||||
' 规则: 全部为真才为真
|
||||
' ========================================
|
||||
Private Function EvaluateAND(expr As String, conditions As Object) As Boolean
|
||||
Dim parts() As String
|
||||
Dim part As Variant
|
||||
|
||||
' 按 AND 分割
|
||||
parts = Split(expr, " AND ")
|
||||
|
||||
' 全部部分为真才返回真
|
||||
For Each part In parts
|
||||
If Not EvaluateExpression(Trim(CStr(part)), conditions) Then
|
||||
EvaluateAND = False
|
||||
Exit Function
|
||||
End If
|
||||
Next part
|
||||
|
||||
EvaluateAND = True
|
||||
End Function
|
||||
|
||||
' ========================================
|
||||
' EvaluateSimpleCondition 方法 (私有)
|
||||
' 功能: 计算单个条件表达式
|
||||
' 支持: = (等于), != (不等于)
|
||||
' 格式: varName=value 或 varName!=value
|
||||
' ========================================
|
||||
Private Function EvaluateSimpleCondition(cond As String, conditions As Object) As Boolean
|
||||
cond = Trim(cond)
|
||||
|
||||
' 处理特殊值 TRUE/FALSE (括号计算的结果)
|
||||
If UCase(cond) = "TRUE" Then
|
||||
EvaluateSimpleCondition = True
|
||||
Exit Function
|
||||
ElseIf UCase(cond) = "FALSE" Then
|
||||
EvaluateSimpleCondition = False
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
Dim varName As String
|
||||
Dim expectedValue As String
|
||||
Dim actualValue As String
|
||||
Dim isNotEqual As Boolean
|
||||
|
||||
' 判断是 != 还是 =
|
||||
If InStr(cond, "!=") > 0 Then
|
||||
isNotEqual = True
|
||||
Dim parts1() As String
|
||||
parts1 = Split(cond, "!=")
|
||||
If UBound(parts1) < 1 Then
|
||||
EvaluateSimpleCondition = False
|
||||
Exit Function
|
||||
End If
|
||||
varName = Trim(parts1(0))
|
||||
expectedValue = Trim(parts1(1))
|
||||
ElseIf InStr(cond, "=") > 0 Then
|
||||
isNotEqual = False
|
||||
Dim parts2() As String
|
||||
parts2 = Split(cond, "=")
|
||||
If UBound(parts2) < 1 Then
|
||||
EvaluateSimpleCondition = False
|
||||
Exit Function
|
||||
End If
|
||||
varName = Trim(parts2(0))
|
||||
expectedValue = Trim(parts2(1))
|
||||
Else
|
||||
' 无效的条件格式
|
||||
EvaluateSimpleCondition = False
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
' 获取实际值
|
||||
If conditions.Exists(varName) Then
|
||||
actualValue = Trim(CStr(conditions(varName)))
|
||||
Else
|
||||
actualValue = ""
|
||||
End If
|
||||
|
||||
' 比较值 (不区分大小写)
|
||||
Dim isEqual As Boolean
|
||||
isEqual = (UCase(actualValue) = UCase(expectedValue))
|
||||
|
||||
' 返回结果
|
||||
If isNotEqual Then
|
||||
EvaluateSimpleCondition = Not isEqual
|
||||
Else
|
||||
EvaluateSimpleCondition = isEqual
|
||||
End If
|
||||
End Function
|
||||
|
||||
' ========================================
|
||||
' TestExpression 方法
|
||||
' 功能: 测试表达式是否有效 (用于调试)
|
||||
' 参数: expr - 表达式字符串
|
||||
' 返回: String - "有效" 或 错误信息
|
||||
' ========================================
|
||||
Public Function TestExpression(expr As String) As String
|
||||
On Error GoTo ErrorHandler
|
||||
|
||||
' 创建测试条件
|
||||
Dim testConditions As Object
|
||||
Set testConditions = CreateObject("Scripting.Dictionary")
|
||||
testConditions("gclj") = "M20"
|
||||
testConditions("jycz") = "3"
|
||||
testConditions("lcfw") = "M16"
|
||||
|
||||
' 尝试计算
|
||||
Dim result As Boolean
|
||||
result = IsMatch(expr, testConditions)
|
||||
|
||||
TestExpression = "有效 (结果: " & IIf(result, "True", "False") & ")"
|
||||
Exit Function
|
||||
|
||||
ErrorHandler:
|
||||
TestExpression = "无效: " & Err.description
|
||||
End Function
|
||||
Reference in New Issue
Block a user