我有两个 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/