TDbf и OnTranslate

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

TDbf и OnTranslate

Сообщение tria » 23.12.2009 21:00:50

Вроде как все старо как мир но что-то нигде так решения и не нашел...
Есть ДБФ в кодировке ДОС или 1251.
Надо бы чтобы dbGrid правильно отображал текст.
Не могу никак добится. OnTranslate просто не вызывается.
По коду - он вроде должен вызыватья если свойства FFileCodePage: Cardinal;
FUseCodePage: Cardinal у DbfFile отличаются. Но :
TDbf = class(TDataSet)
private
FDbfFile: TDbfFile;

соответственно, я в него не залезу...
Попытки изменять
Dbf1.LanguageID:=DbfLangId_RUS_866;
тоже ни к чему не привели.

Брать данные из ДБФ, перекодировать самому и ложить самому в обычный грид не интересно...
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: TDbf и OnTranslate

Сообщение SAK » 23.12.2009 23:17:22

Ещё надо в конструкторе TStringField поставить Transliterate:=true для использования метода DataSet.Translate.
Только я когда-то пробовал и обнаружил, что есть какая-то ошибка в самом TDbf и он начинает при этом глючить. Искать ошибку не стал, т.к особой необходимости небыло.
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Re: TDbf и OnTranslate

Сообщение v-t-l » 24.12.2009 14:58:48

во вложении пример. Там много лишнего - результаты экспериментов :) .
К сожалению в линухе CP866 не перекодируется, модифицированный мной synachar.pas утерян :cry: .
У вас нет необходимых прав для просмотра вложений в этом сообщении.
v-t-l
энтузиаст
 
Сообщения: 741
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Re: TDbf и OnTranslate

Сообщение amateur » 24.12.2009 16:48:29

Кажись на форуме проскакивали сообщения про такую проблему...
Если не изменяет память (самого интересовало данное) OnTranslate в лазаре, на тот момент, вообще не работало (хотя и имелось). Было эт около года назад... Решение, у меня, было простенькое GetData и setData перекодировало таким макаром. Функций море. Кста это дело работало только если дбгрид в режиме просмотра....
Самое обидное: когда проверял данную штуку(OnTranslate, написал строчку и оно перекодирует в то что нуно, только проблемка с украинской і была :)) в дельфине заработало на ура... Перечитал много чего, но реально работающим было GetData и setData. На данный момент может и исправили OnTranslate а может и....

Добавлено спустя 5 минут 4 секунды:
Может че и не так указал - ссори (давненько эт было). Тогда я пользовался книжечкой (хелпник по дбф - на сайте тдбф лежит). Хоть и скудненько но более менее понятно (анг. токо :)).
Аватара пользователя
amateur
энтузиаст
 
Сообщения: 552
Зарегистрирован: 03.08.2007 10:15:32

Re: TDbf и OnTranslate

Сообщение tria » 25.12.2009 11:56:10

Пока что просто перекодировал строковые поля ДБФ в utf8.
Вроде заработало - отображение нормальное, потихоньку вылазят другие проблемы...

К счастью, мне текст редактировать не надо.
У меня задача такая - в КПК засылается справочник товаров, а дальше записывать надо будет толко коды/штрихкоды/количество - задачи инвентаризации, планограмма...

Я так понял, если дойдет до переделки ТДБФ, но в GetFieldData SetFieldData надо будет вставить вызов OnTranslate.
Последний раз редактировалось tria 25.12.2009 12:13:07, всего редактировалось 1 раз.
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: TDbf и OnTranslate

Сообщение Mr.Smart » 25.12.2009 12:09:01

tria
Я бы для данной задачи всё таки использовал SQLite3 :wink:
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: TDbf и OnTranslate

Сообщение tria » 25.12.2009 12:16:41

Mr.Smart писал(а):tria
Я бы для данной задачи всё таки использовал SQLite3 :wink:


А он по Win CE работает?
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: TDbf и OnTranslate

Сообщение Mr.Smart » 25.12.2009 12:19:03

Порт где то встречал. Вот только щас найти не могу :wink: Впринцепе можно самому компильнуть...
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: TDbf и OnTranslate

Сообщение tria » 25.12.2009 12:24:48

Спасибо за идею, буду иметь как резервный вариант

Mr.Smart писал(а):Впринцепе можно самому компильнуть...


Вот это пугает. Тут tdbf при компилировании под CE ведет себя малость по-другому, а что с цельным серваком может быть....

ДБФ для данной задачи удобнее еще тем, что на выход я буду выдавать просто готовый файл, без выгрузок/загрузок из БД.
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: TDbf и OnTranslate

Сообщение Mr.Smart » 25.12.2009 12:38:40

tria
Кстати вот нашёл проект порта SQLite3 на WinCE http://sqlite-wince.sourceforge.net/.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: TDbf и OnTranslate

Сообщение amateur » 25.12.2009 16:54:05

tria писал(а):Пока что просто перекодировал строковые поля ДБФ в utf8.
Вроде заработало - отображение нормальное, потихоньку вылазят другие проблемы...

К счастью, мне текст редактировать не надо.
У меня задача такая - в КПК засылается справочник товаров, а дальше записывать надо будет толко коды/штрихкоды/количество - задачи инвентаризации, планограмма...

Я так понял, если дойдет до переделки ТДБФ, но в GetFieldData SetFieldData надо будет вставить вызов OnTranslate.


Добавлено спустя 3 минуты 26 секунд:
проблема была в самом лазаре, а тдбф переделывать не нуно...
Аватара пользователя
amateur
энтузиаст
 
Сообщения: 552
Зарегистрирован: 03.08.2007 10:15:32

Re: TDbf и OnTranslate

Сообщение SAK » 27.12.2009 16:04:01

Посмотрите файл fields.inc:
Код: Выделить всё
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.
SAK
постоялец
 
Сообщения: 158
Зарегистрирован: 18.02.2006 00:45:14
Откуда: Тим

Re: TDbf и OnTranslate

Сообщение tria » 29.12.2009 12:25:34

нда
с кодировкой то обошел - перекодировал строки в utf8
но в WinCE вылезла другая проблема - при попытке использовать индексы (SetRange или SearchKey) вылетает с ошибкой "Bus error or misaligned data acces"
При чем тот же код в ХР работает нормально...
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: TDbf и OnTranslate

Сообщение Mr.Smart » 29.12.2009 16:01:29

tria
Запомните, что WinXP и WinCE абсолютно разные системы схожие только реализацией API :wink:
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: TDbf и OnTranslate

Сообщение dima_gsv » 10.03.2010 18:51:19

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.
tria писал(а):Надо бы чтобы dbGrid правильно отображал текст.
dbGrid отображает русский текст вопросиками потому, что он оперирует строками в кодировке UTF8, а TDbf выдаёт их в текущей кодовой странице системы. TDbf вроде бы не рассчитан на выдачу строк сразу в UTF8. И исправлением пары строк, наверно, поддержку UTF8 не добавить. Я этот вопрос глубоко не исследовал, это моё предположение после беглого взгляда на код. Скорее всего такое плачевное состояние дел вызвано тем, что проектом TDbf давно никто не занимался. Для себя я решил проблему использования TDbf следующим образом. Везде в коде приложения после получения строки от TDbf использую AnsiToUTF8. А для корректного отображения в dbGrid сделал два обработчика для TStringField OnGetText и OnSetText:
Код: Выделить всё
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.
dima_gsv
незнакомец
 
Сообщения: 2
Зарегистрирован: 05.03.2010 17:15:46

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 242

Рейтинг@Mail.ru