Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Не присваиваются значения в записи Record


Автор: Akella 2.8.2010, 12:27
Есть запись
Код

Type
  TStatisticsDatas = record
    dtStart, dtEnd: TDate;
  end;



есть глобальная переменная
Код
StatisticsDatas: TStatisticsDatas;


есть в процедуре код:

Код

  case StatPeriod of
    spToday:    begin StatisticsDatas.dtStart := now; StatisticsDatas.dtEnd := now; end;
    spYesterday:begin StatisticsDatas.dtStart := now - 1; StatisticsDatas.dtEnd := now - 1; end;
    spWeek:     begin StatisticsDatas.dtStart := now - 7; StatisticsDatas.dtEnd := now; end;
    spMounth:   begin StatisticsDatas.dtStart := now - 30; StatisticsDatas.dtEnd := now; end;
    spYear:     begin StatisticsDatas.dtStart := now - 365; StatisticsDatas.dtEnd := now; end;
    spAllPeriod:begin StatisticsDatas.dtStart := 0; StatisticsDatas.dtEnd := Date; end;
  end;


код работает, в Case заходит (пробовал все строки), но значения dtStart и dtEnd не меняются 

Смотрю дебаггером. Как были до присвоения, так и остались: 2,6395166155e-308 и 5,1542870537e-278 соответственно

Сделал обе переменные локальными, так всё работает.
Что не так с типом TDate в записях?
D2007.

Автор: Akella 2.8.2010, 12:47
Странно, если добавить в конце
Код
ShowMessage(DateToStr(StatisticsDatas.dtStart));

то показывается правильная дата %)

Автор: Демо 2.8.2010, 13:01
А структура где-то используется?

Автор: Akella 2.8.2010, 13:13
В какой-то из процедур была объявлена ещё одна переменная локально
Код
StatDatas: TStatisticsDatas;

Видать как-то они пересеклись, т.к. после того, как оставил только глобальную, проблема исчезла.

Автор: Frees 2.8.2010, 13:14
может это фича оптимизатора, раз ты только пишешь в StatisticsDatas то это все лишнее, попробуй убрать оптимизацию

Автор: Keeper89 2.8.2010, 13:15
Демо, +1

Akella, 
вообще, раз 
Код

dtStart, dtEnd: TDate;

лучше использовать везде не now, а Date.

Автор: xkor 2.8.2010, 16:30
Keeper89, чем лучше? Date просто возвращает результат Now отбросив дробную часть.

Автор: k0rvin 2.8.2010, 17:31
Цитата(Akella @ 2.8.2010,  12:27)
есть в процедуре код:

Код

  case StatPeriod of
    ...
    spMounth:   begin StatisticsDatas.dtStart := now - 30; StatisticsDatas.dtEnd := now; end;
    spYear:     begin StatisticsDatas.dtStart := now - 365; StatisticsDatas.dtEnd := now; end;
    ...
  end;

как-то это неправильно

Автор: Keeper89 2.8.2010, 23:46
xkor, просто насколько я помню Now возвращает TDateTime, а не Date, это конечно не принципиально.

Хотя, не прав и то, и то TDateTime smile

Автор: Akella 3.8.2010, 09:00
Цитата(Keeper89 @  2.8.2010,  13:15 Найти цитируемый пост)
лучше использовать везде не now, а Date.

Я и использовал именно Date с самого начала



k0rvin, 
Цитата(k0rvin @  2.8.2010,  17:31 Найти цитируемый пост)
как-то это неправильно 

Почему? Предложи лучший вариант.

Добавлено через 24 секунды
Цитата(Keeper89 @  2.8.2010,  13:15 Найти цитируемый пост)
лучше использовать везде не now, а Date. 

Да пофиг

Автор: CodeMonkey 3.8.2010, 10:24
Цитата(Akella @  3.8.2010,  10:00 Найти цитируемый пост)
Да пофиг 


Потрясающее наплевательство к качеству кода. Кообще-то Keeper прав: использовать надо Date, потому что она возвращает только дату, Now - возвращает дату и время.

Если мне достанется ваш код и я не видел, как вы заполняете запись, то, смотря на объявление:

Код
Type
  TStatisticsDatas = record
    dtStart, dtEnd: TDate;
  end;


а). Я решу, что в dtStart лежит дата и время?
или всё же
б). Я решу, что в dtStart лежит только дата?

Наверное всё же второе, как вы считаете? И тогда я начну делать какие-то проверки и вычисления, и для меня станет полной неожиданностью, что у dtStart ВНЕЗАПНО появляется дробная часть.

Не надо врать компилятору - целее будете. Хотите использовать Now - измените тип на TDateTime. То, что TDateTime = TTime и TDate не имеет никакого значения. Зачем создавать потенциальное место для бага?

Автор: Akella 3.8.2010, 10:35
Цитата(CodeMonkey @  3.8.2010,  10:24 Найти цитируемый пост)
б). Я решу, что в dtStart лежит только дата?

конечно же только дата

Добавлено через 1 минуту и 44 секунды
Цитата(CodeMonkey @  3.8.2010,  10:24 Найти цитируемый пост)
у dtStart ВНЕЗАПНО появляется дробная часть.

откуда она там появится?

Добавлено через 2 минуты и 43 секунды
Цитата(CodeMonkey @  3.8.2010,  10:24 Найти цитируемый пост)
Не надо врать компилятору - целее будете. Хотите использовать Now - измените тип на TDateTime. То, что TDateTime = TTime и TDate не имеет никакого значения. Зачем создавать потенциальное место для бага?

1. Никакой ошибки не будет.
2. Я изначально использовал не now, а date

Автор: CodeMonkey 3.8.2010, 14:23
Цитата(Akella @  3.8.2010,  11:35 Найти цитируемый пост)
откуда она там появится?


Отсюда:
Цитата(Akella @  2.8.2010,  13:27 Найти цитируемый пост)
StatisticsDatas.dtStart := now


Цитата(Akella @  3.8.2010,  11:35 Найти цитируемый пост)
Никакой ошибки не будет.


Да ну.

Пусть:
Код
var
  dtStart: TDate;
begin
  dtStart := Now;


Теперь мы хотим определить, сегодня ли было начало:

Код
if dtStart = Date then // или EncodeDate(2010, 8, 3), если нужно фиксированное число
  ShowMessage('Начало сегодня!')


Надо ли говорить, что никакого сообщения не появится?

Но стоит исправить этот код на правильный вариант:
Код
  dtStart := Date;


Как баг исчезает!

Автор: Akella 3.8.2010, 14:37
Да, т.к. сравнение идёт вещественных чисел. Спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)