Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Создание динамических отчетов



Из вышесказанного следует, что колонки в отчетах могут меняться в зависимости от запроса. Использованный нами прием ручного добавления компонентов заголовков и значений записей по полям имеет тот недостаток, что при всяком новом запросе придется добавлять или удалять старые компоненты и менять привязку к новым полям вручную. Это существенно осложняет процесс создания отчетов. Проблема могла бы быть решена если эти компоненты в зависимости от полученных запросом полей создавались бы не вручную, а автоматически. Сейчас мы решим эту проблему.

Добавьте к проекту новую форму (рис. 5). Дайте ей имя fQueryRep. Ее модуль сохраните под именем QueryRep. pas.

Рис. 5. Форма динамического отчета

Перейдите на главную форму, добавьте на нее новую кнопку (рис. 6).

Рис. 6. Новая кнопка на главной форме

Командой File / Use unit добавьте в список видимых модулей главной формы модуль QueryRep. Создайте для кнопки с надписью " Создать динамический отчет с использование компонента Query " событие для щелчка на ней с программным кодом модального вызова формы данного отчета:

procedure TForm1.bQueryRepClick(Sender: TObject);
begin
fQueryRep.ShowModal;
end;

Перейдите на новую форму (рис. 5.) Слева вверху положите на новую форму компонент Memo (закладка Standard ) и дайте ему имя MemoSQL. В качестве примера запроса внесите внесите в поле MemoSQL следующий текст его текст:

select Id, Category, LenSm from biolifes
WHERE LenSm > 180 and LenSm < 500
order by category

В данном примере производится отбор полей Id, Category, LenSm из таблицы biolifes. Из всех записей таблицы отбираются только те, для которых длина рыб находится в интервале (180, 500) см. Сортировка записей производится по полю category в алфавитном порядке.

Положите на форму компонент источника данных DataSource (закладка Data Access ) и компонент запроса Query (закладка BDE ). На рис. 7.5 они лежат на MemoSQL. Дайте компоненту Query имя QuRep. Привяжите его к БД DbFishReport (свойство Database ). DataSource по его свойству DataSet привяжите к QuRep.

Справа положите пять кнопок и два компонента Label (закладка Standard ) с пояснющими надписями к этим кнопкам.

Ниже разместите сетку DBGrid (закладка Data Controls ) и растяните ее по всей ширину формы. Сетку DbGrid привяжите к DataSource.

Скопируйте с формы ранее разработанного отчета компонент QR и положите его копию на форму ниже сетки DbGrid. Удалите с нее компоненты заголовков колонок и данных по колонкам. Оставьте лишь заголовок отчета и компоненты номеров страниц и времени создания отчета.

В окончательном виде форма должна выглядеть так, как показано на рис. 7.5.

Новшеством в нашем отчете является компонент запроса QuRep. Он имеет привязку к определенной БД (свойство Database ). Главным же для него свойством является SQL, которое представляет собой компонент многострочного текста запроса, записанного на языке SQL. Это свойство точно совпадает с компонентом типа Memo, то есть является простейшим текстовым редактором, напоминающем редактор Notepad (Блокнот). Компонент QuRep имеет 2 важных метода - Prepare (подготовка к выполнению запроса) и ExecSQL (выполнение запроса).

Текст запроса мы будем вводить в MemoSQL, передавать его в SQL компонента Query и уже там выполнять сам запрос. Этот процесс оформим в виде отдельной процедуры:

procedure DoRepSQL;
// процедура выполнения запроса
begin
With fQueryRep do
begin
QuRep.Close; // закрыть запрос
QuRep.Prepare; // препарировать
QuRep.SQL.Assign(MemoSQL.Lines); // передать текст запроса из MemoSQL в QuRep.SQL
QuRep.ExecSQL; // выполнить запрос
QuRep.Open; // открыть полученные после запроса данные
end;
end;

Дважды щелкните на кнопке с надписью Выполнить запрос и создайте для щелчка на ней событие

procedure TfQueryRep.bDoQueryClick(Sender: TObject);
begin
DoRepSQL; // выполнение запроса на отбор данных
end;

Как видно из теста обработчика, щелчок на этой кнопке приведет к выполнению запроса по вышеприведенной процедуре. Если текст запроса не содержит ошибок, то после выполнения запроса и открытия QuRep в сетке можно видеть результат отбора данных:

Рис. 7. Форма динамического отчета

