VBA Excel大数据操作永远占用

Aja*_*ayR 2 memory arrays excel vba excel-vba

我有两个excel文件.

第一个excel文件包含Person Name和Total Days Present列Ex.

PersonName       TotalDays
xyz               
abcd             
Run Code Online (Sandbox Code Playgroud)

另一个excel文件包含人名,日期和状态(存在/不存在).

PersonName      Date      Status
xyz           1/1/2011    Present
xyz           1/1/2011    Present
Run Code Online (Sandbox Code Playgroud)

我需要将类似的日期状态分组为一个,并将它们计入第一个excel文件中进行更新.

我在第一个文件中有大约100行,其中第二个文件中有20,000行,我需要检查.因此,为了加快速度,我将第二个文件中的所有行加载到一个数组中并读取它们以计算每个条目是否正常工作.

问题是,在Windows中需要大量内存,所以很多应用程序会自动打开并且系统几乎挂起.

是否有任何替代方法可以在没有内存问题和快速处理的情 我遇到了Scripting.Dictionary,但不确定它是否会占用更少的内存.

编辑 我尝试使用redim保留和20,000个大小的静态数组,在这两种情况下都会出现同样的问题.

编辑

lblStatus.Caption = "Loading to memory"
 Dim ArrAuditData() As AData
 Dim TotalLookUpCount As Integer
 For J = 1 To 50000

 If lookUpRange.Cells(J, cmbChoice.ListIndex) = "Fail" Then
  ReDim Preserve ArrAuditData(J) As AData
    ArrAuditData(TotalLookUpCount).AuditType = lookUpRange.Cells(J, cmdAudit2.ListIndex)
    ArrAuditData(TotalLookUpCount).TransTime = lookUpRange.Cells(J, cmbChoice.ListIndex - 1)
    ArrAuditData(TotalLookUpCount).AuditValue = lookUpRange.Cells(J, cmbChoice.ListIndex)
    ArrAuditData(TotalLookUpCount).Slno = lookUpRange.Cells(J, 0)

    TotalLookUpCount = TotalLookUpCount + 1
ElseIf lookUpRange.Cells(J, cmbChoice.ListIndex) = "" And J > 4 Then Exit For

    End If
    DoEvents
  Next
Run Code Online (Sandbox Code Playgroud)

Jea*_*ett 5

包含4个变量的20,000个元素的数组每个将占用不到2 MB的RAM.我不认为记忆与你的问题有任何关系 - 除非你碰巧使用的是一台带有2 MB RAM的旧电脑或类似的东西.

您的代码如此繁重的一个更可能的原因是您正在循环遍历单元格.VBA和Excel工作表数据之间的每次通信都会产生很大的开销,当您一次引用一个单元格时,这会增加.在您的情况下,您的循环最多可以执行200,000个单独的单元格引用.

相反,您应该将所有数据一次加载到Variant数组中,然后遍历该数组,如下所示.这明显更快(即使这会占用更多内存,而不是更少;但同样,我认为内存不是你的问题).

lblStatus.Caption = "Loading to memory"
Dim ArrAuditData() As AData
Dim varTemp As Variant
Dim TotalLookUpCount As Integer

' Load everything into a Variant array. 
varTemp = lookUpRange

ReDim ArrAuditData(1 To UBound(varTemp, 1)) As AData

For J = 1 To UBound(varTemp, 1)

    If varTemp(J, cmbChoice.ListIndex) = "Fail" Then

        ArrAuditData(TotalLookUpCount).AuditType = varTemp(J, cmdAudit2.ListIndex)
        ArrAuditData(TotalLookUpCount).TransTime = varTemp(J, cmbChoice.ListIndex - 1)
        ArrAuditData(TotalLookUpCount).AuditValue = varTemp(J, cmbChoice.ListIndex)
        ArrAuditData(TotalLookUpCount).Slno = varTemp(J, 0)
        TotalLookUpCount = TotalLookUpCount + 1

    ElseIf varTemp(J, cmbChoice.ListIndex) = "" And J > 4 Then
        Exit For

    End If

    DoEvents
Next

ReDim Preserve ArrAuditData(TotalLookUpCount) As AData
Run Code Online (Sandbox Code Playgroud)

如需进一步阅读,请查看这篇旧的但仍然相关的文章:http://www.avdf.com/apr98/art_ot003.html

如果你仍然认为RAM是问题,那么请告诉我们AData类型声明.

编辑:此外,永远不要ReDim Preserve在这样的循环内!ReDim Preserve是一个非常昂贵的操作,很少需要在任何给定的阵列上多次执行.这样做20,000次会降低你的代码速度.在这里,我将它从循环中取出,并在最后使用它一次以修剪掉未使用的元素.(请注意我最初是如何ReDim编辑数组以适应最大可能数量的元素.)