Excel VBA不向解算器模型添加图元
我之前遇到过一个问题,就是解算器没有通过VBA将二进制约束添加到模型中……我(大部分)已经解决了这个问题。但现在我有了一个新问题。首先,让我发布违规代码的相关部分。我应该注意到这是在Excel2007中运行的Excel VBA不向解算器模型添加图元,excel,vba,solver,Excel,Vba,Solver,我之前遇到过一个问题,就是解算器没有通过VBA将二进制约束添加到模型中……我(大部分)已经解决了这个问题。但现在我有了一个新问题。首先,让我发布违规代码的相关部分。我应该注意到这是在Excel2007中运行的 'build string of ByChange cells and set up cascading constraints by_change_string = "" For i = 1 To j - 1 If Len(by_change_string) > 0 Th
'build string of ByChange cells and set up cascading constraints
by_change_string = ""
For i = 1 To j - 1
If Len(by_change_string) > 0 Then 'there are already some elements in the string, so we might start with a comma
If Not (Right(by_change_string, 1) = ",") Then 'make sure the last character isn't already a comma
by_change_string = by_change_string & ","
End If
End If
current_status = Sheets("Buyback Risk Area").Range("C1").Offset(i).Value
Select Case current_status
Case "Y" 'risk area is currently yellow, so green transition is available
by_change_string = by_change_string & "$E$" & i + 1
solverok setcell:="$B$" & j + 4, MaxMinVal:=2, ValueOf:="0", ByChange:=by_change_string
'add binary constraints
solveradd cellref:="$E$" & i + 1, relation:=5, formulatext:="binary"
Case "O" 'risk area is currently orange, so green and yellow transitions are available
by_change_string = by_change_string & "$E$" & i + 1 & ",$G$" & i + 1
solverok setcell:="$B$" & j + 4, MaxMinVal:=2, ValueOf:="0", ByChange:=by_change_string
'add cascading constraints
solveradd cellref:="$E$" & i + 1, relation:=1, formulatext:="$G$" & i + 1 'says E <= G, which means you can't select green unless you've already selected yellow
'add binary constraints
solveradd cellref:="$E$" & i + 1, relation:=5, formulatext:="binary"' solveradd cellref:="$G$" & i + 1, relation:=5, formulatext:="binary"
Case "R" 'risk area is currently red, so green, yellow, and orange transitions are available
by_change_string = by_change_string & "$E$" & i + 1 & ",$G$" & i + 1 & ",$I$" & i + 1
'solverok setcell:="$B$" & j + 4, MaxMinVal:=2, ValueOf:="0", ByChange:=by_change_string
'add cascading constraints
solveradd cellref:="$E$" & i + 1, relation:=1, formulatext:="$G$" & i + 1 'says E <= G, which means you can't select green unless you've already selected yellow
solveradd cellref:="$G$" & i + 1, relation:=1, formulatext:="$I$" & i + 1 'says G <= I, which means you can't select yellow unless you've already selected orange
'add binary constraints
solveradd cellref:="$E$" & i + 1, relation:=5, formulatext:="binary"
solveradd cellref:="$G$" & i + 1, relation:=5, formulatext:="binary"
solveradd cellref:="$I$" & i + 1, relation:=5, formulatext:="binary"
Case "B" 'risk area is black, so green, yellow, orange and red transitions are avaailable
by_change_string = by_change_string & "$E$" & i + 1 & ",$G$" & i + 1 & ",$I$" & i + 1 & ",$K$" & i + 1
solverok setcell:="$B$" & j + 4, MaxMinVal:=2, ValueOf:="0", ByChange:=by_change_string
'add cascading constraints
solveradd cellref:="$E$" & i + 1, relation:=1, formulatext:="$G$" & i + 1 'says E <= G, which means you can't select green unless you've already selected yellow
solveradd cellref:="$G$" & i + 1, relation:=1, formulatext:="$I$" & i + 1 'says G <= I, which means you can't select yellow unless you've already selected orange
solveradd cellref:="$I$" & i + 1, relation:=1, formulatext:="$K$" & i + 1 'says K <= M, which means you can't select orange unless you've already selected red
'add binary constraints
solveradd cellref:="$E$" & i + 1, relation:=5, formulatext:="binary"
solveradd cellref:="$G$" & i + 1, relation:=5, formulatext:="binary"
solveradd cellref:="$I$" & i + 1, relation:=5, formulatext:="binary"
solveradd cellref:="$K$" & i + 1, relation:=5, formulatext:="binary"
End Select
Next i
'buyback amount constraint
solveradd cellref:="$O$" & j + 1, relation:=1, formulatext:="$B$" & j + 2
'set target cell
solverok setcell:="$B$" & j + 4, MaxMinVal:=2, ValueOf:="0", ByChange:=by_change_string
'set binary constraints
'binary_array = Split(by_change_string, ",")
'For i = 0 To UBound(binary_array)
' solveradd cellref:=Range(binary_array(i)), relation:=5, formulatext:="binary"
'Next i
Application.ScreenUpdating = True
SolverSolve userFinish:=False
这里的想法是通过从选择的案例中获取所有那些solverok和solverad语句来提高效率。等到最后一个solverok语句之后,所有变量现在都在模型中,因此您应该能够单步遍历By_change_字符串,并将其中的每一个变为二进制变量。这样,您只需要一个SolverRok语句,就可以在选定的情况下删除所有solveradd语句。因此,我注释掉了所选案例中的所有SolverRok和SolverRadd,然后再次运行宏。我没有从解算器得到任何输出。运行后查看“解算器”对话框时,“目标单元格”和“通过更改单元格”字段均为空。这就好像最后的solverok声明从未运行过一样
然后我尝试取消对所有solverok的注释,但将solveradd留给注释掉的二进制变量。我返回到只获取前41个决策变量。设置二进制约束的循环完成了它的工作,但是solverad没有将变量输入到模型中
在这一点上我几乎被难住了。有什么想法吗?正如我所想:
通过更改单元格参数,解算器最多只允许255个字符。如果您不相信,请尝试手动添加所需的单元格。你将无法做到这一点
可以传递解算器的最大非连续范围为51(假设每个组只有1个单元格,格式类似于$A$1,
带有1个字母1个数字2个美元符号和1个逗号)。如果您尝试手动添加更多,它将删除以前的所有选择。假设在代码中执行此操作时,一旦满足长度约束,就会忽略所有内容
老实说,我从未使用过解算器,也不知道如何通过代码访问它。不管怎样,你试图让它做一些它做不到的事情
现在,与其只是告诉你这行不通,不如说这里有一个可能的(但在我看来是令人讨厌的)解决办法。如果我必须做你正在做的事,我会这么做。将重要的值复制到工作簿中的另一个位置,并将它们彼此相邻设置,以便可以将它们作为连续范围传递。解算器运行后,将值放回其应位于的位置
编辑:可能有点过时,但说明如下:
模型决策变量通过更改编辑单元格输入到中
盒子。Excel允许用户输入所谓的多重选择,即
最多由16个范围(矩形、行或列或单个区域)组成
单元格)用逗号分隔
这意味着您只能对解算器使用16个非连续范围,并且希望它能够正常工作。Daniel Cook关于问题原因的看法似乎是正确的。不过我会提出一个不同的解决办法。创建一个包含所有非连续范围的命名范围,并通过“更改”字符串将其设置为表示该命名范围的字符串。我想在这些答案中添加以下内容:
'set binary constraints
'binary_array = Split(by_change_string, ",")
'For i = 0 To UBound(binary_array)
' solveradd cellref:=Range(binary_array(i)), relation:=5, formulatext:="binary"
'Next i