Как видно из рис. 7, результаты отбора точно соответствуют тексту вышеприведенного примера запроса: в таблице присутствуют требуемые поля, записи отсортированы по полюCategory, а среди записей присутствуют лишь те, для которых длина рыб находится в заданных пределах.

Теперь нам известны поля и порядок их следования в таблице, а значит и в отчете и можно приступить к автоматизации создания заголовков колонок отчета и значений отобранных записей по этим колонкам.

На составную часть заголовков таблицы, которой дадим имя HeaderBand, надо автоматически (без участия человека) положить 3 компонента TQRLabel и изменить их свойство Caption на имена отобранных запросом полей. Аналогично на составную часть данных отчета, которой дадим имя DetailBand, надо положить 3 компонента TQRDBText, привязать их свойство DataSet к QuRep, а свойство DataField к именам тех полей, которые поименованы в запросе и присутствуют в таблице, показанной на рис. 7.

Поскольку наперед не известно количество полей, которые будут присутствовать в таблице результатов запроса, то объявим два динамических массива, каждый элемент которых будет соответствовать заголовку поля таблицы и данным по такому полю:

L: array of TQRLabel; // массив надписей на колонках полей
T: array of TQRDBText; // массив значения по по полям таблицы

Эти операторы разместите в тексте модуля так, как показано на рис. 8.

Рис. 7.8. Динамические массивы отчета и их место в модуле программного кода

Теперь составим процедуру создания этих массивов. Ее текст с комментариями приведен ниже.

procedure CreateReportComponents;
// создание динамических компонентов отчета
var n, i: Integer;
begin
With fQueryRep do
if QuRep.Active then // если таблица по выполненному запросу открыта, то
begin
n: = QuRep.FieldCount; // число полей в полученном запросе QuRep
SetLength(L, n); // выделим память в массиве заголовков под столько же элементов
SetLength(T, n); // выделим память в массиве данных под столько же элементов
for i: = 0 to n-1 do // проход по каждому полю
begin
L[i]: = TQRLabel.Create(HeaderBand); // создаем элемент заголовка конкретного поля с номером i
L[i].Parent: = HeaderBand; // назначаем ему родителя составную часть заголовков HeaderBand
L[i].Left: = 12+i*140; // первый заголовок будет с отступом 12 пикселов, остальные через 140 от соседнего
L[i].Caption: = QuRep.Fields[i].FieldName; // надпись на заголовке будет совпадать с именем поля

T[i]: = TQRDBText.Create(DetailBand); // создаем элемент данных конкретного поля с номером i
T[i].Parent: = DetailBand; // его родителем будет составная часть данных DetailBand
T[i].Left: = L[i].Left; // отступы также, как для заголовков
T[i].DataSet: = QR.DataSet; // данные те же, что и для компонента отчета QR
T[i].DataField: = QuRep.Fields[i].FieldName; // данные по колонке брать из соответствующего поля таблицы
end;
end;
end;

Двойным щелчком на кнопке с надписью " Создать компоненты " создайте событие для щелчка на ней и введите в него обращение к процедуре создания названных компонентов:

procedure TfQueryRep.bCreateDynamicComponentsClick(Sender: TObject);
begin
CreateReportComponents;
end;

Если после созданного запроса щелкнуть на этой кнопке, то на составные части заголовков полей данных по этим полям лягут нужные нам компоненты рис. 9):

Рис. 9. Динамически созданные компоненты заголовком колонок и данных по этим колонкам

Теперь можно создавать отчет. Создайте событие для щелчка на кнопке с надписью " Создать отчет ":

procedure TfQueryRep.bDoReportClick(Sender: TObject);
begin
QR.Preview;
end;

После того, как компоненты созданы щелчок на этой кнопке даст отчет следующего вида (рис 10):

Рис. 10. Отчет с динамически созданным компонентами

После созданного отчета динамические массивы можно удалить из оперативной памяти. Это можно сделать при выполнении следующей процедуры:

procedure DestroyReportComponents;
// уничтожение динамических массивов для компонентов отчета
var n, i: Integer;
begin
n: = Length(L); // количество элементов
if n > 0 then // если они есть, то
for i: = 0 to n-1 do // по каждому из них освободить занятую ими память
begin
L[i].Free; // освободить надпись на колонке с номером i
T[i].Free; // освободить данные по колонке с номером i
end;
L: = Nil; T: = Nil; освободить память, занятую массивами
end;

