如何解决VBA 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行。因此,为了使其更快,我将第二个文件中的所有行加载到Array中,并读取它们以计算每个条目的正确运行。
问题是,它占用大量内存,因此在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
解决方法
包含四个Variant的20,000个元素的阵列将占用不到2 MB的RAM。我认为内存与您的问题无关-除非您碰巧正在使用带有2 MB RAM或类似内存的旧计算机。
代码如此繁重的一个更可能的原因是,您在单元格中循环。 VBA和Excel工作表数据之间的每次通信都存在大量开销,并且当您一次引用多个单元格时,这会加起来。在您的情况下,您的循环最多可以进行200,000个单独的单元格引用。
相反,您应该一次将所有数据加载到“ 3”数组中,然后遍历该数组,如下所示。这显着提高了速度(即使这会使用更多的内存,而不是更少;不过,我认为内存不是您的问题)。
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次会减慢您的代码速度。在这里,我将其从循环中取出,并在末尾仅使用一次以修剪未使用的元素。 (请注意,我最初是如何对数组进行“ 8”运算以适合最大可能数量的元素。)
,我建议使用另一种方法。
如果我正确解释了这个问题:
您想计算每个人的天数为“当前”或“不存在”
第一个文件(称为file1)每人(约100人)包含一行
第二个文件(称为文件2)每人每天包含一行(100个人和200天= 20000行)
所需的输出是文件1中的两个额外列,即\“ Present \”的计数和\“ Absent \”的计数
我要使用的方法是使用COUNTIF(或者如果您使用Excel 2007或更高版本的COUNTIFS)
假设
file1在Sheet1上包含一个名为StatusReport的表,列A =名称,B =当前,C =不存在
每个唯一名称一行
file2在Sheet1上包含一个名为StatusData的表,列A =名称,B =日期,C =状态
每个日期每个名称一行
Excel 2007或2010解决方案
file1单元格B2
=COUNTIFS(file2.xlsx!StatusData[Name],[Name],file2.xlsx!StatusData[Status],StatusReport[[#Headers],[Present]])
file1单元格C2
=COUNTIFS(file2.xlsx!StatusData[Name],[Absent]])
Excel 2003解决方案
向file2 StatusData表中添加一个额外的列D(称为代码)
=Sheet1!$A2&\"_\"&Sheet1!$C2
file1单元格B2
=COUNTIF([file2.xls]Sheet1!$D:$D,Sheet2!$A2&\"_\"&Sheet2!$B$1)
file1单元格C2
=COUNTIF([file2.xls]Sheet1!$D:$D,Sheet2!$A2&\"_\"&Sheet2!$C$1)
注意:虽然这些公式给出的结果相同,但是如果不快的话,COUNTIFS + Table引用的版本会在2010年变得不那么有趣(我对大约300,000行的测试在几秒钟内进行了更新)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。