Excel Solver Ignoring Constraint in VBA

北慕城南 提交于 2019-12-11 03:36:02

问题


I am trying to find a maximum return for a simple portfolio using Solver. Using Solver in the worksheet directly works sensibly, however it does not when the commands are set in VBA. Instead (as you can see from the screengrab)it ignores one of the constraints (that the sum of weights calculated in T10 should =1). Interestingly it works fine if I change the third line to say:

SolverAdd CellRef:="$T$10", Relation:=2, FormulaText:="100"

Or any other integer other than "1". (It may also be ignoring the other constraint but I cannot check this). The table looks like this:

And my code is:

Sub FindRange()

                SolverReset
                SolverOk SetCell:="$T$7", MaxMinVal:=1, ValueOf:="0", ByChange:="$O$10:$R$10"
                SolverAdd CellRef:="$T$10", Relation:=2, FormulaText:="1"
                SolverAdd CellRef:="$O$10:$R$10", Relation:=3, FormulaText:="0"
                SolverSolve UserFinish:=True
                SolverFinish KeepFinal:=1
                Range("T9").Value = Range("T7").Value
           End Sub

Any suggestions gratefully welcomed!


回答1:


Found a work around for the bug. For the flag "FormulaText:=1". instead of using 1, use a reference to any cell with the value 1 instead.

I.e., Change "FormulaText:=1" to "FormulaText:=$H$5" where $H$5's value is 1




回答2:


I think there is a bug here whenever the value is exactly 1. Other postings state that the above solution (putting the value into a cell) is unreliable. I have found it does not work a my code always refers to a cell which holds the constraint limit. My (crude) solution is to shift the limit value by 1 part in 10^12 or lower in the appropriate direction which sort of makes the constraint into a < or > rather than a <= or >=. So rather than:

SolverAdd CellRef:=Range("SolverParam").Address, Relation:=3, _ FormulaText:=Range("SolverConstraint").value

Use:

SolverAdd CellRef:=Range("SolverParam").Address, Relation:=3, _ FormulaText:=Range("SolverConstraint").value + Abs(Range("SolverConstraint").value) * 1e-12

And use the opposite sign for Relation:=1

In this trivial example SolverParam is a single cell parameter to be adjusted and SolverConstraint is a single cell lower bound.

This is the only consistent approach I can foresee to have a uniform handling of all values

On further looking I found another solution from the web

FormulaText:="=" & Range("SolverConstraint").value

Seems to work reliably




回答3:


I had the exact same issue. I solved it in the following way: Just type FormulaText:=1 without the quotes for 1.



来源:https://stackoverflow.com/questions/15620177/excel-solver-ignoring-constraint-in-vba

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!