refactor: implement two-phase BOM matching error validation with warning support
All checks were successful
NTFY Notification / notify (push) Successful in 4s

Major refactoring of BOM matching error handling mechanism to separate
matching phase from validation phase, enabling cross-worksheet validation
and non-blocking warnings.

Changes:
- clsErrorLogger: Add warning support
  - Add RecordWarning() method for non-blocking issues
  - Add HasWarnings and HasIssues properties
  - Update PrintReport() to show errors and warnings with color coding
  - Add "Type" column to distinguish errors from warnings

- M09_BOMExtractor: Implement two-phase validation
  - Replace MatchAllMaterialTypes() with MatchAllMaterialTypesWithValidation()
  - Add ValidateAllMatchResults() for unified cross-worksheet validation
  - Phase 1 (Collection): Gather all worksheet matches without recording errors
  - Phase 2 (Validation): Validate all results with special rules for components
  - Phase 3 (Generation): Create final material collection based on validation
  - Add ToArray() helper for Collection to Array conversion

- Enhanced component/joint/element validation:
  - Support warnings for non-blocking conflicts (e.g., component + joint both matched)
  - Better cross-validation between "部件", "接头", "弹性元件" worksheets
  - Distinguish between errors (blocking) and warnings (non-blocking)

- Documentation updates:
  - Update BOM匹配错误判断机制详解.md to v2.0
  - Document two-phase verification approach
  - Add warning scenarios and handling

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-02-12 15:36:23 +08:00
parent 68798920d6
commit 8271958adf
3 changed files with 1701 additions and 54 deletions

View File

@@ -5,9 +5,11 @@
Option Explicit
Private pErrors As Collection
Private pWarnings As Collection
Private Sub Class_Initialize()
Set pErrors = New Collection
Set pWarnings = New Collection
End Sub
' 记录错误
@@ -21,35 +23,83 @@ Public Property Get HasErrors() As Boolean
HasErrors = (pErrors.count > 0)
End Property
' 是否有警告
Public Property Get HasWarnings() As Boolean
HasWarnings = (pWarnings.count > 0)
End Property
' 是否有问题(错误或警告)
Public Property Get HasIssues() As Boolean
HasIssues = (pErrors.count > 0 Or pWarnings.count > 0)
End Property
' 记录警告
Public Sub RecordWarning(RowIndex As Long, SourceFunc As String, WarningType As String, Desc As String, Context As String)
pWarnings.Add Array(RowIndex, SourceFunc, WarningType, Desc, Context)
End Sub
'
Public Sub PrintReport(targetWb As Workbook)
If pErrors.count = 0 Then Exit Sub
If pErrors.count = 0 And pWarnings.count = 0 Then Exit Sub
Dim ws As Worksheet
Set ws = targetWb.Worksheets.Add(After:=targetWb.Worksheets(targetWb.Worksheets.count))
ws.Name = "错误报告_" & Format(Now, "hhmmss")
'
ws.Range("A1:E1").Value = Array("原表行号", "来源模块", "错误类型", "详细描述", "原始数据")
ws.Range("A1:E1").Font.Bold = True
ws.Range("A1:E1").Interior.Color = RGB(255, 200, 200)
' ("类型")
ws.Range("A1:F1").Value = Array("类型", "原表行号", "来源模块", "错误类型", "详细描述", "原始数据")
ws.Range("A1:F1").Font.Bold = True
ws.Range("A1:F1").Interior.Color = RGB(217, 217, 217)
' 准备输出数组
Dim totalIssues As Long
totalIssues = pErrors.count + pWarnings.count
Dim arrOutput() As Variant
ReDim arrOutput(1 To pErrors.count, 1 To 5)
ReDim arrOutput(1 To totalIssues, 1 To 6)
Dim i As Long
Dim vItem As Variant
'
For i = 1 To pErrors.count
vItem = pErrors(i)
arrOutput(i, 1) = vItem(0)
arrOutput(i, 2) = vItem(1)
arrOutput(i, 3) = vItem(2)
arrOutput(i, 4) = vItem(3)
arrOutput(i, 5) = vItem(4)
arrOutput(i, 1) = "错误"
arrOutput(i, 2) = vItem(0)
arrOutput(i, 3) = vItem(1)
arrOutput(i, 4) = vItem(2)
arrOutput(i, 5) = vItem(3)
arrOutput(i, 6) = vItem(4)
Next i
ws.Range("A2").Resize(UBound(arrOutput, 1), 5).Value = arrOutput
'
For i = 1 To pWarnings.count
vItem = pWarnings(i)
arrOutput(pErrors.count + i, 1) = "警告"
arrOutput(pErrors.count + i, 2) = vItem(0)
arrOutput(pErrors.count + i, 3) = vItem(1)
arrOutput(pErrors.count + i, 4) = vItem(2)
arrOutput(pErrors.count + i, 5) = vItem(3)
arrOutput(pErrors.count + i, 6) = vItem(4)
Next i
ws.Range("A2").Resize(totalIssues, 6).Value = arrOutput
'
If totalIssues > 0 Then
Dim rngErrors As Range
Dim rngWarnings As Range
If pErrors.count > 0 Then
Set rngErrors = ws.Range("A2").Resize(pErrors.count, 6)
rngErrors.Interior.Color = RGB(255, 200, 200)
End If
If pWarnings.count > 0 Then
Set rngWarnings = ws.Range("A" & (pErrors.count + 2)).Resize(pWarnings.count, 6)
rngWarnings.Interior.Color = RGB(255, 255, 200)
End If
End If
ws.Columns.AutoFit
End Sub