我有一个300k行的电子表格BO2009。只有一列包含公式其他列都是粘贴值,因此只需要在整个工作簿中计算一个公式。下面是公式:=IFERROR(INDEX('RE2009'!H:H,MATCH('BO2009'!A2,'RE2009'!A:A,0)),1)
此公式被复制到工作表的底部,因此300k次。
RE2009表有180k行。 'RE2009'!H:H包含十进制数字和'RE2009'!A:A,'BO2009'!A:A包含ID代码 - 数字和字母的8个字符组合。两个'RE2009'!A:A,'BO2009'!A:A被格式化为通用。
我一直使用INDEX / MATCH,虽然我的大部分电子表格都不是300k长,但典型的是60k-100k。现在,为了完成计算,我需要花几分钟的时间将我的CPU投入99%的Excel。
这是正常的吗?有没有办法提高Excel的性能?
最重要的是,我得到的结果不准确:查找产生错误而不是0.3。
正如所建议的那样,我已将BO2009表格过滤到80k行,但仍然存在相同的问题。我决定特别关注一个公式:=IFERROR(INDEX('RE2009'!H:H,MATCH('BO2009'!A108661,'RE2009'!A:A,0)),1)
以确定它是否正常工作。它使用MATCH函数寻找的ID是查找数组中的第3个条目,但它仍然无法生成正确的值(0.3)
答案 0 :(得分:1)
您似乎找到了一个令人满意的问题解决方案,但出于好奇心的考虑,您可能希望将此时间与您当前基于公式的解决方案进行对比,以确定速度是否有可测量的增加。 / p>
Sub index_match_mem()
Dim v As Long, vVALs As Variant, vTMP As Variant
Dim dRE2009 As Object
Debug.Print Timer
Application.ScreenUpdating = False
With Worksheets("RE2009")
With .Cells(1, 1).CurrentRegion
With .Resize(.Rows.Count, 8)
vTMP = .Cells.Value2
End With
End With
End With
Set dRE2009 = CreateObject("Scripting.Dictionary")
dRE2009.CompareMode = vbTextCompare
For v = LBound(vTMP, 1) To UBound(vTMP, 1)
If Not dRE2009.exists(vTMP(v, 1)) Then _
dRE2009.Add Key:=vTMP(v, 1), Item:=vTMP(v, 8)
Next v
With Worksheets("BO2009")
With .Cells(1, 1).CurrentRegion
With .Resize(.Rows.Count - 1, 2).Offset(1, 0)
vVALs = .Cells.Value2
For v = UBound(vVALs, 1) To LBound(vVALs, 1) Step -1
If dRE2009.exists(vVALs(v, 1)) Then
vVALs(v, 2) = dRE2009.Item(vVALs(v, 1))
Else
vVALs(v, 2) = 1
End If
Next v
.Cells = vVALs
End With
End With
End With
dRE2009.RemoveAll: Set dRE2009 = Nothing
Application.ScreenUpdating = True
Debug.Print Timer
End Sub
这将在 BO2009 工作表的B列中生成静态值。以秒为单位的经过的开始和停止将在VBE的立即窗口(Ctrl + G)
中