excel - VBA用数组/字典加速For循环?
问题描述
我正在尝试加快我的 For 循环,因为对于一些具有多行/多列的工作表需要很长时间。已经用数组和字典尝试了一些东西,但我不明白。如何优化此代码以检查单元格的内容并将新计算的内容(如果为真)插入其他单元格?非常感谢!
Pos = 1
lngWS = ws_Table.ListRows.Count
For Pos = Pos To lngWS
If ws_Table.DataBodyRange(Pos, Column_Date).Value2 <> vbNullString And _
ws_Table.DataBodyRange(Pos, Column_Verify).Value2 <> "OK" Then
ws_Table.DataBodyRange(Pos, Column_Year).Value2 = Year(ws_Table.DataBodyRange(Pos, Column_Date).Value2)
ws_Table.DataBodyRange(Pos, Column_Month).Value2 = Format(ws_Table.DataBodyRange(Pos, Column_Date).Value2, "MMMM")
ws_Table.DataBodyRange(Pos, Column_Compare_1).FormulaLocal = "=1+1"
ws_Table.DataBodyRange(Pos, Column_Compare_1).Value2 = ws_Table.DataBodyRange(Pos, Column_Compare_1).Value2
ws_Table.DataBodyRange(Pos, Column_Compare_2).FormulaLocal = "=2+2"
ws_Table.DataBodyRange(Pos, Column_Compare_2).Value2 = ws_Table.DataBodyRange(Pos, Column_Compare_2).Value2
End If
Next Pos
解决方案
为了加快处理范围内的数据,将数据从范围复制到数组,处理数组,然后将数据复制回范围要快得多。
这适用于具有多个单元格的范围:
Dim Lst as Variant ' The array
Dim Idx as Long ' The row index
' First copy the range to an array
Lst = ws_Table.DataBodyRange
For Idx = LBound(Lst) To UBound(Lst)
' Change the rows in the array here, for example:
' Lst(Idx, 1) = Lst(Idx, 1) * 3
'
' Be aware that you might need to recreate your formulas, as
' it is the results of the forumalas that are copied to the array:
' Lst(Idx, 2) = "=1+1"
Next Idx
' Then copy the array back to the range
ws_Table.DataBodyRange = Lst
处理数组快速的原因是因为它是内存中的数据结构,而列表对象、范围或单元格是 COM 对象。引用 COM 对象需要很长时间。
我推荐的方法只引用一个 COM 对象 2 或 3 次,而您的示例中使用的方法或 Tim Williams 提出的解决方案,为范围内的每一行引用一个 COM 对象多次。
推荐阅读
- git - 尝试使用 powershell 下载 git repo 时出现“(406)不可接受”
- c++ - linux命令查看/列出上次对文件所做的更改
- php - 试图获取非对象的属性'user_name':在单页中获取单行的数据
- java - 如何在 Android 中使用我所在地区的回历日期?
- django - 将 DateTimeField 与今天的日期进行比较的 Django 过滤器不起作用
- javascript - 如何检查数组的值并根据条件删除一些属性?
- c# - 可访问性不一致:参数类型“ICourseRepository”比方法 ASP.NET Core MVC 更难访问
- git - 我怎样才能让 .gitignore exclude 工作以忽略 /AppData 中的所有内容,但仍然索引我的 /AppData/Roaming/doublecmd/doublecmd.xml?
- python - 如何根据数据框中的行值和列值删除行?
- javascript - 加载属性延迟加载不适用于本地图像