3

ソルバーを使用して単純なポートフォリオの最大リターンを見つけようとしています。ワークシートで Solver を直接使用すると適切に機能しますが、コマンドが VBA で設定されている場合は機能しません。代わりに (スクリーン グラブからわかるように) 制約の 1 つを無視します (T10 で計算された重みの合計が 1 になる必要があります)。興味深いことに、3 行目を次のように変更すると、問題なく動作します。

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

または、「1」以外の整数。(他の制約も無視している可能性がありますが、これを確認することはできません)。テーブルは次のようになります。 ここに画像の説明を入力

そして私のコードは次のとおりです。

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

どんな提案でも大歓迎です!

4

3 に答える 3

3

バグの回避策を見つけました。フラグ「FormulaText:=1」の場合。1 を使用する代わりに、値が 1 の任意のセルへの参照を使用します。

つまり、「FormulaText:=1」を「FormulaText:=$H$5」に変更します。ここで、$H$5 の値は 1 です。

于 2013-05-07T17:54:58.910 に答える
1

値が正確に 1 である場合は常に、ここにバグがあると思います。他の投稿では、上記の解決策 (値をセルに入れる) は信頼できないと述べています。私のコードは常に制約制限を保持するセルを参照しているため、機能しないことがわかりました。私の(大まかな)解決策は、制限値を適切な方向に10 ^ 12以下の1部分だけシフトして、制約を<=または> =ではなく<または>にすることです。そうではなく:

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

使用する:

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

Relation:=1 には反対の記号を使用します。

この簡単な例では、SolverParam は調整する単一セルのパラメーターであり、SolverConstraint は単一セルの下限です。

これは、すべての値を均一に処理できると予測できる唯一の一貫したアプローチです。

さらに調べてみると、Webから別の解決策を見つけました

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

確実に動作するようです

于 2016-12-11T21:38:55.903 に答える
0

まったく同じ問題がありました。私は次の方法でそれを解決しました: 1 の引用符なしで FormulaText:=1 と入力するだけです。

于 2014-03-14T13:13:01.863 に答える