2016-11-02 5 views
0

Во-первых, я попытался изучить проблему, которую я имею, но решения, которые я нашел (например, here, не сработали для меня). Я пытаюсь написать макрос, который использует (обычно) простые функции Solver решения для значения.VBA Solver Constraints Not Set Error (без ограничений)

код я попал следующим образом:

Sub SolverAEP() 

    Dim GeneratedPower As Double 
    GeneratedPower = Worksheets("AEP").Range("D57") 

    SolverReset 

    SolverOk SetCell:="$D$58", _ 
     MaxMinVal:=3, _ 
     ValueOf:=GeneratedPower, _ 
     ByChange:="$D$65" _ 
     , Engine:=1, EngineDesc:="GRG Nonlinear" 

    SolverSolve userFinish:=False  

End Sub 

Ошибка в настоящее время является то, что Solver could not find a feasible solution. Sovler can not find a point for which all Constraints are satisified.

То, что я пробовал:

  • Некоторые онлайн руководство говорит о том, что ValueOf должен быть строкой - я попробовал подход CStr как к Range("D57"), так и к Cells(57,"D").Value, и оба придумали ошибку Solver.
  • Когда я вручную пытаюсь открыть Solver, он всегда открывается с запятой, а не полной остановкой, поэтому я использовал небольшой скрипт для замены всех запятых с полной остановкой, но это ничего не меняло (только пробовал это, когда Я имел дело со строкой как ValueOf. [Я не уверен, почему это происходит на самом деле, но я думаю, что есть какой-то конфликт культуры, поскольку я использую как клавиатуру Continental, так и Великобританию, а настройки локализации довольно случайны.]
  • Запись макроса делает то же самое вручную в Solver дает мне ниже, как код Solver:

    Sub Macro2() 
        SolverOk SetCell:="$D$58", MaxMinVal:=3, ValueOf:=21000#, ByChange:="$D$65" _ 
         , Engine:=1, EngineDesc:="GRG Nonlinear" 
    
        SolverOk SetCell:="$D$58", MaxMinVal:=3, ValueOf:=21000#, ByChange:="$D$65" _ 
         , Engine:=1, EngineDesc:="GRG Nonlinear" 
    
        SolverSolve 
    End Sub 
    
  • В.А. lues, который я теперь мог бы округлить, если это необходимо, - как мне кажется, когда я перешагнул свой написанный макрос, десятичное значение все еще использовало запятую вместо полной остановки. Я попытался округлить значение и поместить его туда, но та же ошибка появилась.

Наконец, я должен добавить, что нет проблем при решении этого вручную с помощью Solver. Связанная ячейка D58 представляет собой сумму других ячеек, значение которых зависит от значения D65.

Может ли кто-нибудь подчеркнуть, что я делаю неправильно, пожалуйста?

В случае, если это имеет значение, я использую Excel 2016

+0

(a) Вы пробовали использовать 'ValueOf: = Worksheets (« AEP »). Диапазон (« D57 »)' вместо 'ValueOf: = GeneratedPower'? (Не уверен, почему это поможет, но стоит попробовать.) (Б) Является ли «AEP» активным листом при запуске макроса? – YowE3K

+0

Я попробую, когда смогу. И нет, не активный лист. Считаете ли вы, что это может изменить ситуацию? – gktscrk

+0

Являются ли ячейки $ D $ 58 и $ D $ 65 рассчитанными на активный лист? Или на лист AEP? Поскольку он в настоящее время настроен, они будут ссылаться на активный лист. – YowE3K

ответ

1

Это выглядит так, будто вы не активируя лист, на котором существуют свои формулы, и поэтому решить делает свой процесс на любой активный в данный момент лист является.

Я рекомендую изменить свой код:

Sub SolverAEP() 

    With Worksheets("AEP") 
     .Activate 

     SolverReset 

     SolverOk SetCell:="$D$58", _ 
       MaxMinVal:=3, _ 
       ValueOf:=[$D$57], _ 
       ByChange:="$D$65", _ 
       Engine:=1, _ 
       EngineDesc:="GRG Nonlinear" 

     SolverSolve userFinish:=False 
    End With 

End Sub 

Activate гарантирует, что выбран правильный лист при выполнении Solver. (Подобно тому, как я ненавижу использование Activate, Select, Selection и т.д., это один из тех моментов, что требуется - решатель будет работать только на активном листе.)


Re ваш комментарий о значениях не обновляясь до тех пор, пока вы не запустите Solver во второй раз, если у вас есть заявка Application.ScreenUpdating = False, я не могу думать ни о какой другой причине, кроме довольно очевидного вопроса: «Вы тоже включили заявление Application.ScreenUpdating = True?».

Я попытался запустить его только с =False и работает SolverAEP заставил экран обновляться после завершения макроса.

Однако, если я написал другую подпрограмму, такие как следующие:

Sub Test 
    SolverAEP 
    MsgBox "Finished first solve" 
    SolverAEP 
    MsgBox "Finished second solve" 
End Sub 

и побежал, а затем (с только =False и без соответствующего =True) экран не обновляется до тех пор, End Sub из Sub Test не будет достигнута , Это ожидаемое поведение остановки ScreenUpdating.

+0

Спасибо за оба счета. Я думаю ты прав; У меня есть соответствующий '= True' для экранирования, но я думаю, что он не оптимально размещен. Я попробую вашу версию рабочего листа активировать и посмотреть, как это работает. Однако основная проблема решена. – gktscrk