Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.01.2010, 15:21   #1
usa10co
holod-proekt.com
 
Аватар для usa10co
 
Регистрация: 29.01.2010
Сообщений: 5
Стрелка ошибка #ДЕЛ/0! при итерации

всех приветствую!
я новенький на этом форуме.
пытался решить проблему своими силами и умственными возможностями, но "воз и ныне там"
собсна, поэтому и пишу.

начну издалека и плавно перейду к главному.
с помощью excel мною была построена математическая модель работы асборбционной холодильной машины (изменение температуры и энтальпии водоаммиачного раствора описывается математическими уравнениями).
задача данной модели - расчет цикла (прямого и обратного) при изменении исходных данных, которыми служат температура слабого раствора после генератора t2, температура конденсации t6 и температура паров аммиака после испарителя t8.
благодаря применению циклических ссылок (читай, итераций), расчет ведется успешно, хоть и долго.
и вот, когда пришел черед автоматизации при определении температуры слабого раствора после регенеративного теплообменника t3 проблема и проявила себя.
итак, суть: эта температура t3 зависит от нескольких факторов:
1) мольной концентрации слабого раствора ψa - определена ранее опять же с помощью итерации, т.е. в данном случае выступает уже как постоянная;
2) давления p - его и необходимо просчитать. формула для определения была проста: =если((t3-t6)>5,0001;p-0,0001;если((t3-t6)<5,0001;p+0,0001))
и когда я клацаю enter начинается процесс обработки и через некоторое время выдается ошибка "#ДЕЛ/0!".
загвоздка в том, что это давление р присутствует в знаменателе при определении t3.
процесс итерации, как я понимаю, начинается с 0, а, как нам известно, на ноль делить нельзя. ну, можно, конечно, но получится бесконечность 8-)
вопрос в следующем: что делать?
вижу 2 варианта:
1) задание области итерации, но мои поиски такой функции закончились безуспешно =( ;
2) ваш вариант.

в меню "сервис" такой вкладки как "поиск решения" у меня нет.
есть подбор параметра, но то не то пальто

вскользь читал, что могут использоваться возможности надстройки ВБА, если она поможет, буду осваивать.

я понимаю, что поставленная задача абстрактна в своей постановке, но разрешима, если разобраться.

а вот и файлик, где все это делается
Только идущий осилит дорогу!
holod-proekt - Проектирование холодильных систем

Последний раз редактировалось usa10co; 29.01.2010 в 15:45. Причина: добавления файла
usa10co вне форума Ответить с цитированием
Старый 29.01.2010, 15:26   #2
javvva
Пользователь
 
Аватар для javvva
 
Регистрация: 23.01.2010
Сообщений: 70
По умолчанию

еще бы файлик где все это делается. было бы совсем замечательно.
javvva вне форума Ответить с цитированием
Старый 29.01.2010, 15:42   #3
usa10co
holod-proekt.com
 
Аватар для usa10co
 
Регистрация: 29.01.2010
Сообщений: 5
По умолчанию

а вот и сам файлик, где все это делается
Только идущий осилит дорогу!
holod-proekt - Проектирование холодильных систем
usa10co вне форума Ответить с цитированием
Старый 30.01.2010, 12:58   #4
usa10co
holod-proekt.com
 
Аватар для usa10co
 
Регистрация: 29.01.2010
Сообщений: 5
По умолчанию

пока безуспешно пробую все варианты.
Только идущий осилит дорогу!
holod-proekt - Проектирование холодильных систем
usa10co вне форума Ответить с цитированием
Старый 01.02.2010, 15:43   #5
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию

Свой файлик-то Вы так и не приаттачили к своим сообщениям!

