You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化处理11000条数据的VBA代码?

VBA仓库耗材数据处理性能优化方案

针对11000条数据的处理瓶颈,核心优化思路是减少工作表交互次数、用字典替代嵌套循环查找,具体方案如下:

一、禁用Excel界面相关开销

在代码首尾添加以下代码,避免处理过程中频繁刷新界面、触发计算或事件,大幅降低无意义的性能消耗:

' 代码开头
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

' 代码结尾
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

二、批量读写数据到内存数组

把Feuil1和Feuil2的所有数据一次性读入内存数组,所有判断、处理都在内存中完成,最后再一次性写入工作表——这是大数量级数据处理提速的核心:

Dim ws1 As Worksheet, ws2 As Worksheet
Dim data1 As Variant, data2 As Variant
Set ws1 = ThisWorkbook.Sheets("Feuil1")
Set ws2 = ThisWorkbook.Sheets("Feuil2")

' 读取Feuil1全量数据(假设数据从A1开始)
data1 = ws1.Range("A1:" & ws1.Cells(ws1.Rows.Count, ws1.Columns.Count).End(xlUp).Address).Value
' 读取Feuil2全量数据
data2 = ws2.Range("A1:" & ws2.Cells(ws2.Rows.Count, ws2.Columns.Count).End(xlUp).Address).Value

三、用字典快速识别新耗材

替代逐行嵌套循环比对,用Scripting.Dictionary存储Feuil2已有的耗材标识,遍历Feuil1时直接查字典,时间复杂度从O(n*m)降到O(n+m):

Dim existingParts As Object
Set existingParts = CreateObject("Scripting.Dictionary")
Dim i As Long

' 把Feuil2的耗材编号(假设在第1列)存入字典
For i = 2 To UBound(data2, 1) ' 跳过表头
    If Not existingParts.Exists(data2(i, 1)) Then
        existingParts.Add data2(i, 1), True
    End If
Next i

' 收集Feuil1中的新耗材(含4个描述列,假设是第2-5列)
Dim newPartsList As Collection
Set newPartsList = New Collection
For i = 2 To UBound(data1, 1)
    If Not existingParts.Exists(data1(i, 1)) Then
        newPartsList.Add Array(data1(i, 1), data1(i, 2), data1(i, 3), data1(i, 4), data1(i, 5))
    End If
Next i

' 批量写入新耗材到Feuil2末尾
If newPartsList.Count > 0 Then
    Dim writeArr() As Variant
    ReDim writeArr(1 To newPartsList.Count, 1 To 5)
    For i = 1 To newPartsList.Count
        writeArr(i, 1) = newPartsList(i)(0)
        writeArr(i, 2) = newPartsList(i)(1)
        writeArr(i, 3) = newPartsList(i)(2)
        writeArr(i, 4) = newPartsList(i)(3)
        writeArr(i, 5) = newPartsList(i)(4)
    Next i
    ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(newPartsList.Count, 5).Value = writeArr
End If

四、预分组领域数据,减少重复遍历

先把Feuil1中每个耗材对应的领域信息存入字典,再遍历Feuil2时直接查字典获取领域标记,避免对每个Feuil2耗材都遍历一遍Feuil1:

Dim partDomains As Object
Set partDomains = CreateObject("Scripting.Dictionary")
Dim domainCol As Long ' 假设Feuil1的领域列是第6列
domainCol = 6

' 遍历Feuil1,记录每个耗材的领域(用子字典去重)
For i = 2 To UBound(data1, 1)
    Dim partID As String
    partID = data1(i, 1)
    Dim currentDomain As String
    currentDomain = data1(i, domainCol)
    
    If Not partDomains.Exists(partID) Then
        partDomains.Add partID, CreateObject("Scripting.Dictionary")
    End If
    partDomains(partID)(currentDomain) = True
Next i

' 批量标记Feuil2的领域(假设Flottation标记在第6列,Cyanuration在第7列)
Dim markArr As Variant
markArr = ws2.Range(ws2.Cells(2, 6), ws2.Cells(UBound(data2, 1), 7)).Value

For i = 1 To UBound(markArr, 1)
    partID = data2(i + 1, 1) ' 对应Feuil2的第i+1行数据
    markArr(i, 1) = IIf(partDomains.Exists(partID) And partDomains(partID).Exists("Flottation"), "是", "否")
    markArr(i, 2) = IIf(partDomains.Exists(partID) And partDomains(partID).Exists("Cyanuration"), "是", "否")
Next i

' 写回标记结果
ws2.Range(ws2.Cells(2, 6), ws2.Cells(UBound(data2, 1), 7)).Value = markArr

内容的提问来源于stack exchange,提问作者Catherine Desmeules

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 13:03:26