Excel 求解器忽略 VBA 中的约束

问题描述 投票:0回答:4

我正在尝试使用求解器找到简单投资组合的最大回报。在工作表中直接使用 Solver 可以正常工作,但在 VBA 中设置命令时则不然。相反(正如您从屏幕截图中看到的)它忽略了其中一个约束(T10 中计算的权重总和应 = 1)。有趣的是,如果我将第三行改为:

,效果很好
SolverAdd CellRef:="$T$10", Relation:=2, FormulaText:="100"

或“1”以外的任何其他整数。 (它也可能忽略其他约束,但我无法检查这一点)。 该表如下所示: enter image description here

我的代码是:

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

任何建议都非常欢迎!

excel vba optimization constraints solver
4个回答
3
投票

找到了解决该错误的方法。对于标志“FormulaText:=1”。不要使用 1,而是使用对任何值为 1 的单元格的引用。

即,将“FormulaText:=1”更改为“FormulaText:=$H$5”,其中 $H$5 的值为 1


1
投票

我认为只要该值恰好为 1,就会出现错误。其他帖子指出上述解决方案(将值放入单元格中)不可靠。 我发现它不起作用,因为我的代码总是引用一个包含约束限制的单元格。 我的(粗略)解决方案是将极限值在适当的方向上移动 10^12 或更低的 1 部分,这使得约束变成 < or > 而不是 <= or >=。 所以而不是:

SolverAdd CellRef:=Range("SolverParam").地址,关系:=3, _ FormulaText:=Range("SolverConstraint").value

用途:

SolverAdd CellRef:=Range("SolverParam").地址,关系:=3, _ FormulaText:=Range("SolverConstraint").value + Abs(范围("SolverConstraint").value) * 1e-12

并使用相反的符号表示关系:=1

在这个简单的示例中,SolverParam 是要调整的单个单元格参数,SolverConstraint 是单个单元格下界。

这是我可以预见的唯一一致的方法,可以统一处理所有值

进一步查看,我从网上找到了另一个解决方案

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

看起来工作可靠


0
投票

我也遇到了完全相同的问题。我通过以下方式解决了它: 只需输入 FormulaText:=1,不带 1 的引号。


0
投票

按照sevenkul的建议添加“=”对我有用。

SolverAdd CellRef:=“$F$13”,关系:=2,FormulaText:=“=1”

在此之前,我还在求解器窗口中得到了缺失的约束。从工作表手动添加约束效果很好,但在运行 VBA 代码后不会显示(由于 SolverReset 调用)。我还认为问题不限于值 1。我也尝试过 2 并得到了类似的结果。

奇怪的是,在运行建议的修复一次后,我不再需要 FormulaText 中额外的“=”。我关闭并重新打开工作簿,不需要解决方法。运行一次似乎就可以了。不确定是否需要在代码中使用求解器在每个新工作簿上完成此操作。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.