2013-03-25 4 views
2

Я пытаюсь найти максимальную отдачу для простого портфеля с помощью Solver. Использование Solver на листе непосредственно работает разумно, однако это не происходит, когда команды заданы в VBA. Вместо этого (как вы можете видеть из screengrab) он игнорирует одно из ограничений (сумма весов, рассчитанная в T10, должна = 1). Интересно, что работает хорошо, если я меняю третью строчку, чтобы сказать:Excel Solver Игнорирование ограничений в VBA

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 

Любые предложения с благодарностью приветствуется!

+0

Код выглядит хорошо для меня. Кажется ли это так же, как и VBA против VBA? Может быть, попробуйте добавить «CellRef' перед« SolverOK »? –

+0

Может быть, попробуйте использовать только 'Формул-текст: = 1'?(без двойных кавычек) я упоминаю это, потому что [код в MSDN] (http://msdn.microsoft.com/en-us/library/office/ff838657.aspx) не использует кавычки. –

+0

Спасибо. Удаление двойных кавычек помогает (т. Е. Оно остается ниже 10), однако теперь оно игнорирует «$ O $ 10: $ R $ 10» должно равняться 0. Таким образом, оба ограничения игнорируются – Mary

ответ

2

Обнаружена работа вокруг ошибки. Для флага «FormulaText: = 1». вместо использования 1, используйте ссылку на любую ячейку со значением 1 вместо.

есть, изменение "FormulaText: = 1" в "FormulaText: = $ H $ 5", где значение $ H $ 5 является 1

+0

К сожалению, это по-прежнему не удается. – Mary

0

Я был точно такой же вопрос. Я решил это следующим образом: Просто введите FormulaText: = 1 без котировок для 1.

1

Я думаю, что здесь есть ошибка здесь, когда значение равно 1. В других сообщениях указано, что приведенное выше решение (помещая значение в ячейку) ненадежна. Я нашел, что это не работает, мой код всегда ссылается на ячейку, которая содержит ограничение ограничения. Мое (сырое) решение состоит в том, чтобы сдвинуть предельное значение на 1 часть в 10^12 или ниже в соответствующем направлении, которое делает ограничение в < или>, а не < = или> =. Таким образом, вместо:

SolverAdd CellRef:. = Range ("SolverParam") Адрес, связь: = 3, _ FormulaText:. = Range ("SolverConstraint") значение

Использование:

SolverAdd CellRef: = Диапазон («SolverParam»). Адрес, отношение: = 3, _ ФормулаText: = Диапазон («SolverConstraint»). Значение + Abs (Диапазон (значение «SolverConstraint»)). 1e-12

И используйте обратный знак для связи: = 1

В этом тривиальном примере SolverParam - это параметр одиночной ячейки, подлежащий настройке, и SolverConstraint - это нижняя граница одной ячейки.

Это единственный последовательный подход, который я могу предвидеть, чтобы иметь равномерную обработку всех значений

При дальнейшем глядя я нашел другое решение из Интернета

FormulaText: = «=» & Range ("SolverConstraint "). Значение

Кажется, что надёжно работает

+0

Изменение 'Relation: = 2, FormulaText: 1' to' Relation: = 2, FormulaText: = "= 1" "решена моя проблема. – sevenkul

Смежные вопросы