TDbf и OnTranslate
Модератор: Модераторы
TDbf и OnTranslate
Вроде как все старо как мир но что-то нигде так решения и не нашел...
Есть ДБФ в кодировке ДОС или 1251.
Надо бы чтобы dbGrid правильно отображал текст.
Не могу никак добится. OnTranslate просто не вызывается.
По коду - он вроде должен вызыватья если свойства FFileCodePage: Cardinal;
FUseCodePage: Cardinal у DbfFile отличаются. Но :
TDbf = class(TDataSet)
private
FDbfFile: TDbfFile;
соответственно, я в него не залезу...
Попытки изменять
Dbf1.LanguageID:=DbfLangId_RUS_866;
тоже ни к чему не привели.
Брать данные из ДБФ, перекодировать самому и ложить самому в обычный грид не интересно...
Есть ДБФ в кодировке ДОС или 1251.
Надо бы чтобы dbGrid правильно отображал текст.
Не могу никак добится. OnTranslate просто не вызывается.
По коду - он вроде должен вызыватья если свойства FFileCodePage: Cardinal;
FUseCodePage: Cardinal у DbfFile отличаются. Но :
TDbf = class(TDataSet)
private
FDbfFile: TDbfFile;
соответственно, я в него не залезу...
Попытки изменять
Dbf1.LanguageID:=DbfLangId_RUS_866;
тоже ни к чему не привели.
Брать данные из ДБФ, перекодировать самому и ложить самому в обычный грид не интересно...
-
SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 17.02.2006 23:45:14
- Откуда: Тим
- Контактная информация:
Ещё надо в конструкторе TStringField поставить Transliterate:=true для использования метода DataSet.Translate.
Только я когда-то пробовал и обнаружил, что есть какая-то ошибка в самом TDbf и он начинает при этом глючить. Искать ошибку не стал, т.к особой необходимости небыло.
Только я когда-то пробовал и обнаружил, что есть какая-то ошибка в самом TDbf и он начинает при этом глючить. Искать ошибку не стал, т.к особой необходимости небыло.
во вложении пример. Там много лишнего - результаты экспериментов
.
К сожалению в линухе CP866 не перекодируется, модифицированный мной synachar.pas утерян
.
К сожалению в линухе CP866 не перекодируется, модифицированный мной synachar.pas утерян
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Кажись на форуме проскакивали сообщения про такую проблему...
Если не изменяет память (самого интересовало данное) OnTranslate в лазаре, на тот момент, вообще не работало (хотя и имелось). Было эт около года назад... Решение, у меня, было простенькое GetData и setData перекодировало таким макаром. Функций море. Кста это дело работало только если дбгрид в режиме просмотра....
Самое обидное: когда проверял данную штуку(OnTranslate, написал строчку и оно перекодирует в то что нуно, только проблемка с украинской і была
) в дельфине заработало на ура... Перечитал много чего, но реально работающим было GetData и setData. На данный момент может и исправили OnTranslate а может и....
Добавлено спустя 5 минут 4 секунды:
Может че и не так указал - ссори (давненько эт было). Тогда я пользовался книжечкой (хелпник по дбф - на сайте тдбф лежит). Хоть и скудненько но более менее понятно (анг. токо
).
Если не изменяет память (самого интересовало данное) OnTranslate в лазаре, на тот момент, вообще не работало (хотя и имелось). Было эт около года назад... Решение, у меня, было простенькое GetData и setData перекодировало таким макаром. Функций море. Кста это дело работало только если дбгрид в режиме просмотра....
Самое обидное: когда проверял данную штуку(OnTranslate, написал строчку и оно перекодирует в то что нуно, только проблемка с украинской і была
Добавлено спустя 5 минут 4 секунды:
Может че и не так указал - ссори (давненько эт было). Тогда я пользовался книжечкой (хелпник по дбф - на сайте тдбф лежит). Хоть и скудненько но более менее понятно (анг. токо
Пока что просто перекодировал строковые поля ДБФ в utf8.
Вроде заработало - отображение нормальное, потихоньку вылазят другие проблемы...
К счастью, мне текст редактировать не надо.
У меня задача такая - в КПК засылается справочник товаров, а дальше записывать надо будет толко коды/штрихкоды/количество - задачи инвентаризации, планограмма...
Я так понял, если дойдет до переделки ТДБФ, но в GetFieldData SetFieldData надо будет вставить вызов OnTranslate.
Вроде заработало - отображение нормальное, потихоньку вылазят другие проблемы...
К счастью, мне текст редактировать не надо.
У меня задача такая - в КПК засылается справочник товаров, а дальше записывать надо будет толко коды/штрихкоды/количество - задачи инвентаризации, планограмма...
Я так понял, если дойдет до переделки ТДБФ, но в GetFieldData SetFieldData надо будет вставить вызов OnTranslate.
Последний раз редактировалось tria 25.12.2009 11:13:07, всего редактировалось 1 раз.
tria
Я бы для данной задачи всё таки использовал SQLite3
Я бы для данной задачи всё таки использовал SQLite3
Mr.Smart писал(а):tria
Я бы для данной задачи всё таки использовал SQLite3
А он по Win CE работает?
Порт где то встречал. Вот только щас найти не могу
Впринцепе можно самому компильнуть...
Спасибо за идею, буду иметь как резервный вариант
Вот это пугает. Тут tdbf при компилировании под CE ведет себя малость по-другому, а что с цельным серваком может быть....
ДБФ для данной задачи удобнее еще тем, что на выход я буду выдавать просто готовый файл, без выгрузок/загрузок из БД.
Mr.Smart писал(а):Впринцепе можно самому компильнуть...
Вот это пугает. Тут tdbf при компилировании под CE ведет себя малость по-другому, а что с цельным серваком может быть....
ДБФ для данной задачи удобнее еще тем, что на выход я буду выдавать просто готовый файл, без выгрузок/загрузок из БД.
tria
Кстати вот нашёл проект порта SQLite3 на WinCE http://sqlite-wince.sourceforge.net/.
Кстати вот нашёл проект порта SQLite3 на WinCE http://sqlite-wince.sourceforge.net/.
tria писал(а):Пока что просто перекодировал строковые поля ДБФ в utf8.
Вроде заработало - отображение нормальное, потихоньку вылазят другие проблемы...
К счастью, мне текст редактировать не надо.
У меня задача такая - в КПК засылается справочник товаров, а дальше записывать надо будет толко коды/штрихкоды/количество - задачи инвентаризации, планограмма...
Я так понял, если дойдет до переделки ТДБФ, но в GetFieldData SetFieldData надо будет вставить вызов OnTranslate.
Добавлено спустя 3 минуты 26 секунд:
проблема была в самом лазаре, а тдбф переделывать не нуно...
-
SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 17.02.2006 23:45:14
- Откуда: Тим
- Контактная информация:
Посмотрите файл fields.inc:
OnTranslate вызывается в методе TDbf.Translate
Но это не работает потому, что по умолчанию TStringField.Transliterate = false.
В Delphi по умолчанию TStringField.Transliterate = true.
Код: Выделить всё
function TStringField.GetValue(var AValue: string): Boolean;
Var Buf, TBuf : TStringFieldBuffer;
begin
Result:=GetData(@Buf);
If Result then
begin
if transliterate then { <========= }
begin
DataSet.Translate(Buf,TBuf,False); { <==========}
AValue:=TBuf;
end
else
AValue:=Buf
end
end;
OnTranslate вызывается в методе TDbf.Translate
Но это не работает потому, что по умолчанию TStringField.Transliterate = false.
В Delphi по умолчанию TStringField.Transliterate = true.
нда
с кодировкой то обошел - перекодировал строки в utf8
но в WinCE вылезла другая проблема - при попытке использовать индексы (SetRange или SearchKey) вылетает с ошибкой "Bus error or misaligned data acces"
При чем тот же код в ХР работает нормально...
с кодировкой то обошел - перекодировал строки в utf8
но в WinCE вылезла другая проблема - при попытке использовать индексы (SetRange или SearchKey) вылетает с ошибкой "Bus error or misaligned data acces"
При чем тот же код в ХР работает нормально...
tria
Запомните, что WinXP и WinCE абсолютно разные системы схожие только реализацией API
Запомните, что WinXP и WinCE абсолютно разные системы схожие только реализацией API
SAK писал(а):Ещё надо в конструкторе TStringField поставить Transliterate:=true для использования метода DataSet.Translate.
Действительно, для использования OnTranslate в FPC/Lazarus необходимо во всех строковых полях поставить Transliterate:=true. Но так как свойство TStringField.Transliterate public, а не published, то его не видно в конструкторе. Значит Transliterate:=true надо прописывать в коде. Например, в OnFormCreate:
Код: Выделить всё
for i:= 0 to Dbf.FieldCount -1 do
if Dbf.Fields.Fields[ i ].DataType = ftString then
TStringField( Dbf.Fields.Fields[ i ] ).Transliterate:= true;SAK писал(а):Только я когда-то пробовал и обнаружил, что есть какая-то ошибка в самом TDbf и он начинает при этом глючить. Искать ошибку не стал, т.к особой необходимости небыло.
На мой взгляд, ошибка действительно находится в TDbf. После установки Transliterate:=true строки начинают конвертиться в нужную кодовую страницу, но к ней добавляется мусор. Видимо разработчики забыли добавить #0 в конец nullterminated-строки и из-за этого появился мусор. Мусор убирается следующим образом. Надо в файле dbf.pas найти строку
Код: Выделить всё
Result := TranslateString(FromCP, ToCP, Src, Dest, -1);и после неё добавить
Код: Выделить всё
Dest[Result] := #0;Этот патч я выложил тут https://sourceforge.net/tracker/?func=detail&aid=2967241&group_id=34085&atid=410671.
dbGrid отображает русский текст вопросиками потому, что он оперирует строками в кодировке UTF8, а TDbf выдаёт их в текущей кодовой странице системы. TDbf вроде бы не рассчитан на выдачу строк сразу в UTF8. И исправлением пары строк, наверно, поддержку UTF8 не добавить. Я этот вопрос глубоко не исследовал, это моё предположение после беглого взгляда на код. Скорее всего такое плачевное состояние дел вызвано тем, что проектом TDbf давно никто не занимался. Для себя я решил проблему использования TDbf следующим образом. Везде в коде приложения после получения строки от TDbf использую AnsiToUTF8. А для корректного отображения в dbGrid сделал два обработчика для TStringField OnGetText и OnSetText:tria писал(а):Надо бы чтобы dbGrid правильно отображал текст.
Код: Выделить всё
procedure TForm1.DbfSetUTF8Text(Sender: TField; const aText: string);
begin
Sender.Value := Utf8ToAnsi(aText);
end;
procedure TForm1.DbfGetUTF8Text(Sender: TField; var aText: string;
DisplayText: Boolean);
begin
aText := AnsiToUtf8(Sender.Value);
end;
Подводя итог, для полного счастья не хватает патча к TDbf добавляющего поддержку конвертации строк в UTF8.
