简体   繁体   English

Excel规划求解忽略VBA中的约束

[英]Excel Solver Ignoring Constraint in VBA

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. 在工作表中直接使用规划求解是明智的,但是在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). 而是(如您从屏幕抓图中看到的)它忽略了一个约束(在T10中计算的权重之和应为= 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". 或“ 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! 任何建议表示感谢!

Found a work around for the bug. 找到了解决该错误的方法。 For the flag "FormulaText:=1". 对于标志“ FormulaText:= 1”。 instead of using 1, use a reference to any cell with the value 1 instead. 而不是使用1,而是使用对值为1的任何单元格的引用。

Ie, Change "FormulaText:=1" to "FormulaText:=$H$5" where $H$5's value is 1 即,将“ FormulaText:= 1”更改为“ FormulaText:= $ H $ 5”,其中$ H $ 5的值为1

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. 我认为每当值正好为1时,这里就有一个bug。其他帖子指出上述解决方案(将值放入单元格)是不可靠的。 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 >=. 我的(粗略)解决方案是在适当的方向上将极限值在10 ^ 12或更低的范围内移动1个部分,这使约束成为<或>而不是<=或> =。 So rather than: 因此,而不是:

SolverAdd CellRef:=Range("SolverParam").Address, Relation:=3, _ FormulaText:=Range("SolverConstraint").value 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 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 并对关系使用相反的符号:= 1

In this trivial example SolverParam is a single cell parameter to be adjusted and SolverConstraint is a single cell lower bound. 在这个简单的示例中,SolverParam是要调整的单个单元格参数,而SolverConstraint是单个单元格的下限。

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 FormulaText:=“ =”&Range(“ SolverConstraint”)。value

Seems to work reliably 似乎工作可靠

I had the exact same issue. 我有完全相同的问题。 I solved it in the following way: Just type FormulaText:=1 without the quotes for 1. 我通过以下方式解决了问题:只需键入FormulaText:= 1,而不用引号将1括起来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM