Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.12;
Скачать: CL | DM;

Вниз

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

 
DelphiN! ©   (2004-11-30 08:38) [0]

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

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) [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) дает отрицательное число, а минус на минус дает плюс, почему получается отрицательное число я еще не разобрался(времени совсем нет). Может у кого есть немного свободного времени поможет решить проблемму, ото второй("Рабочий") вариант ф-ии слишком долго считает большие суммы, а мне надо быстро, и это быстро можно только если исправить ошибку в первой ф-ии ...



Страницы: 1 вся ветка

Текущий архив: 2004.12.12;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.022 c
14-1101045870
Piter
2004-11-21 17:04
2004.12.12
Зачем делать Set8087CW после вызова WinApi функций?


1-1101392626
SV
2004-11-25 17:23
2004.12.12
Изменение позиции формы.


1-1101371135
Инког
2004-11-25 11:25
2004.12.12
treeview


4-1098889217
boban
2004-10-27 19:00
2004.12.12
Как заблокировать Print Screen ?


3-1100019083
Existas
2004-11-09 19:51
2004.12.12
Ошибка в SQL запросе (ADODataset) к нескольким таблицам... (+)