Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

мет_BD Delphi

.pdf
Скачиваний:
18
Добавлен:
26.02.2016
Размер:
702.49 Кб
Скачать

WHERE T.Tovar=P.Tovar

ORDER BY P.DataPrih, P.Tovar

5 Закрыть редактор нажатием кнопки ОK.

Как видно из текста запроса, набор данных собирается из двух таблиц: «Tovary» и «Prihod» (from Tovary T, Prihod P). При этом соединяются записи, имеющие одинаковое значение поля «Tovar» (where T.Tovar = P.Tovar).

Строка запроса «SELECT P.DataPrih, P.Tovar, P.Kolvo, P.Zena_Ed, (P.Kolvo*P.Zena_Ed) As Stoim» определяет выбираемые поля, причем создается вычисляемое поле «Stoim» со значением «Р.Kolvo*P.Zena_Ed».

Строка «ORDER BY P.DataPrih, P.Tovar» определяет порядок сортировки записей в возвращаемом наборе данных.

6 Для выполнения запроса установить для компонента ADOQuery1 свойство Active в значение True.

7Разместить на форме компонент TBitBtn (страница Additional) и установить для него свойство Kind в значение bkClose.

8Сохранить изменения и запустить программу на выполнение.

Замечание. Изменить отображаемые в DBGrid1 данные нельзя.

5.5 Использование группировок и агрегатных функций

Агрегатные функции предназначены для выдачи итоговых значений. К агрегатным относятся функции:

COUNT (<выражение>) – подсчитывает число вхождений значения выражения во все записи результирующего НД;

SUM(<выражение>) – суммирует значения выражения;

AVG (<выражение>) – находит среднее значение выражения;

МАХ(<выражение>) – определяет максимальное значение выражения;

МIN(<выражение>) – определяет минимальное значение выражения.

Если из группы одинаковых записей нужно учитывать только одну, перед выражением в скобках включают слово DISTINCT, например,

COUNT(DISTINCT POKUP)

Чаще всего в качестве выражения выступают имена столбцов. Выражение может вычисляться и по значениям нескольких таблиц.

Пример запроса, вычисляющего общую стоимость поступивших товаров за

23.01.2007:

SELECT SUM(P.KOLVO*T.ZENA_ED) AS STOIM FROM PRIHOD P, TOVARY T

WHERE (P.TOVAR=T.TOVAR) AND (P.DATAPRIH="23.01.2007")

Часто нужно выдать агрегированные значения (минимум, максимум, среднее) не по всему результирующему набору данных, а по каждой из входящих в него групп записей, характеризующихся одинаковым значением какого-либо столбца. Например, выдать общее число поступившего товара по каждому товару. В этом случае в оператор SELECT перед предложением WHERE вводят предложение

GROUP BY столбец [,столбец1 ...]

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

Запрос, выдающий общее количество прихода по каждому из товаров:

SELECT P.TOVAR,SUM(P.KOLVO) AS PRIHOD FROM PRIHOD P GROUP BY P.TOVAR;

31

1 Открыть проект «Proect_Query_4.dpr». Сохранить форму приложения как

«Unit_Query_5.pas», а проект – как «Proect_Query_5.dpr».

2Изменить свойство SQL компонента ADOQuery1, чтобы запрос выдавал общую сумму прихода по каждому из товаров:

SELECT P.TOVAR, SUM(P.KOLVO*T.ZENA_ED) AS STOIM FROM PRIHOD P, TOVARY T

WHERE T.TOVAR=P.TOVAR GROUP BY P.TOVAR

3Запустить приложение на выполнение и проверить работу запроса.

4Сохранить форму приложения как «Unit_Query_6.pas», а проект – как

«Proect_Query_6.dpr».

5Изменить свойство SQL компонента ADOQuery1, чтобы запрос выдавал общую

сумму прихода по каждому из товаров на каждую дату:

SELECT P.TOVAR, P.DATAPRIH, SUM(P.KOLVO*T.ZENA_ED) FROM PRIHOD P, TOVARY T

WHERE T.TOVAR=P.TOVAR

