Все это возможно благодаря архитектуре FastReport и компонентам, написанным Виталием Барминым, о которых мы уже упоминали выше.
Для этого добавим в наше приложение компоненты TfrDesigner, TfrDialogControls (как видно из названия, этот компонент предназначен для построения и использования самостоятельных диалоговых окон в составе отчета), а также кнопку для вызова диалога редактирования шаблона отчета (рис. 2.41).
Обработчик для этой кнопки будет исключительно простым:
procedure TMainForm.DesignPClick(Sender: TObject);
begin
frReport.DesignReport;
end;
Теперь при запуске приложения мы можем нажать на кнопку "Дизайн отчетов" и создать отчет прямо в run-time, сохранить его в отдельном файле и потом использовать в приложении. Все эти шаги, в сущности, являются тем же самым, что мы уже делали в предыдущих разделах. Теперь же мы хотим сосредоточиться на дополнительных возможностях FastReport, а именно на создании независимых отчетов.
Рис 2.41. Компоненты для встраивания дизайнера отчетов в программу
Если вы обратите внимание, то шаблон для отчета по умолчанию имеет одну страницу, на которой мы и располагаем полосы для печати. Добавим к отчету специальную страницу - диалоговую, на которой расположим компоненты доступа к данным (рис. 2.42).
Рис 2.42. Добавление диалоговой страницы к шаблону отчета
После добавления диалога и перехода на страницу 2 нашего шаблона на панели инструментов с объектами, доступными для отчета, вы увидите ряд визуальных компонентов, которые можно располагать на диалоге (рис. 2.43).
Рис 2.43. Компоненты для доступа к базе данных из шаблона отчета
Положим на диалог компонент Query: TfrFIBQuery, укажем ему существующее подключение к базе данных в свойстве Database и напишем следующий запрос в свойстве SQL:
SELECT "Categories"."Name", "Categories"."GoodsCount"
FROM "Categories"
WHERE "Categories"."GoodsCount" > 0
Очевидно, что мы хотим вывести на печать только те категории товаров, количество наименований по которым больше нуля. Остается только создать сам шаблон печати, привязав соответствующие полосы (bands) к Query как к источнику данных (рис. 2.44).
Рис 2.44. Шаблон встроенного отчета
Укажем источник данных для Master Data (рис. 2.45).
Рис 2.45. Подключение полосы (band) к встроенному в шаблон запросу
И сохраним наш новый отчет, например, под именем "pricel.frf". Теперь можно несколько изменить реакцию нашего приложения на нажатие кнопки печати. Положим на форму компонент OpenDialog: TopenDialog - и напишем следующий обработчик нажатия на кнопку "Печать":
procedure TMainForm.PrintBClick(Sender: TObject);
begin
if not OpenDialog.Execute then exit;
GoodsDataSet.DetailConditions :=
GoodsDataSet.DetailConditions [dcWaitEndMasterScroll];
frReport.LoadFromFile(OpenDialog.FileName);
frReport.PrepareReport;
frReport.ShowPreparedReport;
GoodsDataSet.DetailConditions :=
GoodsDataSet.DetailConditions + [dcWaitEndMasterScroll] ;
end;
Таким образом, когда пользователь нажмет на кнопку "Печать", он сможет выбрать любой шаблон отчета и вывести его на печать. Учитывая, что при помощи дизайнера отчетов тот же самый пользователь (или вы, как разработчик) может подготовить неограниченное количество самых разных отчетов без необходимости изменения основного кода приложения, становится очевидным преимущество использования FIBPlus совместно с FastReport. Конечно, возможность создавать отчеты в run-time доступна в FastReport и для других пакетов работы с данными, в частности с IBX, однако FIBPlus делает эту возможность значительно более гибкой за счет использования макросов. Более подробно механизм макросов мы рассмотрим чуть позже, а сейчас лишь продемонстрируем, как, используя макросы, мы можем создавать более функциональные диалоговые отчеты.
Скопируем "pricel.frf" в "price2.frf", откроем "price2.frf" для редактирования в дизайнере отчетов и перейдем на диалоговую страницу. Там мы поместим дополнительные компоненты: ComboBoxl, Editl, Labell и Buttonl (рис. 2.46).
Рис 2.46. Внешний вид диалога, встроенного в шаблон отчета
Изменим запрос в Query.SQL:
SELECT "Categories"."Name", "Categories"."GoodsCount"
FROM "Categories"
WHERE "Categories"."GoodsCount" @COND
COND в данном случае является макросом FIBPlus, и вместо него мы можем поставить любой текст. Удобство же заключается прежде всего в том, что макросы в FIBPlus рассматриваются как полноценные параметры, а значит, FastReport тоже будет считать, что в данном случае имеет дело с параметром. В данном примере мы можем позволить пользователю самому указать условия для выборки категорий прайс-листа. Заполним ComboBoxl.Items символами сравнения:
>
<
>=
< =
<>
=
Теперь нам достаточно только указать FastReport, какое значение необходимо "подставить" вместо нашего макроса-параметра. Для этого надо изменить свойство Params у компонента Query (рис. 2.47).
Рис 2.47. Выражение для получения значение макроса COND