Двойным щелчком на кнопке с надписью " Уничтожить компоненты " создайте событие для щелчка на ней и введите в него обращение к процедуре уничтожения упомянутых компонентов:

procedure TfQueryRep.bDestroyDynamicComponentsClick(Sender: TObject);
begin
DestroyReportComponents;
end;

Если в запущенной программе после создания компонентов (рис. 7.9 они присутствуют) щелкнуть на такой кнопке, то компоненты исчезнут со своих составных частей (рис. 11):

Рис. 11. Панель отчета после уничтожения динамически созданных компонентов

Таким образом, создание отчета сопровождается следующими операциями:

1) подготовка запроса в редакторе MemoSQKи его выполнение;

2)создание динамических компонентов для колонок отчета:

3) создание отчета;

4) уничтожение компонентов в памяти компьютера.

Этот процесс можно сократить до двух операций:

1) подготовка запроса;

2) выполнение запроса, уничтожение динамических компонентов, если они не уничтожены, создание динамических компонентов, создание отчета, уничтожение динамических компонентов.

Создайте событие для щелчка на кнопке с надписью " Динамический отчет " со следующим кодом:

procedure TfQueryRep.bDoDiynamicReportClick(Sender: TObject);
begin
DestroyReportComponents; // уничтожить компоненты если они находятся в памяти
DoRepSQL; // выполнить запрос
CreateReportComponents; // создать компоненты
QR.Preview; // создать отчет
DestroyReportComponents; // уничтожить компоненты
end;

Щелчок на такой кнопке сразу выполнит запрос, создаст компоненты отчета, создаст отчет и уничтожит созданные компоненты.

Если теперь создать текст нового запроса, где колонок больше:

select Id, Category, CommonName, SpeciesName, LenSm
from biolifes
WHERE LenSm < 400 and LenSm > 0
order by LenSm

то после щелчка на кнопке " Динамический отчет " получим такой результат, представленный на рис. 12.

Рис. 12. Динамически созданный отчет с пятью колонками

Как видим, на не пришлось заботиться о том, чтобы создавать компоненты вручную. За нас это сделала программа. Отчет также удовлетворяет всем требованиями запроса, в частности, записи там отсортированы в порядке возрастания длины рыб.

Вместе с тем, легко заметить очевидный недостаток отчета - первая колонка там имеет излишнюю ширину, а последняя колонка выведена вплотную к соседней, для которой выделенной ширины колонки не хватило чтоб поместить в нее нужный текст. Это объясняется тем, что у всех колонок одинаковая ширина (140 пикселов) и для одних полей она вполне подходит, а для других может оказаться избыточной или недостаточной. Ситуацию можно исправить, если перед выводом отчета, вычислить необходимую ширину каждой колонки и сделать небольшие зазоры между ними.

Другой недостаток состоит в том, что предложенный код способен выводит лишь числовые и текстовые поля. Вывод графики и многострочного текста такой код не может обеспечить.

Желающие могут заняться решением этих проблем. Мы же на этом закончим изучение технологии создания отчетов с применением компонентов пакета Quick Report.


Поделиться:



Популярное:

  1. Банковская система и предложение денег. Центральный банк, его функции. Коммерческие банки. Создание денег банковской системой. Банковский мультипликатор. Денежная база.
  2. БЛОК 3. Создание работоспособности.
  3. Влияние гемодинамических и лимфодинамических факторов на строение стенки вен и лимфатических сосудов.
  4. Воссоздание крупного Македонского государства
  5. ВТОРОЙ ЭТАП — СОЗДАНИЕ ТЕЛА ДЛЯ ДУШИ Причины появления формы человека
  6. Глава 19. Создание российской государственности и ее институтов (1989-1999 гг.)
  7. Идея №4. Создание WEB-студии.
  8. Изменения в религиозном и общественном сознании в связи с созданием Средиземноморской державы и переходом к Империи
  9. Какое отрицательное явление может провоцировать натуживание при выполнении статодинамических упражнений
  10. Коммерческие банки. Создание денег коммерческими банками. Банковский мультипликатор.
  11. Лабораторная работа 2. Создание макроса
  12. Лабораторная работа № 2. Создание баз данных посредством SQL


Последнее изменение этой страницы: 2016-06-04; Просмотров: 843; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.034 с.)
Главная | Случайная страница | Обратная связь