Excel 运行小VBA宏的更快方法?
我正在使用这个小代码,它需要将近250ms的时间来运行:I是行上循环的增量Excel 运行小VBA宏的更快方法?,excel,vba,performance,range,Excel,Vba,Performance,Range,我正在使用这个小代码,它需要将近250ms的时间来运行:I是行上循环的增量 Sheets("sheet1").Select val1 = Sheets("sheet2").Range("D" & Sheets("sheet1").Range("A" & i).Value + 1) val2 = Sheets("sheet2").Range("E" & Sheets("sheet1").Range("A" & i).Value + 1) Sheets("sheet1
Sheets("sheet1").Select
val1 = Sheets("sheet2").Range("D" & Sheets("sheet1").Range("A" & i).Value + 1)
val2 = Sheets("sheet2").Range("E" & Sheets("sheet1").Range("A" & i).Value + 1)
Sheets("sheet1").Range("G" & i).Value = val1
Sheets("sheet1").Range("O" & i).Value = val2
我不知道为什么要花这么长时间。
是因为我将数据从一张图纸移动到另一张图纸吗?也许使用变体会更快
你有什么建议可以让我做得更快吗?此循环执行300-400次,因此总时间太长
不确定这在这里或代码评审中是否有更好的位置,如果我错了,请告诉我
谢谢你的帮助
[编辑]
这是您建议的更改后的循环,谢谢大家,它将花费的时间减少了30%。
然而,这对我来说还是太长了,我已经注意到您的建议,将所有sh1和SH2表复制到一个表中,我将尝试实现这一点。如果你有其他想法,请随时通知我=
i = 2
While sh1.Cells(i, 1).Value <> ""
val5 = sh1.Cells(i, 1).Value2 + 1
With sh2
val3 = .Cells(val5, 4).Value2
val4 = .Cells(val5, 5).Value2
End With
With sh1
.Cells(i, 7).Value2 = val3
.Cells(i, 15).Value2 = val4
End With
i = i + 1
Wend
不要使用。选择之后,您似乎不会对选择执行任何操作
将工作表存储在两个变量中:dim oSheet1作为工作表;设置oSheet=SheetsSheet1。或者使用代号:Sheet1和Sheet2
使用.Cells可能比使用.Range更快,以避免字符串串联
如果有的话,尽量避免变量,并声明类型安全变量
您的代码可以修改为:
Dim sh as Worksheet, sh2 as Worksheet
Dim val1, val2
Set sh = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
With sh
val1 = sh2.Cells(.Cells(1, i).Value2 + 1, 4)
val2 = sh2.Cells(.Cells(1, i).Value2 + 1, 5)
.Cells(i, 7).Value = val1
.Cells(i, 15).Value = val2
End With
并进一步降低,除非您需要在其他地方使用val1和val2:
Dim sh as Worksheet, sh2 as Worksheet, r as Long
Set sh = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
With sh
r = .Cells(1, i).Value2 + 1
.Cells(i, 7).Value = sh2.Cells(r, 4).Value2
.Cells(i, 15).Value = sh2.Cells(r, 5).Value2
End With
有关如何避免使用选择/激活以及正确使用变量的其他信息,请参见:
去掉Sheetssheet1.Select-它在您发布的代码中没有做任何事情,如果它在循环中,它将重复什么也不做
去掉中间变量var1和var2,直接在单元格之间赋值
与块和存储的对象引用一起使用,以避免重复取消引用对象。您正在Excel工作表集合中重复执行对象查找
使用带数字索引的.Cells,而不是带字符串连接和字母引用的范围-Excel只需将它们转换回
缓存将重复使用的中间值,即Sheetssheet1.RangeA和i.Value+1
更像是:
'Outside loop:
Dim source As Worksheet
Dim target As Worksheet
Set source = Sheets("sheet2")
Set target = Sheets("sheet1")
'...
'Inside loop:
Dim targetRow As Long
With target
targetRow = .Cells(i, 1).Value + 1
.Cells(i, 7).Value = source.Cells(targetRow, 4)
.Cells(i, 15).Value = source.Cells(targetRow, 5)
End With
如果这还不够快,考虑把整个工作范围拉到一个不同的数组中,然后用它工作。完成后,一次写回整个过程。
正如@ScottCraner评论的那样,最小化对应用程序的调用是加快VBA宏速度的关键之一。例如,一次复制整个列,而不是逐单元格复制:Dim c As Long
c = Sheet2.Cells(2, 1).End(xlDown).Row - 1 ' count = last row - first row - 1
Application.ScreenUpdating = False ' optional
Sheet1.Cells(2, 7).Resize(c).Value2 = Sheet2.Cells(2, 4).Resize(c).Value2
Sheet1.Cells(2, 15).Resize(c).Value2 = Sheet2.Cells(2, 5).Resize(c).Value2
Application.ScreenUpdating = True ' optional
您将希望通过将所有内容加载到内存数组中来减少对工作表的调用次数。为什么将值存储到变量中,而只在下一行使用这些变量?您可以将Sheetssheet1.RangeG&i.Value=Sheetssheet2.RangeD&Sheetssheet1.RangeA&i.Value+1设置为Sheetssheet1.RangeG&i.Value,但将其与其他建议(如内存中的数组)相结合可以显示循环代码吗?有很多方法可以通过一次复制几个细胞而不是一个接一个的细胞来提高速度。它刚刚从250毫秒下降到170毫秒,谢谢!Value和Value2之间有区别吗?请注意,在上面的第二个代码段中,使用sh2.Cellsr、4.Value2和sh2.Cellsr、5.Value2,这可能会有更大的改进。