refactor: improve BOM library matching logic with column-name-based lookup
All checks were successful
NTFY Notification / notify (push) Successful in 3s

- Add BOM library column name constants (名称, 编码, 数量, etc.)
- Add GetBOMConditionFields() and IsConditionField() utility functions
- Refactor ExtractMaterialInfo to use column names instead of hardcoded positions
- Refactor ExtractSingleSubComponent to use column names for 接头/弹性元件
- Refactor ExtractComponentInfo to use column names
- Improve MatchAllMaterialTypes to iterate all worksheets dynamically
- Add debug logging for troubleshooting

This fix resolves issues where worksheets with non-standard column counts
(like 表壳, 罩壳) could not extract material information properly.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-02-12 13:59:48 +08:00
parent c204a8878e
commit 867b1979af
4 changed files with 181 additions and 104 deletions

View File

@@ -195,27 +195,38 @@ Private Function ExtractComponentInfo( _
Dim componentInfo As Object
Set componentInfo = CreateObject("Scripting.Dictionary")
componentInfo("materialType") = componentType
' 通过列名常量查找物料信息列
Dim nameKey As String, codeKey As String, qtyKey As String
nameKey = LCase(BOMLIB_COL_NAME)
codeKey = LCase(BOMLIB_COL_CODE)
qtyKey = LCase(BOMLIB_COL_QTY)
' 查找物料名称列
If headerMap.Exists("物料名称") Then
componentInfo("materialName") = Trim(CStr(wsComponent.Cells(rowNum, headerMap("物料名称")).Value))
If headerMap.Exists(nameKey) Then
Dim nameCol As Long
nameCol = headerMap(nameKey)
componentInfo("materialName") = Trim(CStr(wsComponent.Cells(rowNum, nameCol).Value))
Else
componentInfo("materialName") = ""
End If
' 查找物料编码列
If headerMap.Exists("物料编码") Then
componentInfo("materialCode") = Trim(CStr(wsComponent.Cells(rowNum, headerMap("物料编码")).Value))
If headerMap.Exists(codeKey) Then
Dim codeCol As Long
codeCol = headerMap(codeKey)
componentInfo("materialCode") = Trim(CStr(wsComponent.Cells(rowNum, codeCol).Value))
Else
componentInfo("materialCode") = ""
End If
' 查找物料数量列
If headerMap.Exists("物料数量") Then
If headerMap.Exists(qtyKey) Then
Dim qtyCol As Long
qtyCol = headerMap(qtyKey)
Dim qtyValue As Variant
qtyValue = wsComponent.Cells(rowNum, headerMap("物料数量")).Value
qtyValue = wsComponent.Cells(rowNum, qtyCol).Value
If IsNumeric(qtyValue) Then
componentInfo("materialQty") = CLng(qtyValue)
Else
@@ -304,9 +315,10 @@ End Function
' 输出:
' Object (Scripting.Dictionary) - 子件物料信息
'
' 注意:
' - 列名格式: "接头_物料名称"、"接头_物料编码"、"接头_物料数量"
' - 或者: "子件1_物料名称"、"子件1_物料编码"等
' 逻辑:
' - 通过列名查找子部件信息(不依赖列位置)
' - 接头: 查找"接头名称"、"接头编码"、"接头数量"
' - 弹性元件: 查找"弹性元件名称"、"弹性元件编码"、"弹性元件数量"
' ------------------------------------------------------------------------------
Private Function ExtractSingleSubComponent( _
ByVal wsComponent As Worksheet, _
@@ -318,36 +330,53 @@ Private Function ExtractSingleSubComponent( _
Dim subInfo As Object
Set subInfo = CreateObject("Scripting.Dictionary")
subInfo("materialType") = subComponentType
' 查找子件物料名称列
Dim nameColKey As String
nameColKey = LCase(subComponentType & "_物料名称")
' 根据子件类型确定列名
Dim nameKey As String, codeKey As String, qtyKey As String
If headerMap.Exists(nameColKey) Then
subInfo("materialName") = Trim(CStr(wsComponent.Cells(rowNum, headerMap(nameColKey)).Value))
If subComponentType = "接头" Then
nameKey = LCase(BOMLIB_COL_JOINT_NAME)
codeKey = LCase(BOMLIB_COL_JOINT_CODE)
qtyKey = LCase(BOMLIB_COL_JOINT_QTY)
ElseIf subComponentType = "弹性元件" Then
nameKey = LCase(BOMLIB_COL_ELEMENT_NAME)
codeKey = LCase(BOMLIB_COL_ELEMENT_CODE)
qtyKey = LCase(BOMLIB_COL_ELEMENT_QTY)
Else
' 未知类型,返回空信息
subInfo("materialName") = ""
subInfo("materialCode") = ""
subInfo("materialQty") = 0
subInfo("remarks") = "未知子件类型: " & subComponentType
Set ExtractSingleSubComponent = subInfo
Exit Function
End If
' 提取物料名称
If headerMap.Exists(nameKey) Then
Dim nameCol As Long
nameCol = headerMap(nameKey)
subInfo("materialName") = Trim(CStr(wsComponent.Cells(rowNum, nameCol).Value))
Else
subInfo("materialName") = ""
End If
' 查找子件物料编码
Dim codeColKey As String
codeColKey = LCase(subComponentType & "_物料编码")
If headerMap.Exists(codeColKey) Then
subInfo("materialCode") = Trim(CStr(wsComponent.Cells(rowNum, headerMap(codeColKey)).Value))
' 提取物料编码
If headerMap.Exists(codeKey) Then
Dim codeCol As Long
codeCol = headerMap(codeKey)
subInfo("materialCode") = Trim(CStr(wsComponent.Cells(rowNum, codeCol).Value))
Else
subInfo("materialCode") = ""
End If
' 查找子件物料数量
Dim qtyColKey As String
qtyColKey = LCase(subComponentType & "_物料数量")
If headerMap.Exists(qtyColKey) Then
' 提取物料数量
If headerMap.Exists(qtyKey) Then
Dim qtyCol As Long
qtyCol = headerMap(qtyKey)
Dim qtyValue As Variant
qtyValue = wsComponent.Cells(rowNum, headerMap(qtyColKey)).Value
qtyValue = wsComponent.Cells(rowNum, qtyCol).Value
If IsNumeric(qtyValue) Then
subInfo("materialQty") = CLng(qtyValue)
Else