2011-04-18 34 views
1

在大型數據集上執行優化任務時,我會不時收到溢出運行時錯誤6(通常在1小時或2小時後)。當我從它停止的位置重新啓動宏時,錯誤消失,即從發生錯誤的位置再次啓動宏。溢出錯誤是否與創建過多的使用後未被正確銷燬的對象有關?Excel VBA:來自太多未被破壞的對象的溢出錯誤?

下面是我的容器類的一個(簡化版本),它被銷燬(通過Set ... = Nothing)和重建(通過Set ... = New)成千上萬次。

'CG_data_point custom collection class 
    Public data_points As Collection 
Private Sub Class_Initialize() 
    Set data_points = New Collection 
End Sub 

Public Sub AddDataPoint(mydate as date, price as double) 
    Dim new_data_point As CG_data_point 
    Set new_data_point = New CG_data_point 
    new_data_point.EnterData mydate, price 
    data_points.Add new_data_point 
    Set new_data_point = Nothing 'I assume this one could also be skipped 
End Sub 

Public Sub RMSE(X as double) as double 
... 
End Sub 

Private Sub Class_Terminate() 
    Dim data_point As CG_data_point 
    For Each data_point In data_points 'destruct each data point individually 
     Set data_point = Nothing 
    Next data_point 
    Set data_points = Nothing 
End Sub 

'Main module 
dim global_container as CG_data_container 

sub do_optimizations() 
    Do 
      set global_container= new CG_data_container 
      .... do something with the data, have in call to global function RMSE_UDF as a cell formula for Solver 
      set global_container= nothing 
    While (...) 
end sub 

'worksheet function 
function RMSE_UDF(X as double) 
    global_container.RMSE(X) 
end function 

容器變量global_container必須是全球因爲它必須從工作表UDF(RMSE_UDF)調用的對象;就我所知,工作表公式不能有一個對象作爲參數,如「= RMSE(MyContainer,...)」。使用Excel Solver進行均方根誤差(RMSE)的最小化。

回答

1

我不認爲這是你錯誤的原因,但無論如何它值得修復。

比較和對比你的代碼的這兩個部分:

AddDataPoint

data_points.Add new_data_point 
Set new_data_point = Nothing 

在這裏,我們要添加一個對象提到了臨時變量new_data_point到集合中。然後,我們將new_data_point設置爲Nothing以刪除對其所引用對象的引用。顯然,收集仍會有這個對象

參考從Class_Terminate

For Each data_point In data_points 'destruct each data point individually 
    Set data_point = Nothing 
Next data_point 

在這裏,我們正在閱讀依次從收集每個項目分爲稱爲data_point一個臨時變量。然後,我們將data_point設置爲Nothing,以刪除對其引用的對象的引用。 (可能不太如此)顯然,集合仍然會引用此對象。

要從集合中的每個對象嘗試集合中刪除重複的第一個對象,直至集合爲空:

Do Until (data_points.Count < 1) 
    data_points.Remove 1 
Loop 
+0

這很有道理。感謝您向我指出這個錯誤。使用其他語言的指針和引用計數器時,有點混淆。但是,如果任何機構有另一個想法,爲什麼可能會有這個問題,我會很樂意在這裏。 – Steve06 2011-04-18 23:49:30

+0

我對你提出的解決方案有一個額外的問題:是不是在析構函數中使用Set data_points = Nothing命令清空集合? – Steve06 2011-04-19 00:26:33

+0

你真的碰到了印記,在用你的Class_Terminate替換我的循環後(包括刪除),即使連續運行了10個小時的宏,錯誤也沒有彈出!所以我推斷,正如我最初猜測的那樣,溢出錯誤(即運行時錯誤6)很可能源於未被破壞的對象。 – Steve06 2011-04-19 16:28:57

0

在這種情況下,當您嘗試進行超出分配目標限制的分配時,會出現overflow結果。你的數據集是否有超過日期或可能是雙重限制的內容?那些是我看到的兩種類型,也許在某個地方有一個不匹配的地方,而一個大的雙重地位作爲一個日期傳入。您可以使用子例程檢查這種東西,例如,在嘗試將其寫入集合之前檢查日期的邊界。

另一種可能性是集合本身的大小,因爲它被索引了很長時間。但這是一個相當大的數字,你將不得不超過2,147,483,647條記錄。

+0

集合增長約僅2500只記錄(天)對每個優化運行。正如你所看到的,集合類每次都被銷燬,所以它不打算超過這個數量級。我會再次檢查沒有變量碰到它的類型邊界,但是我確信沒有變量沒有,因爲當我重新啓動它停止的過程(讓它再次處理相同的實際數據)時,我不能再現錯誤。所以你排除了一些內存泄漏從非受損對象可能的原因? – Steve06 2011-04-18 19:01:43