Страницы

суббота, 7 февраля 2009 г.

Стандартный DbGrid с многострочными заголовками.

Обещанный пост о многострочных заголовках с группированием в стандартном TDbGrid.

Группируемый заголовок в DbGrid сделанный с помощью TObjectField

 

История поста

Меня давно интересовало, как использовать свойство Expanded у TColumn. Свойство это объявлено как read-only. В справке о нём написано:

Expanded относится только к тем колонкам, которые представляют поля, являющиеся наследниками TObjectField. Когда колонка раскрыта(expanded), она выводится для каждого дочернего поля объектного поля. У каждой колонки, представляющей дочернее поле, есть свой заголовок, который выводится под заголовком колонки родительского поля. Когда свойство Expanded равно false, значения дочерних полей выводятся в строку, через запятую, и не могут быть отредактированы.

Но, работая только с Firebird, мне не приходилось сталкиваться с объектными полями.

Многострочный группируемый заголовок в TDbGrid

С объектными полями я столкнулся случайно, когда выполнял изучал как Delphi работает с объектными типами СУБД Oracle через dbExpress.

Вручную включить многострочные группируемые заголовки в DbGrid-е нельзя. Грид сам решает как отображать колонку. Тип отображения колонки задаётся типом поля в Dataset. Более того, методы отвечающие за вывод групповых колонок в TCustomDbGrid объявлены неперезагружаемыми. Поэтому единственный способ воспользоваться этой фичей – это сделать так, чтобы Dataset возвращал поля объектных типов. Можно конечно и написать свою реализацию DbGrid.

Наследники TObjectField

Помимо распространённых TStringField, TDateTimeField, TintegerField в Delphi присутствуют типы полей:

  • TObjectField – базовый класс для реализации объектных полей
  • TAdtField – поле объектного типа. Конкретная реализация. TField.DataType = ftADT
  • TArrayField – поле типа массив. TField.DataType = ftArray
  • TDatasetField – поле с вложенным Dataset-ом. TField.DataType = ftDataSet

Пример

Чтобы DbGrid начал показывать такие заголовки, всего-то и нужно – подключить его к набору данных(Dataset) с объектными полями(наследниками TAdtField). Я сделал небольшой пример, демонстрирующий работу TAdtField-полей в TClientDataSet.

Пример можно скачать по ссылке:
http://lazyproject.googlecode.com/files/ExpandedTitleDbGrid.zip

В архиве исходники для Delphi 7 и скомпилированный exe-файл. Исходники без проблем собираются и в Delphi 2009.

Смотрите также

7 комментариев:

  1. Может дашь совет как установить ehlib под delphi 2009, скачал библиотеку 4.4, поддержка 2009 есть, но при установке куча ошибок incopatible types comctrls.Tbyte and prnDbgeh.Tbyte и there is no overloaded version of 'Convert' that can be called with these arguments

    ОтветитьУдалить
  2. Я с такой ошибкой не сталкивался.

    Могу, даже несколько советов дать:
    1) Проверь, что ты устанавливаешь в правильную версию Delphi.
    2) Проверь, что устанваливаешь по инструкции.
    3) Попробуй установить пэкэдж из IDE.
    4) Попробуй обратиться к автору компонента за помощью.

    ОтветитьУдалить
  3. большое спасибо, просто я че то по запарке втупил. не увидел в инструкции что надо папку common и папку delphi 2009 слить в корень. после этого все встало
    Еще раз спасибо за то что побудил меня почитать rtfm)))

    ОтветитьУдалить
  4. Пример не работает. Ошибка:
    [Fatal Error] uObjectFieldsTest.pas(120): Could not create output file '%D7BUILD%\Dcu\uObjectFieldsTest.dcu'

    ОтветитьУдалить
  5. Удали из папки с проектом файл ObjectFields.dof.

    ОтветитьУдалить
  6. Попытался прикрутить к DbGrid + AdoQuery + DataSource, что то никак, ругается на отсутсвие полей. Или так работает только при задании для ClientDataSet?

    ОтветитьУдалить
  7. r3code - для реализации многострочных заголовков, AdoQuery должен содержать поле типа TADTField. ADO умеет делать это для объектных полей в Oracle. Про другие БД не знаю.

    ОтветитьУдалить