2012-01-12 30 views
7

我有一個相當大的工作簿,需要很長時間來計算。過去計算一直是一個相當大的挑戰,因爲如果你仔細觀察,Excel非常渴望無聲地中止計算。如何確定計算是否已完成或檢測到計算中斷?

爲了幫助緩解這個問題,我創建了一些VBA代碼來啓動計算,這是由一個表單啓動的,結果是它不是很容易中斷計算過程,但它仍然是可能的。 (我可以通過點擊窗體上的關閉X輕鬆實現此操作,但我想有其他方法)

與其採取更多步驟來嘗試並使其更難以中斷計算,我想讓代碼檢測計算是否完成,因此它可以通知用戶,而不是盲目地鍛造我的代碼中的其餘步驟。到目前爲止,我找不到任何方法來做到這一點。

我已經看到了Application.CalculationState引用,但價值xlDone後我打斷計算,即使我打斷計算,幾秒鐘後(一般需要一個小時左右)。

我不能想辦法通過檢查細胞的價值要做到這一點,因爲我不知道哪一個是最後的計算做。我發現有一種方法可以將細胞標記爲「骯髒」,但我無法找到檢查細胞污垢的方法。而且我不知道這是否是正確的路徑,因爲我可能必須檢查每張表格中的每個單元格。

中斷計算不產生錯誤的行爲,所以我的錯誤不會被觸發。

有什麼我失蹤?有任何想法嗎?

任何想法?

+1

您可以防止中斷髮生,但我建議您花費一些努力加速計算:一小時計算是非常過分的。請參閱http://www.decisionmodels.com/optspeed.htm或http://msdn.microsoft.com/en-us/library/ff700515.aspx – 2012-01-12 23:59:46

+0

我衷心贊同。但即使我將腳本運行時間減少了一個數量級,它仍將運行6分鐘,並且由於Excel對於中斷計算的傾向是如此安靜,我的數據是否準確,我還是會懷疑。 我其實對防止中斷和更感興趣知道中斷是否發生不太感興趣。 – BenTobin 2012-01-13 00:22:35

+2

偉大的問題。我注意到,當計算中斷時,狀態欄中會出現「計算」一詞。除了簡單地查看狀態欄,我不知道有什麼方法來利用這些信息。 – JimmyPena 2012-01-13 01:25:24

回答

0

我從來沒有真正使用它,但我認爲這可能會阻止計算被打斷。

Application.CalculationInterruptKey = xlNoKey

+0

這可以幫助防止意外中斷,但仍然不會讓我知道計算是否已被中斷。 – BenTobin 2012-01-18 15:34:57

+0

你說得對。這是解決問題的最終結果。 (假設它有效) – mischab1 2012-01-19 01:47:46

2

我認爲你需要實現(如果你在Excel 2007中運行應用程序或更高版本)的伎倆與Application.AfterCalculate事件,這既是計算後提出來處理,這是完全沒有未解決的查詢。

如果你從來沒有與事件VBA工作過,有來自cpearson.com一個很好的概述。

1

我想我聽到你需要一種方法來監視是否執行正在執行的計算中的每一步。

假設你不感興趣的重新設計使用更易於追蹤比表格計算(如內VBA或數據透視表揮發物計算)方法的工作簿,這可能會爲你工作:

在VB中,你可以利用.EnableCalculation.Calculate設置整個工作表爲「髒」(需要計算),然後重新計算。這與您當前流程的主要區別在於,我們將在手動模式下執行這些操作一個工作表。通過在VBA中一次啓動一個工作表的計算,您將能夠執行額外的中間操作,用於追蹤您在計算過程中的進度。

請注意,這種方法假設一個相當線性的工作簿結構,這樣如果我們首先按照您希望的順序重新計算Sheet1,Sheet2,Sheet3等,您的工作簿將產生正確的結果。如果你的公式依賴性比線性更「意大利麪條」,這可能不適合你。它還假定您正在使用Excel 2000或更高版本。

例如,您可以編寫一個VBA例程來完成以下步驟。 您需要了解自己的依賴關係,才能知道哪些計算必須先於其他計算,並從工作表開始處於「乾淨」狀態,此時不存在任何計算。

