refactor: support filtered data processing and optimize performance
- Add clear data button functionality to Sheet9 - Refactor AccessDataModule to safely handle filtered data with memory array optimization - Refactor BIPUploadModule to process only visible rows with screen updating optimization - Refactor ComponentInventoryCheckModule to support filtered data and improve performance - Refactor MainModule to handle filtered data and remove '代号' field - Add RestoreAppStatus helper for better application state management - Improve overall performance by using memory arrays instead of cell-by-cell operations Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'=====================================================================
|
||||
' 模块名: ComponentInventoryCheckModule
|
||||
' 功能: 部件库存核对模块 - 自动核对产品订单中"部件"类物料的库存情况
|
||||
' 说明: 当库存不足时,按订单顺序将超出部分的订单的"部件优先"字段标记为"否"
|
||||
' 功能: 部件库存核推模块 - 自动核对产品订单中"部件"类物料的库存情况
|
||||
' 特性: [已重构] 支持仅对筛选后的数据进行处理,采用内存极速读取
|
||||
'=====================================================================
|
||||
|
||||
Option Explicit
|
||||
@@ -43,6 +43,10 @@ Public Sub CheckComponentInventory()
|
||||
Dim startTime As Double
|
||||
startTime = Timer
|
||||
|
||||
' 提升性能:关闭屏幕更新和自动计算
|
||||
Application.ScreenUpdating = False
|
||||
Application.Calculation = xlCalculationManual
|
||||
|
||||
' 获取工作表对象
|
||||
Dim orderSheet As Worksheet
|
||||
Dim inventorySheet As Worksheet
|
||||
@@ -50,18 +54,21 @@ Public Sub CheckComponentInventory()
|
||||
|
||||
Set orderSheet = GetOrderSheet()
|
||||
If orderSheet Is Nothing Then
|
||||
RestoreAppStatus
|
||||
MsgBox "未找到[产品订单]工作表!", vbExclamation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Set inventorySheet = GetInventorySheet()
|
||||
If inventorySheet Is Nothing Then
|
||||
RestoreAppStatus
|
||||
MsgBox "未找到[现存量]工作表!", vbExclamation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Set bomSheet = GetBomSheet()
|
||||
If bomSheet Is Nothing Then
|
||||
RestoreAppStatus
|
||||
MsgBox "未找到[平台配置清单]工作表!", vbExclamation
|
||||
Exit Sub
|
||||
End If
|
||||
@@ -70,16 +77,30 @@ Public Sub CheckComponentInventory()
|
||||
Dim lastRow As Long
|
||||
lastRow = orderSheet.Cells(orderSheet.Rows.count, 3).End(xlUp).row
|
||||
If lastRow < 2 Then
|
||||
RestoreAppStatus
|
||||
MsgBox "[产品订单]工作表没有数据!", vbExclamation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' 【核心重构】获取筛选后的可见单元格区域 (A列)
|
||||
Dim visibleRange As Range
|
||||
On Error Resume Next
|
||||
Set visibleRange = orderSheet.Range("A2:A" & lastRow).SpecialCells(xlCellTypeVisible)
|
||||
On Error GoTo ErrorHandler
|
||||
|
||||
If visibleRange Is Nothing Then
|
||||
RestoreAppStatus
|
||||
MsgBox "当前筛选状态下没有可见的数据。", vbInformation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' 初始化BOM提取器
|
||||
Dim BomExtractor As BomExtractor
|
||||
Set BomExtractor = New BomExtractor
|
||||
BomExtractor.SetWorksheet bomSheet
|
||||
|
||||
If Not BomExtractor.LoadBomData Then
|
||||
RestoreAppStatus
|
||||
MsgBox "加载BOM数据失败:" & BomExtractor.GetErrorSummary, vbCritical
|
||||
Exit Sub
|
||||
End If
|
||||
@@ -89,16 +110,18 @@ Public Sub CheckComponentInventory()
|
||||
Set inventoryData = LoadInventoryData(inventorySheet)
|
||||
|
||||
If inventoryData.count = 0 Then
|
||||
RestoreAppStatus
|
||||
MsgBox "[现存量]工作表没有有效数据!", vbExclamation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' 读取订单数据
|
||||
' 【核心重构】传递可见区域和总行数,仅读取可见订单数据
|
||||
Dim orders As Collection
|
||||
Set orders = LoadOrderData(orderSheet)
|
||||
Set orders = LoadOrderData(orderSheet, visibleRange, lastRow)
|
||||
|
||||
If orders.count = 0 Then
|
||||
MsgBox "没有有效的订单数据!", vbExclamation
|
||||
RestoreAppStatus
|
||||
MsgBox "可见区域中没有有效的订单数据!", vbExclamation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
@@ -110,7 +133,8 @@ Public Sub CheckComponentInventory()
|
||||
Set componentDemands = CalculateComponentDemand(orders)
|
||||
|
||||
If componentDemands.count = 0 Then
|
||||
MsgBox "没有订单包含'部件'类别物料,无需处理库存!", vbInformation
|
||||
RestoreAppStatus
|
||||
MsgBox "筛选的订单中没有包含'部件'类别物料,无需处理库存!", vbInformation
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
@@ -118,17 +142,20 @@ Public Sub CheckComponentInventory()
|
||||
Dim validationWarnings As Collection
|
||||
Set validationWarnings = ValidateInventory(componentDemands, inventoryData)
|
||||
|
||||
' 按订单顺序分配库存
|
||||
' 按订单顺序分配库存并标记
|
||||
Dim stats As Statistics
|
||||
AllocateInventory orders, componentDemands, orderSheet, stats
|
||||
|
||||
' 恢复应用状态
|
||||
RestoreAppStatus
|
||||
|
||||
' 输出结果统计
|
||||
Dim elapsedTime As Double
|
||||
elapsedTime = Timer - startTime
|
||||
|
||||
Dim resultMsg As String
|
||||
resultMsg = "部件库存核对完成!" & vbCrLf & vbCrLf
|
||||
resultMsg = resultMsg & "处理订单数: " & stats.TotalOrders & vbCrLf
|
||||
resultMsg = resultMsg & "处理筛选订单数: " & stats.TotalOrders & vbCrLf
|
||||
resultMsg = resultMsg & "包含部件订单: " & stats.OrdersWithComponent & vbCrLf
|
||||
resultMsg = resultMsg & "库存充足订单: " & stats.OrdersSufficient & vbCrLf
|
||||
resultMsg = resultMsg & "库存不足订单: " & stats.OrdersInsufficient & vbCrLf
|
||||
@@ -148,37 +175,54 @@ Public Sub CheckComponentInventory()
|
||||
Exit Sub
|
||||
|
||||
ErrorHandler:
|
||||
RestoreAppStatus
|
||||
MsgBox "部件库存核对异常: " & Err.Description, vbCritical
|
||||
End Sub
|
||||
|
||||
'=====================================================================
|
||||
' 辅助过程: RestoreAppStatus
|
||||
' 功能: 恢复Excel应用程序的状态
|
||||
'=====================================================================
|
||||
Private Sub RestoreAppStatus()
|
||||
Application.Calculation = xlCalculationAutomatic
|
||||
Application.ScreenUpdating = True
|
||||
End Sub
|
||||
|
||||
'=====================================================================
|
||||
' 函数: LoadOrderData
|
||||
' 功能: 读取订单数据
|
||||
' 参数: ws - [产品订单]工作表
|
||||
' 返回: Collection - 每个元素是字典对象,包含订单信息
|
||||
'=====================================================================
|
||||
Private Function LoadOrderData(ws As Worksheet) As Collection
|
||||
Private Function LoadOrderData(ws As Worksheet, visibleRange As Range, lastRow As Long) As Collection
|
||||
Set LoadOrderData = New Collection
|
||||
|
||||
' 调整为按C列获取最后一行
|
||||
Dim lastRow As Long
|
||||
lastRow = ws.Cells(ws.Rows.count, 3).End(xlUp).row
|
||||
' 全量读入内存数组提升速度
|
||||
Dim sourceDataArr As Variant
|
||||
sourceDataArr = ws.Range("A2:F" & lastRow).value
|
||||
|
||||
Dim i As Long
|
||||
For i = 2 To lastRow
|
||||
Dim cell As Range
|
||||
Dim arrIndex As Long
|
||||
|
||||
' 仅遍历可见的单元格
|
||||
For Each cell In visibleRange
|
||||
Dim model As String
|
||||
Dim qty As Variant
|
||||
|
||||
' --- 核心修改:列索引向右移1列 ---
|
||||
model = Trim(ws.Cells(i, 3).value) ' C列: 产品型号 (原B列)
|
||||
qty = ws.Cells(i, 4).value ' D列: 产品数量 (原C列)
|
||||
' 数组索引 = Excel行号 - 1
|
||||
arrIndex = cell.row - 1
|
||||
|
||||
' 从内存数组中提取数据
|
||||
model = Trim(sourceDataArr(arrIndex, 3)) ' C列: 产品型号
|
||||
qty = sourceDataArr(arrIndex, 4) ' D列: 产品数量
|
||||
|
||||
' 跳过空行
|
||||
If model <> "" Then
|
||||
Dim order As Object
|
||||
Set order = CreateObject("Scripting.Dictionary")
|
||||
|
||||
order.Add ORDER_ROW, CLng(i)
|
||||
' 记录真实的Excel行号,用于后续库存不足时精准写入F列
|
||||
order.Add ORDER_ROW, CLng(cell.row)
|
||||
order.Add ORDER_MODEL, CStr(model)
|
||||
order.Add ORDER_QUANTITY, CDbl(IIf(IsNull(qty) Or IsEmpty(qty), 0, qty))
|
||||
order.Add ORDER_COMP_CODE, ""
|
||||
@@ -188,7 +232,7 @@ Private Function LoadOrderData(ws As Worksheet) As Collection
|
||||
|
||||
LoadOrderData.Add order
|
||||
End If
|
||||
Next i
|
||||
Next cell
|
||||
End Function
|
||||
|
||||
'=====================================================================
|
||||
@@ -327,15 +371,12 @@ Private Function ValidateInventory(componentDemands As Object, _
|
||||
|
||||
' 检查库存中是否存在该部件
|
||||
If Not inventoryData.Exists(compInv(INV_CODE)) Then
|
||||
' 库存中找不到,设置库存为0,并添加警告
|
||||
compInv(INV_STOCK) = 0
|
||||
compInv(INV_SHORTAGE) = True
|
||||
ValidateInventory.Add "部件 '" & compInv(INV_CODE) & "' 在[现存量]中未找到"
|
||||
Else
|
||||
' 设置可用库存
|
||||
compInv(INV_STOCK) = inventoryData(compInv(INV_CODE))
|
||||
|
||||
' 检查是否短缺
|
||||
If compInv(INV_DEMAND) > compInv(INV_STOCK) Then
|
||||
compInv(INV_SHORTAGE) = True
|
||||
End If
|
||||
@@ -402,8 +443,7 @@ Private Sub AllocateInventory(orders As Collection, _
|
||||
compInv(INV_STOCK) = compInv(INV_STOCK) - requiredQty
|
||||
stats.OrdersSufficient = stats.OrdersSufficient + 1
|
||||
Else
|
||||
' --- 核心修改:回填结果写入F列(第6列) ---
|
||||
' 库存不足,标记为"否"
|
||||
' --- 因为已经保存了真正的行号 ORDER_ROW, 在关闭屏幕刷新的情况下,这里直接写入是非常快的 ---
|
||||
orderSheet.Cells(order(ORDER_ROW), 6).value = "否"
|
||||
compInv(INV_STOCK) = compInv(INV_STOCK) - requiredQty
|
||||
stats.OrdersInsufficient = stats.OrdersInsufficient + 1
|
||||
|
||||
Reference in New Issue
Block a user