GROUP BY P.TOVAR, P.DATAPRIH

6 Запустить приложение на выполнение и проверить работу запроса.

5.6 САМОСТОЯТЕЛЬНАЯ РАБОТА 4

Создать приложение, выполняющее следующие запросы:

1 Выдать информацию о приходе товаров, общая стоимость которых не меньше значения, введенного в компонент TEdit.

2 Выдать информацию о датах, на которые приходится минимальное поступление товаров.

3 Выдать информацию о товарах, цена которых не превосходит среднюю цену всех товаров.

4 Выдать информацию о приходе на склад определенного товара за определенный промежуток времени, например, с 15.04.08 по 1.04.08. Наименование товара и границы временного интервала задаются в компоненты TEdit. При вводе товара использовать оператор LIKE.

ЛАБОРАТОРНАЯ РАБОТА 6 Создание отчетов

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

Перед разработкой отчета, так же как и перед разработкой формы, следует определить следующее:

информационное наполнение отчета;

наборы данных содержащие требуемую информацию;

внешний вид отчета;

поля сортировки и группировки;

содержание итоговой части отчета (если она присутствует).

Чаще всего отчеты формируют на основе SQL-запросов, т.к. они позволяют

вернуть необходимый набор данных.

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

32

можно разделить на четыре группы:

базовый компонент TQuickRep, являющийся контейнером полос отчета и обеспечивающий генерацию и печать отчета;

полосы отчета (TQRBand) – специальные компоненты, являющиеся контейнерами для элементов отображения данных и формирующие структуру отчета;

компоненты отображения данных, используемые для визуализации информации, содержащейся в таблицах базы данных, а также для вывода любой дополнительной информации;

фильтры (TQRExportFilter) – невизуальные компоненты, применяемые для экспорта отчета в файлы некоторых распространенных форматов.

Всреде Delphi 7 и более поздних версиях генератора отчетов QuickReport по умолчанию нет в палитре компонентов.

Добавление QuickReport в палитру компонетов

1В главном меню Delphi 7 выбрать пункт меню Component\ Install Packages.

2В открывшемся окне управления загружаемыми пакетами нажать кнопку Add.

3В окне выбора файлов перейти в папку С:\Program Files\Borland\Delphi7\Bin.

4Найти файл с именем dclqrt70.bpl и нажать кнопку Открыть.

5Нажать кнопку ОК для закрытия окна диалога.

6.1 Создание простого отчета

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

1Создать новый проект, сохранив модуль формы с именем «Unit_Rep_1.pas», а

проект – с именем «Proect_Rep_1.dpr».

2Разместить на форме компонент ADOQuery, связать его с БД Sklad.mdb.

3В свойстве SQL компонента ADOQuery1 ввести строки запроса:

SELECT p.N_prih, p.Tovar, p.DataPrih, p.Kolvo, t.Zena_Ed FROM Prihod p, Tovary t

WHERE t.Tovar = p.Tovar

4Установить для компонента ADOQuery1 свойство Active = True.

5Разместить в форме компонент QuickRep (страница QReport палитры компонентов). Установить для него свойство DataSet = ADOQuery1, назначив таким образом отчету набор данных, записи из которого будут выводиться в отчет.

6Добавить в отчет компонент QRBand (имя QRBand1), по умолчанию его свойство BandTvpe = rbTitle, т.е. данный компонент определяет заголовок отчета.

7Разместить в пространстве отчета, занимаемом компонентом QRBand1, компо-

нент QRLabel с именем QRLabel1. Установить для него свойство Caption = «Приход товаров на склад», а в свойстве Font задать жирный наклонный шрифт высотой 16 пунктов.

8Для размещения в отчете данных поместить в отчет новый компонент QRBand (имя QRBand2) и установить его свойство BandType = rbDetail.

9В области компонента QRBand2 разместить пять компонентов QRDBText. Связать эти компоненты с полями набора данных N_Prih, Tovar, Kolvo, Zena_Ed, DataPrih. Для этого в свойство DataSet каждого компонента QRDBText установите значение ADOQuery1, а в свойство DataField – значение имени соответствующего поля. Вид отчета показан на рисунке 26.

