Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Иерархическое отображение категорий в Embarcadero Delphi 2010 с использованием Access

Delphi , Компоненты и Классы , TDBGrid

Вопрос пользователя заключается в том, как отобразить иерархию категорий в Embarcadero Delphi 2010, используя Access-базу данных. В таблице MCategory присутствует колонка parentcategory, которая указывает на родительскую категорию для каждой записи. Пользователь хочет отобразить эту иерархию в виде дерева на DBGrid, не прибегая к сложным рекурсивным методам.

Для решения этой задачи можно использовать следующий подход:

  1. Преобразование всех записей набора данных в TStringList и их сортировка.
  2. Реализация компонента TCategoryItem, который будет содержать информацию о категории, включая родительскую категорию и идентификатор.
  3. Обработка события AfterOpen компонента ADOQuery, где происходит добавление каждого элемента в TStringList.
  4. Создание процедуры OnGetFieldText, которая будет обрабатывать текст родительской категории, формируя иерархию.
  5. Привязка процедуры OnGetFieldText к полю parentcategory в ADOQuery для отображения иерархии в DBGrid.

Вот пример кода, который можно использовать для реализации предложенного подхода:

type
  TCategoryItem = class
  private
    FCategoryTitle: string;
    FId, FParentId: Variant;
  public
    property CategoryTitle: string read FCategoryTitle write FCategoryTitle;
    property Id: Variant read FId write FId;
    property ParentId: Variant read FParentId write FParentId;
  end;

var
  RecordList: TStringList;

procedure TForm1.AdoQuery1AfterOpen(DataSet: TDataSet);
var
  Item, RootItem: TCategoryItem;
begin
  DataSet.First;
  DataSet.DisableControls;
  try
    // Добавление корневого элемента в RecordList, если это необходимо
    // RootItem := TCategoryItem.Create;
    // RootItem.CategoryTitle := 'ROOT';
    // RecordList.AddObject('', RootItem);
    while not DataSet.Eof do
    begin
      Item := TCategoryItem.Create;
      Item.CategoryTitle := DataSet['category'];
      Item.Id := DataSet['codecategory'];
      Item.ParentId := DataSet['parentcategory'];
      RecordList.AddObject(VarToStr(Item.Id), Item);
      DataSet.Next;
    end;
  finally
    RecordList.Sort; // для использования бинарного поиска
    DataSet.EnableControls;
    DataSet.First;
  end;
end;

procedure TForm1.OnGetFieldText(Sender: TField; var Text: string;
  DisplayText: Boolean);
var
  Idx: Integer;
  ParentValue: Variant;
  Item: TCategoryItem;
  Texts: TStringList;
begin
  ParentValue := Sender.Value;
  Texts := TStringList.Create;
  try
    while RecordList.Find(VarToStr(ParentValue), Idx) do
    begin
      Item := RecordList.Objects[Idx] as TCategoryItem;
      Texts.Insert(0, Item.CategoryTitle);
      ParentValue := Item.ParentId;
    end;
    Texts.Delimiter := '>';
    Text := Texts.DelimitedText;
  finally
    Texts.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery1.FieldByName('parentcategory').OnGetText := OnGetFieldText;
  ADOQuery1.Refresh;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RecordList := TStringList.Create(True);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  RecordList.Free;
end;

Этот код предполагает, что события OnCreate и OnDestroy формы будут использоваться для создания и освобождения TStringList. Процедура OnGetFieldText используется для модификации отображаемого текста для одного поля, не для вычислений, связанных с набором данных; для таких вычислений следует использовать TDataset.OnCalcFields. Однако, если рассматривать большие объемы данных, предпочтительнее было бы выполнение подобных операций на стороне сервера, в базе данных, а не на клиенте.

Использование TStringList для сортированного доступа может быть быстрее, чем использование TDictionary, так как поиск в TStringList использует бинарный поиск, в то время как TDictionary использует поиск по хешу. Также стоит учесть, что если вы выполняете ограниченный выбор категорий (SELECT...WHERE), вам нужно будет загрузить все категории заранее, так как иначе вы не сможете найти родительские категории, если они не были загружены изначальным запросом.

Создано по материалам из источника по ссылке.

Вопрос связан с реализацией иерархического отображения категорий в Embarcadero Delphi 2010 с использованием Access-базы данных, где для каждой категории указана родительская категория, и задача состоит в отображении этой иерархии в виде дерева


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: TDBGrid ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-16 10:45:04/0.0061380863189697/0