更快的方式来运行小的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议,把表格sh1sh2全部复制到一张表中,我会尽力去实现。 如果您有其他想法,请保留我的发帖=)

 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(除非你需要在其他地方使用val1val2

 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 – 它没有在你发布的代码中做任何事情,如果这是一个循环,它将不会重复。

摆脱中间variablesvar1var2并直接在单元格之间赋值。

使用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