Технология создания отчетов
Создание простейшего отчета. Рассмотрим пример построения отчета, содержащего информацию о жителях из таблицы Person учебной базы данных TUTOR_DATABASE, разработанной в первой части лабораторного практикума.
Разместим на форме компонент TTable, свяжем его с таблицей Person.DB и откроем таблицу, задав для этого компонента, получившего имя Table1, значение свойства Active равным True. Затем разместим на форме компонент TQuickRep и свяжем его с таблицей с помощью свойства DataSet.
Из локального меню компонента TQuickRep выберем пункт Report settings и в одноименном окне (см. рис.1) в группе элементов Bands зададим наличие в отчете полосы заголовка отчета (Title), полосы для детальной информации (Detail band) и полосы итогов для отчета (Summary), щелкнув мышью по соответствующим переключателям. После нажатия на кнопку ОК в компоненте TQuickRep появятся три компонента TQRBand (TitleBand1, DetailBand1 и SummaryBand1).
Разместим в полосе отчета TitleBand1 компонент TQRLabel, установим в свойстве Caption этого компонента значение Список жителей и выберем в свойстве Font полужирный наклонный шрифт высотой 14.
Затем разместим в полосе отчета DetailBand1 шесть компонентов TQRDBText для вывода данных из шести полей текущей записи (строки) таблицы Person, содержащей шесть столбцов (Nom, FIO, RDate, Pol, SumD, Adr), и свяжем каждый компонент с соответствующим полем. Для этого в свойство DataSet каждого компонента TQRDBText установим значение Table1, а в свойство DataField - имя нужного поля.
И наконец, разместим в полосе отчета SummaryBand1 по два компонента TQRLabel и TQRExpr. Для первого компонента TQRLabel зададим значение свойства Caption равным Всего жителей:, а для второго - Сумма доходов:. С помощью редактора формул для компонентов TQRExpr в свойстве Expression сформируем выражения для подведения итогов: для первого компонента TQRExpr зададим агрегатную функцию COUNT, для второго - агрегатную функцию SUM(Table1.SumD).
На рис.4 показаны компоненты отчета с установленными свойствами.
Для просмотра получившегося отчета щелкнем по нему правой кнопкой мыши и из локального меню выберем пункт Preview. В результате откроется окно предварительного просмотра отчета, вид которого показан на рис.2. Первые три кнопки на инструментальной панели этого окна позволяют изменять масштаб отображения отчета, следующие четыре кнопки - последовательно показывать одну из страниц отчета. Далее первая группа из двух кнопок предназначена для печати отчета, вторая группа - для сохранения и загрузки отчета, а кнопка Close закрывает окно.
Чтобы в процессе выполнения приложения окно предварительного просмотра отчета открывалось при активизации формы, необходимо задать процедуру обработки события OnShow для формы:
procedure TForm1.FormShow (Sender:TObject);
begin
QuickRep1.Preview;
end;
а чтобы после выхода из окна предварительного просмотра отчета закрывалась бы и форма, на которой создан отчет, нужно предусмотреть процедуру обработки события OnAfterPreview для компонента TQuickRep:
procedure TForm1.QuickRep1AfterPreview (Sender: TObject);
begin
Form1.Close;
end;
Данные, выводимые в отчете, всегда сортируются в соответствии с текущим индексом, который задается с помощью свойства IndexName компонентов доступа к данным (в рассматриваемом примере это компонент Table1). По умолчанию сортировка производится в соответствии с первичным ключом. Можно отсортировать строки отчета по фамилиям, если указать для свойства IndexName значение индекса PERSON03_FIO, который имеется у таблицы Person.
Создание отчета с группировкой данных. В отчете, выводящем список жителей, сгруппируем жителей по адресам квартир и для каждой группы подсчитаем количество жителей квартиры и суммарную величину их общих доходов.
Для этого поместим в сетку созданного ранее простейшего отчета компонент TQRGroup. Появившаяся при этом полоса GroupHeader будет заголовком группы с именем QRGroup1. Размещенная на ней информация будет печататься каждый раз в начале новой группы. Оставим эту полосу незанятой и уменьшим ее высоту (свойство Height) до нуля, чтобы скрыть наличие этой полосы в отчете, поскольку в нашем случае информация об адресе квартиры будет печататься не в начале группы строк, а содержаться в самих строках.
Группировка строк таблицы по значению поля, хранящего адрес квартиры, указывается свойством Expression компонента QRGroup1, являющегося заголовком группы. Значение этого свойства с помощью редактора формул (см. рис.3) установим равным Table1.Adr, чтобы в группу включались строки с одинаковым значением поля Adr.
Строки таблицы перед группировкой должны быть отсортированы по полю, указанному в свойстве Expression компонента QRGroup1, поэтому в компоненте Table1 в качестве текущего индекса таблицы укажем поле Adr.
Разместим в сетке отчета компонент TQRBand, который автоматически получит имя QRBand1, и свяжем его с заголовком группы QRGroup1, установив для заголовка группы свойство FooterBand равным QRBand1. В результате у компонента QRBand1 свойство BandType автоматически станет равным rbGroupFooter, и в отчете появится полоса для итогов группы GroupFooter, связанная с заголовком группы.
На полосе GroupFooter разместим две пары компонентов TQRLabel и TQRExpr. Для первой пары зададим свойство Caption компонента TQRLabel равным Количество жителей, а свойство Expression компонента TQRExpr равным функции COUNT; для второй пары компонентов зададим те же свойства равными Общие доходы и функции SUM(Table1.SumD). Свойству ResetAfterPrint обоих компонентов TQRExpr присвоим значение True, чтобы агрегатные функции, указанные в свойстве Expression, применялись отдельно к каждой группе
На рис.5 показаны компоненты отчета с установленными свойствами (на рисунке наличие полосы GroupHeader в отчете не скрыто). Для просмотра получившегося отчета выполним приложение, выбрав в главном меню системы Delphi команду Run | Run или нажав на клавиатуре клавишу F9.
Создание отчета с информацией из главной и подчиненной таблиц. Сформируем отчет, выводящий сведения о квартирах (из таблицы Flat учебной базы данных) и установленных в квартирах телефонах (из таблицы TPhone, которая подчинена главной таблице Flat).
В форму нового проекта поместим два компонента TTable (с именами Table1 и Table2) и компоненты TDataSource и TQuickRep (с именами DataSource1 и QuickRep1). Настроим компоненты TTable, чтобы компонент Table1 ассоциировался с таблицей Flat, а компонент Table2 - с таблицей TPhone, и установим между ними связь "главная-подчиненная" через компонент DataSource1, соединенный с Table1. Укажем в качестве основного источника информации для отчета таблицу Flat, задав свойство DataSet компонента QuickRep1 равным Table1, и откроем обе таблицы, установив для них значение свойства Active, равное True.
В сетке отчета (в компоненте QuickRep1) разместим полосу заголовка отчета (Title) и полосу детальной информации (Detail band). В полосе заголовка отчета расположим компонент TQRLabel с надписью Квартиры и телефоны, а полосу детальной информации поместим четыре компонента TQRDBText и свяжем их соответственно с полями Adr, NRooms, Skv, KCategory из таблицы Flat. В этой же полосе разместим слева от каждого из компонентов TQRDBText по одному компоненту TQRLabel с надписями Адрес, Число комнат, Площадь, Категория.
Поместим в сетку отчета компонент TQRSubDetail и свяжем его с подчиненной таблицей TPhone, установив его свойство DataSet равным Table2. В области компонента TQRSubDetail расположим компонент TQRLabel с надписью Телефон и компонент TQRDBText, связанный с полем Ntel таблицы TPhone.
Компоненты отчета показаны на рис.6. В результирующем отчете (рис.7) для каждой строки таблицы Flat выводится информация из подчиненной ей строки таблицы TPhone; если подчиненной строки нет, то номер телефона в отчете отсутствует.
Создание отчета в свободной форме. Отчет в свободной форме строится таким же способом, что и табличный отчет, но данные, выводимые в полосу детальной информации (Detail band), не упорядочиваются по столбцам, а располагаются произвольно. Отчеты в свободной форме обычно применяются для вывода каких-либо бланков, в которых информация не представлена в виде таблиц. Типичными примерами отчетов в свободной форме являются письма со стандартным текстом и этикетки с почтовыми адресами для конвертов. Такие отчеты содержат только полосу детальной информации.
При создании отчета в свободной форме удобно использовать специальный шаблон QuickReport Labels. Воспользуемся этим шаблоном для печати этикеток с почтовыми адресами для конвертов с письмами, которые рассылаются жителям 8-го микрорайона.
Командой File | New Application главного меню системы Delphi создадим новое приложение с формой Form1. Выберем команду File | New главного меню и шаблон QuickReport Labels в открывшемся окне хранилища объектов на закладке Forms. В результате созданное приложение будет дополнено формой QRLabelForm с заготовкой отчета для печати этикеток, на которой размещены компонент TQuickRep (имя компонента QuickRep1), содержащий полосу детальной информации (имя компонента DetailBand1), компонент TQRLabel (имя компонента QRLabel2) и компонент TTable (имя компонента MasterTable).
Настроим компонент MasterTable, чтобы он был связан с таблицей Person.DB учебной базы данных TUTOR_DATABASE, и откроем таблицу, задав для этого компонента значение свойства Active равным True. Компонент QRLabel2 используем для размещения на этикетке надписи Адрес и получатель.
На полосу DetailBand1 поместим два компонента TQRDBText и зададим для них значение свойства DataSet равным MasterTable, связав их таким образом с таблицей Person, а в свойстве DataField этих компонентов укажем поля Adr и FIO (рис.8).
Для вывода в отчет адресов и фамилий жителей только 8-го микрорайона воспользуемся процедурой обработки события BeforePrint полосы DetailBand1. Этой процедуре передается параметр PrintBand, имеющий тип Boolean. Изменяя значение этого параметра, можно управлять выводом полос (строк) в отчет. Если процедура присвоит параметру значение False, то полоса не будет отображаться в отчете. Поэтому выбор строк таблицы Person с информацией о жителях 8-го микрорайона можно задать одним оператором присваивания:
procedure TQRLabelForm.DetailBand1BeforePrint
(Sender: TQRCustomBand;var PrintBand: Boolean);
begin
PrintBand := Pos(', 8',MasterTable['Adr'])<>0; {Шаблон *,_8*}
end;
Эта процедура будет вызываться только во время выполнения программы, поэтому при предварительном просмотре из среды разработки системы Delphi в отчет будут включены все строки, независимо от содержащейся в них информации (рис.9).
Кроме этой процедуры для формы QRLabelForm и компонента QuickRep1 предусмотрим соответственно процедуры обработки событий OnShow и OnAfterPreview:
procedure TQRLabelForm.FormShow (Sender:TObject);
begin
QuickRep1.Preview;
end;
procedure TQRLabelForm.QuickRep1AfterPreview (Sender: TObject);
begin
QRLabelForm.Close;
end;
На форме Form1 разместим кнопку и зададим для нее процедуру обработки события OnClick, которая будет показывать форму QRLabelForm:
procedure TForm1.Button1Click(Sender: TObject);
begin
QRLabelForm.ShowModal;
end;
Выберем в главном меню команду File | Use Unit, чтобы к форме Form1 подключить модуль Unit2, в котором определено имя формы QRLabelForm.
Выполним созданное приложение и убедимся в формировании отчета, состоящего из набора этикеток, в соответствием с заданным условием (рис.10).