0
Ноя 15
Всем привет!
Пробовал ли кто-либо прикрутить встроенный экселевский поиск решения (Solver) в VBA без указания адресов ячеек?
Поясню: по умолчанию солвер записывается так:
SolverOk SetCell:="$B$53", MaxMinVal:=3, ValueOf:=0, ByChange:= "$B$29,$B$36,$B$12", Engine:=1, EngineDesc:="GRG Nonlinear"
Требуется, чтобы макрос обращался к переменной, а не к ячейке с записанными датами.
Возможно, кто-нибудь сможет предложить иной простой минимизатор взамен встроенного экселевского?
Опубликовано
18 Ноя 2015
Активность
11
ответов
6773
просмотра
8
участников
2
Рейтинг
Контекст
VBA x5
А что мешает записать значение переменной в ячейку, и обращаться все таки к ячейке?
Если переменная - вектор, можно поискать употребление именованных диапазонов в макросах и, в частности, солвере - что-то вроде "excel solver named ranges"... Стек-оверфлоу что-то не очень качественное выдает (http://stackoverflow.com/questions/30417923/excel-solver-named-ranges-in-vba)
Google -> excel vba solver macro
Первые пять ссылок дают развернутый ответ.
Прочтите, пожалуйста, мой вопрос повнимательнее. Задача заключается в отказе от использования ссылок на ячейки.
Думаю можно только через именованные ячейки. Для VBA они в каком-то смысле выступают переменными так что зачем изобретать велосипед (не понимаю в чем для вас проблема подхода через ячейки). Второй вариант если solver имеет паблик API через библиотеки dll/xll по типу Crystall Ball где можно вызовы делать напрямую (скорей всего такая опция есть даже если она не документирована).
*Сами подумайте как solver будет знать какие и где переменые вы объявили в своем макросе который к тому же скорее всего зацеплен на одну workbook, а solver внешний ко всем workbook-ам. Т.е. чтобы солверу напрямую обращаться к вашим VBA переменным это надо очень много jumps through hoops ему сделать.
Проблема в том, что у меня функция, в которой находится неизвестная переменная, всегда разная. Поэтому для каждого случая ее приходится прописывать программно через Range.Formula = "=..."
С этим согласен. Вижу выход только в отказе от встроенного солвера.
Тогда, может быть, решать задачу функциональным программированием - средства R или C# вам в помощь. Хотя даже и в простом C можно указатель на функцию использовать в аргументах.
Впрочем, в формулировке проблемы остается не совсем понятным вот что - каким образом формируются функции? Даже если фукнции разные, их код ведь все равно должен быть априори прописан...
Все равно не понимаю в чем проблема. Допустим у вас имеется функция y=f(x) которая может быть y=z(x) и т.д. Сделайте функцию wraper и поставте ее в ячейку '=mywrapfunction(input_cell)'. Эта mywrapfunction будет прописана в VBA и может ссылаться на что угодно, например:
function mywrapfunction(v as double) as double
result=f(v) or result=z(v) и т.д.
end function
Как кто-то выше уже упомянул, эта проблема решается использованием ячейки в качестве переменной. В конце концов, переменная – это просто контейнер определенного типа. Вы так же можете под нее выделить определенную ячейку и, вместо того чтобы присваивать значение переменной в коде, присваивать значение ячейке. Если у вас, скажем, 30 шагов по времени и на каждом шаге вам независимо нужно оптемизировать 10 коэффициентов (оптимизация дебитов скважин, к примеру), то вы можете выделить 10 ячеек для солвера + 1 ячейку для оптимизируемого значения и в коде связывать эти ячейки с ячейками нужной строки таблицы, которая оптимизируется. В данном случае солвер будет тупо менять значения в этих ячейках, а они будут отражаться в таблице и отрабатываться как нужно (лукапы, формулы, и т.д.). Закончили с одной строкой, перекинули ссылки и заново повторили.
Михаил Н. в эксель можно дописать любую свою функцию, погуглите
http://www.firststeps.ru/vba/excel/r.php?72
в новых версиях нужно сохранить книгу в специальном формате (расширении), посмотрите при сохранении что то вроде сохранить с поддержкой функций
Коллеги, хочу вернуться к вопросу прикручивания солвера.
Необходимо вызвать процедуру в процессе решения Solver, чтобы значение в оптимизируемой ячейке посчитать.
При вызове Solver в VBA есть в опциях SolverOptions ключ StepThru. Он позволяет в итоге вызывать макрос для обработки событий, где вроде как можно прописать свою функцию.
В инете ищутся некоторые варианты решений, но не все у меня работает как надо. В 2010 экселе, Solver останавливается (по требованию пользователя), что вроде пишут как баг этой версии.
Есть у кого опыт решения подобной задачи?
Михвил, добрый день!
На сколько я понимаю, вы пытаетесь сделать адрес ячеек (на которые ссылается Solver) динамическим. Ваша проблема решается следующим образом,
a,c-строки, b,d-колонки
SolverOk SetCell:=Cells(a,b), MaxMinVal:=3, ValueOf:=0, ByChange:= Cells(c,d), Engine:=1, EngineDesc:="GRG Nonlinear"