更快的方式来运行小的VBAmacros?
我正在使用这个需要运行近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").Range("G" & i).Value = val1 Sheets("sheet1").Range("O" & i).Value = val2
我不知道为什么现在这么久了。 是因为我把数据从一个表格移动到另一个表格? 也许使用一个variant
会更快?
你有什么指示我可以做些什么来加快速度? (这个循环完成300-400次,所以总的时间太长。)
(不知道这里是否有更好的地方,或在“代码评论”,让我知道如果我错了)
感谢您的帮助!
[编辑]这是您的build议更改后的循环,谢谢大家,这减less了30%的时间。 不过对我来说还是太长了,我已经注意到了你的build议,把表格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 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
并进一步减less(除非你需要在其他地方使用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
有关如何避免使用select / activate和正确使用variables的更多信息,请参见:
如何避免在Excel VBAmacros中使用select
- 不要使用。select(无论如何,你似乎没有对select做任何事情)
- 将工作表存储在两个variables中:dim oSheet1作为工作表; 设置oSheet =表格(“Sheet1”)。 或者使用代码名称:Sheet1和Sheet2(最可能)
- 使用.Cells()比使用.Range()避免string连接可能更快
- 如果有的话,尽可能避免变体,并声明types安全variables
摆脱Sheets("sheet1").Select
– 它没有在你发布的代码中做任何事情,如果这是一个循环,它将不会重复。
摆脱中间variablesvar1
和var2
并直接在单元格之间赋值。
使用With
块和存储的对象引用可以避免对象的重复取消引用。 您正在Excel Sheets集合中执行重复的对象查找。
使用.Cells
与数字索引,而不是与string连接和alpha引用的范围 – Excel只需将它们转换回来。
caching要重复使用的中间值(即Sheets("sheet1").Range("A" & 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
如果这还不够快,可以考虑将整个工作范围拖入一个Variant
数组中,然后使用它。 当你完成后,把整个事情写回来。
正如@ScottCraner所说,最小化对应用程序的调用是加快VBAmacros的关键之一。 例如,一次拷贝整个列而不是逐个单元格:
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