VBA 求解器约束未设置错误(未指定约束)
VBA Solver Constraints Not Set Error (w/ no constraints specified)
首先,我尝试研究我遇到的问题,但我找到了解决方案(例如,here,对我没有用)。我正在尝试编写一个宏,该宏使用(通常)直接求解值的规划求解功能。
我得到的代码如下:
Sub SolverAEP()
Dim GeneratedPower As Double
GeneratedPower = Worksheets("AEP").Range("D57")
SolverReset
SolverOk SetCell:="$D", _
MaxMinVal:=3, _
ValueOf:=GeneratedPower, _
ByChange:="$D" _
, Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve userFinish:=False
End Sub
目前的错误是Solver could not find a feasible solution. Sovler can not find a point for which all Constraints are satisified.
我尝试过的:
- 一些在线指南说 ValueOf 需要是一个字符串 - 我尝试了 CStr 方法来处理
Range("D57")
和 Cells(57,"D").Value
,但都出现了求解器错误。
- 当我手动尝试打开 Solver 时,它总是以逗号而不是句号打开,所以我使用一个小脚本将所有逗号替换为句号,但这并没有改变任何东西(只试过这是当我将字符串作为
ValueOf
处理时。[我不确定为什么会发生这种情况,但我认为存在某种文化冲突,因为我同时使用大陆和英国键盘以及本地化设置相当随机。]
在规划求解中手动记录执行相同操作的宏为我提供以下规划求解代码:
Sub Macro2()
SolverOk SetCell:="$D", MaxMinVal:=3, ValueOf:=21000#, ByChange:="$D" _
, Engine:=1, EngineDesc:="GRG Nonlinear"
SolverOk SetCell:="$D", MaxMinVal:=3, ValueOf:=21000#, ByChange:="$D" _
, Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve
End Sub
如有必要,我目前拥有的值可以四舍五入——当我逐步执行编写的宏时,小数点似乎仍在使用逗号而不是句号。我尝试将值四舍五入并将其放在那里,但出现了同样的错误。
最后,我要补充一点,用求解器手动解决这个问题是没有问题的。引用的单元格 D58 是其他单元格的总和,其值取决于 D65 的值。
谁能指出我做错了什么?
以防万一,我使用的是 Excel 2016。
看起来好像您没有激活您的公式所在的 sheet,因此 Solve 正在对当前活动的 sheet 进行处理。
我建议将您的代码更改为:
Sub SolverAEP()
With Worksheets("AEP")
.Activate
SolverReset
SolverOk SetCell:="$D", _
MaxMinVal:=3, _
ValueOf:=[$D], _
ByChange:="$D", _
Engine:=1, _
EngineDesc:="GRG Nonlinear"
SolverSolve userFinish:=False
End With
End Sub
Activate
将确保在 运行 求解器时选择正确的 sheet。 (尽管我讨厌使用 Activate
、Select
、Selection
等,但这是需要它的时候之一 - Solver 将仅在 Active sheet.)
关于您关于在您 运行 求解器第二次 运行 之后才更新值的评论,如果您包含 Application.ScreenUpdating = False
语句,我想不出任何理由,除了公平显而易见的问题 "have you included a Application.ScreenUpdating = True
statement as well?".
我试过 运行只用 =False
和 运行 宁 SolverAEP
导致屏幕在宏结束后更新。
但是,如果我写另一个子程序,如下所示:
Sub Test
SolverAEP
MsgBox "Finished first solve"
SolverAEP
MsgBox "Finished second solve"
End Sub
和运行它,然后(只有一个=False
而没有相应的=True
)屏幕不会更新,直到Sub Test
的End Sub
到达了。这是停止 ScreenUpdating
.
的预期行为
首先,我尝试研究我遇到的问题,但我找到了解决方案(例如,here,对我没有用)。我正在尝试编写一个宏,该宏使用(通常)直接求解值的规划求解功能。
我得到的代码如下:
Sub SolverAEP()
Dim GeneratedPower As Double
GeneratedPower = Worksheets("AEP").Range("D57")
SolverReset
SolverOk SetCell:="$D", _
MaxMinVal:=3, _
ValueOf:=GeneratedPower, _
ByChange:="$D" _
, Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve userFinish:=False
End Sub
目前的错误是Solver could not find a feasible solution. Sovler can not find a point for which all Constraints are satisified.
我尝试过的:
- 一些在线指南说 ValueOf 需要是一个字符串 - 我尝试了 CStr 方法来处理
Range("D57")
和Cells(57,"D").Value
,但都出现了求解器错误。 - 当我手动尝试打开 Solver 时,它总是以逗号而不是句号打开,所以我使用一个小脚本将所有逗号替换为句号,但这并没有改变任何东西(只试过这是当我将字符串作为
ValueOf
处理时。[我不确定为什么会发生这种情况,但我认为存在某种文化冲突,因为我同时使用大陆和英国键盘以及本地化设置相当随机。] 在规划求解中手动记录执行相同操作的宏为我提供以下规划求解代码:
Sub Macro2() SolverOk SetCell:="$D", MaxMinVal:=3, ValueOf:=21000#, ByChange:="$D" _ , Engine:=1, EngineDesc:="GRG Nonlinear" SolverOk SetCell:="$D", MaxMinVal:=3, ValueOf:=21000#, ByChange:="$D" _ , Engine:=1, EngineDesc:="GRG Nonlinear" SolverSolve End Sub
如有必要,我目前拥有的值可以四舍五入——当我逐步执行编写的宏时,小数点似乎仍在使用逗号而不是句号。我尝试将值四舍五入并将其放在那里,但出现了同样的错误。
最后,我要补充一点,用求解器手动解决这个问题是没有问题的。引用的单元格 D58 是其他单元格的总和,其值取决于 D65 的值。
谁能指出我做错了什么?
以防万一,我使用的是 Excel 2016。
看起来好像您没有激活您的公式所在的 sheet,因此 Solve 正在对当前活动的 sheet 进行处理。
我建议将您的代码更改为:
Sub SolverAEP()
With Worksheets("AEP")
.Activate
SolverReset
SolverOk SetCell:="$D", _
MaxMinVal:=3, _
ValueOf:=[$D], _
ByChange:="$D", _
Engine:=1, _
EngineDesc:="GRG Nonlinear"
SolverSolve userFinish:=False
End With
End Sub
Activate
将确保在 运行 求解器时选择正确的 sheet。 (尽管我讨厌使用 Activate
、Select
、Selection
等,但这是需要它的时候之一 - Solver 将仅在 Active sheet.)
关于您关于在您 运行 求解器第二次 运行 之后才更新值的评论,如果您包含 Application.ScreenUpdating = False
语句,我想不出任何理由,除了公平显而易见的问题 "have you included a Application.ScreenUpdating = True
statement as well?".
我试过 运行只用 =False
和 运行 宁 SolverAEP
导致屏幕在宏结束后更新。
但是,如果我写另一个子程序,如下所示:
Sub Test
SolverAEP
MsgBox "Finished first solve"
SolverAEP
MsgBox "Finished second solve"
End Sub
和运行它,然后(只有一个=False
而没有相应的=True
)屏幕不会更新,直到Sub Test
的End Sub
到达了。这是停止 ScreenUpdating
.