Ваша формула:
= если((t3-t6)>5,0001;p-0,0001;если((t3-t6)<5,0001;p+0,0001))
Где t3, t6, p – другие ячейки, причем t3 – независимая, p – меняется данной формулой, t6 = F(1/p).
Раскладываем логику данной формулы по полочкам:
- если ((t3-t6)>5,0001 то уменьшаем значение переменной p на 0,0001
- иначе (т.е если ((t3-t6)<=5) проверяем условие ((t3-t6)<5) и если оно выполняется, то увеличиваем значение переменной p на 0,0001)
- если не то и не иное, т.е (t3-t6) = 5,0001 то ничего не делаем
Вы именно эту логику имели в виду?
Если это, то алгоритм будет работать, пока не выполнится равенство (t3-t6) = 5,0001 с предельной разрядностью Excel. Даже если результат будет, скажем, p = 5,00010000000000000000001, то он все равно > 5,0001 и приращение для p будет выдано!
Вам для начала надо установить диапазон чувствительности для результата.

Я бы ввел еще две ячейки:
- для независимой переменной «шаг итерации» и вместо цифр в формуле (0,0001) вставил бы ссылку на нее, что позволит быстро подбирать шаг итерации, не влезая в формулу, обозначим d
- для независимой переменной «предельное отклонение от результата» (т.е. от 5,0001), например 0,0001 – обозначим m
Новая формула:
= если((t3-t6)>5,0001+m;p-d;если((t3-t6)<5,0001-m;p+d;p))
Вычисление остановится со значением p в ячейке формулы при вхождении результата в зону 5,0001 (+-) 0,0001
Меняйте m и d и наблюдайте результаты

Если ошибка повторится – то «загвоздка в том, что это давление р присутствует в знаменателе при определении t3.» и если p=0 то возникает ошибка деления на нуль – введите в формулу дополнительное условие Если p=0 и его обработку:
alvazor вне форума Ответить с цитированием
Старый 01.02.2010, 21:02   #6
Teslenko_EA
Участник клуба
 
Регистрация: 10.08.2009
Сообщений: 1,796
По умолчанию

Здравствуйте usa10co.
из Вашего неработоспособного файла (выложенного на стороннем сайте, с некорректным именем и отсутствующим расширением ) мне удалось извлечь формулу ячейки E20:
=ЕСЛИ((C21-C4)>5,0001;E20-0,0001;ЕСЛИ((C21-C4)<5,0001;E20+0,0001))
одного взгляда достаточно - формула с циклической ссылкой, т.е. ссылается на себя, и потому конструкция не может быть работоспособна в принципе.
Для решения задачи со сложной логикой вычислений удобно применять Пользовательские функции которые избавят от подобных "нагромождений":
Код:
=J66*((L52*(1-I8)^J52*(LN(L66/E8))^K52)+(L53*(1-I8)^J53*(LN(L66/E8))^K53)+(L54*(1-I8)^J54*(LN(L66/E8))^K54)+
(L55*(1-I8)^J55*(LN(L66/E8))^K55)+(L56*(1-I8)^J56*(LN(L66/E8))^K56)+(L57*(1-I8)^J57*(LN(L66/E8))^K57)+
(L58*(1-I8)^J58*(LN(L66/E8))^K58)+(L59*(1-I8)^J59*(LN(L66/E8))^K59)+(L60*(1-I8)^J60*(LN(L66/E8))^K60)+
(L61*(1-I8)^J61*(LN(L66/E8))^K61)+(L62*(1-I8)^J62*(LN(L66/E8))^K62)+(L63*(1-I8)^J63*(LN(L66/E8))^K63)+
(L64*(1-I8)^J64*(LN(L66/E8))^K64)+(L65*(1-I8)^J65*(LN(L66/E8))^K65))
и самое главное будут работоспособны.
Пользовательские функции могут располагаться как в Надстройке так и в собственном Модуле документа, применяя их можно избавиться и от нагромождения формул и от непредвиденных ошибок.
Как(?):
создайте в файле модуль и разместите в нем подобный код:
Код:
Public Function result1() as double
On Error resume Next 'обработчик ошибок
' в случае неверных исходных данных функция вернет 0
   With Sheets(1)
       result1 = .[a1] * .[b1] / .[c1]
    End With
End Function
введите в ячейки A1, B1, C1 первого листа числовые значения, а в ячейке D1 разместите функцию = result1(), и она вернет Вам результат вычисления.
Пытайтесь, удачи Вам.
Евгений.
Teslenko_EA вне форума Ответить с цитированием
Старый 02.02.2010, 09:40   #7
alvazor
Форумчанин
 
Регистрация: 02.07.2009
Сообщений: 122
По умолчанию

И в дополнение
Teslenko_EA конечно прав, что для итераций положено использовать пользовательские функции, просто для освоения этого потребуется определенное время. Электронные таблицы - не для организации циклов!
А чтобы разрешить выполнение итераций (циклических ссылок) на листе - поставьте галочку в пункте Итерации (меню Сервис - Параметры - закладка Вычисления). Там же Вы можете установить допустимое число итераций и предел отклонения. При более-менее правильных алгоритмах, это позволяет вчерне отработать решения, чтобы потом все перевести в нормальные программы (макросы) или применить надстройки, напр. Поиск решения
alvazor вне форума Ответить с цитированием
Старый 02.02.2010, 13:40   #8
usa10co
holod-proekt.com
 
Аватар для usa10co
 
Регистрация: 29.01.2010
Сообщений: 5
Восклицание Re: ошибка #ДЕЛ/0! при итерации

Цитата:
Свой файлик-то Вы так и не приаттачили к своим сообщениям!
уже сделал!

для ячейки I8: =ЕСЛИ((C9-C3)>0,0005;I8+0,00001;ЕСЛИ((C9-C3)<-0,0005;I8-0,00001;I8))
описание: если разность между заданной в начале t2 и полученной в расчете t2 больше 0,0005, то I8+0,00001; иначе если эта разность меньше -0,0005, то I8-0,00001; если -0,0005<I8<0,0005, остается текущее I8.
для ячейки I10: =ЕСЛИ((C11-C4)>0,0005;I10+0,00001;ЕСЛИ((C11-C4)<-0,0005;I10-0,00001;I10))
описание: аналогично вышеизложенному с той лишь разницей, что это для темпераутры t4.
для ячейки I20: =ЕСЛИ(ЕОШ(ЕСЛИ((C21-C11)>5,0005;E20-0,0001;ЕСЛИ((C21-C11)<4,9995;E20+0,0001)));0,01;ЕСЛИ ((C21-C11)>5,0005;E20-0,0001;ЕСЛИ((C21-C11)<4,9995;E20+0,0001;E20)))
описание: если в условии (C21-C11)>5,0005;E20-0,0001;ЕСЛИ((C21-C11)<4,9995;E20+0,0001 ошибка (конкретно, в значении С21), то присваивается значение р=0,01; если нет, то считается по аналогии с предыдущими примерами.
для ячейки I22: =ЕСЛИ(ЕОШ(ЕСЛИ((K22-B38)>0,005;E22-0,0001;ЕСЛИ((K22-B38)<-0,005;E20+0,0001)));E8;ЕСЛИ((K22-B38)>0,005;E22-0,0001;ЕСЛИ((K22-B38)<-0,005;E22+0,0001;E22)))
описание: аналогично вышеизложенному с той лишь разницей, что сравниваются не температуры, а энтальпии: (K22-B38) (энтальпия, полученная с помощью формул из зарубежной статьи i1ф и в результате расчета цикла i1р=i4+(qт/a)).

Цитата:
Я бы ввел еще две ячейки:
- для независимой переменной «шаг итерации» и вместо цифр в формуле (0,0001) вставил бы ссылку на нее, что позволит быстро подбирать шаг итерации, не влезая в формулу, обозначим d
- для независимой переменной «предельное отклонение от результата» (т.е. от 5,0001), например 0,0001 – обозначим m
Новая формула:
= если((t3-t6)>5,0001+m;p-d;если((t3-t6)<5,0001-m;p+d;p))
Вычисление остановится со значением p в ячейке формулы при вхождении результата в зону 5,0001 (+-) 0,0001
Меняйте m и d и наблюдайте результаты
спасибо, учту.
тогда формула чуть изменится: =если((t3-t6)>5+m;p-d;если((t3-t6)<5-m;p+d;p))

Код:
=J66*((L52*(1-I8)^J52*(LN(L66/E8))^K52)+(L53*(1-I8)^J53*(LN(L66/E8))^K53)+(L54*(1-I8)^J54*(LN(L66/E8))^K54)+
(L55*(1-I8)^J55*(LN(L66/E8))^K55)+(L56*(1-I8)^J56*(LN(L66/E8))^K56)+(L57*(1-I8)^J57*(LN(L66/E8))^K57)+
(L58*(1-I8)^J58*(LN(L66/E8))^K58)+(L59*(1-I8)^J59*(LN(L66/E8))^K59)+(L60*(1-I8)^J60*(LN(L66/E8))^K60)+
(L61*(1-I8)^J61*(LN(L66/E8))^K61)+(L62*(1-I8)^J62*(LN(L66/E8))^K62)+(L63*(1-I8)^J63*(LN(L66/E8))^K63)+
(L64*(1-I8)^J64*(LN(L66/E8))^K64)+(L65*(1-I8)^J65*(LN(L66/E8))^K65))
эту формулу писал не я, она из той же статьи, но представлена там в виде суммы от 1 до 16, потому и нагромождение такое в экселе получилось!
Код:
Public Function result1() as double
On Error resume Next 'обработчик ошибок
' в случае неверных исходных данных функция вернет 0
   With Sheets(1)
       result1 = .[a1] * .[b1] / .[c1]
    End With
End Function
это уже использование надстройки ВБА началось?
для меня темный лес =(

Цитата:
При более-менее правильных алгоритмах, это позволяет вчерне отработать решения, чтобы потом все перевести в нормальные программы (макросы) или применить надстройки, напр. Поиск решения
ну, в принципе цикл на сегодняшний день считается нормально, значения вполне согласуются с подсчетами вручную.

вот несколько проблем:
1. итерации не останавливаются, пока не закончатся (т.е. если задал 10000 итераций, даже если условие выпоняется - процесс не останавливается).
пример: при определении t2, допустим, имеем разницу 0,0003, которая меньше 0,0005 и как бы по логике итерации должны остановиться, оставив то значение концентрации (ячейки I8 и I10), при котором разница составляет 0,0003.
так и дожно быть?
2. когда использую итерации, нередко в конце процесса подсчета остается такое значение концентрации, при котором разница температур t2 заданная и полученная соствляет, допустим, -0,0012 или 0,0009, хотя как бы, опять же по логике, должно быть 0,0003.

Попробую надстройку "Поиск решения" поосваивать.

Спасибо, что откликнулись.
Вложения
Тип файла: rar для форуму моделювання з РТО, Р та Д (30;0).rar (15.0 Кб, 12 просмотров)
Только идущий осилит дорогу!
holod-proekt - Проектирование холодильных систем
usa10co вне форума Ответить с цитированием
Старый 03.02.2010, 16:26   #9
usa10co
holod-proekt.com
 
Аватар для usa10co
 
Регистрация: 29.01.2010
Сообщений: 5
Лампочка

специалисты, что подскажите по верхнему посту?
Только идущий осилит дорогу!
holod-proekt - Проектирование холодильных систем
usa10co вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Метод простой итерации. (ЧМ) Rise Помощь студентам 2 05.11.2009 18:00
Метод простых итерации для нелинейных уравнений. Подскажите где ошибка DuHbka Помощь студентам 15 31.05.2009 22:46
Метод простой итерации Artemm Общие вопросы C/C++ 17 31.05.2009 14:06
Изменение расширения файла при каждой итерации Jack Torrance Помощь студентам 3 18.12.2007 23:24