我試圖在工作表上使用求解器,比如表A中。我也在表A中有一些帶「= rand()」的單元格,或者在表格中使用寫入Application.Volatile
的自定義函數說出任何公式。我希望這些揮發性細胞在我解算器時停止重新計算,所以我在我的求解器程序中使用了Application.Calculation = xlCalculationManual
,但在運行求解器後我發現那些易失性細胞已經發生了變化。我在哪裏做錯了?在VBA中使用Solver時,如何關閉重新計算?
回答
有2種方法來避免這種情況:
不要求解使用!如果您編寫自己的子文件來執行這些操作,您可以使用
Range.Calculate
,而計算是手動計算這些單元格(所有其他單元格將被忽略)。更改公式並進行迭代選項 - >公式 - >啓用迭代計算。現在使用的輔助細胞持有真/假(或1/0或其他)和變化的公式,你不想計算如下(輔助細胞A1/A2公式):
=IF(A1,A2,[your old formula])
這樣,只要A1是true
它會輸出計算前的值。
據我所知,沒有其他辦法,因爲求解器每次測試一個新的循環時都會執行Calculate
。
編輯:
具有揮發性UDF它不需要揮發的全部時間,你可以使用一個簡單的技巧(又一個輔助細胞)需要:
A1: [volatile function like =NOW() or =RAND()]
A2: =MY_UDF(A1)
在模塊中:
Public Function MY_UDF(a As Variant) As Double
a = a
MY_UDF = Now
End Function
只要A1持有一些易變的東西,你的UDF就會每次重新計算。但是如果你清空了A1(或者使其處於非易失性狀態),那麼對於提交給UDF的值就不會有任何變化,這樣excel/vba就會假定不會發生變化,只需跳過它就可以進行重新計算。這樣,只要輔助單元是非易失性的,您也可以建立自己的RAND
-UDF(當然有不同的名稱)來停止工作簿中的所有易失性函數。
作爲說明:在使A1(本例中)非易失性之後,之後的第一次計算仍然會運行1次,就像它是易失性的。同時將A1從一個值更改爲另一個值(如0到1)將運行一次。
這是一種解決方法,可以幫助您在電子表格中隨機選擇可以隨意重新計算並且可以開啓和關閉波動率的值。
首先,創建一個名爲範圍1節,說「觸發」
然後,把下面的代碼在一個標準的代碼模塊:
Function SemiVolatileRand(x As Variant) As Double
SemiVolatileRand = x - x + Rnd()
End Function
Sub ReSample()
Randomize
Range("trigger").Value = Range("trigger").Value + 0.01
End Sub
附上ReSample
子到一個按鈕。用 =SemiVolatileRand(trigger)
替換所有的出現的=RAND()
。只要按下按鈕,他們就會重新調節。此外,如果您想要恢復全部波動率,只需將公式=RAND()
放入觸發單元格中即可。 (在這最後一種情況下獲得全面波動似乎需要我的代碼確實與虛擬變量x
,因此有些無點x - x
)。
Randomize
從系統時鐘重新生成隨機數發生器。它應該在每個會話中至少調用一次。如果您不這樣做,那麼每次打開使用VBA rnd
的Excel工作簿時,都會得到相同的隨機值序列。您可以通過一個空白工作簿,並在ThisWorkbook
代碼模塊放驗證這一點:
Private Sub Workbook_Open()
MsgBox Rnd()
End Sub
消息塊將在每次打開工作簿時顯示的值相同。另一方面,如果您將Randomize
一行放在MsgBox
之前,那麼每次打開它時都會得到不同的值。
請注意,如果您打算使用rnd
,則工作簿打開事件是放置語句Randomize
的自然地點。
我沒有把Randomize
放在函數本身中的原因既是爲了節省CPU週期,也是因爲一個令人擔憂的問題,即在一定比例的時間內你將用完全相同的系統時間重新發送隨機數發生器。運行最新版本的Excel的現代體系結構可能是不可能的,但例如,如果您有Randomize Timer
(您在閱讀其他代碼時有時會遇到),有時會發生,因爲定時器功能具有1毫秒的分辨率,與系統時鐘無關。
我有的代碼確實有缺點,如果你繞過按鈕,只是改變觸發單元,那麼你可能會錯過重新播種。如果這是一個問題,1個可能會是這樣的:
公共初始化爲布爾
功能SemiVolatileRand(X爲Variant)爲雙 如果未初始化然後 隨機化 初始化=真 結束如果 SemiVolatileRand = x - x + Rnd() End Function
如果rnd
未正確接種,這將阻止函數運行。
Excel本身會自動處理工作表函數Rand()
,因此它嚴格是VBA併發症。
爲什麼你要在你的ReSample()子程序中使用Randomize? – Nicholas
@NicholasLiu這是種子的僞隨機數發生器。查看編輯。 –
- 1. 如何使用EPPLUS在excel中關閉重新計算選項
- 2. knockout.js - 何時計算項目重新計算依賴關係?
- 3. Advise Solver Loop VBA
- 4. 如何在用戶關閉計算器時打印消息?
- 5. Android - 即使在關閉應用時計算背景時間
- 6. 計算機在運行eclipse時關閉
- 7. 如何在MS Solver Foundation中使用If運算符?
- 8. 如何在應用程序關閉/重新啓動時關閉db4o連接?
- 9. Excel VBA重新計算選擇
- 10. 使用nasm關閉計算機
- 11. 如何使用VBA鎖定計算機
- 12. 如何取消在計算機關閉時聲明進程?
- 13. 如何計算時間,發動機和關閉在MySQL
- 14. 如何從ASP.NET關閉計算機
- 15. Java應用程序在關閉時如何重新啓動?
- 16. 使用關閉而不是關閉重新使用套接字
- 17. excel vba關閉工作簿在其他計算機上打開
- 18. 如何使用VBA在Access中關閉單個窗體實例?
- 19. 計算時間差重新
- 20. ajax:如何在使用ajax關閉後重新打開div
- 21. 如何在新的一年到來時重新計算值,Ruby
- 22. 在VB.NET中保存關閉/重新啓動計算機上的數據
- 23. 如何重新計算VBA用戶表單中文本框的值?
- 24. 使用RPC關閉Windows XP計算機時出錯
- 25. QVBoxLayout何時重新計算佈局?
- 26. 處理 - 關閉計算機
- 27. 關閉計算機編程
- 28. 如果我們關閉並重新打開預準備語句,是否會重新計算查詢計劃?
- 29. python jumble solver算法
- 30. 如何在活動關閉時觸發重新加載?
你當然是對的。解算器顯然不可能在不重新計算的情況下實現其魔力,因爲要求優化的函數和約束由*電子表格公式組成。 –
但是爲什麼Solver會重新計算整個工作表/整張工作表?爲什麼不使用範圍。計算?我遇到了這個問題,因爲我正在做一個非線性OLS(可能沒有機會跳過Solver?),但我想這樣做N次,每次優化函數(SolverOk中的第一個參數)是簡單的,因爲我用它們可以得到N個不同的優化函數!),雖然它們不直接參與優化,但是它們不能改變,因爲它們會改變優化函數。所以這是故事:( – Nicholas
順便說一句,那麼將它們複製到一個新的區域作爲價值? – Nicholas