14. Введение в построение отчетов
14.1. Компоненты для построения отчетов
В
Delphi 3 на странице палитры компонентов QReport расположено около двух десятков компонентов, применяемых для построения отчетов. "Главным" компонентом, несомненно, является TQuickRep, определяющий поведение отчета в целом. Другие компоненты определяют составные части отчета:TQRBand -
заготовка для расположения данных, заголовков, титула отчета и др.; отчет, в основном, строится из компонентов TQRBand, которые реализуют:• область заголовка отчета; • область заголовка страницы; • область заголовка группы; • область названий столбцов отчета; • область детальных данных, предназначенную для отображения данных самого нижнего уровня детализации; • область подвала группы; • область подвала страницы; • область подвала отчета.
• TQRSubDetail -
определяет область, в которой располагаются данные подчиненной таблицы при реализации в отчете связи Master-Detail на основе существующей связи между ТБД;• TQRGroup -
применяется для группировок данных в отчете;• TQRLabel -
позволяет разместить в отчете статический текст;• TQRDBText -
позволяет разместить в отчете содержимое поля набора данных;• TQRExpr -
применяется для вывода значений, являющихся результатом вычисления выражений; алгоритм вычисления выражений строится при помощи редактора формул данного компонента;• TQRSysDate -
служит для вывода в отчете даты, времени, номера страницы, счетчика повторений какого-либо значения и т.д.;• TQRMemo -
служит для вывода в отчете содержимого полей комментариев;• TQRRich Text -
служит для вывода в отчете содержимого полей форматированных комментариев;• TQRDBRich Text -
служит для вывода в отчете содержимого полей форматированных комментариев, источником которых является поле набора данных;TQRShape -
служит для вывода в отчете графических фигур, например, прямоугольников;• TQRImage -
служит для вывода в отчете графической информации, источником которой является поле набора данных;• TQRChwt -
служит для встраивания в отчет графиков. TQuickRepРис 141 Пустая сетка отчета Образуется послеразмещения в форме компонента T
QuickRepРис 14 2 Сетка отчета с размещенными в ней компонентами отчета
Перечислим важнейшие свойства, методы и события компонента
TQuickRep.Свойство
property Bands: TQuickRepBands; состоит из множества логических значений (False/True), которые определяют включение в отчет отдельных видов составляющих:• HasColumnHeader -
заголовка столбцов отчета;• HasDetail -
детальной информации;• HasPageFooter -
подвала страницы;• HasPageHeader -
заголовка страницы;• HasSummary -
подвала отчета;• Has Title -
заголовка отчета.property DataSet: TDataSet;
указывает на набор данных, на основе которого и создается отчет. Обычно для выдачи отчета используется один НД.Если нужно вывести связанную информацию из нескольких таблиц БД, ее объединяют в одном НД при помощи оператора
SELECT. В этом случае в качестве НД для отчета может использоваться компонент TQuery. Информацию из нескольких связанных НД можно включать в отчет, если эти наборы данных связаны в приложении отношением Master-Detail. В этом случае в качестве НД отчета указывается Master-набор, а ссылка на соответствующие Detail-наборы осуществляется в компонентах TQRSubDetail.Если в отчет нужно включить информацию из несвязанных наборов данных, применяют композитный отчет, то есть отчет, составленный из группы других отчетов.
property Frame: TQRFrame;
определяет параметры рамки отчета:• Color
- цвет линии рамки;DrawBottom -
определяет, следует ли выводить линию снизу;DrawLeft-
определяет, следует ли выводить линию слева;DrawRight-
определяет, следует ли выводить линию справа;Draw Top
- определяет, следует ли выводить линию сверху;Style
- определяет стиль линии;Width -
определяет ширину линии в пикселях.property Page: TQRPage;
определяет параметры страницы.property PrinterSettings: TQuickRepPrinterSettings;
определяет параметры принтера.property PrintIfEmpty: Boolean;
указывает (True), что следует печатать отчет даже в том случае, если он не содержит данных.Методы
procedure NewPage;
Выполняет переход на новую страницу. Может использоваться в обработчиках событий компонентов отчета BeforePrini или AfterPrint и не может - в обработчиках событий OnPrint, OnStartPage и OnEndPage.procedure Preview; выводит отчет в окно предварительного просмотра (рис. 14.3).
Чтобы во время разработки отчета просмотреть в окне предварительного просмотра содержимое отчета в том виде, как он будет выводиться на печать, необходимо:
выбрать отчет при помощи мыши;
• нажать правую кнопку мыши;
• во всплывающем меню выбрать элемент Preview.
Следует заметить, что при этом не будут видны некоторые данные, например, значения вычисляемых полей наборов данных. Они будут выводиться только во время выполнения.
procedure Print;
печатает отчет на принтере.procedure PrinterSetup;
обеспечивает установки параметров принтера.События
property AfterPreview : TQRAfterPreviewEvent;
наступает после закрытия окна предварительного просмотра отчета.property AfterPrint: TQRAfterPrintEvent;
наступает после вывода отчета на печать.property BeforePrint: TQRBeforePrintEvent;
наступает в момент генерации отчета, до выдачи окна предварительного просмотра отчета и до вывода отчета на печать.property OnEndPage : procedure(Sender : TObject);
наступает в момент подготовки к генерации последней страницы отчета.property OnStartPage : procedure(Sender : TObject);
наступает в момент подготовки к генерации первой страницы отчета. TQRBandКомпоненты
TQRBand являются основными составными частями отчета и используются для размещения в них статического текста и данных. Месторасположение компонента в отчете и его поведение определяются свойством property BandType : TQRBandType;Ниже перечислены возможные значения этого свойства.
• rb Title
- определяет компонент заголовка отчета. Информация, размещенная в компоненте TQRBand, располагается перед всеми другими частями отчета. Этот вид компонента TQRBand используется для вывода заголовочной информации отчета.• rbPageHeader -
определяет компонент заголовка страницы. Информация, размещенная в компоненте с этим значением свойства BandType, выводится всякий раз при печати новой страницы отчета прежде всех иных частей отчета (но после информации, размещенной в компоненте заголовка отчета - для первой страницы).• rbDetail -
компонент детальной информации. Выводится всякий раз при переходе на новую запись в НД отчета. Отчет печатается для всех записей НД, определяемого свойством отчета DataSet, начиная с первой записи и заканчивая последней. Позиционирование на первую запись и последовательный перебор записей в НД осуществляется компонентом TQuickRep автоматически.• rbPageFooter -
компонент подвала страницы. Выводится для каждой страницы отчета после всех иных данных на странице. rbSummary - компонент подвала отчета. Выводится на последней странице отчета после всей иной информации, но перед подвалом последней страницы отчета.•
rbGroupHeader - компонент заголовка группы Применяется при группировках информации в отчете Выводится всякий раз при выводе новой группы• rbGroupFooter
- компонент подвала группы Применяется при группировках информации в отчете Выводится всякий раз при окончании вывода группы, после всех данных группы• rbSubDetail -
компонент для выдачи детальной информации из подчиненного набора данных, при выводе в отчете информации из двух или более наборов данных, связанных в приложении при помощи механизма Master-Detail. Это значение присваивается компоненту автоматически, когда генерируется компонент TQRBand при размещении в форме компонента TQRSubDetail Программа не должна устанавливать это значение в свойство BandType• rbColumnHeader -
компонент для размещения заголовков столбцов Размещается в отчете на каждой странице после заголовка страницы• rbOverlay -
используется для совместимости с более ранними версиями отчетовСвойство
property Enabled : Boolean; указывает, печатается в отчете (True) или нет (False) информация, содержащаяся в компоненте TQRBandСвойство
property ForceNewPage : Boolean; указывает, должна ли информация в составе TQRBand всегда печататься с новой страницы (True) или нет (False)Событие
property BeforePrint: TQRBeforePrintEvent; наступает перед печатью информации, размещенной в области компонента TQRBand.14.4. Создание простейшего отчета
Компоненты
TQuickRep и TQRBand являются минимально достаточными для создания простого отчета, не содержащего внутри себя группировок информации.Пусть имеется таблица БД
Rashod DB, содержащая сведения об отпуске материалов со склада. В состав ТБД входят поля• N_RASH
- уникальный номер события отпуска товара;• DEN
- номер дня;• MES
- номер месяца;•
GOD - номер года;• TOVAR
- наименование отпущенного товара;• POKUP
- наименование покупателя,• KOLVO
- количество единиц отпущенного товараЗаметим, что дата отпуска товара хранится в разбивке на день, год и месяц Сделано так специально, с целью показать, как в отчетах используются выражения и вычисляемые поля
Создадим простейший отчет, состоящий из заголовка и сведений об отпуске товара В отчет включаются все факты отпуска товара Сортировка производится по номеру события отпуска товара
Рис 14.4 В отчете определен только его заголовок Рис 14.5 Отчет с заготовкой и группой детальной информации
Теперь разместим в отчете данные, соответствующие текущей записи таблицы Rashod Для этого поместим в отчет новый компонент TQRBand (имя QRBandl) и установим в его свойство BandType значение rbDetail Затем разместим в группе шесть компонентов TQRDBText с именами QRDBText1. QRDBText6. Свяжем данные компоненты соответственно с полями НД -N_RASH, TOVAR, KOLVO, DEN, MES, GOD Для этого в свойство DataSet каждого компонента QRDBText установим значение Table1, а в свойство DataField- значение имени соответствующего поля Вид отчета показан на рис 14.5Для просмотра получившегося отчета щелкнем по нему правой кнопкой мыши и из всплывающего меню выберем элемент Рreview. Получим окно предварительного просмотра отчета (рис 14.6)
Чтобы окно предварительного просмотра выдавалось при активизации формы, введем в обработчик события
OnActivate формы такой кодprocedure TForm1.FormActivate(Sender: TObject)
begin
QuickRep!.Preview; end;
Чтобы после выхода из окна предварительного просмотра отчета закрывалась и форма, в которой расположен отчет, введем в обработчик события
AfterPreviCK отчета такой кодprocedure TForm1.QuickReplAfterPreview (Sender : T0bject);
begin
Form1.Close;
end;
14.5. Использование компонента
TQRExpr для определения выраженийИз рис 14.6 видно что в простейшем отчете выводится дата, составленная из трех полей -
DEN, MES GOD Объединим значения из этих трех полей в одно значение являющееся результатом вычисчения выражения Выражение в отчетах формируется при помощи компонента TQRExpr Удалим из компонента QRBandl компоненты QRDBText4 QRDBText6, связанные с полями DEN, MES, GOD Вместо них разместим в отчете компонент TQRExpr (имя QRExprI)Для того чтобы войти в редактор формул данного компонента, выберем в инспекторе объектов свойство
Expression и нажмем кнопку в поле данных этого свойстваПоявится окно редактора формул -
Expression builder, (построителя выражений) (рис 14.7)Группа
Constant позволяет включить в выражение константы, при этом комбинированный список предназначен для выбора типа константы - числовая (Numeric) или строковая (String). Группа Function позволяет включить в выражение функцию, при этом выпадающий список Category определяет категорию функции (по умолчанию показываются все функции, значение All). Группа DataField позволяет включить в выражение поля набора данных, причем список DataSet определяет НД, а в списке Fields перечисляются поля текущего НД.В каждой из указанных групп присутствует кнопка
Add. Она позволяет добавить константу, функцию или поле непосредственно в текст выражения (самая нижняя группа без названия).Выберем в списке функций
STR - функцию, преобразующую числовое значение в строковое и нажмем кнопку Add в группе функций. Поскольку функция имеет параметр, редактор формул перейдет в режим ввода параметра. Выберем в группе Data Field's окне DataSet набор данных Table1 и в списке полей - DEN, после чего нажмем кнопку Add и затем Ok. В поле формулы будет сформирована часть формула STR(Table1.DEN). На панели Operators нажмем кнопку '+'. В группе констант установим тип строковой константы (String) и введем точку, после чего нажмем кнопку Add (рис. 14.8).Аналогичным образом введем другие части формулы, чтобы она в конечном виде была такой:
STR(Table1.DEN) + '.' + STR(Table1.MES) + '.' + STR(Table1.GOD)
Затем-нажмем кнопку
Ok и выйдем в инспектор объектов. Установим в свойство AutoSize компонента QRExpr! значениеРа^е и изменим размеры компонента QRExprI так, чтобы он занимал примерно 10 символов, затем установим выравнивание вправо (свойство Alignment = taRightJustify). Запустим режим предварительного просмотра содержимого отчета (рис. 14.9). Как видим, дата отпуска товара приобрела более привычный вид.ЗАМЕЧАНИЕ. Другим способом составление значения даты из трех полей могло бы быть создание для НД
Table1 вычисляемого поля (например, SymData) и определение алгоритма вычисления его значения в таком обработчике события OnCalcFields:procedure TForm1.Table1CalcFields(DataSet: TDataSet) ;
begin
Table1SymData.Value := Table1DEN.AsString + '.' + Table1MES.AsString + '.' + Table1GOD.AsString;
end;
TQRBand для представления заголовков столбцовКомпонент
TQRBand, у которого в свойство BandType установлено значение rbColumnHeader, используется для представления заголовков столбцов. Заголовки столбцов определяются при помощи компонентов TQRLabel.Рис. 14.10. Определение заголовков столбцов Рис 14.11 В отчете появились заголоаки столбцов
Выйдем в окно предварительного просмотра отчета. Для каждой страницы отчета вверху страницы будут выводиться названия столбцов (рис. 14.11).
TQRBand для показа заголовка и подвала страницыКомпонент
TQRBand, у которого в свойство BandType установлено значение rbPageHeader, используется для показа заголовка страницы. Он выводится для каждой новой страницы перед выводом другой информации. Компонент TQRBand, у которого в свойство BandType установлено значение rbPageFooter, используется для показа подвала страницы. Он выводится для каждой страницы после вывода любой иной информации.Информация в заголовке и подвале страницы может формироваться на основе статического текста (компоненты
TQRLabel), значений полей (компоненты TQRDBText) и результатов вычисления выражений (компоненты TQRExpr).В отчете, рассмотренном в предыдущих разделах, разместим компонент
TQRBand (имя QRBand4) и установим в его свойство BandType значение rbPageHeader. Не будем размещать в заголовке страницы никакого текста, просто отчеркнем линию вверху страницы. Для этого установим в свойство компонента заголовка страницы Frame. DrawTop значение True, что обеспечивает вывод линии по верхнему краю области, занимаемой компонентом.Аналогичным образом определим в отчете компонент подвала страницы (имя
QRBand5) и установим в его свойство Frame.DrawBottom значение True, что обеспечивает вывод линии по нижнему краю области, занимаемой компонентом. Войдя в режим предварительного просмотра отчета, увидим, что вверху и внизу каждой страницы отчета выводятся линии. 4.8. Использование компонента TQRSysData для показа вспомогательной и системной информацииКомпонент
TQRSysData используется для показа вспомогательной и системной информации. Вид показываемой информации определяется свойством property Data : TQRSysDataType;Ниже указаны возможные значения этого свойства.
qrsColumnNo -
номер текущей колонки отчета (для одноколоночного отчета всегда 1).qrsDate -
текущая дата.arsDate Time
-текущие дата и время.qrsDetailCount -
число записей в НД; при использовании нескольких НД - число записей в master-наборе. Для случая, когда НД представлен компонентом TQuery, эта возможность может быть недоступной, что связано с характером работы компонента TQuery, который возвращает столько записей, сколько необходимо для использования в текущий момент, а остальные предоставляет по мере надобности;qrsDetaiINo -
номер текущей записи в НД. При наличии нескольких наборов - номер текущей записи в master-наборе.qrsPageNumber -
номер текущей страницы отчета.qrsPageCount -
общее число страниц отчета.qrs ReportTitle -
заголовок отчета.ars Time
- текущее время.Разместим в компоненте подвала отчета
QRBand5 два компонента TQRSysData (имена QRSysDatal... QRSysData2). В свойство Data первого из них установим значение arsDate (текущая дата), второго - значение qrsPageNumber (номер текущей страницы отчета). Войдем в режим предварительного просмотра результатов отчета. Теперь в подвале каждой страницы отчета выводятся номер страницы и текущая дата (рис. 14.12).14.9. Группировки данных в отчете
Выше мы рассмотрели отчет, в котором информация об отпуске товаров из ТБД
Rashod.DB со склада выводилась "как есть". Такое представление информации в отчете не всегда информативно. Пусть, например, в нашем случае требуется сгруппировать информацию по товарам.Для группировки информации используется компонент
TQRGroup. Его свойство Expression указывает выражение. В группу входят записи НД, удовлетворяющие условию выражения. При смене значения выражения происходит смена группы. Для каждой группы, если определены, выводятся заголовок группы и подвал группы. В качестве заголовка группы служит компонент TQRBand со значением свойства BandType, равным rbColumnHeader. В качестве подвала группы служит компонент TQRBand со значением свойства BandType, равным rbGroupFooter.Свойство
FooterBand компонента TQRGroup содержит ссылку на компонент подвала группы.В заголовке группы, как правило, выводится выражение, по которому происходит группировка, и различные заголовки, если они нужны. В подвале группы обычно выводится агрегированная информация - суммарные, средние и т.п. значения по группе.
Пример. Построим отчет о расходе товара со склада, в котором информация группируется по наименованию товара. Для этого определим набор данных отчета (компонент
TTable, имя Table1). Установим у НД текущим индекс по полю Tovar (в свойстве Fieldlndex Names или IndexNawe). Разместим в отчете:заголовок отчета - компонент
TQRBand с именем QRBandl, свойство BandType = rb Title;• заголовок столбцов - компонент
TQRBand с именем QRBandS, свойство BandType = rbColumnHeader,•
группу - компонент TQRGroup с именем QRGroupl.• область детальной информации - компонент
TQRBand с именем QRBand2, свойство BandType = rbDetail;подвал группы - компонент
TQRBand с именем QRBand4, свойство BandType = rbGroupFooter.В компоненте QRGroupl установим:
в свойство FooterBand значение QRBand4;
• в свойство Expression значение Table1.TOVAR, которое является формулой и строится в редакторе формул.
Поскольку свойство Expression не визуализирует значения выражения, необходимо разместить в группе компонент TQRExr (имя QRExrl) и определить значение его свойства Expression так, чтобы оно содержалоTable1.TOVAR.
В компоненте подвала группы QRBand4 будем подсчитывать сумму по полю Kolvo (сумму отпущенного конкретного товара). Для этого разместим в подвале группы компонент TQRExr (имя QRExr2) и определим значение его свойства Expression так, чтобы оно содержало формулу SUM(Table1.KOLVO).
В группе детальной информации разместим компоненты
TQRDBText, связанные с полями Pokup и Kolvo НД. Заполним другие области отчета статическим текстом, как это показано на рис.14.13.На рис 14.14 показан отчет в режиме предварительного просмотра На рис 14.15 показан подвал одной из групп - там выводится информация о суммарном расходе товара
Множественная группировка данных в отчетеЧасто внутри группы должны содержаться другие группы, например, по названию товара и внутри каждой группы - по покупателям В этом случае внутри одной группы определяют другую группу посредством дополнительных компонентов
TQRGroup Пример Пусть требуется представить в отчете сведения о расходе товаров со склада, группируя данные по товарам, а внутри группы - по покупателям Установим текущий индекс в НД Table1 по полям Tovar, Pokup Общий вид отчета приводится на рис 14.16Вид отчета в окне предварительного просмотра представлен на рис 14.17
14.11. Построение отчета на основе нескольких наборов данных, связанные в приложении как
Master - DetailЕсли необходимо выдавать отчет на основе более чем одной ТБД, можно поступить двумя способами
1 В рамках компонента
TQuery произвести соединение данных из нескольких таблиц БД в один НД, после чего определить в отчете нужные группировки;2 Создать в приложении по одному НД на каждую таблицу БД, соединить эти наборы между собой связью
Master-Detail (используя свойства MasterSource, MasterFields набора данных) и применить в отчете компонент (или несколько компонентов) TQRSubDetail для вывода информации из подчиненного (Detail) НД (или группы подчиненных НД), для вывода информации из основного (Master) НД, как и в обычных отчетах, применяется компонент TQRBand, у которого в свойстве BandType установлено значение rbDetail Построение отчета для первого случая осуществляется аналогично тому, как это описано выше Построение отчета для второго случая имеет некоторые отличительные особенностиРассмотрим второй способ
Компонент TQRSubDetail предназначен для показа информации в отчете из подчиненного НД Его свойство
property DataSet: TDataSet; указывает имя подчиненного НД, информация из которого будет выводиться в пространстве компонента TQRSubDetail. В остальном использование данного компонента аналогично использованию компонента TQRBand, у которого значение в свойство BandType установлено значение rbDetailПример
Пусть имеется таблица БД Tovary DB, содержащая помимо прочих поле Tovar (название товара)Пусть также имеется таблица БД
Rashod DB, содержащая сведения об отпуске материалов со склада В состав ТБД входят поля• N_RASH
- уникальный номер события отпуска товара,• DEN
-номер дня,• MES
- номер месяца,• GOD -
номер года,• TOVAR
- наименование отпущенного товара,• POKUP
- наименование покупателя,• KOLVO
- количество единиц отпущенного товараТаблицы
Tovary DB и Rashod DB находятся в отношении "один-комногим", то есть одному товару может соответствовать более одного факта отпуска товара со складаРазместим в форме компонент
TTable (имя TovaryTable), ассоциированный с ТБД Tovary DB Разместим в форме компонент TDataSource (имя DS_TovaryTable) и свяжем его с TovaryTable. Разместим в форме компонент TTable (имя RashodTable), ассоциированный с ТБД Rashod DBУстановим связь
Master-Detail в приложении между НД TovaryTable и RashodTable Для этого при помощи редактора связей установим в свойство RashodTable MasterSource значение DS_TovaryTable, и в свойство RashodTable MasterFields значение 'TOVAR' (рис 14.18) Заметим что после установления связей между НД в НД RashodTable текущим индексом должен быть индекс по полю Tovar (свойство RashodTable IndexFieldNames = Tovar)Приступим к разработке отчета Пусть отчет имеет имя
QuickRepI Определим заголовок отчета компонент TQRBand с именем QRBand2 в свойство BandType которого установлено значение rb TitleУстановим в качестве основного НД отчета
TovaryTable указав QuickRepI DataSet = TovaryTableРазместим в отчете компонент типа
TQRBand с именем QRBand1 и установим в его свойство BandType значение ibDelail Этот компонент будет использоваться для выдачи детальной информации из НД TovaryTable Разместим в области компонента QRBandl компонент TQRDBText (имя QRDBText1) и свяжем его с полем Tovar НД TovaryTable Разместим в отчете компонент TQRSubDetail (имя QRSubDetaill) Установим в его свойство DataSet значение RashodTable связав таким образом данный компонент с подчиненным НД Разместим в области компонента QRSubDetail1 три компонента TQRDBText (имена QRDBTextl QRDBText4) и свяжем их с полями НД RashodTable соответственно Pokup Kolvo D Поле D опредечено в НД RashodTable как вычисляемое по значениям полей DEN MES GOD Разместим в области компонента QRBandl заголовки столбцов Вид формы отчета показан на рис 14.19Войдем в режим предварительного просмотра результатов В результирующем отчете для каждой записи НД
TovaryTable выводятся по (чиненные ей записи в НД RashodTable (рис 14 20)ЗАМЕЧАНИЕ Если необходимо определить заголовок и подвал для информации группируемой в компоненте TQRSubDetail следует воспользоваться свойством этого компонента
property Bands : TQRSubDetailGroupBands,
Данное свойство обладает двумя подсвоиствами указывающими на наличие или отсутствие заголовка и подвала Этоproperty HasHeader . Boolean;
property HasFooter. Boolean;
14.12. Построение композитного отчета
Композитный (составной сложный) отчет объединяет в себе несколько простых отчетов При выдаче композитного отчета входящие в его состав простые отчеты выводятся друг за другом
Композитный отчет реализуется при помощи компонента
TQR CompositeReport В обработчике события OnAdd'Report ранее определенные простые отчеты добавляются в списковое свойство Reportprocedure TCompozitnyjOtchet.QRCompositeReportlAddReports(Sender:TObject) ;
begin
WITH QRCompositeReportI do begin
Reports.Add(ManyGroup.QuickRep1) ;
Reports.Add(Prostoj) .QuickRep1) ;
END;//with
end;
В приведенном выше обработчике композитный отчет составляется из двух отчетов:
QuickRep1 (определенный в форме ManyGroup) и QuickRep1 (определенный в форме Prostoj). Печать композитного отчета или его предварительный просмотр осуществляется так же, как для простых отчетов, напримерQRCompositeReportI.Preview
ж Ha рис. 14.21. показан композитный отчет, построенный из двух ранее разработанных нами отчетов - отчета без группировок и отчета с множественными группировками по товару и покупателю.Рис 14.21. Композитный отчет, составленный из двух простых отчетов