33

Рисунок 26 – Отчет с заголовком и группой детальной информации

10Сохранить изменения.

11Для просмотра на этапе проектирования получившегося отчета щелкнуть по нему правой кнопкой мыши и из всплывающего меню выбрать Рreview. После ознакомления закрыть окно предварительного просмотра отчета.

11Чтобы окно просмотра отчета выдавалось при активизации формы, создать обработчик события OnActivate формы с кодом: QuickRep1.Preview;

12Чтобы после выхода из окна предварительного просмотра отчета закрывалась

иформа, в которой расположен отчет, создатm обработчик события AfterPreviw компонента QuickRep1 с кодом: Form1.Close;

13Сохранить изменения и запустить приложение на выполнение.

6.2 Добавление вычисляемого поля в отчет

Добавим в отчет поле, содержащее полную стоимость каждого товара.

1Выделить компонент QRBand2 и добавить не него компонент QRExpr.

2Для входа в редактор формул компонента QRExpr выбрать в инспекторе объектов свойство Expression и нажать кнопку . Появится окно редактора формул (построителя выражений) (рисунок 27).

Рисунок 27 – Окно редактора формул

Кнопка Database Field позволяет включить в выражение поля текущего набора данных. Кнопка Function позволяет включить в выражение функцию, при этом выпадающий список Category определяет категорию функции (по умолчанию показываются все функции, значение All). Кнопка Variable позволяет включить в выражение системные константы.

34

3Нажать кнопку Database Field, выбрать в списке поле Kolvo и нажать OK. В поле формулы будет сформирована первая часть формулы: ADOTable1.Kolvo.

4На панели операций нажать кнопку операции умножения [*].

5Нажать кнопку Database Field, выбрать в списке поле Zena_ed и нажать OK. В поле формулы будет сформирована вся формула:

ADOTable1.Kolvo * ADOTable1.Zena_Ed

6Нажать кнопку OK, чтобы закрыть построитель выражений.

7Установить для компонента QRExpr1 свойство AutoSize = True.

8Сохранить изменения и запустить приложение на выполнение.

6.3 Использование в отчете дополнительной информации

Компонент TQRBand, у которого свойство BandType = rbColumnHeader, используется для представления заголовков столбцов. Сами заголовки столбцов определяются при помощи компонентов TQRLabel.

1Поместить в отчет новый компонент QRBand (имя QRBand3) и установить для него свойство BandType = rbColumnHeader.

2В области компонента QRBand3 разместить шесть компонентов QRLabel. В свойство Caption этих компонентов ввести соответственно «№№», «Товар», «Кол-во», «Цена», «Дата» и «Стоимость». В свойстве Font компонентов установить режим подчеркивания шрифта, а сам шрифт определите как наклонный (рисунок 28).

3Сохранить изменения и запустить приложение на выполнение. Для каждой страницы отчета теперь вверху страницы выводятся названия столбцов

Рисунок 28 – Определение заголовков столбцов

Компонент TQRBand, у которого свойство BandType=rbPageHeader, используется для показа заголовка страницы. Он выводится для каждой новой страницы перед выводом другой информации, т.е. выполняет роль верхнего колонтитула. Компонент TQRBand, у которого свойство BandType=rbPageFooter, выводится для каждой страницы после вывода любой иной информации, т.е. выполняет роль нижнего колонтитула.

Информация в колонтитулах страницы может формироваться на основе статического текста (компоненты TQRLabel), значений полей (компоненты TQRDBText) и результатов вычисления выражений (компоненты TQRExpr).

4В отчете разместить компонент QRBand (имя QRBand4) и установить его свой-

ство BandType=rbPageHeader.

5Не будем размещать в заголовке страницы никакого текста, просто разместим

линию вверху страницы. Для этого установить для QRBand4 свойство Frame.DrawBottom=True, что обеспечивает вывод линии по нижнему краю области, занимаемой компонентом.

35

6Рзместить в отчете компонент QRBand (имя QRBand5), установить его свойства BandType=rbPageFooter и Frame.DrawTop=True, что обеспечивает вывод линии по верхнему краю области, занимаемой нижним компонентом.

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

