Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамические структуры 
V
    Опции темы
TheCetus
Дата 13.9.2006, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: 2
Всего: 2



Есть необходимость хранить в делфи описание нескольких таблиц, причем количество и типы полей у таблиц разные...
на данный момент использую структуру:

Код


type

  TCetFields = array [0..maxFieldCount-1, 0..3] of string;

  TCetTableDesc = record
    TableName  : string;                  // имя таблицы
    FieldCount : integer;                 // количество полей
    Fields     : TCetFields;              // двумерный массив в котором храняться описания полей
  end;



но получается очень неудобно когда максимальное число полей и число полей в таблице различается... приходится неиспользуемые поля забивать пустыми строками...
есть ли возможность сократить описание таблицы? т.е. использовать не статическую структуру записи а переменную?
PM MAIL   Вверх
Yanis
Дата 13.9.2006, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 72
Всего: 111



Конечно. Просто создавай динамический массив. Для добавления/удаления новых/старых полей создай специальные процедуры.


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
TheCetus
Дата 13.9.2006, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: 2
Всего: 2



хм... дело в том, что структуру описываю в секции Const
а в ней не получается скомпилировать такую структуру...

Код

type
  tmass = array of string;
  trec = record
    a : integer;
    b : tmass;
  end;

const

  myrec : trec = (
    a : 5;
    b : ('asd','qwe','uio')
  );


PM MAIL   Вверх
Elfebet
Дата 13.9.2006, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 545
Регистрация: 15.5.2006
Где: Украина. Запорожь е.

Репутация: 2
Всего: 14



ну дык вместо const поставь var...


--------------------
Программист не должен всё знать... он должен знать где можно посмотреть
PM MAIL ICQ GTalk   Вверх
Rodman
Дата 13.9.2006, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


CIO
****


Профиль
Группа: Участник
Сообщений: 6144
Регистрация: 7.5.2006
Где: Ukraine ⇛ Kyiv ci ty

Репутация: 7
Всего: 122



Цитата(TheCetus @  13.9.2006,  11:57 Найти цитируемый пост)
но получается очень неудобно когда максимальное число полей и число полей в таблице различается...


так тебе описание в таблице надо что-то  типа (название-КоличествоПолей)??? зачем заполнять пустыми значениями если можно просто количество поставить...

PM MAIL WWW Skype GTalk YIM MSN   Вверх
TheCetus
Дата 13.9.2006, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: 2
Всего: 2



Видимо я недостаточно четко выразился:
Храняться описания структур многих DBF файлов и структура у них не меняется.
Периодически происходит выгрузка данных в DBF файл, но перед выгрузкой файл необходимо сформировать...
Описание структуры лежит в отдельном модуле, единственное неудобство - большой размер записи описывающей структуру таблицы...

Elfebet, замена Const на var не помогла
PM MAIL   Вверх
Snowy
Дата 13.9.2006, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



А мне всегда казалось, что для создания DBF таблицы необходимо также знать Имя поля, длину поля, тип, а для некоторых полей и другие дополнительные параметры.
Как можно создать таблицу с полями только по именам?
PM MAIL   Вверх
TheCetus
Дата 13.9.2006, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: 2
Всего: 2



Snowy, если это как то поможет решить проблему smile

Код


  tblHDRT : TCetTableDesc = (
    TableName  : 'HDRT.DBF';
    FieldCount : 13;
    Fields     : (('BIC',     'C', '9',  ''),
                  ('DAT_V',   'D', '',   ''),
                  ('DAT_VL',  'D', '',   ''),
                  ('NLS',     'C', '20', ''),
                  ('KOD_W',   'C', '3',  ''),
                  ('I_KR',    'N', '17', '2'),
                  ('DB_KR',   'N', '17', '2'),
                  ('DB_DT',   'N', '17', '2'),
                  ('O_KR',    'N', '17', '2'),
                  ('K_PD_PR', 'N', '5',  '0'),

                  ('K_PD_RS', 'N', '5',  '0'),
                  ('NUM_V',   'C', '10', ''),
                  ('KODT_V',  'C', '8',  ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),

                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),

                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', ''),
                  ('', '', '', '')
  )); // tblHDRT



описание структуры смотри в самом первом моем посте
PM MAIL   Вверх
Snowy
Дата 13.9.2006, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Так просто от задачи не отделаться.
Нужно писать трехклассовую модель.
Могу набросать модуль с реализацией модели.

Добавлено @ 14:51 
Нельзя такую задачу упрощать до записи.
Задача полностью объектная.
Такие вещи нужно делать грамотно.
PM MAIL   Вверх
TheCetus
Дата 13.9.2006, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: 2
Всего: 2



Snowy, было б замечательно увидеть этот модуль smile
PM MAIL   Вверх
Snowy
Дата 13.9.2006, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Код
unit Unit2;

interface

uses Classes;

type
  TCetField = class
  {* Класс - поле таблицы }
  public
    Name: string; // имя поля
    Tip:  char;   // тип поля
    Len:  byte;   // длина поля
    dot:  byte;   // после запятой
  end;

  TCetTable = class
  {* Класс - таблица }
  private
    FFields: TStringList;
    FName: string;
    function GetCount: Integer;
    function GetFields(Name: string): TCetField;
    function GetItems(Index: integer): TCetField;
  public
    constructor Create;
    destructor Destroy; override;
    procedure CreateDBF(Path: string);
    {* Создать DBF - это уже сам ;-) }
    function Add(Name: string; Tip: char; Len: byte; dot: byte = 0): TCetField;
    {* Добавить поле }
    property Items[Index: integer]: TCetField read GetItems; default;
    {* Поля }
    property Fields[Name: string]: TCetField read GetFields;
    {* Поле по имени }
    property Count: Integer read GetCount;
    {* Число полей }
    property Name: string read FName write FName;
    {* Имя таблицы }
  end;

  TCetTables = class
  {* Класс - список таблиц }
  private
    FTabs: TStringList;
    function GetTabI(Index: Integer): TCetTable; overload;
    function GetTabN(Name: string): TCetTable; overload;
    function GetCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    function Add(Name: string): TCetTable;
    {* Добавить таблицу }
    property Items[Index: Integer]: TCetTable read GetTabI; default;
    {* Список таблиц }
    property Count: Integer read GetCount;
    {* Количество таблиц }
    property Tabs[Name: string]: TCetTable read GetTabN;
    {* Получить таблицу по имени }
  end;


