Lazarus DBF понимание рабочего кода

Форум для изучающих FPC и их учителей.

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

Lazarus DBF понимание рабочего кода

Сообщение wzn » 24.07.2018 14:11:36

Есть рабочий код:
...
private
//!!! Добавить эту процедуру
procedure From1251(Sender: TField; var AText: string; DisplayText: Boolean);
...
{ TForm1 }

//!!! Добавить эту процедуру
procedure TForm1.From1251(Sender: TField; var AText: string; DisplayText: Boolean);
begin
AText:= CP1251ToUTF8(Sender.AsString); //Преобразование из WIN1251 в UTF8
//Если кодировка другая, то можно пробовать другие функции:
//CP866ToUTF8
//KOI8ToUTF8
end;
...
процедура:

begin
Dbf1.Open;
for i:=0 to Dbf1.Fields.Count-1 do
if Dbf1.Fields[i].DataType=ftString then
Dbf1.Fields[i].OnGetText := @From1251;
end;
...
Тут совершенно не ясно как работает строка
Dbf1.Fields[i].OnGetText := @From1251;

Собственно, работает не совсем так, как хочется.
А хочется так:
1. Открыли файл ( не читая записей, еще не описывая структуру)
2. Получить описание полей и CodePage из самого файла (866|1251|кои8...). (как? Предполагаю читать заголовок DBF как цепочку байт)
3. Читаем записи не теряя половину текста (для слова "Привет" поле в DBF L=6 символов CP866 из под OC=Windows)
4. Формируем экранный список данных из DBF, где длина текстового поля экрана =2х длина поля в DBF.
5. Меняем любую ячейку экрана без проблемы с кодировкой
6. Сохраняем, что меняли в экранной таблице, в экранной кодировке UTF8 (по умолчанию).
7. Завершая сохраняем (по кнопке или кресту) данные из экранной таблицы DBGrid в DBF c предварительным преобразованием в CP866.

То что есть - портит данные при попытке редактирования, преобразование происходит, видимо, в полях DBF и половина текста теряется.
Как такое сделать попроще и чтоб наглядность была?
А то не понятно, где источник данных при использовании @From1251или @From866.
И можно ли как-то так:
DBGrid1.Columns.Text := CP866toUTF8(Dbf1.Fields[i].OnGetText);
Len(DBGrid1.Columns.Text):=2*Len(Dbf1.Fields[i].OnGetText); //Двойная экранная длина для преобразований кодировок (в DBF ничего лишнего)
тут хоть видно откуда взять и куда положить. (Вот только не работает - фиг знает как туда обратиться в цикле по полям и записям или конкретно на Pointer к DBF).
Не программа, а какие-то клочки. ХЗ что за чем исполняется. :(
Какие куски кода в какие закоулки/свойства прописать нужно?
Может кто-то уже делал подобное?
wzn
незнакомец
 
Сообщения: 1
Зарегистрирован: 24.07.2018 11:14:31

Re: Lazarus DBF понимание рабочего кода

Сообщение Python » 02.10.2018 00:29:45

Код: Выделить всё
Dbf1.Fields[i].OnGetText := @From1251;

Работает она совершенно прозрачно - назначает обработчик события, ровно то же самое вы делаете каждый раз, когда кидаете на форму кнопку и нажимаете по ней двойным кликом мыши, а потом пишете код в магическим образом появившемся окошке редактора кода. На самом деле, IDE выполняет ровно то же:
Код: Выделить всё
Button1.OnClick:=@Button1Click;

Просто вы этого не видите, а потому вам кажется это простым и естественным.
Далее, по пунктам:
1. Открыли файл ( не читая записей, еще не описывая структуру)

Если верить FreePascal Wiki, то после открытия TDbf сам прочитает всё, что надо и определение полей в том числе, а потому п.2 просто не требуется.
3. Читаем записи не теряя половину текста

Не знаю, как вы там половину текста теряете, у меня всё работает (с).
4. Формируем экранный список данных из DBF, где длина текстового поля экрана =2х длина поля в DBF.

Вы имеете в виду, "переводим в кодировку UTF-8"? И... экранный список - это TStringGrid?
5. Меняем любую ячейку экрана без проблемы с кодировкой

Редактируя TStringGrid крайне сложно проблемы с кодировкой огрести.
6. Сохраняем, что меняли в экранной таблице, в экранной кодировке UTF8 (по умолчанию).

То есть: очищаем DBF и переносим в него информацию из TStringGrid, примерно так?
7. Завершая сохраняем (по кнопке или кресту) данные из экранной таблицы DBGrid в DBF c предварительным преобразованием в CP866.

И опять ничего руками делать не надо - всё уже сделано полностью автоматически.
Вот, набросал примерчик кода, только грид не делал, просто в TMemo выводил:
Код: Выделить всё
unit Unit1;

interface

uses
  Classes, SysUtils, db, dbf, FileUtil, Forms, Controls, Graphics, Dialogs,
  StdCtrls, LazUTF8;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Dbf1: TDbf;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  public
    procedure MyGetText(Sender: TField; var aText: string; DisplayText: Boolean);
    procedure MySetText(Sender: TField; const aText: string);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.MyGetText(Sender: TField; var aText: string; DisplayText: Boolean);
begin
  aText:=WinCPToUtf8(Sender.AsString);
end;

procedure TForm1.MySetText(Sender: TField; const aText: string);
begin
  Sender.AsString:=Utf8ToWinCP(aText);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I:integer;
begin
  Memo1.Lines.Clear;
  Dbf1.FilePath:='e:\exe\';
  Dbf1.TableName:='help.dbf';
  Dbf1.Open;
  For I:=0 to Dbf1.Fields.Count-1 do begin
    Dbf1.Fields[I].OnGetText:=@MyGetText;
    Dbf1.Fields[I].OnSetText:=@MySetText;
  end;
  while not Dbf1.EOF do begin
    Memo1.Lines.Add(Dbf1.Fields[2].Text);
    Dbf1.Edit;
    Dbf1.Fields[2].Text:=Utf8UpperCase(Dbf1.Fields[2].Text);
    Dbf1.Post;
    Dbf1.Next;
  end;
  Dbf1.Close;
end;

end.
Python
новенький
 
Сообщения: 20
Зарегистрирован: 23.01.2018 21:50:17

Re: Lazarus DBF понимание рабочего кода

Сообщение *Rik* » 03.10.2018 20:02:55

Попробуте правленную версию xDBF: http://visual-t.ru/xdbf.html
Работает с win1251 и cp866 без всяких OnGetText.
Для таблиц dbf visual foxpro кодировка может быть указана в самом файле, если кодировка не указана, то
переменные в помощь:
Для открытия таблицы в нужной кодировке:
DBFGlobals.DefaultOpenCodePage := 1251
или
DBFGlobals.DefaultOpenCodePage := 866;

Для создания таблицы с нужной кодировкой, перед созданием dbf программно указать:
DBFGlobals.DefaultCreateLangId := 101;//Если 101 то 866; Если 201 то WIN1251
Аватара пользователя
*Rik*
постоялец
 
Сообщения: 426
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал


Вернуться в Обучение Free Pascal

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

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

Рейтинг@Mail.ru