arrays - VBA Excel 大数据操作需要很长时间

标签 arrays vba memory excel

我有两个 Excel 文件。

第一个 Excel 文件包含“人员姓名”和“出席总天数”列 例如。

PersonName       TotalDays
xyz               
abcd             

另一个 Excel 文件包含人员姓名、日期和状态(出席/缺席)。

PersonName      Date      Status
xyz           1/1/2011    Present
xyz           1/1/2011    Present

我需要将相似的日期状态分组为一个,并将它们计入第一个 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

最佳答案

包含 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

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

如果您仍然认为 RAM 是问题所在,请向我们展示 AData 类型声明。

编辑:另外,永远不要在这样的循环中ReDim Preserve! ReDim Preserve 是一项非常昂贵的操作,很少需要对任何给定数组执行多次。执行 20,000 次会减慢您的代码速度。这里我将它从循环中取出,并在最后使用它一次来修剪掉未使用的元素。 (请注意我最初是如何ReDim'编辑数组以适应最大可能数量的元素。)

关于arrays - VBA Excel 大数据操作需要很长时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6134002/

相关文章:

javascript - Angularjs:从 json 对象创建一个键数组

c - 使用数组汇总调查结果

python - 循环遍历 numpy 数组,将所有数组绘制为单个图形(matplotlib)

vba - Excel VBA排序数组函数

linux - 从 bash 将特定的十六进制模式写入文件

arrays - 在 Apps 脚本中从数组创建新数组并将值推送到不同工作表的最佳方法是什么?

Excel VBA 位控制

excel - 如何在 Excel 中的文本文件中搜索特定行

windows - 用于 64 位 Windows 的 LeakDiag?

C - 获取IPC共享内存信息