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

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

Помогите решить проблемму с функцией


DelphiN! ©   (2004-11-30 08:38:00) 

Есть функция, которая преобразует введенную сумму денег во время, исходя из "Таблицы списка услуг", в которой храниться информация в следующем виде :

Name          Summa   Vremia_S   Vremia_Po   Comp_S   Comp_Po

Игры            60          12:00       18:00            1            200
Интернет      120         18:00       22:00           1            200
...               ...             ...          ...              ...             ...

Поле Summa в таблице заполнено списком цен услуг за час

Так вот данная ф-ия "работает через раз"  То считает правильно, то зацикливается, зацикливается кстати из за того что выражение:

Money := Money - ( ( DateTimeToUnix(Time_Po) - DateTimeToUnix(_Time) ) / 60 ) * ( DataSet.FieldByName('Summa').AsFloat / 60 );
           

иногда не дает никаких результатов, тоесть
( ( DateTimeToUnix(Time_Po) - DateTimeToUnix(_Time) ) / 60 ) * ( DataSet.FieldByName('Summa').AsFloat / 60 )    равно нулю, и получается (Money := Money - 0).  Так вот я понять немогу что тут неправильно, и почему то работает, то неработает ... Похоже это зависит от текущего времени ...

Помогите разобраться, ото совсем голова не варит ...


//Тип возвращаемый ф-ие MoneyToTime
 type
  TimeStruct = Record
    VremyaOkonchania:TTime;
    Prodoljitelnost:String;
 end;

function MoneyToTime(Money:Real;__Time:TTime;Usluga:String;CompNo:Integer;DataSet:TClientDataSet):TimeStruct;

//Ф-ия проверки принадлежности времени заданому диапазону
function TestTime(t,MinTimeInt,MaxTimeInt:TDateTime):Boolean;
begin
 t := StrToDateTime('01.01.2004 '+TimeToStr(t) );
 MinTimeInt := StrToDateTime('01.01.2004 '+TimeToStr(MinTimeInt) );
 MaxTimeInt := StrToDateTime('01.01.2004 '+TimeToStr(MaxTimeInt) );

 if T < MinTimeInt then
   T := T + 1;
 if MaxTimeInt < MinTimeInt then
   MaxTimeInt := MaxTimeInt + 1;

 if InRange(t,MinTimeInt,MaxTimeInt) then
   result := true
 else
   result := false;
end;

//Тело ф-ии преобразования денег во время (MoneyToTime)
var
 _Time:TDateTime;
 i2:integer;
 Time_PO:TDateTime;
 m:Real;
 Count: Integer;
begin
__Time := StrToDateTime('01.01.2004 '+TimeToStr(__Time) );
_Time := __Time;

Count := 0;

 while Money > 0 do
 begin
 Inc(Count);
 if Count > 100 then
 begin
   ShowMessage('В таблице услуг обнвружен разрыв! Исправте таблицу услуг!');
   Exit;
 end;

   for i2 := 1 to DataSet.RecordCount do
   begin
       DataSet.RecNo := i2;
     if DataSet.FieldByName('Name').AsString = Usluga then
       if (CompNo >= DataSet.FieldByName('Comp_s').AsInteger) and (CompNo <= DataSet.FieldByName('Comp_po').AsInteger) then
         if TestTime(_Time,DataSet.FieldByName('Vremia_s').AsDateTime,DataSet.FieldByName('Vremia_po').AsDateTime) then
         begin
           if (Money - ((DateTimeToUnix(StrToDateTime(DateToStr(_Time)+' '+DataSet.FieldByName('Vremia_po').AsString)) - DateTimeToUnix(_Time) ) / 60 ) * (DataSet.FieldByName('Summa').AsFloat / 60)) > 0 then
             Time_Po := StrToDateTime(DateToStr(_Time)+' '+DataSet.FieldByName('Vremia_po').AsString)
           else
           begin
             Time_Po := UnixToDateTime( DateTimeToUnix(_Time) +
             Round((DataSet.FieldByName('Summa').AsFloat / 60)*Money)*60 );
           end;
           Money := Money - ( ( DateTimeToUnix(Time_Po) - DateTimeToUnix(_Time) ) / 60 ) * ( DataSet.FieldByName('Summa').AsFloat / 60 );
           _Time := UnixToDateTime( DateTimeToUnix(_Time) + ( DateTimeToUnix(Time_Po) - DateTimeToUnix(_Time) ) );
         end
   end
 end;
   Result.VremyaOkonchania := _Time;
   Result.Prodoljitelnost :=   (DateTimeToUnix(_Time) - DateTimeToUnix(__Time));
end;


DelphiN!   (2004-12-01 12:47:00) [1]

Переделал ф-ию так :


function MoneyToTime(Money:Real;__Time:TTime;Usluga:String;CompNo:Integer;DataSet:TClientDataSet):TimeStruct;
var
 _Time:TDateTime;
 i2:integer;
 Time_PO:TDateTime;
 m:Real;
 Count: Integer;
begin
__Time := StrToDateTime('01.01.2004 '+TimeToStr(__Time) );
_Time := __Time;

Count := 0;

 while Money > 0 do
 begin

 Inc(Count);
 if Count > 10000 then
 begin
   ShowMessage('В ф-ии обнвружен разрыв! Исправте таблицу услуг!');
   Exit;
 end;

   for i2 := 1 to DataSet.RecordCount do
   begin
       DataSet.RecNo := i2;
     if DataSet.FieldByName('Name').AsString = Usluga then
       if (CompNo >= DataSet.FieldByName('Comp_s').AsInteger) and (CompNo <= DataSet.FieldByName('Comp_po').AsInteger) then
         if TestTime(_Time,DataSet.FieldByName('Vremia_s').AsDateTime,DataSet.FieldByName('Vremia_po').AsDateTime) then
         begin
           Money := Money - (DataSet.fieldbyname('summa').AsFloat / 60);
           _Time := _Time+(1/24/60);
         end
   end
 end;
   Result.VremyaOkonchania := _Time;
   Result.Prodoljitelnost :=   IntToStr((DateTimeToUnix(_Time) - DateTimeToUnix(__Time) ));
end;


Медленно, но считает правильно. Кстати предыдущий вариант зависает из-за
строки

Money := Money - (DataSet.fieldbyname('summa').AsFloat / 60);  Почему-то в некоторых случаях (DataSet.fieldbyname('summa').AsFloat / 60)дает отрицательное число, а минус на минус дает плюс, почему получается отрицательное число я еще не разобрался(времени совсем нет). Может у кого есть немного свободного времени поможет решить проблемму, ото второй("Рабочий") вариант ф-ии слишком долго считает большие суммы, а мне надо быстро, и это быстро можно только если исправить ошибку в первой ф-ии ...


Наверх

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