Динамическое создание структуры RECORD

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Re: Динамическое создание структуры RECORD

Сообщение GrayEddy » 23.09.2009 10:08:04

> Vadim
:wink:
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Re: Динамическое создание структуры RECORD

Сообщение Vadim » 23.09.2009 10:10:29

Если речь идёт о компоненте не связанном с SQLDb, то, я думаю, можно создать класс наследник от TDataSet, в котором и определять динамически поля.
Примерный ( :) ) механизм:
1. Читаем файл *.BTR в поток.
2. Считываем из потока информацию о структуре таблицы.
3. Создаём динамически в наследнике TDataSet аналогичную структуру.
4. Перебрасываем данные из потока в наследника...

Добавлено спустя 3 минуты 38 секунд:
GrayEddy
:wink:
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Динамическое создание структуры RECORD

Сообщение bloodlines » 23.09.2009 10:16:27

2. Считываем из потока информацию о структуре таблицы.

Это не в BTR а в DDF или другом файле словаря храниться. Автоматическое определение полей пока не входит в мои цели.

3. Создаём динамически в наследнике TDataSet аналогичную структуру.

На данный момент это единственное что мне нужно.

Я использую API из Pervasive SDK. И просто оборачиваю это во что то немного более удобное... :D
Аватара пользователя
bloodlines
постоялец
 
Сообщения: 100
Зарегистрирован: 05.11.2008 11:26:19

Re: Динамическое создание структуры RECORD

Сообщение Vadim » 23.09.2009 10:20:20

bloodlines
Тогда всё предельно просто. Если есть нормальный файл словоря (с известной структурой файла ;) ), то считывать информацию о структуре таблицы из него и создаём в наследнике аналогичную структуру.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Динамическое создание структуры RECORD

Сообщение bloodlines » 23.09.2009 10:41:24

Для чтения (позиционирования) из BTR файла используется функция

Код: Выделить всё
  FUNCTION BTRVID(
                 operation      : WORD;
             VAR positionBlock;
             VAR dataBuffer;
             VAR dataLen        : WORD;
             VAR keyBuffer;
                 keyNumber      : SMALLINT;
             VAR clientID )     : SMALLINT;


Где dataBuffer - структура PACKED RECORD в которую заноситься значения полей текущей записи, keyBuffer - структура PACKED RECORD, описывающая постоянную (индексную) часть BTR файла.

Не думаю, что вместо dataBuffer можно поставить например MemDataset1.Fields...

Вся суть задачи заключается в удобном определении полей и чтении данных, остальное для меня пока не критично.
Аватара пользователя
bloodlines
постоялец
 
Сообщения: 100
Зарегистрирован: 05.11.2008 11:26:19

Re: Динамическое создание структуры RECORD

Сообщение Vadim » 23.09.2009 10:54:27

bloodlines писал(а):Не думаю, что вместо dataBuffer можно поставить например MemDataset1.Fields...

Ну ясен перец. :) В TDBF подобный принцип хранения данных, только там dataBuffer - это строка. Согласно данным о структуре файла, т.е. данным о полях таблицы, из этой строки берётся определённое количество символов, равное длине поля и эту выдернутую подстроку выкладывают в заранее созданное поле TDataSet'а. Это, конечно, не в буквальном смысле, но именно таким путём.
У Вас Вы будете выдёргивать определённое кол-во байтов с той позиции, которые указаны в структуре полей.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Динамическое создание структуры RECORD

Сообщение bloodlines » 23.09.2009 10:57:21

У меня сейчас суть вопроса в том, что поставить вместо dataBuffer.
Аватара пользователя
bloodlines
постоялец
 
Сообщения: 100
Зарегистрирован: 05.11.2008 11:26:19

Re: Динамическое создание структуры RECORD

Сообщение GrayEddy » 23.09.2009 11:00:39

1. Берешь MemDataSet1, куда загнал структуру, она может включать: имя поля, длина в байтах, и т.д.
1. В dataBuffer ставишь указатель на начало буфера.
Тут идет цикл
2. Считываешь первое поле из MemDataSet, узнаешь длину в байтах.
3. Читаешь из dataBuffer ... байт, которые считал из пункта 2. При необходимости приводишь к нужному типу. Тип можно считать из п. 2
4. Снова идешь на п. 2 и читаешь следующее поле. Потом снова п.3. И так далее, пока не обойдешь все поля в MemDataSet1, и не прочтешь весь dataBuffer.

PS. Размер dataBuffer должна совпасть с размером всех полей, входящих в MemDataSet1. Это так, для проверки.
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Re: Динамическое создание структуры RECORD