var CetTables: TCetTables;

implementation

{ TCetTableDesc }

function TCetTables.Add(Name: string): TCetTable;
begin
  result := TCetTable.Create;
  result.Name := Name;
  FTabs.AddObject(Name, result);
end;

constructor TCetTables.Create;
begin
  FTabs := TStringList.Create;
  FTabs.Sorted := true;
end;

destructor TCetTables.Destroy;
var i: Integer;
begin
  for i := 0 to FTabs.Count - 1 do FTabs.Objects[i].Free;
  FTabs.Free;
  inherited;
end;

function TCetTables.GetCount: Integer;
begin
  result := FTabs.Count;
end;

function TCetTables.GetTabI(Index: Integer): TCetTable;
begin
  result := TCetTable(FTabs.Objects[Index]);
end;

function TCetTables.GetTabN(Name: string): TCetTable;
var i: Integer;
begin
  if FTabs.Find(Name, i) then result := GetTabI(i)
  else result := nil;
end;

{ TCetTable }

constructor TCetTable.Create;
begin
  FFields := TStringList.Create;
end;

destructor TCetTable.Destroy;
var i: integer;
begin
  for i := 0 to FFields.Count - 1 do FFields.Objects[i].Free;
  FFields.Free;
  inherited;
end;

function TCetTable.GetCount: Integer;
begin
  result := FFields.Count;
end;

function TCetTable.GetItems(Index: integer): TCetField;
begin
  result := TCetField(FFields.Objects[Index]);
end;

function TCetTable.GetFields(Name: string): TCetField;
var i: integer;
begin
  i := FFields.IndexOf(Name);
  if i < 0 then result := nil
  else result := GetItems(i);
end;

function TCetTable.Add(Name: string; Tip: char; Len: byte; dot: byte = 0): TCetField;
begin
  result := TCetField.Create;
  result.Name := Name;
  result.Tip := Tip;
  result.Len := Len;
  result.dot := dot;
  FFields.AddObject(Name, result);
end;

procedure TCetTable.CreateDBF(Path: string);
begin
  // Банзай! Создаём DBF-ку!
end;

initialization
  CetTables := TCetTables.Create;

finalization
  CetTables.Free;

end.


Добавлено @ 15:56 
Далее как это заполнять:
Код

begin
  with CetTables do begin
    with Add('HDRT.DBF') do begin // добавляем таблицу в список и работаем с ней
      Add('BIC', 'C', 9); // добавляем первое поле
      Add('FIELD2', 'N', 4); // второе
      Add('DAT_V', 'D', 8); // т.д.
    end;
    with Add('Table2.dbf') do begin // добавляем вторую таблицу
      Add('FIELD1', 'N', 8); // добавляем в неё первое поле
      Add('FIELD2', 'C', 12); // второе
    end;
    /// и т.д.
  end;
end;


Добавлено @ 15:59 
Далее. Как это использовать:
Код
var
  i: integer;
begin
  for i := 0 to CetTables.Count - 1 do // перебираем все таблицы
    Memo1.Lines.Add(CetTables[i].Name); // Выводим имена каждой в мемо
  // Берём таблицу по имени и выводим имя первого поля
  Memo1.Lines.Add(CetTables.Tabs['HDRT.DBF'][0].Name);
end;

Обращаться к таблицам можно как по номеру, так и по имени.
! При добавлении новой таблицы нумерация остальных меняется, т.к. они сортированы по имени
Нумерация полей никогда не меняется, т.к. структура - дело строгое.

Не сделал:
- Удаление таблиц из списка и полей из таблиц. По ТЗ оно тебе не особо надо. Но доработать легко.
- Сохранение и чтение в/из файл. Можно сделать, если набор таблиц будет редактироваться вручную. А так - забивай программно.
PM MAIL   Вверх
TheCetus
Дата 14.9.2006, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: 2
Всего: 2



Интересное решение использовать для хранения полей TStringList smile
Это как один из вариантов решения. Но без использования TStringList в Record нельзя другим способом хранить массивы разной длинны? именно массив а не класс?
PM MAIL   Вверх
Alexeis
Дата 14.9.2006, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(TheCetus @  14.9.2006,  11:25 Найти цитируемый пост)
хранить массивы разной длинны

Хранить то можно, но вот инициализировать их уже таким образом не получится


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Snowy
Дата 14.9.2006, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Можно. Если не использовать константу, а назначать ручками.
А отчего такая тяга к массивам?
PM MAIL   Вверх
Alexeis
Дата 14.9.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Вот так можно организовать структуру переменной длинны:
Код

type
   arr = array[1..100000] of Integer;
   tmytype = record
               i : Integer;
               buf : Integer;
   end;
   pmytype = ^tmytype;

procedure TForm1.FormCreate(Sender: TObject);
var
  p : pmytype;
  d : ^arr;
begin
  GetMem(p, 1000);
  d := @p.buf;
  d[200] := 12346789;

  ShowMessage(IntToStr( d[200]));



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0647 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.