Текущий архив: 2003.07.28;
Скачать: CL | DM;
Вниз
Несовместимость типов Float в InterBase и типа Real в Delphi Найти похожие ветки
← →
АТ (2003-06-28 02:10) [0]Скажем я пытаюсь выполнить динамический запрос:
INSERT INTO balance (IDBalance, VALUEBALANCE)
VAlUES(33, "12,2")
тип поля VALUEBALANCE - FLOAT
В результате такого добавления я получаю
поле VALUEBALANCE = 122,000
Если в запросе стоит точка:
INSERT INTO balance (IDBalance, VALUEBALANCE)
VAlUES(33, "12 .2")
то в результате добавления получаю
поле VALUEBALANCE = 12,2
Проблема в том, что мне надо получать число 12,2 через функцию FloatToStr а она в случае если в Windows в качестве десятичного разделителя проставлена запятая и поставит запятую. Т.е. выполнение запроса(где VarBalance:Real и равна 12,2):
"INSERT INTO balance (IDBalance, VALUEBALANCE)"+
"VAlUES(33, ""+FloatToStr(VarBalance)+"")"
приведет к неправильному добавлению данных.
Как разрешить эту ситуацию?
Я предполагаю, что приложение возможно будет стоять на машинах с запятой в качестве десятичного разделителя.
← →
Zacho (2003-06-28 10:30) [1]Разрешить эту ситуацию можно двумя способами, и оба очень простые.
1. Почитать в хелпе про переменную DecimalSeparator
2. Вместо динамического формирования запроса использовать параметризированный запрос.
И еще - а ты уверен, что нужен именно FLOAT а не DOUBLE PRECISION или NUMERIC ?
← →
KDS (2003-06-28 12:26) [2]>VAlUES(33, "12,2")
Если тип поля VALUEBALANCE - FLOAT
то зачем тогда 12,2 брать в двойные кавычки как строчный параметр?
Так его и передавай в БД как 12.2
используй функцию типа этой для замены запятой на точку
function ValidatePrice(const textPr:AnsiString):AnsiString;
begin
Result:=Trim(textPr);
if Result="" then Result:="0";
if DecimalSeparator="," // то менять на точку
then Result:=AnsiReplaceStr(Result,",",".")
end;
или вообще в конце модуля главной формы напиши конкретно:
initialization
DecimalSeparator:=".";
DateSeparator:=".";
ShortDateFormat:="dd.mm.yyyy";
end.
и теперь не будешь зависеть от настроек виндовз (MusdDie)
← →
NDeu (2003-06-28 17:02) [3]
> KDS © (28.06.03 12:26)
> ... не будешь зависеть от настроек виндовз
Неуважение юзера :(
← →
kaif (2003-06-29 04:02) [4]1. В IB6.0 и его клонах в таких таблицах лучше использовать тип DECIMAL(18,2), а не FLOAT
2. В IB 5.* для денежных сумм никогда не надо использовать FLOAT - только DOUBLE PRECISION. Иначе столкнешься один день с большой проблемой потери точности при SELECT SUM()
3. Запросы должны быть параметризованными и в них никогда не следует передавать данные таким способом, как ты делаешь:
"INSERT INTO balance (IDBalance, VALUEBALANCE)"+
"VAlUES(33, ""+FloatToStr(VarBalance)+"")"
Правильно:
Q.SQL.Text := "INSERT INTO balance (IDBalance, VALUEBALANCE)"+
"VAlUES(:IDBalance, :ValueBalance)"
Q.PartamByName("IDBalance").AsInteger := 33;
Q.PartamByName(ValueBalance).AsCurrency := 12.2;
Q.ExecSQL;
где Q - компонент запроса.
Особенно опасен твой способ при работе с датами. Достаточно изменить настройку форматирования даты в Windows с dd.mm.yy на mm/dd/yy и у тебя все полетит к черту.
← →
Zacho (2003-06-30 00:15) [5]
> KDS © (28.06.03 12:26)
Ну и зачем лишний IF ? Все гораздо проще:
function ValidatePrice(const textPr:AnsiString):String;
begin
Result:=AnsiReplaceStr(textPr,DecimalSeparator,".")
end;
Вот и вся функция :-)
А насчет:
> или вообще в конце модуля главной формы напиши конкретно:
Далее SKIP ...
У меня, например, такая программа быстро окажется в корзине.
← →
АТ (2003-06-30 17:11) [6]>Zacho
>У меня, например, такая программа быстро окажется в корзине.
Почему?
← →
Zacho (2003-06-30 19:57) [7]
> АТ (30.06.03 17:11)
Потому что программа не должна быть "умнее" пользователя, и ни в коем случае не должна менять пользовательские настройки системы. Если у меня разделитель целой и дробной части стоит "," (или " " например) - значит так мне нужно, а если автор какой-то там программы думает, что лучше меня знает, что мне нужно - этой программе прямая дорога в корзину.
← →
venoel (2003-07-02 23:38) [8]>> Zacho
5 баллов.
← →
kaif (2003-07-03 02:13) [9]2 Zacho © (30.06.03 19:57)
Кстати, Zacho, вот Вы - мыслящий человек. Скажите мне, пожалуйста, почему в Windows 2000 и Windows XP в русских региональных стандартах разделитель тысячных вовсе не пробел (32), а какая-то хрень (160). Я на днях столкнулся с очень большими проблемами при DDE обмене с Excel, в котором разделитель тысячных - нормальный пробел. Когда я локализовал проблему и обнаружил, что ThousandSeparator не равен chr(32), а равен chr(160), хоть и выглядит в Control Panel как пробел, я зашел в Control Panel, забил тот "пробел", что там был и вставил норамьныхй пробел. Все заработало.
Проблема в том, что мне сейчас это приходится делать на всех клинтских компьютерах заказчика...
И я не уверен, что действую верно. Ведь должно быть какое-то научное объяснение у этого парадокса (160 вместо 32)?
Я понимаю, что это off-topic, но просто раз уж зашла речь о региональных настройках...
← →
Alexandr (2003-07-03 07:07) [10]может быть это "неразрывный пробел"
что-то такое я в word видел...
← →
Zacho (2003-07-03 09:00) [11]
> kaif © (03.07.03 02:13)
Насчет chr(160) - ничего сказать не могу, не знаю.
Хочу немного уточнить свое высказывание от (30.06.03 19:57).
Программа не должна менять пользовательские настройки, но она должна их учитывать. И если для работы программы необходимо, чтобы DecimalSeparator был ".", то сделать AnsiReplaceStr(MyVar,DecimalSeparator,".") - прямая обязанность программиста.
← →
kaif (2003-07-03 18:57) [12]2 Alexandr © (03.07.03 07:07)
Спасибо большое! Это действительно неразрывный пробел #160 :(
см.
http://www.iro.yar.ru:8101/partners/peresl/sidorov/nzam17.htm
Но как так получается, что в русских Региональных Настройках он установлен в качестве разделителя тычсяч, а Microsoft Excel его не понимает и хочет в форматах видеть обычный пробел?
видно мне придется еще исследовать Office поподробнее и я пока не уверен, что найду оптимальное решение...
← →
Alexandr (2003-07-04 06:24) [13]1)
тут надо версии смотреть...
какой ОС, какой эксель...
2) DDE тоже может повлиять...
3) ReplaceStr не поможет?
Страницы: 1 вся ветка
Текущий архив: 2003.07.28;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.005 c