Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Переполнение стека


Defort ©   (2006-11-30 17:20:00) 

У меня снова проблема. В процедуре вычисления вычислимых полей у меня происходит переполнение стека. Код выглядит так:

k:=DaysBetween(datemust, datelast);
 for i:=1 to k do //ê - êîëè÷åñòâî äíåé ìåæäó äàòîé ôàêòè÷åñêîé äàòû îïëàòû è äàòû îïëàòû ïî ãðàôèêó
     DataModule1.ADOTable3DSDesigner3.Value{ïåíè}:=ADOTable3DSDes igner2.AsCurrency{ñóììà ïëàòåæà}+ADOTable3DSDesigner2.AsCurrency{ñóììà ïëàòåæà}*ADOTable1DSDesigner4.AsCurrency{ 4;îýôôèöèåíò ïåíè}; // Ôîðìèðîâàíèå ïîëÿ "Ïåíè": çà êàæäûé äåíü ïðñòîÿ äîáàâëÿåòñÿ ïåíè
 DataModule1.ADOTable3DSDesigner5.Value{îñòàòîê ;}:=ADOTable3DSDesigner2.AsCurrency{ñóììà ïëàòåæà}+ADOTable3DSDesigner3.AsCurrency{ïåíè}-ADOTable3DSDesigner7.AsCurrency{ïîñòóïèë î îïëàòû}; // Ôîðìèðîâàíèå ïîëÿ "Îñòàòîê"
 if (ADOTable3DSDesigner2.AsCurrency+ADOTable3DSDesigner3.AsCurrency)=ADOTable3DSDesigner5.AsCurrency then
    ADOTable3DSDesigner4.Value:=true; //ïîãàøåí: äà


Переполнение происходит на строке

DataModule1.ADOTable3DSDesigner5.Value{îñòàòî ;ê}:=ADOTable3DSDesigner2.AsCurrency{ñóììà ïëàòåæà}+ADOTable3DSDesigner3.AsCurrency{ïåíè}-ADOTable3DSDesigner7.AsCurrency{ïîñòóïèë î îïëàòû}; // Ôîðìèðîâàíèå ïîëÿ "Îñòàòîê"

Не подскажете, в чем ошибка?


Anatoly Podgoretsky   (2006-12-02 20:27:00) [1]

> Defort  (02.12.2006 20:08:17)  [17]

Пипол за углом водку пьет, а здесь программисты


Defort   (2006-12-02 20:08:00) [2]

