TDBGridEh — использование ExternalRecalc, SumList, Mногострочных заголовков и т.п.

2011-03-23 papirosnik C++ Builder

Имеется очень замечательная, удобная, красивая библиотека VCL-компонентов EhLib. Центральным звеном в цепочке элементов выступает DBGridEh. Именно он прославил эту библиотеку благодаря широким возможностям по отображению таблиц базы данных в таблицы на мониторе и на принтере. DBGridEh является многофункциональным  наследником стандартного DBGrid, расширяя его возможности такими полезными вещами, как группировка колонок в заголовке, группировка строк, футеры в таблице и в группе, многоцветный вывод строк, в том числе и по условию, шикарные возможности по сортировке и фильтрации данных как на стороне сервера, так и «на лету» , т.е в самой таблице; «автоподстановка» значений — статический аналог DBLookup —  полям, вычисление аггрегатных функций без дополнительного запроса на  сервер, кэширование данных… короче всего не перечислить. Однако следует сразу же признать, что я немного слукавил, назвав DBGridEh наследником от DBGrid. Наследником он является только по «духу», в смысле наследования поведения, но не по «факту», т.е. в терминах ООП таковым не является … так как переписан практически с нуля — и имеют только далёкого общего предка TObject, нежели находятся в одной нисходящемй ветви.

Здесь и здесь мы вкратце касались уже возможностей DBGridEh, но основной целью тогда являлись проблемы разработки собственных компонент, а не проблемы использования стороних. Теперь же обсудим некоторые малоизвестные, но не малополезные возможности этой компоненты. Сразу же оговорюсь, что я не имею чёткого предсталения, какой род приобретает слово Component при переводе с английского, поэтому использую как язык завернёт: то компонент, то компонента. Кому это родовое смешение режет глаз, сразу закрывайте эту страничку, кому пофик — тоже можете закрывать, так как реально пишу  — и не знаю что писать. Выдумываю на ходу.

Тем не менее, приступаем. И начнём, как это ни парадоксально звучит, с итогов. Самый простой способ подбить какой-то итог по колонке заключается в использовании футеров (подвалов) таблицы. Для начала необходимо указать, что наша таблица будет использовать футер (для целей данного примера достаточно и одного, хотя теоретически их число не ограниченно): DBGridEh1.FooterRowCount := 1; Кроме того, активизируем «подбиватель итогов», или в терминах EhLib — SumList:
SumList.Active := True ;
SumList.ExternalRecalc := False ;
SumList.VirtualRecords := False;
И последнее, что требуется — ткнуть носом таблицу в ту колонку, по которой мы хотим видеть итоговое значние. Для этого надо открыть редактор свойств для элемента коллекции Columns. Проще всего это сделать, даблкликнув по самой таблице и выбрав в появившемся списке нужный столбец. А ему уже выставить: Footer.ValueType := fvtSum. Этой строкой мы указали, какой агрегат мы будем накапливать. Ибо ещё можно посчитать минимальное, максимальное, среднее значение и кол-во этих самых значений. Т.е. показать тот результат, который для нас подготавливают так называемые «агрегатные» функции на стороне сервера.

Вроде всё просто и элементарно. Но в критичной к скорости выполнения или обновления программе такой подход будет вызывать раздражение, так как использует дополнительный запрос на сервер или, много более вероятно, циклический перебор всех строк грида —  что ещё хуже. Всё это потому, что мы необдуманно отказались от предложенной палочки-выручалочки в виде SumList.ExternalRecalc. Установив это свойство в «true«, мы тем самым показали гриду, что он по-прежнему должен иметь итоговое значение в футере для данной колонки, только теперь не обязан «париться» с его вычислением. Мы ему сами дадим значение посредством свойства SumList.SumCollection. А вот где мы возьмём это значение — сугубо наши проблемы. Хорошей практикой явлеятся формирование его при помощи функции Random. Но это только если вы программируете какое-нибудь казино, и хотите завлечь клиентов сказочными выигрышами. На самом же деле это число можно получить, закэшировав единожды серверный запрос или ещё каким-либо образом заполучив его (например, прочитав из Ini-файла). речь по-прежнему про число, а не про серверный запрос. Хотя серверный запрос можно прочитать и из ini-файла. Но кроме того что прочитали (проинициализироали), его ещё нужно поддерживать в актуальном состоянии, корректируя каждый раз, когда изменяется значения какого-либо кортежа в интересующей нас колонке. Кто совсем не понимает о чём  это я — закрывайте эту страницу не раздумывая, потому что скоро и я перестану понимать, что я здесь пишу. Кто же желает докопаться до истины… стучитесь — и вам ответят.  Сейчас же только повторюсь, что такой подход даёт ощутимый выигрыш в случае не совсем маленького числа строк в подопытной таблице.

Ладно, пока оставим итоги в покое, а займёмся внешним видом , а ещё точнее тем, что красит таблицу, т.е. будем препарировать её шапку (header). Основная вкусняшка здесь — многострочность. Включается до примтивного просто: DbGridEh1.UseMultiTitle := True; С выключением думаю проблем тоже не возкнет.  А чтоб задать подчинённые заголовки для столбца, нужно в инспекторе объекта прописать их через символ|.
Например: Для двух колонок с комбинированным свойством Title.Caption задать, например, такие значения: «Сальдо | На начало периода» и «Сальдо | На конец периода», то получис сводную колонку «Сальдо», которая имеет две подколноки: «На начало периода» и «На конец периода». Видимо, данную ситуацию проще попробовать сделать, чем объяснять на словах. Но поскольку вдохновление заканчивается и одлолевает лень, то студию я запускать не стану, а оставлю это занятие Вам в качестве самостоятельного упражнения.

Как я уже только что упомянул, из-за лимита вдохновения за рамками данной статьи осталось огромное количество замечательных взможностей компоненты DBGridEh, тем  не менее котрые не скрыты за семью печатями, а легко даются тому, кто пробует их постичь…
Статья получилась больше какая-то лирическая, март всему виной. Но тем не менее, задавая конкретные вопосы по сабжу, Вы будете получать прямые, недвусмысленные ответы в кртачайшие сроки. Если есть пожелания насчёт того, какие моменты осветить дополнительно и более подробно в самой статье — излагайте. Статья открыта для редактирования.
Засим откланиваюсь.

BSGrid, VCL Components,


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Powered by WordPress. Designed by elogi.