步驟1:設置活性片到需要重新計算的第一個工作表

步驟2:設置計算模式爲手動如下:

Application.Calculation = xlCalculationManual 

步驟3 : 「髒」 的整個活性片如下:

With ActiveSheet 

    .EnableCalculation = False 

    .EnableCalculation = True 
使用啓動該工作表只(不是整個工作簿)重新計算:

步驟4

.Calculate 

    End With 

注意,如果計算模式被設置爲自動,步驟3將啓動跨過重新計算整個工作簿。通過使用手動模式和With,我們將該計算限制在當前工作表中。

現在你已經變髒並重新計算第一張紙(歡呼!)。現在,通過將上面的步驟3和4嵌入到For/Each或For/Next循環中,您可以爲工作簿中的每個工作表重複該過程。再次確保您知道工作表需要計算的順序(如果需要訂單)。

現在的大結局 - 通過創建你的循環中的計數器變量,你可以跟蹤通過更新每次完成一個工作表計算你的計數器變量的值,你在計算多遠了。例如,在重新計算工作表後,可以將計數器值設置爲當前值+ 1,並將結果存儲在全局變量中(以便即使在VBA例程結束之後它仍會保留)或工作表中的單元格中。這樣,您可以稍後檢查此值以查看在計算完成或中斷之前更新了多少工作表。

如果你有你的工作簿相對較少的工作表,同樣的方法可以在一個時間,而不是一紙應用到一個範圍。

我不會去了解如何構建一個「反」的細節,環路,還是在這裏全局變量,但如果需要的話,可以用你喜歡的搜索引擎很容易找到這些信息。我也強烈建議您在完成後重新啓用自動計算,因爲很容易忘記它已被設置爲手動模式。

我希望這對你的作品 - 有關計算模式和重新計算的更多信息,這是一個有用的鏈接:在Excel http://msdn.microsoft.com/en-us/library/bb687891.aspx

+0

感謝您的建議,但迄今爲止我的經驗是,如果計算中斷,正在運行的任何代碼立即從.calculate調用繼續前進,就像它正常完成一樣。因此,無論計算是否中斷,計數器的結果都不會有任何不同。不過,我仍然需要調查另一個答案中提到的事件驅動方法。 – BenTobin 2012-05-09 02:11:07

-1

數組是有點笨。那就是爲了完成一些任務,人們避免使用中間列/行來存儲(臨時)數據,所以數組每次都必須從頭開始重新計算員工,因此變得非常慢。我的建議是:

  1. 修復數組以避免多次搜索。使用隱藏的單元格或隱藏的表格
  2. 避免使用A:A,而是在Excel 2007或更高版本中專門使用A1:A1000
  3. 使用公式等於零或錯誤(例如:NA()),而以前的項目不是計算出來的,所以你可以清楚地看到操作是否完成。
  4. 一些VBA可用於注入到位公式一步一個時間,進行計算,然後進行下一個步驟,但是這可能意味着大量的工作...
0

也許下面將工作:

Do Until Application.CalculationState = xlDone 
    DoEvents 
Loop 

不能說我已經測試過了,也不是說我知道Application.CalculationState的功能真的是強大的如何確定是否發生「完整」的計算,相對於一些中斷過程並且標記計算狀態完成。

0
Private sub SomeCodeThatGeneratesFormulas 
    Application.Calculation = xlCalculation.xlCalculationManual 
    '...Some formulas are copied here' 
    Application.OnTime DateTime.DateAdd ("s",.01,DateTime.Now), "Module1.CalculateFullRebuildAndSubsequentSteps" 'By using Application.OnTime, this method will be called in a way that locks the end-user out of providing inputs into Excel until the calculation itself is complete. 
end sub 

public sub CalculateFullRebuildAndSubsequentSteps 
    Application.CalculateFullRebuild 
    '...Do next steps, i.e. paste as values' 
end sub 
0

在狀態欄上,右手邊,它會說Calculating (N processors) X%(其中N是您的計算機和X%上的處理器數量是多少,已完成)重新計算時。如果您沒有看到文字,則不會重新計算。

我正在使用Office 2010,但它應該在所有版本中都有。它有點微妙,所以很容易錯過。

相關問題