Пипол! Чево молчите все? (


Defort   (2006-12-02 16:13:00) [3]


> Приведи свои попытки, тогда поверю.
>


Ок. Ниже код

procedure TDataModule1.ADOTable3CalcFields(DataSet: TDataSet);
var datelast, datemust: TDateTime;
   i, k: word; //счетчик
   peni, ending{остаток}: real;
begin
 datelast:=DataModule1.ADOTable3DSDesigner8.AsDateTime;
 datemust:=DataModule1.ADOTable3DSDesigner.AsDateTime;
 if datelast=NULL then datelast:=now;
 k:=DaysBetween(datelast, datemust);
 for i:=1 to k do //к - количество дней между датой фактической даты оплаты и даты оплаты по графику
     peni{пени}:=ADOTable3DSDesigner2.AsCurrency{сумма платежа}+ADOTable3DSDesigner2.AsCurrency{сумма платежа}*ADOTable1DSDesigner4.AsCurrency{коэффициент пени}; // Формирование поля "Пени": за каждый день прстоя добавляется пени
 DataModule1.ADOTable3DSDesigner3.Value:=peni;
 ending{остаток}:=ADOTable3DSDesigner2.AsCurrency{сумма платежа}+peni-ADOTable3DSDesigner7.AsCurrency{поступило оплаты}; // Формирование поля "Остаток"
 DataModule1.ADOTable3DSDesigner5.Value:=ending;
 if (ADOTable3DSDesigner2.AsCurrency+peni)=ending then
    ADOTable3DSDesigner4.Value:=true; //погашен: да
end;


Я трассировал, у меня процедура выполняется по кругу. (это ведб и есть рекурсия).

Да, и еще проблема: в цикл for программа не входит. видимо я снова перемудрил что то с датами. Может ктонить прочекатЬ?


ЮЮ   (2006-12-02 08:56:00) [4]

Вычислимое поле в этом обработчике можно использовать только слева в операторе присваивания. Любое другое использование приведет к необходимости его вычисления и рекурсивному вазовы этого же обработчика

  DataModule1. ADOTable3DSDesigner3. Value{пени}:=ADOTable3DSDesigner2.AsCurre ncy{сумма платежа}+ADOTable3DSDesigner2.AsCurrency{сумма платежа}*ADOTable1DSDesigner4.AsCurrency{коэффициент пени}; // Формирование поля "Пени": за каждый день прстоя добавляется пени
peni:=DataModule1. ADOTable3DSDesigner3.AsCurrency;
DataModule1. ADOTable3DSDesigner5.Value{остаток}:=ADOTable3DSDesigner2.AsCurrency {сумма платежа}+peni-ADOTable3DSDesigner7.AsCurrency{поступило оплаты}; // Формирование поля "Остаток"
if (ADOTable3DSDesigner2.AsCurrency+peni)= ADOTable3DSDesigner5.AsCurrencythen
   ADOTable3DSDesigner4.Value:=true; //погашен: да


сначала посчитай peni, а потом присваивай полю
аналогично с плем ADOTable3DSDesigner5.AsCurrency


ЮЮ   (2006-12-02 08:47:00) [5]


> вот исходный код:

Исходный код, по определению, приведет к переполнению стека. См.[10]


> Посчет использования промежуточных переменных - я это пытался
> делать. Только толку не слишком.

Пока имеем от тебя только то, что имеем, а именно, код,  по определению, приводящий к переполнению стека. Приведи свои попытки, тогда поверю.


Defort   (2006-12-01 20:16:00) [6]

2Пипл
Посчет копирования понял, вот исходный код:

 k:=DaysBetween(datemust, datelast);
 for i:=1 to k do //к - количество дней между датой фактической даты оплаты и даты оплаты по графику
      DataModule1.ADOTable3DSDesigner3.Value{пени}:=ADOTable3DSDesigner2.AsCurre ncy{сумма платежа}+ADOTable3DSDesigner2.AsCurrency{сумма платежа}*ADOTable1DSDesigner4.AsCurrency{коэффициент пени}; // Формирование поля "Пени": за каждый день прстоя добавляется пени
 peni:=DataModule1.ADOTable3DSDesigner3.AsCurrency;
 DataModule1.ADOTable3DSDesigner5.Value{остаток}:=ADOTable3DSDesigner2.AsCurrency {сумма платежа}+peni-ADOTable3DSDesigner7.AsCurrency{поступило оплаты}; // Формирование поля "Остаток"
 if (ADOTable3DSDesigner2.AsCurrency+peni)=ADOTable3DSDesigner5.AsCurrency then
    ADOTable3DSDesigner4.Value:=true; //погашен: да


Посчет использования промежуточных переменных - я это пытался делать. Только толку не слишком. Если честно я и сам в этих дизайнерах запутался - может что и пропустил.


Desdechado   (2006-12-01 11:03:00) [7]

Gydvin ©   (01.12.06 08:56) [11]
Все гораздо проще - перед Ctrl-C переключиться на русскую раскладку клавы.


Gydvin   (2006-12-01 08:56:00) [8]

[0] сохраняешь проект, юниту открываешь блокнотом, и отуда уже копируешь, тогда кАменты отображаются нормально


ЮЮ   (2006-12-01 05:25:00) [9]

DataModule1.ADOTable3DSDesigner5.Value :=
 ADOTable3DSDesigner2.AsCurrency + ADOTable3DSDesigner3.AsCurrency - ADOTable3DSDesigner7.AsCurrency;


исходя из этого иожно предположить, что Designer5 вычислимое поле
тогда использование его в выражении приводит к очередному вызову обработчика
if (ADOTable3DSDesigner2.AsCurrency+ADOTable3DSDesigner3.AsCurrency) = ADOTable3DSDesigner5.AsCurrencythen
   ADOTable3DSDesigner4.Value:=true;


Решение:
1) заменить на
if ADOTable3DSDesigner7.AsCurrency = 0 then //если Designer7 не вычислимое :)

