feat: integrate inventory verification for component materials in BOM extraction
All checks were successful
NTFY Notification / notify (push) Successful in 7s
All checks were successful
NTFY Notification / notify (push) Successful in 7s
Implement inventory-based component selection logic that accumulates demand
across orders and falls back to sub-components (joint + element) when stock
is insufficient.
**Changes:**
- M04_Config: Add inventory worksheet configuration constants
- INVENTORY_SHEET_NAME = "现存量"
- INVENTORY_HEADER_ROW = 3 (headers on row 3)
- INVENTORY_COL_CODE = "B" (material code)
- INVENTORY_COL_QTY = "J" (stock quantity)
- M08_ComponentProcessor: Implement inventory tracking and verification
- Add module-level variables: g_InventoryDict, g_AccumulatedDemandDict
- Add LoadInventoryData() to load stock from [现存量] worksheet
- Add InitComponentProcessorWithInventory() for initialization with inventory
- Rewrite CheckComponentInventory() with actual inventory logic:
* Calculate cumulative demand = orderQty × bomQty + previousAccumulated
* Compare with available stock
* Return True if stock sufficient, False otherwise
* Update accumulated demand after each order
- Update ProcessComponentRecord() to accept orderQty parameter
- M09_BOMExtractor: Integrate inventory check into main workflow
- Modify ReadInputModels() to read 3 columns (orderNo, model, qty)
- Initialize component processor with inventory support
- Extract order quantity from column C and pass through call chain
- Update ProcessSingleModel() and MatchAllMaterialTypesWithValidation()
signatures to accept orderQty parameter
**Logic Example:**
- 3 orders (PO-001, PO-003, PO-006) use component A
- Each order: quantity=2, BOM qty=1, stock=5
- PO-001: cumulative=2, stock 5>=2 ✓ → return component
- PO-003: cumulative=4, stock 5>=4 ✓ → return component
- PO-006: cumulative=6, stock 5<6 ✗ → return sub-components
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -93,7 +93,11 @@ Public Function RunBOMExtraction() As String
|
||||
' 初始化各模块
|
||||
M06_ModelParser.InitModelParser g_Logger
|
||||
M07_BOMMatcher.InitBOMMatcher g_Logger
|
||||
M08_ComponentProcessor.InitComponentProcessor g_Logger
|
||||
|
||||
' 初始化部件处理器(带库存校验)- 现存量在主工作簿中
|
||||
Dim invWorkbook As Workbook
|
||||
Set invWorkbook = ThisWorkbook ' 现存量在主工作簿中
|
||||
M08_ComponentProcessor.InitComponentProcessorWithInventory g_Logger, invWorkbook
|
||||
|
||||
' 初始化映射器(新增)
|
||||
If WorksheetExists(MAPPING_SHEET_NAME) Then
|
||||
@@ -129,12 +133,14 @@ Public Function RunBOMExtraction() As String
|
||||
' 处理单个型号
|
||||
Dim productionOrderNo As String
|
||||
Dim modelString As String
|
||||
Dim orderQty As Long
|
||||
|
||||
productionOrderNo = CStr(inputModels(i, 1)) ' Column A: 生产订单号
|
||||
modelString = CStr(inputModels(i, 2)) ' Column B: 产品型号
|
||||
orderQty = CLng(inputModels(i, 3)) ' Column C: 数量
|
||||
|
||||
Dim modelResults As Collection
|
||||
Set modelResults = ProcessSingleModel(modelString, g_BOMWorkbook, g_Logger, productionOrderNo)
|
||||
Set modelResults = ProcessSingleModel(modelString, g_BOMWorkbook, g_Logger, productionOrderNo, orderQty)
|
||||
|
||||
' 合并结果
|
||||
Dim result As Variant
|
||||
@@ -295,9 +301,9 @@ Private Function ReadInputModels(ByVal ws As Worksheet) As Variant
|
||||
Exit Function
|
||||
End If
|
||||
|
||||
' 读取数据到数组(返回2列:生产订单号、产品型号)
|
||||
' 假设生产订单号在A列(列1),产品型号在colIdx列
|
||||
ReadInputModels = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, colIdx)).Value
|
||||
' 读取数据到数组(返回3列:生产订单号、产品型号、数量)
|
||||
' 假设:A列(1)=生产订单号, B列(2)=产品型号, C列(3)=数量
|
||||
ReadInputModels = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 3)).Value
|
||||
Exit Function
|
||||
|
||||
ErrorHandler:
|
||||
@@ -326,7 +332,8 @@ Private Function ProcessSingleModel( _
|
||||
ByVal modelString As String, _
|
||||
ByVal bomWb As Workbook, _
|
||||
ByVal logger As clsErrorLogger, _
|
||||
ByVal productionOrderNo As String _
|
||||
ByVal productionOrderNo As String, _
|
||||
ByVal orderQty As Long _
|
||||
) As Collection
|
||||
On Error GoTo ErrorHandler
|
||||
|
||||
@@ -348,7 +355,7 @@ Private Function ProcessSingleModel( _
|
||||
' 步骤2: 匹配所有物料类型(两阶段)
|
||||
Dim allMaterials As Collection
|
||||
Dim validation As Object
|
||||
Set allMaterials = MatchAllMaterialTypesWithValidation(params, bomWb, logger, validation)
|
||||
Set allMaterials = MatchAllMaterialTypesWithValidation(params, bomWb, logger, orderQty, validation)
|
||||
|
||||
' 步骤3: 生成输出行
|
||||
Dim remarks As String
|
||||
@@ -414,6 +421,7 @@ Private Function MatchAllMaterialTypesWithValidation( _
|
||||
ByVal params As Object, _
|
||||
ByVal bomWb As Workbook, _
|
||||
ByVal logger As clsErrorLogger, _
|
||||
ByVal orderQty As Long, _
|
||||
ByRef outValidation As Object _
|
||||
) As Collection
|
||||
On Error GoTo ErrorHandler
|
||||
@@ -457,7 +465,7 @@ Private Function MatchAllMaterialTypesWithValidation( _
|
||||
|
||||
If bomMatchResult("success") Then
|
||||
Set componentMaterials = M08_ComponentProcessor.ProcessComponentRecord( _
|
||||
ws, params, logger, bomMatchResult("rowNums")(1))
|
||||
ws, params, logger, bomMatchResult("rowNums")(1), orderQty)
|
||||
|
||||
Debug.Print " -> 返回物料数: " & componentMaterials.count
|
||||
End If
|
||||
|
||||
Reference in New Issue
Block a user