Компонент TQRSysData используется для показа вспомогательной и системной информации. Вид показываемой информации определяется свойством Data, которое может принимать следующие значения:

qrsColumnNo – номер текущей колонки отчета (для одноколоночного отчета всегда 1);

qrsDate – текущая дата;

arsDateTime – текущие дата и время;

qrsDetailCount – число записей в НД; при использовании нескольких НД число записей в master-наборе. Для случая, когда НД представлен компонентом TQuery, эта возможность может быть недоступной;

qrsDetaiINo – номер текущей записи в НД; при наличии нескольких наборов номер текущей записи в master-наборе;

qrsPageNumber – номер текущей страницы отчета;

qrsPageCount – общее число страниц отчета;

qrsReportTitle – заголовок отчета (текст заголовка хранится в свойстве Text);

qrsTime – текущее время.

8Разместить в компоненте подвала отчета QRBand5 два компонента QRSysData

(имена QRSysData1 и QRSysData2).

9Для компонента QRSysData1 установить свойство Data=qrsDate, для компонента

QRSysData2 – свойство Data=qrsPageNumber.

10Сохранить изменения и запустить приложение на выполнение. Теперь в подвале каждой страницы отчета выводятся номер страницы и текущая дата.

6.4 Группировки данных в отчете

Ранее был создан отчет, в котором информация о приходе товаров из ТБД «Prihod» выводилась «как есть». Такое представление информации в отчете не всегда информативно. Пусть, например, требуется сгруппировать информацию по товарам. Для группировки информации используется компонент TQRGroup. В группу входят записи НД, удовлетворяющие условию группировки в свойстве Expression компонента. При смене условия происходит смена группы.

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

BandType=rbColumnHeader (для заголовка группы) или BandType=rbGroupFooter (для подвала группы). Свойство FooterBand компонента TQRGroup содержит ссылку на компонент подвала группы. В заголовке группы, как правило, выводится выражение, по которому происходит группировка, и различные заголовки, если они нужны. В подвале группы обычно выводится агрегированная информация суммарные, средние и другие значения по группе.

Построим отчет о приходе товара со склада, в котором информация группируется по наименованию товара.

1Создать новый проект, сохранив модуль формы с именем «Unit_Rep_2.pas», а

проект с именем «Proect_Rep_2.dpr».

36

2Поместить на форму компонент ADOTable, связав его с таблицей Prihod базы данных Sklad.mdb.

3Установитm для компонента ADOTable1 текущий индекс по полю Tovar

свойстве lndexFieldNames или IndexName).

4Добавить в отчет следующие элементы:

компонент QuickRep, установив для него свойство DataSet=ADOTable1;

заголовок отчета компонент QRBand с именем QRBand1, его свойство

BandType=rbTitle;

заголовок столбцов компонент QRBand с именем QRBand2, его свойство

BandType=rbColumnHeader;

группу компонент QRGroup с именем QRGroup1;

область детальной информации компонент QRBand с именем QRBand3, его свойство BandType=rbDetail;

подвал группы компонент QRBand с именем QRBand4, его свойство

BandType=rbGroupFooter.

5Для компонента QRGroup1 установить:

в свойстве FooterBand значение QRBand4;

в свойстве Expression значение ADOTable1.Tovar, которое является формулой и строится в редакторе формул.

6Поскольку свойство Expression не визуализирует значения выражения, необходимо разместить в группе QRGroup1 компонент QRExpr (имя QRExpr1) и задать

спомощью построителя его свойство Expression=ADOTable1.Tovar.

7В компоненте подвала группы QRBand4 будем подсчитывать сумму по полю Kolvo (количество отпущенных единиц конкретного товара). Для этого разместить в подвале группы компонент QRExpr (имя QRExpr2) и определить его свойство Expression=SUM(ADOTable1.Kolvo).

8В группе детальной информации QRBand3 разместить два компонента

QRDBText, связанные с полями DataPrih и Kolvo.

9Заполнить другие области отчета статическим текстом (рисунок 29).

Рисунок 29 – Определение элементов отчета