2) вычисления хранить в промежуточных переменных:
  s :=ADOTable3DSDesigner2.AsCurrency + ADOTable3DSDesigner3.AsCurrency - ADOTable3DSDesigner7.AsCurrency;
 DataModule1.ADOTable3DSDesigner5.Value := s;
if (ADOTable3DSDesigner2.AsCurrency+ADOTable3DSDesigner3.AsCurrency) = sthen


Anatoly Podgoretsky   (2006-12-01 00:43:00) [10]

> Defort  (30.11.2006 23:02:08)  [8]

> //e - eiee?anoai aiae ia?ao aaoe oaeoe?aneie aaou iieaou e aau iieaou ii a?aoeeo

Что за муа?


Defort   (2006-11-30 23:02:00) [11]

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

for i:=1 to k do //ê - êîëè÷åñòâî äíåé ìåæäó äàòîé ôàêòè÷åñêîé äàòû îïëàòû è äàòû îïëàòû ïî ãðàôèêó
     DataModule1.ADOTable3DSDesigner3.Value{ïåíè}:=ADOTable3DSDes igner2.AsCurrency{ñóììà ïëàòåæà}+ADOTable3DSDesigner2.AsCurrency{ñóììà ïëàòåæà}*ADOTable1DSDesigner4.AsCurrency{ 4;îýôôèöèåíò ïåíè}; // Ôîðìèðîâàíèå ïîëÿ "Ïåíè": çà êàæäûé äåíü ïðñòîÿ äîáàâëÿåòñÿ ïåíè
 peni:=DataModule1.ADOTable3DSDesigner3.AsCurrency;
 DataModule1.ADOTable3DSDesigner5.Value{îñòàòîê ;}:=ADOTable3DSDesigner2.AsCurrency{ñóììà ïëàòåæà}+peni-ADOTable3DSDesigner7.AsCurrency{ïîñòóïèë î îïëàòû}; // Ôîðìèðîâàíèå ïîëÿ "Îñòàòîê"
 if (ADOTable3DSDesigner2.AsCurrency+peni)=ADOTable3DSDesigner5.AsCurrency then
    ADOTable3DSDesigner4.Value:=true; //ïîãàøåí: äà


Defort   (2006-11-30 21:27:00) [12]


> Поставь точку останова на свое строке и протрассируй.


Делал. Там реально рекурсия. Но блин, по другому я не знаю как сделать. Я в раздумьях!


Джо   (2006-11-30 21:23:00) [13]

Поставь точку останова на свое строке и протрассируй.


Defort   (2006-11-30 21:08:00) [14]


> Твой код читать невозможно, о чем ты говоришь? :)

Читать невозможно толька камменты ;) для этого я отпостил второй пост!


Джо   (2006-11-30 21:04:00) [15]

> [3] Defort ©   (30.11.06 21:02)
> Кстати может быть (( А на примере моего кода непонятно,
> как это исправить?

Твой код читать невозможно, о чем ты говоришь? :)


Defort   (2006-11-30 21:02:00) [16]

Кстати может быть (( А на примере моего кода непонятно, как это исправить?


Desdechado   (2006-11-30 17:26:00) [17]

наверняка в рекурсию ввалился
вычисление одногополя ведет к вычислению другого, а от него снова вычисляется первое


Defort   (2006-11-30 17:23:00) [18]

Что то комменты там криво отображаются, поэтому пишу что делает код:

к - количество дней между фактической датой платежа и датой по графику
Для каждого просроченного дня добавляется пени, равное сумме платежа*коэффициент пени
после этого идет формирования поля остаток: сумма платежа+сумма пени-заплачено - тут и происходит переполнение


Наверх

Титульная страница Поиск, карта сайта Написать письмо