以下代码在我第一次运行时完美运行,
但是当我第二次或第三次再次运行时
它给了我一个来自求解器的msgbox告诉它找到了解决方案,然后当我点击选择OK
它刚从Sub中退出。不明白为什么。
另外我想知道如何通过vba从Solver对话框中提示OK
命令?或者只是简单地避开它。
Option Explicit
Sub MinimizeCost()
Dim wm, ws, wr As Worksheet
Dim i, j, FinalRow As Long
Dim char As Variant
Dim ScnCap, ScnDem As Range
Set wm = Sheets("Model")
Set ws = Sheets("Scenarios")
Set wr = Sheets("Results")
For i = 1 To 5
With ws
j = i + 1
Set ScnCap = .Range(.Cells(5, j), .Cells(7, j))
End With
wm.Range("Capacities") = ScnCap.Value
With ws
j = i + 1
Set ScnDem = .Range(.Cells(10, j), .Cells(13, j))
End With
ScnDem.Copy
wm.Range("Demands").PasteSpecial Transpose:=True
Call Solveit
FinalRow = wr.Range("A9000").End(xlUp).Row
FinalRow = FinalRow + 1
wr.Range("A" & FinalRow + 1) = "Scenario" & " " & i
wr.Range("A" & FinalRow + 2) = "Shipments"
wr.Range("F" & FinalRow + 2) = "Total Cost"
wm.Range("TotalCost").Copy
wr.Range("F" & FinalRow + 3).PasteSpecial xlPasteValues
wm.Range("Shipped").Copy
wr.Range("A" & FinalRow + 3).PasteSpecial xlPasteValues
SendKeys ("{ESC}")
wm.Range("A1").Select
Next i
End Sub
Sub Solveit()
Dim wk As Worksheet
Set wk = Sheets("Model")
wk.Select
SolverOk SetCell:="$B$20", MaxMinVal:=2, ValueOf:=0, ByChange:="$C$13:$F$15", _
Engine:=2, EngineDesc:="Simplex LP"
SolverOk SetCell:="$B$20", MaxMinVal:=2, ValueOf:=0, ByChange:="$C$13:$F$15", _
Engine:=2, EngineDesc:="Simplex LP"
SolverSolve
End Sub
答案 0 :(得分:0)
在microsoft website上,它解释了Excel-VBA中有关sovler的所有内容。用
替换SolverSolve
行
SolverSolve UserFinish:=True
应该避免在最后弹出msgBox。
关于错误的第二次运行解决方案的问题,我建议在SolverReset
函数的开头添加Solveit()
。正如here所解释的那样,它会导致单元格选择重置,这在多次运行求解器时可能会出现问题。
而且,你不应该在解算器中设置2 SolverOk
,特别是如果它们具有完全相同的属性...
最后,这样的事情应该起到作用:
Sub Solveit()
Dim wk As Worksheet
Set wk = Sheets("Model")
wk.Select
SolverReset
SolverOk SetCell:="$B$20", MaxMinVal:=2, ValueOf:=0, _
ByChange:="$C$13:$F$15", Engine:=2, EngineDesc:="Simplex LP"
SolverSolve UserFinish:=True
End Sub
顺便说一下,请注意以下陈述:
wm.Range("Shipped").Copy
wr.Range("A" & FinalRow + 3).PasteSpecial xlPasteValues
VBA处理复制/粘贴非常糟糕,如果你只是想将一个单元格的值复制到另一个(如果它们具有相同的维度,也适用于Range),只需写:
wr.Range("A" & FinalRow + 3).value = wn.Range("Shipped").value
这将使您的代码更加清晰,可以调试并更快地运行。