10Самостоятельно добавить обработчики события OnActivate формы Form1 и события AfterPreviw компонента QuickRep1 (как в предыдущем проекте).

11Сохранить изменения и запустить приложение на выполнение.

37

Замечание. Часто внутри группы должны содержаться другие группы. Например, при группировке по названию товара нужно внутри каждой группы дополнительно сгруппировать информацию по цене. В этом случае внутри одной группы определяют другую группу посредством дополнительных компонентов

TQRGroup.

6.5 Построение отчета на основе нескольких наборов данных

Если необходимо формировать отчет на основе более чем одной ТБД, можно поступить двумя способами:

1 В рамках компонента TADOQuery произвести соединение данных из нескольких таблиц базы данных в один набор данных, после чего определить в отчете нужные группировки.

2 Создать в приложении по одному набору данных на каждую таблицу БД, соединить эти наборы между собой связью Master-Detail (используя свойства MasterSource, MasterFields) и применить в отчете компонент (или несколько компонентов) TQRSubDetail для вывода информации из подчиненного (Detail) набора данных (или группы подчиненных НД). Для вывода информации из основного (Master) набора данных применяется компонент TQRBand, у которого в свойстве BandType установлено значение rbDetail.

Построение отчета для первого случая осуществляется аналогично тому, как это описано выше. Построение отчета для второго случая имеет некоторые отличительные особенности. Компонент TQRSubDetail предназначен для показа информации в отчете из подчиненного НД. Его свойство DataSet указывает имя подчиненного НД, информация из которого будет выводиться в пространстве компонента TQRSubDetail. В остальном использование данного компонента аналогично использованию компонента TQRBand, у которого в свойстве BandType установлено значение rbDetail.

Рассмотрим второй способ. Пусть имеется таблица БД «Tovary», содержащая поле «Tovar» (название товара). Пусть также имеется таблица БД «Prihod», содержащая сведения о приходе товаров на склад. Таблицы «Tovary» и «Prihod» находятся в отношении "один-ко-многим", то есть одному товару может соответствовать более одного факта прихода его на склад.

1Создать новый проект, сохранив модуль формы с именем «Unit_Rep_3.pas», а

проект – с именем «Proect_Rep_3.dpr».

2Разместить в форме компонент ADOTable (имя TovaryTable), ассоциированный с таблицей Tovary базы данных Sklad.mdb.

3Разместить в форме компонент DataSource (имя DataSource1) и свяжите его с

TovaryTable.

4Разместить в форме еще один компонент ADOTable (имя PrihodTable), ассоциированный с таблицей Prihod базы данных Sklad.mdb.

5Установить связь Master-Detail в приложении между TovaryTable и RashodTable. Для этого установить для компонента PrihodTable свойства

MasterSource=DataSource1 и MasterFields=TOVAR.

Заметим, что после установления связей между наборами данных в НД PrihodTable текущим индексом должен быть индекс по полю Tovar (свойство

IndexFieldNames=Tovar).

6Поместить на форму компонент QuickRep (имя QuickRep1).

7Установить для QuickRep1 свойство DataSet=TovaryTable, указав тем самым в

38

качестве основного источника данных отчета НД TovaryTable.

8Определить заголовок отчета с помощью компонента QRBand (имя QRBand1, свойство BandType=rbTitle) и компонента QRLabel.

9Разместить в отчете компонент QRBand (имя QRBand2) и установить его свойство BandType=rbDelail. Этот компонент будет использоваться для выдачи детальной информации из НД TovaryTable.

10Разместить в области компонента QRBand2 компонент QRDBText (имя

QRDBText1) и связать его с полем Tovar НД TovaryTable.

11Разместить в отчете компонент QRSubDetail (имя QRSubDetail1). Установить его свойство DataSet=PrihodTable, связав таким образом данный компонент с подчиненным НД (проследите, чтобы для компонента QRSubDetail1 свойство

Master=QuickRep1).

12Разместить в области компонента QRSubDetail1 два компонента QRDBText и

связать их с полями Kolvo и DataPrih НД PrihodTable.

