2015-02-12 130 views
2

我第一次使用VBA。直到現在,我成功地建立了一個模型。但是,我仍然想加快計算(我已經關閉了ScreenUpdating,EnableEvents,xlCalculationAutomatic,DisplayPageBreaks)。我已經在互聯網上看到,for-loops非常耗時。不幸的是,我真的有很多。因此,我的問題:VBA Excel避免與可變列循環

假設我有這種類型的代碼:

For p = 1 To Periods 
Demand(p) = Worksheets("Sheet1").Cells(3, 1 + p) 
Next p 

我的第一個問題:這是否爲環真正減慢運行時間?第二個問題:我如何重寫它,從而加速計算?

我一直在嘗試以下操作:

Demand = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(3, 2), Worksheets("Sheet1").Cells(3, 1 + Periods)) 

但不幸的是,這似乎並沒有工作。我已經Google了這個,但我似乎沒有找到答案。

非常感謝您的幫助!

回答

0

這不是需要花時間的For循環,而是你在裏面做的事情。使用Excel VBA,您可以做的最慢的事情之一是與工作表交互。你可以考慮

一個快速變化是這樣的:

With Worksheets("Sheet1") 
    For p = 1 To Periods 
     Demand(p) = .Cells(3, 1 + p) 
    Next p 
End With 

......這意味着你的代碼知道它總是在處理同一個工作表,並沒有每次來查找正確的你繞過循環。您可能不會注意到很多差異,但是您已經從每個時期的一個工作表查找到每個運行一個工作表。儘管如此,你仍然有一個單元格查找每個時期。

可以到工作表一個電話,但:得到一個呼叫中的所有值,並完全避免循環:

​​

那將讓你在Demand一個1個週期陣列。試試吧 - 使用「查看...本地窗口」來查看你有什麼。

+0

非常感謝您的幫助。快速變化已經是一個巨大的改進。但是,我嘗試單一呼叫時遇到一些問題。我得到這個錯誤:「運行時錯誤'13':類型不匹配」。你有什麼想法可能出錯的地方? – Ann 2015-02-12 14:00:25

+0

您需要發佈更多的代碼。 – 2015-02-12 14:21:21

+0

你是在聲明'Demand'嗎?像'昏暗的需求(1到期)'?如果是這樣,請嘗試刪除類型聲明「Dim Demand」或明確將其變爲「Variant」:Dim Demand As Variant。否則,正如已經指出的那樣,我們需要看到更多的代碼,特別是導致問題行發生的情況。 – 2015-02-12 14:42:44

0

它實際上取決於你的結束計數器多大,你的步數是多少。如果您的最終計數器大於500K(真的很大),您可能會經歷明顯的減速。

但是,你應該考慮以下幾點:

優化環路

你的速度是更容易被循環內的指令影響裏面的說明。你最好優化它們,然後擔心你是否應該使用For eachFor Loop

例如:在循環中使用.Rows().EntireRow屬性通常會降低代碼的速度,因爲Excel會考慮佔用可能爲一百二十萬個單元格的行的範圍。這正是會讓您的代碼變慢的原因。

避免使用重複引用

With聲明是提高你的代碼的速度的好方法。只要確保你的循環嵌套在With聲明中。這樣,VBA就不必多次瀏覽父母的參考資料。

@Mike Woodhouse的回答是如何使用With語句來提高代碼速度的一個很好的例子。

VBA將執行週期的時間與一個參考你的指令到Worksheets("Sheet1")

With Worksheets("Sheet1") 
    For p = 1 To Periods 
     Demand(p) = .Cells(3, 1 + p) 
    Next p 
End With 
您的舊代碼(如下圖),VBA執行你的指令,並在這樣做時,它會調用週期時間 WorkSheets("Sheet1")

然而 ​​