2011-02-17 33 views
3

在我的excel VBA代码中,我需要将一些数据从一个范围移动到另一个工作表。迭代100个单元需要很长的时间

截至目前,我通过迭代的范围,并复制值是这样的:

For offset = 0 To 101 
     ActiveWorkbook.Sheets(Sheet).Range("C3").offset(offset, 0).Value = ActiveSheet.Range("D4").offset(offset, 0).Value 
    Next offset 

但是,它需要几乎一分钟,重复和复制值的100个单元。

我会更好地使用Copy-Paste以编程方式,还是有办法一次复制整个范围?类似:

ActiveWorkbook.Sheets(Sheet).Range("C3:C102").Value = ActiveSheet.Range("D4:D104").Value 

回答

2

,您可以一次读取整个范围为Variant数组,然后将它写回另一个范围。这也是快速,无闪烁的,并且有额外的好处,如果你是这样倾向的,你可以对数据进行一些操作。

Dim varDummy As Variant 
varDummy = ActiveSheet.Range("D4:D104") 
' Can insert code to do stuff with varDummy here 
Workbook.Sheets(Sheet).Range("C3:C103") = varDummy 

这我学到了艰辛的道路:避免复制/粘贴如果可能的话!复制并粘贴使用剪贴板。其他程序可能会在您的代码运行时从剪贴板读取/写入,这会导致无法预料的结果。

此外,最小化VBA和Excel之间的交互次数通常是一个好主意,因为它们很慢。在循环中进行这样的交互会慢得多。

1
Columns("A:Z").Select 
Selection.Copy 
Sheets("Sheet2").Select 
Range("A1").Select 
ActiveSheet.Paste 

这将列A从表1复制到Z到表2。这是由录制宏生成。您也可以将其应用于如下所示的范围:

Range("D4:G14").Select 
Selection.Copy 
Sheets("Sheet2").Select 
Range("D4").Select 
ActiveSheet.Paste 

这是类似于您之后的事情吗?

如果您需要任何特定的内容并且您可以手动执行(例如复制和粘贴),请记录该宏以获取其VBA代码。

+0

我希望不需要复制粘贴,因为当你这样做时,你的工作表视图从源工作表跳转到目标工作表。我需要重复这个总共20次,最后我会盯着excel闪烁的表单。但我会尝试一下,如果性能明显加快,我就不得不去做。 – xbonez 2011-02-17 22:35:48

+0

有趣的是,仅需100行就需要45秒。我有一个宏,可以一次遍历1000行,并且可以从另一个电子表格中更新大约50个左右的宏,并且它在几秒钟内都可以工作。 – joshhendo 2011-02-18 09:28:13

+1

重要注意事项计入Application.Calculation。如果打开了计算,则单元格中输入的每个值都会触发重新计算(每个工作簿打开)。 – CaBieberach 2011-02-19 12:18:35

2

所以,愚蠢的我没有尝试之前张贴在这里。尽可能快地复制粘贴

Workbook.Sheets(Sheet).Range("C3:C102").Value = ActiveSheet.Range("D4:D104").Value 

其不张的切换:显然,我可以为整个范围内移动数据这种方式。 使用for循环遍历范围需要大约45个100个单元,而上述两个选项是即时的。

+2

这些范围似乎没有相同的大小,因此请注意意想不到的结果。 – 2011-02-18 05:11:39

+0

你说得对。调整大小使得它工作起来相当麻烦。 – xbonez 2011-02-22 14:00:52

1

复制和粘贴在VBA中有相当多的开销,就像处理这样的范围一样。自从我完成了VBA以来,它已经有一段时间了,但是如果我正确地记得做这种事情的最快方法就是将所需的值写入数组,然后使用Resize函数。所以这样的事情:

Option Base 0 
Dim firstrow as integer 
Dim lastrow as integer 
Dim valuesArray() as Long 
Dim i as integer 

//Set firstrow and lastrow however you deem appropriate 
... 

//Subtracing first row from last row gets you the needed size of the 0 based array 
ReDim valuesArray(lastrow-firstrow) 

for int i = 0 to (lastrow-firstrow) 
    valuesArray(i)=Cells(i+firstrow, COLUMNNUMBER).value 
next i 

当然用你正在迭代的任何列替换COLUMNNUMBER。这应该用你想要的值填充你的数组。然后选择你的目标单元格,并使用调整大小来放入值。所以,如果你的目的小区是D4:

Range("D4").Resize(UBound(valuesArray)+1, 0).value = valuesArray 

的写入阵列中所有起始于D4和下降为许多单元的值在数组中。稍微复杂一些,但如果你要加快速度,我认为我从来没有想过更快。我也是从头到尾做了这个,所以请测试一下,确保你不会在这里和那边切断一个单元格。

1

这OZGrid页面具有非常有用的信息 - http://www.ozgrid.com/VBA/SpeedingUpVBACode.htm

以我为例,我需要的格式,所以我一直用这个被复制,以及:

Sheet1.Range("A1:A200").Copy Destination:=Sheet2.Range("B1") 

但仍然很慢执行 - 以锁定应用程序 - 我终于发现问题 - 在过去的某个时候,一些空的文本框进入我的页面 - 当我的代码每次运行时它们都被复制,但它们没有被我的代码来清除工作区域。结果就像是4,500个空文本框 - 每个文本框都被上面的代码复制和粘贴。

如果您使用编辑 - 转到... - 单击特殊 - 然后选择对象 - 并且您没有看到任何好的东西 - 如果您看到一堆您在页面上不知道的对象这是不好的。