Есть проблема с кодировками или же с пониманием работы с БД.
1-я задача
простейший текстовый редактор, проблем нет, есть функции типа "ИЗ-->В" (CP866ToUTF8) все просто и понятно.
2-я задача
простейший редактор DBF, тут уже сложней и мениие понятней
как используя TDBF, DataSource, DBGrid считывать из DBF-а в CP866 отобразить в DBGrid-e в UTF8 ?
и обратно из DBGrid-a измененные/добавлиные записи в DBF файл из UTF8 в CP866 ?
3-я задача
теперь уже работа с СУБД FireBird
a) не могу понять где перекодировать данные в DBGrid, DataSource, ... ?
как из СУБД FireBird они проходят в DBGrid и обратно ?
b) как из DBF файла с кодировкой cp866(cp1125) перенести данные в СУБД FireBird с кодировкой UTF8(CP1251) ?
на этот вопрос ответ может быть получен из 2-й задачи
желательно собственная разработка а не стороння утилита
c) как из СУБД FireBird кодовая страница CP1251 отображать в DBGrid-e в UTF8 ?
туда и обратно или работа с кодировками
Модератор: Модераторы
Чтобы получше разобраться, начните с изучения работы с кодировкой под Delphi.
(Если лень читать) Суть в том, что кодировка теперь является свойством строки, так же как и ее длина. В книжках по FreePascal об этом не пишут, кстати, а зря (или их авторы не разбираются в этом?).
Так вот, при присвоении строк происходит автоматическое перекодирование в соответствии с кодовыми таблицами, чтобы, к примеру, русское "А" всегда было им. В Вашей первой задаче:
(Если лень читать) Суть в том, что кодировка теперь является свойством строки, так же как и ее длина. В книжках по FreePascal об этом не пишут, кстати, а зря (или их авторы не разбираются в этом?).
Так вот, при присвоении строк происходит автоматическое перекодирование в соответствии с кодовыми таблицами, чтобы, к примеру, русское "А" всегда было им. В Вашей первой задаче:
Код: Выделить всё
var
c:AnsiString(866); // не уверен с кодом кодировки CP866
s:UTF8String;
begin
c:="ВАСЯ"; // 4 байта
s:=c; // перекодирование "по смыслу", в s теперь 8 байт
Label1.Caption:= s; // выводит "ВАСЯ"
Timid
Работа с кодировками во FreePascal/Lazarus сейчас отличается от того, что сделано в Delphi после перехода на юникод. Строки во FreePascal НЕ хранят информацию о кодировке. Работа над этим ведётся в отдельной ветке (cpstrnew), и когда эти изменения попадут в основную ветку -- неизвестно.
nic1982
Ответы на некоторые вопросы, возможно, появятся после просмотра этой ветки англоязычного форума:
http://www.lazarus.freepascal.org/index ... pic=5963.0
и этой ветки русского:
http://www.freepascal.ru/forum/viewtopi ... =26&t=4481
Ничего более конкретного посоветовать, к сожалению, не могу - ни с DBF, ни с Firebird не работал.
Работа с кодировками во FreePascal/Lazarus сейчас отличается от того, что сделано в Delphi после перехода на юникод. Строки во FreePascal НЕ хранят информацию о кодировке. Работа над этим ведётся в отдельной ветке (cpstrnew), и когда эти изменения попадут в основную ветку -- неизвестно.
nic1982
Ответы на некоторые вопросы, возможно, появятся после просмотра этой ветки англоязычного форума:
http://www.lazarus.freepascal.org/index ... pic=5963.0
и этой ветки русского:
http://www.freepascal.ru/forum/viewtopi ... =26&t=4481
Ничего более конкретного посоветовать, к сожалению, не могу - ни с DBF, ни с Firebird не работал.
Odissey, хм, это плохо.
Раньше переносить проекты из Delphi было проще, теперь, когда все уже переписано под XE, а в Лазаре еще "конь не валялся" со строками
Отсюда вывод - нужно лезть в DataSource - писать свою обертку над потоком данных. Для перекодировки "на лету"
Раньше переносить проекты из Delphi было проще, теперь, когда все уже переписано под XE, а в Лазаре еще "конь не валялся" со строками
Отсюда вывод - нужно лезть в DataSource - писать свою обертку над потоком данных. Для перекодировки "на лету"
Вот такой костыль можно применить:
Код: Выделить всё
uses lconvencoding;
{ TForm1 }
procedure TForm1.DbFieldGetText(Sender: TField; var aText: string;
DisplayText: Boolean);
begin
aText:=CP866ToUTF8(Sender.AsString);
end;
procedure TForm1.DbFieldSetText(Sender: TField; const aText: string);
begin
Sender.AsString:=UTF8ToCP866(aText);
end;
procedure TForm1.DbAfterOpen(DataSet: TDataSet);
var i: Integer;
begin
for i:=0 to DataSet.FieldCount-1 do
if DataSet.Fields[i].DataType in [ftString, ftMemo, ftFixedChar] then
begin
DataSet.Fields[i].OnGetText:=@DbFieldGetText;
DataSet.Fields[i].OnSetText:=@DbFieldSetText;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
for i:=0 to ComponentCount-1 do
if Components[i] is TDataSet then
begin
(Components[i] as TDataSet).AfterOpen:=@DbAfterOpen;
if (Components[i] as TDataSet).Active then
DbAfterOpen(Components[i] as TDataSet);
end;
end;Лучше перевести базы в utf8 и раз и навсегда и забыть о костылях.
На худой конец работать в одну сторону, импортировать новые данные из dbf в свою базу в utf8
На худой конец работать в одну сторону, импортировать новые данные из dbf в свою базу в utf8
