Delphi, тип FLOAT

Добрый день!)
Столкнулась с проблемой, не знаю, как лучше ее решить
В БД есть поле типа float, т.е используется разделитель точка.
Мне необходимо прочитать это поле и далее буду это поле сравнивать и выполнять ариф.действия
image

Так а это где выдает, что в коде?

выдает при компиляции

 if (cdsAll.FieldByName('Hours').AsFloat) < 8.2
              then
              begin
                ExcelApp.WorkBooks[1].WorkSheets[1].Cells[i,
                  j].Value := cdsAll.FieldByName
                  ('Hours').AsString;
              end
              else
              begin
                ExcelApp.WorkBooks[1].WorkSheets[1].Cells[i, j ].Value := ' ';
              end;

Ругается на if

В поле Hours я храню такие значения: 2.5, 3.5, 8.2 (тип флоат)

В интернете пишут, что скорее всего из-за того, что используется разделитель “точка”
Не знаю, как лучше сделать замену на запятую

ну, можно написать примерно так:

var s:String;
      tempHourValue:Double;
begin

...........

    s := cdsAll.FieldByName('Hours').AsString;
    s := StringReplace(s, '.', DecimalSeparator, []);
    s := StringReplace(s, ',', DecimalSeparator, []);
    if not TryStrToFloat(s, tempHourValue) then begin
      ShowMessage(Format('Значение %s не является действительным числом', [s]));
      Exit;
    end
    else begin
       if tempHourValue<8.2 then begin
                <тут ваш код>
       end;
    end;

Точно у Вас Hours значение с плавающей запятой? А что такое 8.2 ?

Либо другой вариант.
Меняйте системный разделитель в программе на точку.
Тогда все вещественные переменные будут через точку.

  DecimalSeparator:='.';

8.2 - это я просто фильтрую данные по условию
Попробую Ваш вариант
Да, тип float
DecimalSeparator - для этого нужна доп библиотека?

нет. не нужна.
судя по вопросу, у Вас свежая версия Delphi.
Там DecimalSeparator находится в TFormatSettings
см.
https://docwiki.embarcadero.com/Libraries/Sydney/en/System.SysUtils.TFormatSettings.DecimalSeparator

установить новый для программы можно вот так:

  System.SysUtils.FormatSettings.DecimalSeparator := '.';

ну или его же использовать в StringReplace

А почему для времени используется float?
Обычно его хранят в чем-нибудь типа секунд с какого-то момента (1970, …).
В БД есть специальные типы данных для даты и времени.

1 лайк

Вот и я бы начал с того, чтобы подумал, верно ли хранить часы в формате Float…
И только после этого решал проблему с преобразованием.

мне нужен именно период, чтобы можно было вводить: 2ч, 3,5ч

Я попробую использовать ваши рекомендации

да, в случае, когда меняем для программы глобального FormatSettings системный разделитель, то лучше запретить системе обновлять региональные настройки.
То есть лучше сделать так:

System.SysUtils.FormatSettings.DecimalSeparator := '.';
Application.UpdateFormatSettings:=False;

ну или менять перед преобразованием:

    s := cdsAll.FieldByName('Hours').AsString;
    s := StringReplace(s, '.', FormatSettings.DecimalSeparator, []);
    s := StringReplace(s, ',', FormatSettings.DecimalSeparator, []);
    if not TryStrToFloat(s, tempHourValue) then begin

А если надо будет минуты или дни вводить?

Лучше вводить как угодно и при записи в БД конвертировать в секунды, и потом при выводе обратно если надо, в подходящий вид (если 120 сек, то выводить 2 минуты, если 3660, то 1 ч. 1 мин. и т.д.).

1 лайк

:+1:

а при необходимости отобразить пользователю целое число секунд легко приводить в любой удобный пользователю для понимания формат, хоть 8.2 (кстати, это сколько? 8 часов и сколько минут?! )
хоть в формат XX часов YY минут ZZ секунд…)

8.2 = 8ч 12 мин

ну, это, по крайней мере, логично.
Но я бы всё же прислушался к совету @AlexP хранить время целым числом секунд - это и удобнее и точнее и более универсально и гибко.
К тому же, не знаю, знаете ли Вы или нет, но вещественный формат всегда имеет погрешности представления чисел:
см. например,
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374

попробую переделать!