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:
@@ -1,6 +1,6 @@
|
||||
' ========================================
|
||||
' 模块: modBOMTest
|
||||
' 用途: 测试和使用BOM数据结构-同步测试2
|
||||
' 用途: 测试和使用BOM数据结构
|
||||
' ========================================
|
||||
Option Explicit
|
||||
|
||||
@@ -19,19 +19,19 @@ Sub TestBOMStructure()
|
||||
bomMgr.LoadData wsConfig, wsPlatform
|
||||
|
||||
' 打印类别树结构到新工作表
|
||||
' Dim wsOutput As Worksheet
|
||||
' On Error Resume Next
|
||||
' Application.DisplayAlerts = False
|
||||
' ThisWorkbook.Worksheets("BOM结构").Delete
|
||||
' Application.DisplayAlerts = True
|
||||
' On Error GoTo 0
|
||||
'
|
||||
' Set wsOutput = ThisWorkbook.Worksheets.Add
|
||||
' wsOutput.Name = "BOM结构"
|
||||
Dim wsOutput As Worksheet
|
||||
On Error Resume Next
|
||||
Application.DisplayAlerts = False
|
||||
ThisWorkbook.Worksheets("BOM结构").Delete
|
||||
Application.DisplayAlerts = True
|
||||
On Error GoTo 0
|
||||
|
||||
Set wsOutput = ThisWorkbook.Worksheets.Add
|
||||
wsOutput.Name = "BOM结构"
|
||||
|
||||
'bomMgr.PrintCategoryTree wsOutput
|
||||
|
||||
Dim cats As Collection
|
||||
Dim cats As collection
|
||||
Dim i As Integer
|
||||
Set cats = bomMgr.GetRootCategories()
|
||||
For i = 1 To cats.Count
|
||||
@@ -40,7 +40,7 @@ Sub TestBOMStructure()
|
||||
|
||||
|
||||
|
||||
'MsgBox "BOM数据结构加载完成!" & vbCrLf & _
|
||||
MsgBox "BOM数据结构加载完成!" & vbCrLf & _
|
||||
"请查看 'BOM结构' 工作表", vbInformation
|
||||
End Sub
|
||||
|
||||
@@ -55,19 +55,19 @@ Sub GetCategoryMaterials()
|
||||
bomMgr.LoadData wsConfig, wsPlatform
|
||||
|
||||
' 获取"部件"类别的物料(使用父类别)
|
||||
Dim Materials As Collection
|
||||
Set Materials = bomMgr.GetMaterialsForPicking("部件", True)
|
||||
Dim materials As collection
|
||||
Set materials = bomMgr.GetMaterialsForPicking("部件", True)
|
||||
|
||||
Debug.Print "部件类别物料数量(父类别): " & Materials.Count
|
||||
Debug.Print "部件类别物料数量(父类别): " & materials.Count
|
||||
|
||||
' 获取"部件"类别的物料(使用子类别)
|
||||
Set Materials = bomMgr.GetMaterialsForPicking("部件", False)
|
||||
Set materials = bomMgr.GetMaterialsForPicking("部件", False)
|
||||
|
||||
Debug.Print "部件类别物料数量(子类别展开): " & Materials.Count
|
||||
Debug.Print "部件类别物料数量(子类别展开): " & materials.Count
|
||||
|
||||
' 遍历物料
|
||||
Dim mat As clsMaterialItem
|
||||
For Each mat In Materials
|
||||
For Each mat In materials
|
||||
Debug.Print mat.code & " - " & mat.Name & _
|
||||
" | 数量:" & mat.Quantity & _
|
||||
" | 条件:" & mat.Condition
|
||||
@@ -98,36 +98,36 @@ Sub GeneratePickingList()
|
||||
' 写入表头
|
||||
Dim row As Long
|
||||
row = 1
|
||||
wsPickList.Cells(row, 1).Value = "代号"
|
||||
wsPickList.Cells(row, 2).Value = "名称"
|
||||
wsPickList.Cells(row, 3).Value = "类别"
|
||||
wsPickList.Cells(row, 4).Value = "数量"
|
||||
wsPickList.Cells(row, 5).Value = "选择条件"
|
||||
wsPickList.Cells(row, 6).Value = "领料方式"
|
||||
wsPickList.Cells(row, 1).value = "代号"
|
||||
wsPickList.Cells(row, 2).value = "名称"
|
||||
wsPickList.Cells(row, 3).value = "类别"
|
||||
wsPickList.Cells(row, 4).value = "数量"
|
||||
wsPickList.Cells(row, 5).value = "选择条件"
|
||||
wsPickList.Cells(row, 6).value = "领料方式"
|
||||
row = row + 1
|
||||
|
||||
' 遍历所有根类别
|
||||
Dim rootCats As Collection
|
||||
Dim rootCats As collection
|
||||
Set rootCats = bomMgr.GetRootCategories
|
||||
|
||||
Dim cat As clsCategory
|
||||
Dim Materials As Collection
|
||||
Dim materials As collection
|
||||
Dim mat As clsMaterialItem
|
||||
Dim i As Long, j As Long
|
||||
|
||||
For i = 1 To rootCats.Count
|
||||
Set cat = rootCats(i)
|
||||
' 默认使用父类别物料
|
||||
Set Materials = bomMgr.GetMaterialsForPicking(cat.categoryName, True)
|
||||
Set materials = bomMgr.GetMaterialsForPicking(cat.categoryName, True)
|
||||
|
||||
For j = 1 To Materials.Count
|
||||
Set mat = Materials(j)
|
||||
wsPickList.Cells(row, 1).Value = mat.code
|
||||
wsPickList.Cells(row, 2).Value = mat.Name
|
||||
wsPickList.Cells(row, 3).Value = mat.Category
|
||||
wsPickList.Cells(row, 4).Value = mat.Quantity
|
||||
wsPickList.Cells(row, 5).Value = mat.Condition
|
||||
wsPickList.Cells(row, 6).Value = "父类别"
|
||||
For j = 1 To materials.Count
|
||||
Set mat = materials(j)
|
||||
wsPickList.Cells(row, 1).value = mat.code
|
||||
wsPickList.Cells(row, 2).value = mat.Name
|
||||
wsPickList.Cells(row, 3).value = mat.Category
|
||||
wsPickList.Cells(row, 4).value = mat.Quantity
|
||||
wsPickList.Cells(row, 5).value = mat.Condition
|
||||
wsPickList.Cells(row, 6).value = "父类别"
|
||||
row = row + 1
|
||||
Next j
|
||||
Next i
|
||||
@@ -139,64 +139,6 @@ Sub GeneratePickingList()
|
||||
MsgBox "领料清单生成完成!", vbInformation
|
||||
End Sub
|
||||
|
||||
' 示例: 在立即窗口打印领料清单
|
||||
Sub PrintPickingList()
|
||||
Dim bomMgr As New clsBOMManager
|
||||
Dim wsConfig As Worksheet, wsPlatform As Worksheet
|
||||
|
||||
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
|
||||
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
|
||||
|
||||
bomMgr.LoadData wsConfig, wsPlatform
|
||||
|
||||
' 打印表头
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "领料清单"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
' 遍历所有根类别
|
||||
Dim rootCats As Collection
|
||||
Set rootCats = bomMgr.GetRootCategories
|
||||
|
||||
Dim cat As clsCategory
|
||||
Dim Materials As Collection
|
||||
Dim mat As clsMaterialItem
|
||||
Dim i As Long, j As Long
|
||||
Dim totalCount As Long
|
||||
|
||||
totalCount = 0
|
||||
|
||||
For i = 1 To rootCats.Count
|
||||
Set cat = rootCats(i)
|
||||
|
||||
' 打印类别分隔符
|
||||
Debug.Print ""
|
||||
Debug.Print "【类别: " & cat.categoryName & "】"
|
||||
Debug.Print String(40, "-")
|
||||
|
||||
' 默认使用父类别物料
|
||||
Set Materials = bomMgr.GetMaterialsForPicking(cat.categoryName, True)
|
||||
|
||||
For j = 1 To Materials.Count
|
||||
Set mat = Materials(j)
|
||||
Debug.Print " " & mat.code & _
|
||||
String(20 - Len(mat.code), " ") & _
|
||||
mat.Name & _
|
||||
" | 数量:" & mat.Quantity & _
|
||||
" | 条件:" & IIf(mat.Condition = "", "(无)", mat.Condition)
|
||||
totalCount = totalCount + 1
|
||||
Next j
|
||||
|
||||
Debug.Print " 小计: " & Materials.Count & " 项"
|
||||
Next i
|
||||
|
||||
' 打印汇总
|
||||
Debug.Print ""
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "总计: " & totalCount & " 项物料"
|
||||
Debug.Print String(80, "=")
|
||||
End Sub
|
||||
|
||||
' 示例: 查询特定物料信息
|
||||
Sub QueryMaterialInfo()
|
||||
Dim bomMgr As New clsBOMManager
|
||||
@@ -214,15 +156,15 @@ Sub QueryMaterialInfo()
|
||||
If Not cat Is Nothing Then
|
||||
Debug.Print "类别: " & cat.categoryName
|
||||
Debug.Print "父类别: " & cat.ParentCategoryName
|
||||
Debug.Print "物料数: " & cat.Materials.Count
|
||||
Debug.Print "物料数: " & cat.materials.Count
|
||||
Debug.Print "子类别数: " & cat.SubCategories.Count
|
||||
Debug.Print "是否叶子类别: " & cat.IsLeafCategory
|
||||
|
||||
' 列出所有物料
|
||||
Dim mat As clsMaterialItem
|
||||
Dim i As Long
|
||||
For i = 1 To cat.Materials.Count
|
||||
Set mat = cat.Materials(i)
|
||||
For i = 1 To cat.materials.Count
|
||||
Set mat = cat.materials(i)
|
||||
Debug.Print " - " & mat.code & ": " & mat.Name
|
||||
Next i
|
||||
|
||||
@@ -232,7 +174,7 @@ Sub QueryMaterialInfo()
|
||||
For j = 1 To cat.SubCategories.Count
|
||||
Set subCat = cat.SubCategories(j)
|
||||
Debug.Print " 子类别: " & subCat.categoryName & _
|
||||
" (物料数:" & subCat.Materials.Count & ")"
|
||||
" (物料数:" & subCat.materials.Count & ")"
|
||||
Next j
|
||||
End If
|
||||
End Sub
|
||||
375
VBA/Modules/modModelParserExamples.bas
Normal file
375
VBA/Modules/modModelParserExamples.bas
Normal file
@@ -0,0 +1,375 @@
|
||||
' ========================================
|
||||
' 模块: modModelParserExamples
|
||||
' 用途: 型号解析与物料匹配的实际应用示例
|
||||
' ========================================
|
||||
Option Explicit
|
||||
|
||||
' ========================================
|
||||
' 示例1: 根据型号生成完整的领料清单
|
||||
' ========================================
|
||||
Sub Example1_GeneratePickingListByModel()
|
||||
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.M16.Y3|BP-095.2312.M16.PA3"
|
||||
|
||||
' 创建领料清单工作表
|
||||
Dim wsPickList As Worksheet
|
||||
On Error Resume Next
|
||||
Application.DisplayAlerts = False
|
||||
ThisWorkbook.Worksheets("型号领料清单").Delete
|
||||
Application.DisplayAlerts = True
|
||||
On Error GoTo 0
|
||||
|
||||
Set wsPickList = ThisWorkbook.Worksheets.Add
|
||||
wsPickList.Name = "型号领料清单"
|
||||
|
||||
' 写入表头
|
||||
Dim row As Long
|
||||
row = 1
|
||||
wsPickList.Cells(row, 1).value = "产品型号"
|
||||
wsPickList.Cells(row, 2).value = modelStr
|
||||
row = row + 1
|
||||
|
||||
' 提取条件并显示
|
||||
Dim conditions As Object
|
||||
Set conditions = bomMgr.ParseModelAndExtractConditions(modelStr)
|
||||
wsPickList.Cells(row, 1).value = "提取条件"
|
||||
Dim condStr As String
|
||||
Dim key As Variant
|
||||
For Each key In conditions.Keys
|
||||
condStr = condStr & key & "=" & conditions(key) & "; "
|
||||
Next key
|
||||
wsPickList.Cells(row, 2).value = condStr
|
||||
row = row + 2
|
||||
|
||||
' 表头
|
||||
wsPickList.Cells(row, 1).value = "类别"
|
||||
wsPickList.Cells(row, 2).value = "代号"
|
||||
wsPickList.Cells(row, 3).value = "名称"
|
||||
wsPickList.Cells(row, 4).value = "数量"
|
||||
wsPickList.Cells(row, 5).value = "选择条件"
|
||||
wsPickList.Cells(row, 6).value = "匹配状态"
|
||||
wsPickList.Range("A" & row & ":F" & row).Font.Bold = True
|
||||
row = row + 1
|
||||
|
||||
' 遍历所有根类别
|
||||
Dim rootCats As collection
|
||||
Set rootCats = bomMgr.GetRootCategories
|
||||
|
||||
Dim cat As clsCategory
|
||||
Dim materials As collection
|
||||
Dim mat As clsMaterialItem
|
||||
Dim i As Long
|
||||
|
||||
For i = 1 To rootCats.Count
|
||||
Set cat = rootCats(i)
|
||||
|
||||
' 获取该类别符合条件的物料
|
||||
Set materials = bomMgr.GetMaterialsByModel(modelStr, cat.categoryName)
|
||||
|
||||
' 写入物料
|
||||
Dim j As Long
|
||||
For j = 1 To materials.Count
|
||||
Set mat = materials(j)
|
||||
wsPickList.Cells(row, 1).value = cat.categoryName
|
||||
wsPickList.Cells(row, 2).value = mat.code
|
||||
wsPickList.Cells(row, 3).value = mat.Name
|
||||
wsPickList.Cells(row, 4).value = mat.Quantity
|
||||
wsPickList.Cells(row, 5).value = IIf(mat.Condition = "", "(无条件)", mat.Condition)
|
||||
wsPickList.Cells(row, 6).value = "?"
|
||||
row = row + 1
|
||||
Next j
|
||||
Next i
|
||||
|
||||
' 格式化
|
||||
wsPickList.Columns("A:F").AutoFit
|
||||
|
||||
MsgBox "领料清单生成完成!" & vbCrLf & _
|
||||
"请查看工作表: 型号领料清单", vbInformation
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 示例2: 批量处理多个型号
|
||||
' ========================================
|
||||
Sub Example2_BatchProcessModels()
|
||||
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 models() As String
|
||||
models = Split("YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3," & _
|
||||
"YTHN-100.A0.532.M203.M02.Y3|BP-095.2312.M02.PA3," & _
|
||||
"YTHN-100.A0.532.M203.M12.Y3|BP-095.2312.M12.PA3", ",")
|
||||
|
||||
' 创建汇总表
|
||||
Dim wsReport As Worksheet
|
||||
On Error Resume Next
|
||||
Application.DisplayAlerts = False
|
||||
ThisWorkbook.Worksheets("批量型号汇总").Delete
|
||||
Application.DisplayAlerts = True
|
||||
On Error GoTo 0
|
||||
|
||||
Set wsReport = ThisWorkbook.Worksheets.Add
|
||||
wsReport.Name = "批量型号汇总"
|
||||
|
||||
' 表头
|
||||
Dim row As Long
|
||||
row = 1
|
||||
wsReport.Cells(row, 1).value = "型号"
|
||||
wsReport.Cells(row, 2).value = "提取条件"
|
||||
wsReport.Cells(row, 3).value = "匹配物料数"
|
||||
wsReport.Cells(row, 4).value = "部件物料"
|
||||
wsReport.Range("A1:D1").Font.Bold = True
|
||||
row = row + 1
|
||||
|
||||
' 处理每个型号
|
||||
Dim modelStr As String
|
||||
Dim i As Long
|
||||
|
||||
For i = LBound(models) To UBound(models)
|
||||
modelStr = Trim(models(i))
|
||||
If modelStr <> "" Then
|
||||
' 提取条件
|
||||
Dim conditions As Object
|
||||
Set conditions = bomMgr.ParseModelAndExtractConditions(modelStr)
|
||||
|
||||
Dim condStr As String
|
||||
condStr = ""
|
||||
Dim key As Variant
|
||||
For Each key In conditions.Keys
|
||||
condStr = condStr & key & "=" & conditions(key) & "; "
|
||||
Next key
|
||||
|
||||
' 获取物料
|
||||
Dim materials As collection
|
||||
Set materials = bomMgr.GetMaterialsByModel(modelStr, "部件")
|
||||
|
||||
' 写入结果
|
||||
wsReport.Cells(row, 1).value = modelStr
|
||||
wsReport.Cells(row, 2).value = condStr
|
||||
wsReport.Cells(row, 3).value = materials.Count
|
||||
|
||||
' 列出部件物料
|
||||
Dim matList As String
|
||||
matList = ""
|
||||
Dim mat As clsMaterialItem
|
||||
For Each mat In materials
|
||||
matList = matList & mat.code & "(" & mat.Name & "); "
|
||||
Next mat
|
||||
wsReport.Cells(row, 4).value = matList
|
||||
|
||||
row = row + 1
|
||||
End If
|
||||
Next i
|
||||
|
||||
' 格式化
|
||||
wsReport.Columns("A:D").AutoFit
|
||||
|
||||
MsgBox "批量处理完成!", vbInformation
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 示例3: 查询并显示某个型号的详细信息
|
||||
' ========================================
|
||||
Sub Example3_ShowModelDetails()
|
||||
' 弹出输入框
|
||||
Dim modelStr As String
|
||||
modelStr = InputBox("请输入产品型号:", "型号查询", _
|
||||
"YTHN-100.A0.532.M203.M16.Y3")
|
||||
|
||||
If modelStr = "" Then Exit Sub
|
||||
|
||||
' 解析型号
|
||||
Dim parser As New clsModelParser
|
||||
If Not parser.ParseModel(modelStr) Then
|
||||
MsgBox "型号解析失败: " & parser.ErrorMessage, vbCritical
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' 提取条件
|
||||
Dim extractor As New clsConditionExtractor
|
||||
Dim conditions As Object
|
||||
Set conditions = extractor.ExtractConditions(parser)
|
||||
|
||||
' 显示详细信息
|
||||
Dim msg As String
|
||||
msg = "【型号解析结果】" & vbCrLf & vbCrLf
|
||||
msg = msg & "原始型号: " & parser.RawModel & vbCrLf
|
||||
msg = msg & "表头型号: " & parser.HeaderModel & vbCrLf
|
||||
msg = msg & "表盘型号: " & parser.DialModel & vbCrLf & vbCrLf
|
||||
|
||||
msg = msg & "【表头各部分】" & vbCrLf
|
||||
msg = msg & "型号: " & parser.ModelType & vbCrLf
|
||||
msg = msg & "公称外径: " & parser.Diameter & vbCrLf
|
||||
msg = msg & "安装形式: " & parser.InstallForm & vbCrLf
|
||||
msg = msg & "壳体形式: " & parser.ShellForm & vbCrLf
|
||||
msg = msg & "过程连接&材质: " & parser.ConnectionCode & vbCrLf
|
||||
msg = msg & "量程范围: " & parser.RangeCode & vbCrLf
|
||||
msg = msg & "仪表特性: " & parser.Characteristics & vbCrLf & vbCrLf
|
||||
|
||||
msg = msg & "【提取的物料选择条件】" & vbCrLf
|
||||
Dim key As Variant
|
||||
For Each key In conditions.Keys
|
||||
msg = msg & key & " = " & conditions(key) & vbCrLf
|
||||
Next key
|
||||
|
||||
MsgBox msg, vbInformation, "型号详细信息"
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 示例4: 对比两个型号的差异
|
||||
' ========================================
|
||||
Sub Example4_CompareModels()
|
||||
Dim model1 As String, model2 As String
|
||||
|
||||
model1 = InputBox("请输入第一个型号:", "型号对比", _
|
||||
"YTHN-100.A0.532.M203.M16.Y3")
|
||||
If model1 = "" Then Exit Sub
|
||||
|
||||
model2 = InputBox("请输入第二个型号:", "型号对比", _
|
||||
"YTHN-100.A0.532.M203.M02.Y3")
|
||||
If model2 = "" Then Exit Sub
|
||||
|
||||
' 解析两个型号
|
||||
Dim parser1 As New clsModelParser
|
||||
Dim parser2 As New clsModelParser
|
||||
Dim extractor As New clsConditionExtractor
|
||||
|
||||
parser1.ParseModel model1
|
||||
parser2.ParseModel model2
|
||||
|
||||
Dim cond1 As Object, cond2 As Object
|
||||
Set cond1 = extractor.ExtractConditions(parser1)
|
||||
|
||||
Set extractor = New clsConditionExtractor
|
||||
Set cond2 = extractor.ExtractConditions(parser2)
|
||||
|
||||
' 对比
|
||||
Dim msg As String
|
||||
msg = "【型号对比】" & vbCrLf & vbCrLf
|
||||
msg = msg & "型号1: " & model1 & vbCrLf
|
||||
msg = msg & "型号2: " & model2 & vbCrLf & vbCrLf
|
||||
|
||||
msg = msg & "【条件差异】" & vbCrLf
|
||||
Dim key As Variant
|
||||
Dim allKeys As Object
|
||||
Set allKeys = CreateObject("Scripting.Dictionary")
|
||||
|
||||
For Each key In cond1.Keys
|
||||
allKeys(key) = True
|
||||
Next key
|
||||
For Each key In cond2.Keys
|
||||
allKeys(key) = True
|
||||
Next key
|
||||
|
||||
For Each key In allKeys.Keys
|
||||
Dim val1 As String, val2 As String
|
||||
val1 = ""
|
||||
val2 = ""
|
||||
|
||||
If cond1.Exists(key) Then val1 = cond1(key)
|
||||
If cond2.Exists(key) Then val2 = cond2(key)
|
||||
|
||||
If val1 <> val2 Then
|
||||
msg = msg & key & ": " & val1 & " → " & val2 & " ?" & vbCrLf
|
||||
Else
|
||||
msg = msg & key & ": " & val1 & " ?" & vbCrLf
|
||||
End If
|
||||
Next key
|
||||
|
||||
MsgBox msg, vbInformation, "型号对比结果"
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 示例5: 验证物料选择条件的有效性
|
||||
' ========================================
|
||||
Sub Example5_ValidateMaterialConditions()
|
||||
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 wsValidation As Worksheet
|
||||
On Error Resume Next
|
||||
Application.DisplayAlerts = False
|
||||
ThisWorkbook.Worksheets("条件验证结果").Delete
|
||||
Application.DisplayAlerts = True
|
||||
On Error GoTo 0
|
||||
|
||||
Set wsValidation = ThisWorkbook.Worksheets.Add
|
||||
wsValidation.Name = "条件验证结果"
|
||||
|
||||
' 表头
|
||||
Dim row As Long
|
||||
row = 1
|
||||
wsValidation.Cells(row, 1).value = "代号"
|
||||
wsValidation.Cells(row, 2).value = "名称"
|
||||
wsValidation.Cells(row, 3).value = "选择条件"
|
||||
wsValidation.Cells(row, 4).value = "验证结果"
|
||||
wsValidation.Range("A1:D1").Font.Bold = True
|
||||
row = row + 1
|
||||
|
||||
' 获取所有根类别
|
||||
Dim rootCats As collection
|
||||
Set rootCats = bomMgr.GetRootCategories
|
||||
|
||||
Dim cat As clsCategory
|
||||
Dim materials As collection
|
||||
Dim mat As clsMaterialItem
|
||||
Dim matcher As New clsConditionMatcher
|
||||
Dim i As Long
|
||||
|
||||
' 遍历所有物料
|
||||
For i = 1 To rootCats.Count
|
||||
Set cat = rootCats(i)
|
||||
Set materials = New collection
|
||||
|
||||
' 收集该类别的所有物料
|
||||
Dim j As Long
|
||||
For j = 1 To cat.materials.Count
|
||||
materials.Add cat.materials(j)
|
||||
Next j
|
||||
|
||||
' 验证每个物料的条件
|
||||
For Each mat In materials
|
||||
wsValidation.Cells(row, 1).value = mat.code
|
||||
wsValidation.Cells(row, 2).value = mat.Name
|
||||
wsValidation.Cells(row, 3).value = IIf(mat.Condition = "", "(无)", mat.Condition)
|
||||
|
||||
If mat.Condition = "" Then
|
||||
wsValidation.Cells(row, 4).value = "? 无条件"
|
||||
Else
|
||||
Dim validResult As String
|
||||
validResult = matcher.TestExpression(mat.Condition)
|
||||
wsValidation.Cells(row, 4).value = validResult
|
||||
End If
|
||||
|
||||
row = row + 1
|
||||
Next mat
|
||||
Next i
|
||||
|
||||
' 格式化
|
||||
wsValidation.Columns("A:D").AutoFit
|
||||
|
||||
MsgBox "条件验证完成!", vbInformation
|
||||
End Sub
|
||||
309
VBA/Modules/modModelParserTest.bas
Normal file
309
VBA/Modules/modModelParserTest.bas
Normal file
@@ -0,0 +1,309 @@
|
||||
' ========================================
|
||||
' 模块: modModelParserTest
|
||||
' 用途: 测试型号解析和物料匹配功能
|
||||
' ========================================
|
||||
Option Explicit
|
||||
|
||||
' ========================================
|
||||
' 测试1: 型号解析器基础功能
|
||||
' ========================================
|
||||
Sub Test1_ModelParser()
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "测试1: 型号解析器基础功能"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
Dim parser As New clsModelParser
|
||||
Dim modelStr As String
|
||||
|
||||
' 测试用例1: 完整型号
|
||||
modelStr = "YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3"
|
||||
Debug.Print "【测试用例1】完整型号"
|
||||
Debug.Print "输入: " & modelStr
|
||||
|
||||
If parser.ParseModel(modelStr) Then
|
||||
Debug.Print parser.ToString()
|
||||
Debug.Print "? 解析成功"
|
||||
Else
|
||||
Debug.Print "? 解析失败: " & parser.ErrorMessage
|
||||
End If
|
||||
|
||||
Debug.Print ""
|
||||
|
||||
' 测试用例2: 仅表头
|
||||
modelStr = "YTHN-100.A0.532.M203.M16.Y3"
|
||||
Debug.Print "【测试用例2】仅表头"
|
||||
Debug.Print "输入: " & modelStr
|
||||
|
||||
If parser.ParseModel(modelStr) Then
|
||||
Debug.Print " 螺纹代码: " & parser.GetThreadCode()
|
||||
Debug.Print " 材质代码: " & parser.GetMaterialCode()
|
||||
Debug.Print " 量程代码: " & parser.GetRangeCode()
|
||||
Debug.Print "? 解析成功"
|
||||
Else
|
||||
Debug.Print "? 解析失败: " & parser.ErrorMessage
|
||||
End If
|
||||
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print ""
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 测试2: 条件提取器
|
||||
' ========================================
|
||||
Sub Test2_ConditionExtractor()
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "测试2: 条件提取器"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
Dim parser As New clsModelParser
|
||||
Dim extractor As New clsConditionExtractor
|
||||
Dim modelStr As String
|
||||
|
||||
modelStr = "YTHN-100.A0.532.M203.M16.Y3"
|
||||
Debug.Print "输入型号: " & modelStr
|
||||
|
||||
If parser.ParseModel(modelStr) Then
|
||||
Dim conditions As Object
|
||||
Set conditions = extractor.ExtractConditions(parser)
|
||||
|
||||
Debug.Print extractor.ToString()
|
||||
|
||||
' 验证提取结果
|
||||
Debug.Print "【验证】"
|
||||
Debug.Print " gclj = " & extractor.GetConditionValue("gclj") & _
|
||||
IIf(extractor.GetConditionValue("gclj") = "M20", " ?", " ?")
|
||||
Debug.Print " jycz = " & extractor.GetConditionValue("jycz") & _
|
||||
IIf(extractor.GetConditionValue("jycz") = "3", " ?", " ?")
|
||||
Debug.Print " lcfw = " & extractor.GetConditionValue("lcfw") & _
|
||||
IIf(extractor.GetConditionValue("lcfw") = "M16", " ?", " ?")
|
||||
Else
|
||||
Debug.Print "? 型号解析失败"
|
||||
End If
|
||||
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print ""
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 测试3: 条件匹配器
|
||||
' ========================================
|
||||
Sub Test3_ConditionMatcher()
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "测试3: 条件匹配器"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
Dim matcher As New clsConditionMatcher
|
||||
Dim conditions As Object
|
||||
Set conditions = CreateObject("Scripting.Dictionary")
|
||||
conditions("gclj") = "M20"
|
||||
conditions("jycz") = "3"
|
||||
conditions("lcfw") = "M16"
|
||||
|
||||
Debug.Print "【测试条件】"
|
||||
Debug.Print " gclj = M20"
|
||||
Debug.Print " jycz = 3"
|
||||
Debug.Print " lcfw = M16"
|
||||
Debug.Print ""
|
||||
|
||||
' 测试用例
|
||||
Dim testCases As Variant
|
||||
testCases = Array( _
|
||||
Array("", True, "空条件"), _
|
||||
Array("lcfw=M16", True, "简单等于"), _
|
||||
Array("lcfw=M17", False, "简单不匹配"), _
|
||||
Array("lcfw=M16 AND gclj=M20", True, "AND 全真"), _
|
||||
Array("lcfw=M16 AND gclj=M10", False, "AND 一假"), _
|
||||
Array("lcfw=M16 OR lcfw=M17", True, "OR 一真"), _
|
||||
Array("lcfw=M15 OR lcfw=M17", False, "OR 全假"), _
|
||||
Array("gclj!=M10", True, "不等于 真"), _
|
||||
Array("gclj!=M20", False, "不等于 假"), _
|
||||
Array("lcfw=M02 AND gclj!=M20", False, "复合条件1"), _
|
||||
Array("lcfw=M16 AND gclj!=M10", True, "复合条件2"), _
|
||||
Array("gclj=M20 AND (lcfw=M16 OR lcfw=M17)", True, "括号优先级1"), _
|
||||
Array("gclj=M20 AND (lcfw=M15 OR lcfw=M17)", False, "括号优先级2") _
|
||||
)
|
||||
|
||||
Dim i As Long
|
||||
Dim testCase As Variant
|
||||
Dim expr As String
|
||||
Dim expected As Boolean
|
||||
Dim actual As Boolean
|
||||
Dim description As String
|
||||
Dim passCount As Long
|
||||
Dim failCount As Long
|
||||
|
||||
passCount = 0
|
||||
failCount = 0
|
||||
|
||||
Debug.Print "【测试用例】"
|
||||
For i = LBound(testCases) To UBound(testCases)
|
||||
testCase = testCases(i)
|
||||
expr = testCase(0)
|
||||
expected = testCase(1)
|
||||
description = testCase(2)
|
||||
|
||||
actual = matcher.IsMatch(expr, conditions)
|
||||
|
||||
If actual = expected Then
|
||||
Debug.Print " ? " & description & ": " & IIf(expr = "", "(空)", expr)
|
||||
passCount = passCount + 1
|
||||
Else
|
||||
Debug.Print " ? " & description & ": " & expr
|
||||
Debug.Print " 预期: " & expected & ", 实际: " & actual
|
||||
failCount = failCount + 1
|
||||
End If
|
||||
Next i
|
||||
|
||||
Debug.Print ""
|
||||
Debug.Print "【统计】"
|
||||
Debug.Print " 通过: " & passCount
|
||||
Debug.Print " 失败: " & failCount
|
||||
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print ""
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 测试4: 完整流程 - 根据型号获取物料
|
||||
' ========================================
|
||||
Sub Test4_GetMaterialsByModel()
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "测试4: 根据型号获取物料(完整流程)"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
' 加载BOM数据
|
||||
Dim bomMgr As New clsBOMManager
|
||||
Dim wsConfig As Worksheet
|
||||
Dim wsPlatform As Worksheet
|
||||
|
||||
On Error Resume Next
|
||||
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
|
||||
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
|
||||
On Error GoTo 0
|
||||
|
||||
If wsConfig Is Nothing Or wsPlatform Is Nothing Then
|
||||
Debug.Print "? 错误: 找不到必需的工作表"
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
bomMgr.LoadData wsConfig, wsPlatform
|
||||
Debug.Print "? BOM数据加载完成"
|
||||
Debug.Print ""
|
||||
|
||||
' 测试型号
|
||||
Dim modelStr As String
|
||||
modelStr = "YTHN-100.A0.532.M203.M16.Y3|BP-095.2312.M16.PA3"
|
||||
|
||||
' 获取"部件"类别的符合条件的物料
|
||||
Dim materials As collection
|
||||
Set materials = bomMgr.GetMaterialsByModel(modelStr, "部件")
|
||||
|
||||
Debug.Print ""
|
||||
Debug.Print "【结果验证】"
|
||||
If materials.Count = 1 Then
|
||||
Dim mat As clsMaterialItem
|
||||
Set mat = materials(1)
|
||||
If mat.code = "01011019018" And mat.Name = "高压接头部件" Then
|
||||
Debug.Print "? 测试通过!成功匹配到正确的物料"
|
||||
Debug.Print " 代号: " & mat.code
|
||||
Debug.Print " 名称: " & mat.Name
|
||||
Debug.Print " 条件: " & mat.Condition
|
||||
Else
|
||||
Debug.Print "? 匹配到的物料不正确"
|
||||
End If
|
||||
Else
|
||||
Debug.Print "? 匹配数量不正确,预期1个,实际" & materials.Count & "个"
|
||||
End If
|
||||
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print ""
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 测试5: 获取所有类别的符合条件的物料
|
||||
' ========================================
|
||||
Sub Test5_GetAllMaterialsByModel()
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "测试5: 获取所有类别的符合条件的物料"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
' 加载BOM数据
|
||||
Dim bomMgr As New clsBOMManager
|
||||
Dim wsConfig As Worksheet
|
||||
Dim wsPlatform As Worksheet
|
||||
|
||||
On Error Resume Next
|
||||
Set wsConfig = ThisWorkbook.Worksheets("领料配置")
|
||||
Set wsPlatform = ThisWorkbook.Worksheets("平台配置清单")
|
||||
On Error GoTo 0
|
||||
|
||||
If wsConfig Is Nothing Or wsPlatform Is Nothing Then
|
||||
Debug.Print "? 错误: 找不到必需的工作表"
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
bomMgr.LoadData wsConfig, wsPlatform
|
||||
|
||||
' 测试型号
|
||||
Dim modelStr As String
|
||||
modelStr = "YTHN-100.A0.532.M203.M16.Y3"
|
||||
|
||||
' 获取所有类别的符合条件的物料
|
||||
Dim materials As collection
|
||||
Set materials = bomMgr.GetMaterialsByModel(modelStr)
|
||||
|
||||
Debug.Print ""
|
||||
Debug.Print "【匹配结果汇总】"
|
||||
Debug.Print " 共匹配 " & materials.Count & " 个物料"
|
||||
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print ""
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 运行所有测试
|
||||
' ========================================
|
||||
Sub RunAllTests()
|
||||
Debug.Print vbCrLf & vbCrLf
|
||||
Debug.Print "╔" & String(78, "═") & "╗"
|
||||
Debug.Print "║" & Space(20) & "型号解析与物料匹配 - 完整测试套件" & Space(20) & "║"
|
||||
Debug.Print "╚" & String(78, "═") & "╝"
|
||||
Debug.Print ""
|
||||
|
||||
Test1_ModelParser
|
||||
Test2_ConditionExtractor
|
||||
Test3_ConditionMatcher
|
||||
Test4_GetMaterialsByModel
|
||||
Test5_GetAllMaterialsByModel
|
||||
|
||||
Debug.Print "╔" & String(78, "═") & "╗"
|
||||
Debug.Print "║" & Space(30) & "所有测试完成" & Space(30) & "║"
|
||||
Debug.Print "╚" & String(78, "═") & "╝"
|
||||
End Sub
|
||||
|
||||
' ========================================
|
||||
' 测试6: 条件提取规则展示
|
||||
' ========================================
|
||||
Sub Test6_ShowExtractionRules()
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print "测试6: 当前配置的条件提取规则"
|
||||
Debug.Print String(80, "=")
|
||||
|
||||
Dim extractor As New clsConditionExtractor
|
||||
Dim rules As Object
|
||||
Set rules = extractor.GetExtractionRules()
|
||||
|
||||
Debug.Print "【提取规则配置】"
|
||||
Dim key As Variant
|
||||
For Each key In rules.Keys
|
||||
Dim ruleInfo As Variant
|
||||
ruleInfo = rules(key)
|
||||
Debug.Print " 变量名: " & key
|
||||
Debug.Print " 源字段: " & ruleInfo(0)
|
||||
Debug.Print " 提取方法: " & ruleInfo(1)
|
||||
Debug.Print ""
|
||||
Next key
|
||||
|
||||
Debug.Print String(80, "=")
|
||||
Debug.Print ""
|
||||
End Sub
|
||||
Reference in New Issue
Block a user