13Разместить в области компонента QRBand2 заголовки столбцов. Вид формы отчета показан на рисунке 30.

14Самостоятельно добавить обработчики события OnActivate формы Form1 и события AfterPreviw компонента QuickRep1 (как в предыдущем проекте).

15Сохранить изменения и запустить приложение на выполнение. В отчете для каждой записи из TovaryTable выводятся подчиненные записи из PrihodTable.

Рисунок 30 – Макет отчета на основе нескольких наборов данных

Замечание. Если необходимо определить заголовок и подвал для информации, группируемой в компоненте TQRSubDetail, следует воспользоваться свойством этого компонента Bands. Данное свойство обладает двумя подсвойствами, указывающими на наличие или отсутствие заголовка и подвала. Это HasHeader и HasFooter соответственно.

ЛАБОРАТОРНАЯ РАБОТА 7 Многооконные приложения для работы с базой данных

Создадим многооконное приложение для работы с базой данных Sklad.mdb. Главная форма приложения должна содержать:

таблицы базы данных, связанные отношением «главная – подчиненная»;

меню с пунктами:

Файл: Выход (с запросом подтверждения о выходе из программы);

Товары: Добавить*;

Приход товаров: Добавить*, Редактировать*, Удалить;

Поиск*.

39

При выборе в меню команд, отмеченных символом «*», должна открываться соответствующая дочерняя форма.

При выборе команды «Поиск» должна открываться форма с полями ввода и независимыми переключателями, позволяющими выполнять запрос на поиск данных по товару, по дате, по количеству и по комбинации параметров.

7.1Создание главной формы приложения

1В среде Delphi создать новое приложение. Сохранить форму приложения как

«Unit_Lab_6.pas», а проект – как «Proect_ Lab_6.dpr».

2Для формы в свойстве Caption ввести текст «База данных “ Склад”». Установить неизменяемый размер у формы (свойство BorderStyle=bsSingle).

3Для эффективной работы с данными создать специальный модуль данных (Data Module). Для этого выполнить команду File\ New\ Data Module. Сохранить модуль данных под именем «Unit_DM».

4В модуль данных добавить компонент TADOConnection и два компонента

TADOTable с именами «ADOT_Tovary» и «ADOT_Prihod».

5Перейти к редактированию модуля Unit_Lab_6 и в разделе Uses добавить Unit_DM для подключения модуля к главной форме приложения.

6Для компонента ADOConnection1 в свойстве ConnectionString настроить соединение с файлом базы данных Sklad.mdb. В свойстве LoginPrompt компонента установить значение False.

7Установить для ADOT_Tovary свойства: Connection – ADOConnection1; TableName – Tovary.

8Установить для ADOT_Prihod свойства: Connection – ADOConnection1; TableName – Prihod.

9Для подключения к базе данных через диалог открытия файла поместить на форму приложения компонент TOpenDialog со свойствами: DefaultExt – .mdb;

Filter – « База данных MsAccess|*.mdb».

10Создать обработчик события активации главной формы приложения (событие onActivate объекта Form1):

procedure TForm1.FormActivate (Sender: TObject);

begin

DataModule1.ADOConnection1.Close; //закрыть подключение

if OpenDialog1.Execute then //вызывается диалог открытия файла begin // для ADOConnection1 формируем строку подключения,

используя имя файла, возвращаемое диалогом

DataModule1.ADOConnection1.ConnectionString:=

'Data Source='+OpenDialog1.FileName+';'; DataModule1.ADOT_Tovary.Open; // активируем DataModule1.ADOT_Prihod.Open; // подключение к БД

end;

end;

11 Для организации отображения данных включить в модуль данных

(DataModule1) два компонента TDataSource с именами DS_Tovary и DS_Prihod.

Установить для DS_Tovary в свойстве DataSet значение ADOT_Tovary, а для компонента DS_Prihod – ADOT_Prihod ( рисунок 31).

12 Для компонента ADOT_Tovary открыть редактор полей и добавить все поля таблицы «Tovary». Для компонента ADOT_Prihod открыть редактор полей и добавить все поля таблицы «Prihod».

40