![]() |
|
|
![]()
|
|
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Блин. Опять проблема с национальными настройками
Есть программа:
Так вот. Если в системе установлен разделитель дробной части '.' (точка) то все ок. Оба locate будут успешными. Но, если в системе установлен разделитель дробной части ',' (запятая) то беда. Первый locate не в состоянии найти существующую запись! Т.е. если в таком случае (разделитель ','), нет возможности найти запись по значению вещественного поля! Передавать значение в виде строки возможно не всегда. -------------------- Все знать невозможно, но хочется |
|||
|
||||
| Grig |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 809 Регистрация: 29.4.2005 Где: Иркутск Репутация: 4 Всего: 16 |
В файле SysUtils.pas есть переменная DecimalSeparator.
Попробуй использовать ее. Например:
Добавлено @ 11:29 Или во! Еще круче:
Это сообщение отредактировал(а) Grig - 18.7.2005, 11:25 -------------------- |
||||
|
|||||
| Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 17 Всего: 162 |
В свое время писал:
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Ребята, вы меня не поняли.
ds.Locate('fld','2.123',[]) всегда сработает правильно не зависимо от текущего значения DecimalSeparator. А вот ds.Locate('fld',2.123,[]), опять же вне зависимости от от текущего значения DecimalSeparator, может сработать, а может и не сработать. Все зависит от состояния настройки в системе! Причем, обратите внимание что второй параметр это значение типа Double (Currency, и т.п.). Специально включил в пост полноценно работающий пример. Можете проверить. -------------------- Все знать невозможно, но хочется |
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Разборки показали что это похоже косяк Microsoft!
У Borland'а, при обработке Locate, происходит преобразование всех числовых параметров в строку, в соответствии с текущими настройками системы (не DecimalSeparator!). Для этого используется функция VarToStr. А полученные значения передаются в COM-объекту Recordset в параметр Criteria метода Find. Так вот при выполнении этого метода, запись и не находится. Более того, когда таких параметров много (поиск по нескольким полям), я иногда наблюдал Exception ADO! Ему видете-ли похоже всегда надо '.' давать. Проверял и на MSACCESS, и на MS-SQL. В MSDN об этом естествеенно ничего не сказано. В принципе, если бы быть уверенным что Recordset.Find всегда требует '.' в качестве разделителя, то можно было бы подправить ADODB.pas, и выполнять преобразование не зависимо от текущих настроек системы. -------------------- Все знать невозможно, но хочется |
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Вот. Alex нашел сообщение об аналогичной проблемме http://coding.derkeiler.com/Archive/Delphi...04-03/0290.html
-------------------- Все знать невозможно, но хочется |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 29 Всего: 329 |
тогда нужно на время работы программы или определённого куска кода (или формы) в системе (глобально) менять разделитель. Вернее Проверять, если не точка, то менять на точку. Пока другого выхода я не вижу.
|
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Уж лучше тогда подправить ADODB.pas -------------------- Все знать невозможно, но хочется |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 29 Всего: 329 |
продолжай
|
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
Петрович мне кажется все так и должно быть.
попробуи в начало скрипта вставить
|
|||
|
||||
| Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 17 Всего: 162 |
kobra, сам попробуй и увидишь, что это ни как не повлияет.
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
извеняюс, не дописал
|
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Блин. Ты сам-то пробовал -------------------- Все знать невозможно, но хочется |
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
да, все работает (по краинеи мере у меня). |
|||
|
||||
| Петрович |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Да вариантов много. Вот например решение "в лоб". В модуле ADODB.pas, надо подправить процедуру GetFilterStr. Там есть case:
А вообще, все дело в том, что при выполнении преобразования Variant -> String, в некоторых случаях, в частности когда в Variant значение типа Currency, используется процедура преобразования из OS (в данном случае CurrToWStrViaOS). Мне в принципе не понятно почему в одних случаях используется преобразование реализуемое Delphi, а в других, реализуемое OS. Но, это уже отдельная тема. -------------------- Все знать невозможно, но хочется |
||||||
|
|||||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Тогда, если не трудно, укажи версию Delphi на которой ты это пробовал. И еще, важное напоминание. Не работает только если в системе установлено ',' Это сообщение отредактировал(а) Петрович - 19.7.2005, 13:00 -------------------- Все знать невозможно, но хочется |
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
скриншот посмотрите, там разделителем установил "/". Присоединённый файл ( Кол-во скачиваний: 7 )
untitled.JPG 31,03 Kb |
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
у меня 7 делфи
а вот скриншот с запетым Присоединённый файл ( Кол-во скачиваний: 5 )
untitled11.JPG 27,66 Kb |
|||
|
||||
| Петрович |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Да, но пример-то несколько отличается от приведенного мной. Причем, именно в ключевом моменте:
У меня:
При чем тут floattostr? Дело в том, что в реальной жизни, я не знаю о каком конкретно типе идет речь. У меня сохраняются значения всех полей абстрактного датасета, и потом, мне надо спозиционировать его на сохраненную запись. Поэтому, я не могу выполнять явного преобразования в строку. Добавлено @ 13:16 Хотя, конечно можно проверять тип поля и соответственно мудро конвертировать в строку. Но, это не есть хорошо. Все и без преобразования должно работать! Добавлено @ 13:21 На самом деле, проблему преобразования variant(currency)->String можно продемонстрировать на более простом примере:
Результат, при установленном в системе разделителе ',' :
Это сообщение отредактировал(а) Петрович - 19.7.2005, 13:26 -------------------- Все знать невозможно, но хочется |
||||||||
|
|||||||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
а так не подоидет?
|
|||
|
||||
| Петрович |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
А вот еще забавнее:
Если v имеет тип Currency, то результат будет:
-------------------- Все знать невозможно, но хочется |
||||||
|
|||||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
ето ещо забавнее, но главное, наверняка тебе поможет. тоже самое что и в предидушем примере
поменял код, тогда промежуточныи вариант запостил Это сообщение отредактировал(а) kobra - 19.7.2005, 13:50 |
|||
|
||||
| Петрович |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Я тащусь как нас разводят!
Вот выдержка их хелпа по функции Str (выделено мной):
Однако, выполняю такой код:
и получаю:
Вот так. Добавить просто нечего Добавлено @ 13:51
Увы нет. Как я уже писал, я заранее не знаю тип лежащий в варианте. В Str отреагирует не адекватно в том случае если ей передать вариант содержащий например tDateTime. Добавлено @ 13:53
Добавлено @ 13:55 На самом деле проблема только с Currency. Пэтому, конечно можно проверить что это именно он, и преобразовать его явно в строку с помощью FloatStr например. -------------------- Все знать невозможно, но хочется |
||||||||||
|
|||||||||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
я в предыдущем посте код поменял, но в принцыпе ты и без етого меня понял
|
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
и с денежным типом все в порядке, специално проверил переделав в таблице тип поля. или я чтото не так понял? |
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Пардон. Это я про VarToStr
Кстати, значения полей типа decimal(15, 4)) интерпретируются как Variant(Currency). Например, добавь после ds.Open; оператор:
-------------------- Все знать невозможно, но хочется |
|||
|
||||
| kobra |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
даааааа...
сам танцует сам поет, да ешо и музыку сам заказывает |
|||
|
||||
| SergeBS |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 11 Всего: 22 |
Петрович
Я тебе еще один косяк аналогичный изложу: Берем numpad (ну это справа где буковок нет 1 запуск - "ААААААААА! Программа не работает!" - "Покажи!" - 2 запуск - "Ой! Работает |
|||
|
||||
| SergeBS |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 11 Всего: 22 |
Блин, не привык еще здесь писать, не дописал. Петрович Совсем простой вопрос: у тебя что, автоинкрементных полей в MS SQL нет? Если есть - так сам понимаешь, как твоя проблема с поиском именно той записи, что ты правил, решается "на раз". И чем букмарки не нравятся? |
|||
|
||||
| kobra |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 730 Регистрация: 15.6.2005 Где: Грузия, Тбилиси Репутация: 1 Всего: 9 |
попробуи такое. установи букмарк, переиди на другую запис, измени поле сортировки и поиши по букмарку. или удали какую то запис до букмарка.
|
||||
|
|||||
| Петрович |
|
||||||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Ну и думаешь удивил 1. Это мелкософт так в драйвер русской раскладки заложил. Если установлен режим "латинский" то эта клавиша продуцирует код символа '.' (точка), а если тек.регистр "русский" то продуцируется код ',' (запятая). Это если драйверок не патченный 2. Компонент DBEdit построен на базе TCustomMaskEdit (я его просто ненавижу
Не там ставишь. Надо делать сразу после begin проргаммы, до первого Application.CreateForm.
Ну я это уже проходили. Раньше тоже так делали. Но, нехорошо пользователя напрягать. Если он хочет видеть в качестве разделителя ',', то плохо когда программа принудительно показывает (и требует от него ввода) разделителя '.'. На самом деле, есть два решения. Первое - патчить tMaskEdit. Там помимо этого есть еще ошибка (http://forum.vingrad.ru/index.php?showtopi...ndpost&p=476796) Второе - вешать доп.обработку на свою форму. Это попутно поправить работу всех компонентов на форме, включая например DBGrid. Делается так: 1. У формы ставим свойство KeyPreview в True 2. У формы описываем поле LastKeyDown:
3. Назначаем обработчик на событие OnKeyDown формы:
4. Назначаем обработчик на событие OnKeyPress формы:
Причем, чтобы не писать так в каждой форме, можно сделать в одном, базовом классе формы, а все остальные формы в программе наследовать от него. Вот и все. -------------------- Все знать невозможно, но хочется |
||||||||||||
|
|||||||||||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 6 Всего: 55 |
Это когда ты знаешь с какой таблицей работаешь. Я столкнулся с этим в процедуре работающей с абстрактным tDataSet о котором ничего неизвестно. В этой процедуре нужно закрыть датасет и потом открыть его снова. При этом, надо по возможности сохранить позицию в датасете на той-же записи на которой он был спозиционирован до закрытия. А закладки (букмарки) не годятся. В большинстве наследников tDataSet, закладки реализуются в виде порядкового номера записи в наборе. Соответственно, поскольку перечень записей и даже их количестко в таблице может измениться после close/open, то и закладка может спозиционировать не туда. Проверено практикой. Где то в хелпах даже читал о том что значение Bookmark действительно только пока Dataset не закрыт, хотя, что-то сходу не нашел где. -------------------- Все знать невозможно, но хочется |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 29 Всего: 329 |
не всегда, я меняю количество товара, например, закрываю НД, открываю и закладка позиционируется нормально. Да записей я не добавляю в этом случае, поэтому, наверное, и нормально работает. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Базы данных и репортинг" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами Обязательно указание: 1. Базы данных (Paradox, Oracle и т.п.) 2. Способа доступа (ADO, BDE и т.д.)
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |