Компонент TQRGroup
Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.
Компонент TQRGroup використовується для угруповання інформації. У його властивості Expression вказується деякий вираз, який застосовується для угруповання; іншими словами, до групи включаються записи НД, які задовольняють умові цього висловлювання. При зміні вираження відбувається зміна групи.
Для кожної групи зазвичай створюється її заголовок та підвал (смуга з підсумковою інформацією). В обох випадках використовується смуга TQRBand: як заголовок групи зі значенням властивості BandType, рівним rbColumnHeader, а як підвал-зі значенням rbGroupFooter. Властивість FooterBand компонента TQRGroup має містити посилання на компонент підвалу групи. У заголовку групи, як правило, виводиться групуючий вираз, а в підвалі групи - агрегована інформація: сумарні, середні тощо значення по групі в цілому.
ПРИМІТКА Зазвичай як групуючий вираз використовується одне з полів НД: зміна значення поля сприймається як кінець чергової групи та перехід до наступної. Якщо НД створений компонентом ТТаЫе, необхідно створити індекс групуючого поля і зробити його поточним. Якщо НД створено за допомогою компонента TQuery, у ньому слід відсортувати дані, увімкнувши групуюче поле до списку полів секції ORDER BY.
Для ілюстрації угруповання створимо звіт, у якому виводиться список усіх книг кожного видавництва, а кінці групи вказується загальна кількість найменувань книжок цього видавництва. Вигляд звіту на етапі конструювання показано на рис. 8.35 (проект ChapJ) 8 QReport QRGroup Group.dpr).

Мал. 8.35. Звіт із групуванням даних на етапі конструювання
1. На порожній формі розмістіть запит TQuery з ім'ямBooks, встановивши його властивості такими:
Про DatabaseName = BIBLDATA;
ПРО SQL = SELECT * FROM Books ORDER BY BName;
2. Помістіть на форму компонент TQuickRep та встановіть у його властивість DataSet значення BOOKS.
3. Сформуйте смугу заголовка QRBandl та розмістіть на ній компонент TQRLabel з такими властивостями:
Caption = Список книг з угрупуванням за видавництвами; Про Font .Size = 16;
Про Font.Style = [fsBold, fsltalic].
4. Покладіть на звіт смугу QRBand2 із заголовками колонок та властивостями: Про BandType = rbColumnTitle;
Про Font.Style = [fsBold].
5. Помістіть смугу TQRGroup - вона здійснюватиме угруповання даних. Для цього вручну або за допомогою майстра створення виразів встановіть у її властивість Expression значення Books. BPublish, тобто ім'я того поля, яким будуть групуватися дані. Одночасно ця смуга є заголовком групи, тому розмістіть у ній компонент TQRLabel (Сар-^оп=Видавництво) і TQRDBText (DataSet=Books, DataField=BPublish). Щоб відокремити заголовок групи від наступної за ним детальної інформації, встановіть для смуги як Frame. DrawBottom значення True.
6. За смугою заголовка групи повинна розміщуватися детальна смуга - помістіть на звіт компонент TQRBand із властивістю BandType рівним rbDetail. Встановіть для цієї смуги висоту (властивість Height), що дорівнює 16, щоб заощаджувати простір звіту за рахунок зменшення відстані між сусідніми детальними смугами. Для друку на детальній смузі п'яти колонок звіту помістіть на неї 5 компонентів TQRDBText, встановивши для кожного значення False як AutoSize і значення Books як DataSet. "Розтягніть" мишею компоненти по горизонталі приблизно так, як показано на рис. 8.35, та за допомогою властивостейDataField зв'яжіть їх з полями BName, BAuthor, BYear, BPages і BOpt, причому для останніх трьох компонентів встановіть вирівнювання по центру (Alignment=taCenter).
Якщо ви виконаєте прогін програми, то зауважте, що кількість книг вказана правильно тільки для першого видавництва. Це пов'язано з тим, що компонент TQRExpr, відповідальний за висновок, показує поточний лічильник книг, а не суму книг у групі. Щоб сума виводилася правильно, потрібно доопрацювати програму. Для цього введемо глобальну змінну N та напишемо два обробники подій OnBef orePrint для смуги заголовка групи та детальної смуги. У першому обробнику лічильник N обнулюється, готуючись до підрахунку кількості книг чергової групи, у другому - нарощується на одиницю під час виведення даних про чергову книгу (листинг 8.3).

Лістинг 8.3. Обробники подій для смуги заголовка групи та детальної смуги unit GroupU;
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Qrctrls, QuickRpt, ExtCtrls, Db, DBTables, QRExport;
TPrevGroup = class(TForm) QuickRepl: TQuickRep; QRBandl: TQRBand; QRLabell: TQRLabel; QRBand2: TQRBand; QRLabel2: TQRLabel;
Лістинг 8.3 (продовження)
QRLabel3: TQRLabel; QRLabel4: TQRLabel; QRLabe15: TQRLabe1; QRLabel6: TQRLabel; QRGroupl: TQRGroup; QRBand3: TQRBand; QRDBTextl: TQRDBText; QRLabel7: TQRLabel; QRDBText2: TQRDBText; QRBand4: TQRBand; QRDBText3: TQRDBText; QRDBText4: TQRDBText; QRDBText5: TQRDBText; QRDBText6: TQRDBText; QRLabel8: TQRLabel; GroupTotal: TQRLabel; Books: TQuery;
procedure QRBand4BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean); procedure QRBand3BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
N: Integer; public
PrevGroup: TPrevGroup;implementation
procedure TPrevGroup.QRBand4BeforePrint(Sender: TQRCustomBand;
// Використовує поточне значення N для виведення кіл-ва книг I/ даного вид-ва
II і готує N до наступного циклу підрахунку begin
TQRCustomBand; var PrintBand: Boolean);
// Збільшує кількість найменувань кожного II видавництва begin inc(N)
// Змінна PrintBand за умовчанням має значення True,
// Що дозволяє друк лінії. Не змінюємо її.