Сообщение bloodlines » 23.09.2009 11:15:10

GrayEddy спасибо!

1. В dataBuffer ставишь указатель на начало буфера.

Не совсем понял мысль... dataBuffer по документации должна быть структура PACKED RECORD.
Аватара пользователя
bloodlines
постоялец
 
Сообщения: 100
Зарегистрирован: 05.11.2008 11:26:19

Re: Динамическое создание структуры RECORD

Сообщение Vadim » 23.09.2009 11:48:48

bloodlines писал(а):VAR dataBuffer

А Вы не ошибаетесь? Судя по этому:
Код: Выделить всё
VAR dataBuffer

там как раз нужен безтиповой параметр. На его место можете подставлять всё, что хотите.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Динамическое создание структуры RECORD

Сообщение bloodlines » 23.09.2009 11:52:59

Извиняюсь - туплю...
Ещё пара ламерских вопросов
3. Читаешь из dataBuffer ... байт, которые считал из пункта 2. При необходимости приводишь к нужному типу. Тип можно считать из п. 2

1 - Как считать нужное количество байт из databuffer, должна быть какая то функция, но я не помню.
2 - Как привести результат чтения к нужному типу?
Аватара пользователя
bloodlines
постоялец
 
Сообщения: 100
Зарегистрирован: 05.11.2008 11:26:19

Re: Динамическое создание структуры RECORD

Сообщение GrayEddy » 23.09.2009 11:54:14

Код: Выделить всё
var P: Pointer
...
GetMem(P, размер_структуры);
...


Добавлено спустя 1 минуту 21 секунду:
1. Move(...)
2. Для этого желательно знать тип поля.

Добавлено спустя 7 минут 10 секунд:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=624
Структура DBF-файлов для непродвинутых
Хорошая статья, достаточно посидеть час и все прояснится. У Вас примерно такая же задача по смыслу.
1. Узнать структуру для чтения файла.
2. Зная структуру - читаем данные
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Re: Динамическое создание структуры RECORD

Сообщение Timid » 24.09.2009 10:07:48

Это очень сложный путь. Проще обойтись динамическим массивом

TDynamicStringArray=array of string;

var
mybase:array of TDynamicStringArray;


Далее, считаешь количество полей, заносишь в mybase[0][i] названия
в остальные строки - по мере поступления.

Да, не забываем SetLength использовать....
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15

Re: Динамическое создание структуры RECORD

Сообщение bloodlines » 24.09.2009 16:21:53

Уважаемый, GrayEddy...
Код: Выделить всё
var P: Pointer
...
GetMem(P, размер_структуры);
...


Я так понял, P ставим на место DataBuffer. В сущности, поскольку перед DataBuffer стоит параметр Var это означает, что в функцию BTRVID передаётся на сама переменная, а указатель на область памяти, в которой она храниться. То же самое после указанного кода представляет собой P.

А как занести в область памяти на которую ссылается указатель P значение некоторой переменной причём в определённый участок памяти. Это понадобиться для операций обновления записи и добавления новой записи а так же для работы с индексами.

В одном из примеров индекс описан так
Код: Выделить всё
OPERHEAD_INDEX7 = packed record
appIsn : longint;
appName : array[0..8] of char;
end;

var
OperHeadIndex7 : OPERHEAD_INDEX7; {индекс номер 7}

OperheadIndex0.appIsn := 8 AsInteger; {присвоение параметров поиска}
fillchar(OperheadRecord , SizeOf(OperheadRecord), #0);
dataLen := sizeof(OPERHEAD_STRUCT);
status := BTRVID(B_GET_EQUAL, {системная константа}
PosBlock, {системная}
OperheadRecord, {сюда будет возвращен результат поиска}
dataLen, {см.выше}
OperheadIndex7, {см.выше}
7, {номер индеска - см.выше}
client); {системная}


Как выделить память мне понятно, но как занести в область памяти значение переменной...? В данном случае аналог
Код: Выделить всё
OperheadIndex0.appIsn := 8 AsInteger;
Аватара пользователя
bloodlines
постоялец
 
Сообщения: 100
Зарегистрирован: 05.11.2008 11:26:19

Re: Динамическое создание структуры RECORD

Сообщение GrayEddy » 25.09.2009 08:42:59

Сведений недостаточно.
Вышлите мне на почту btr-файл(ы) и документацию (или ссылки) по структуре этих файлов, посмотрю.
GrayEddy
постоялец
 
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Пред.След.

Вернуться в Free Pascal Compiler

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

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

Рейтинг@Mail.ru