2011-02-17 34 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個空文本框 - 每個文本框都被上面的代碼複製和粘貼。

如果您使用編輯 - 轉到... - 單擊特殊 - 然後選擇對象 - 並且您沒有看到任何好的東西 - 如果您看到一堆您在頁面上不知道的對象這是不好的。