Лабораторные работы по теме

Разработка Баз Данных в среде Delphi
при помощи технологии ADO

Составил: Коднянко В. А.,
2018 г.

 

     Разберем возможности работы Delphi с базами данных, которые создаются и используются в СУБД Microsoft Access.

     Процесс разобьем на 2 этапа.  На первом этапе в Access'е создадим базу данных, таблицы этой БД и установим связи между ними. Работу по наполнению БД записями и обработку этих записей выполним на втором этапе, используя возможности технологии ADO среды Delphi, которая позволят оперировать базами данных СУБД Microsoft Access.

     Настоящие методические указания подготовлены с использованием СУБД Microsoft Access 2007 и среды Delphi XE7.

 


Часть I. Создание БД при помощи СУБД Microsoft Access

     База данных, которую рассмотрим в данной работе, будет содержать сведения организации об имеющихся у нее контрольно-измерительных инструментах и приборах, таких как штангенциркули, нутромеры, микрометры, калибры и т. д. Эта БД будет содержать две таблицы. В первой таблице будут перечислены названия групп приборов и инструментов, во второй - конкретные инструменты этих групп. Создадим и спроектируем такую БД в СУБД Microsoft Access.

1.1 Создание БД "Инструменты"

     Запустите Microsoft Access и создайте новую базу данных Инструменты.accdb с помощью этого приложения. Создайте на диске папку Delphi_Projects, а в ней новую папку с именем Theme3. Сохраните в ней созданную БД Инструменты.accdb.

1.2. Создание таблицы "Список"

     Создайте новую таблицу БД с названием Список с 3-мя полями, как показано на рис. 1.1.

Рис.1.1. Поля таблицы
Список

1.3. Создание таблицы "Инструменты"

     Создайте новую таблицу БД с названием Инструменты с полями, как показано на рис. 1.2.

Рис.1.2. Поля таблицы
Инструменты

1.4. Схема данных (связывание таблиц)

     Установите связи между таблицами, как показано на рис. 1.3.     

Рис.1.3. Схема данных
(связь таблиц отношениями
"один ко многим")

     Таблица Список будет содержать список групп инструментов (нутромеры, калибры, микрометры, штангенциркули и т. д). В таблице Инструменты будут размещены данные по инструментам каждой такой группы. Следовательно, нужно установить между этими таблицами такую связь, когда одной записи таблицы Список будет соответствовать несколько записей из таблицы Инструменты. В таблице Инструменты есть поле ListId (номер группы инструментов, соответствующий значению ключевого поля в таблице Список). С помощью этого поля устанавливается связь "один ко многим" между главной таблицей Список и подчиненной ей таблицей Инструменты. Чтобы установить такую связь ухватите ключевое поле Id таблицы Список и положите его на поле ListId таблицы Инструменты.

    База данных спроектирована. Сохраните все данные и закройте СУБД Microsoft Access. Дальнейшие работы с этой БД будут выполнены с помощью программы, которая подлежит разработке в среде визуального программирования Delphi XE7.

 


Часть II. Разработка СУБД "Инструменты и приборы" в среде Delphi
с использованием технологии ADO

     Технология ADO (ActiveX Data Objects) позволяет получить доступ к данным форматов Microsoft (MDAC), например, к базам данных СУБД Microsoft Access.  

2.1. Создание нового приложения

     Запустите Delphi и создайте новое приложение. Для этого выполните команду File / New / VCL Forms Application - Delphi, как показано на рис. 2.1.

Рис. 2.1. Создание нового приложения

     При этом будет создано новое приложение, в котором содержится модуль с именем Unit1. Вид окна Delphi с этим приложением показан на рис. 2.2.

Рис. 2.2. Вид окна Delphi с новым приложением

     Нажмите кнопку SaveAll (сохранить всё). Сохраните модуль Unit1 в папке Theme3 с новым именем Main.pas и проект приложения под именем Theme3.dproj (в этой папке ранее был размещен файл БД Инструменты.accdb).

 

2.2. Привязка БД "Инструменты.accdb" к приложению

 

     Командой File / New / Other ... / Delphi Projects / Delphi Files / Data Module (рис. 2.3) добавьте в проект новый модуль данных.

Рис. 2.3. Добавление в проект модуля данных

     Щелкните на окне этого модуля и слева в окне Инспектора объектов (Object Inspctor) измените значение свойства Name модуля на dm, как показано на рис. 2.4, и сохраните этот модуль под именем DatMod.pas в папке Theme3.

Рис. 2.4. Изменение имени модуля данных

     Положите на этот модуль компонент TADOConnection. Он находится на закладке dbGo. Для этого сначала щелкните на компоненте, затем на окне модуля dm. При этом компонент будет добавлен в модуль данных dm под именем ADOConnection1. Эта ситуация показана на рис. 2.5.

Рис. 2.5. Добавление компонента TADOConnection

     Компонент ADOConnection1 позволит привязать БД Инструменты.accdb к приложению. Для привязки дважды щелкните на этом компоненте. При этом откроется окно, показанное на рис. 2.6. В нем установите источник связи, выбрав Use Connection String (в строку ввода текст вводить не нужно).

Рис. 2.6. Окно модуля данных

     Теперь нажмите кнопку Build..., перейдите на закладку Поставщик данных и выберите строку Microsoft Office 12.0 Access Database Engine OLE DB Provider (рис. 2.7).

Рис. 2.7. Окно свойств
связи с данными

     Перейдите за закладку Соединение (Подключение), введите в строку Источник данных полный путь к файлу БД, как показано на рис. 2.8. Введите имя пользователя БД, например Admin, и установите галочку на опции Пустой пароль.

Рис. 2.8. Подключение БД
Инструменты.accdb
к приложению

   После этого нажмите кнопку Проверить подключение чтоб проверить подключается ли БД Инструменты.accdb. Если будет дан ответ "Проверка соединения выполнена", то можно продолжить работу над приложением. Закройте окна подключения к БД.

 

2.3. Связывание таблиц БД "Инструменты.accdb" с приложением

 

     Положите на модуль данных компоненты TADOTable (таблица ADO, закладка dbGo) и TDataSource (источник данных, закладка DataAccess). Дайте этим компонентам имена TaList и dsList, соответственно (см. рис. 2.9).

     Привяжите при помощи Инспектора объектов компонент TaList к компоненту ADOConnetion1 (рис. 2.5). Для этого выбором установите свойства Connection и TableName компонента так, как показано на рис. 2.9.

Рис. 2.9. Установка свойств
компонента
TaList

     Этот компонент позволит установить связь приложения с таблицей "Список" базы данных. Установите свойство DataSet компонента dsList в значение TaList.

     Добавьте поля таблицы. Для этого дважды щелкните на компоненте TaList и выполните команду контекстного меню Add all fields (добавить все поля). Эта ситуация показана на рис. 2.10.

Рис. 2.10. Добавление полей
в компонент
TaList

     Поступая аналогичным образом, добавьте соответствующие компоненты для таблицы "Инструменты" (компоненты TaInst, dsInst).

 

2.4. Установление отношений между таблицами БД

 

     Таблица TaInst является подчиненной по отношению к таблице TaList. Установим это отношение. Установите значение свойства MasterSource (источник главной таблицы) компонента TaInst в dsList. Щелкните затем на кнопке свойства MasterFields. В появившемся окне (рис.2.11) выберите поле Id главной таблицы и поле ListId подчиненной таблицы и нажмите кнопку Add 

Рис. 2.11. Добавление полей
в компонент
TaList

     Добавьте на модуль данных компонент TADOQuery1. Этот компонент позволяет создавать запросы. Об его использовании будет упомянуто ниже в разделе подготовки запросов.

  2.5. Компоненты формы модуля Main

     Перейдите к форме модуля Main. Она будет главным окном нашего приложения. Пока форма пуста и ее следует наполнить необходимыми компонентами. После такого наполнения в окончательном виде это окно будет иметь вид, который показан на рис. 2.12.

Рис. 2.12. Окончательный вид формы модуля Main

     Измените заголовок окна на текст БД "Инструменты". Работа студента группы ... (свойство Caption формы). Данный модуль должен "видеть" компоненты БД, которые находятся на модуле dm. Для этого выполните команду File / Use unit ... (Файл / Использовать модуль) и выберите модуль DatMod.

     Положите на форму два компонента TGroupBox (закладка Standard) и дайте им заголовки с названиями таблиц БД (на рис. 2.12 это компоненты с надписями Таблица "Список" и "Таблица "Инструменты"). Каждый такой бокс потребуется для размещения в нем визуальных компонентов соответствующей таблицы БД. Положите в каждый бокс по сетке TDbGrid (закладка Data Controls). Свяжите их свойство TDataSource с соответствующими источниками данных. Дважды щелкните на сетке и в открывшемся окне добавьте в ней поля соответствующих таблиц при помощи кнопки . Поля таблиц на сетках видны на рис. 2.12. Из списка полей сетки Список удалите поле Описание, поскольку для него будет отведен отдельный компонент. Аналогично из сетки Инструменты исключите поле Картинка.

     В бокс сетки Список положите компонент TDbMemo (закладка Data Controls). Свяжите его с источником данных dsList и полем "Описание". В бокс таблицы инструментов положите компонент TDbImage. Он потребуется для визуализации изображений инструментов. Над ним положите метку Label с поясняющей надписью Изображение инструмента и кнопку типа TSpeedButton (закладка Additional) с изображением . Она потребуются для ввода изображений измерительных инструментов. Картинку на кнопку загрузите с помощью ее свойства Glyph. Файлы картинок для кнопок лежат в папке Buttons данных методических указаний.

     Положите на форму еще одну такую же кнопку . Она потребуется для перехода к работе с запросами. Кроме того положите компонент TOpenPictureDialog (закладка Dialogs) . Он потребуется для выбора и открытия картинок инструментов из графических файлов.

 

2.6. Программирование функций по редактированию БД

 

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

     Перейдите на модуль данных dm и создайте события BeforePost (перед сохранением новых иди отредактированных записей) для таблицы TaInstТекст программного кода событий дан ниже.

procedure Tdm.TaInstBeforePost(DataSet: TDataSet);
begin
 TaInstListId.Value:= TaListId.Value;
end;

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

2.6.2. Открытие и закрытие таблиц БД

     При запуске приложения таблицы БД нужно открыть, а при выходе из него, наоборот, закрыть.

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

implementation

uses DatMod;

{$R *.dfm}

var FirstShow: boolean = true;

     При запуске приложения эта переменная получит значение true (истина), как указано в описании этой переменной в операторе var секции implementation.

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

     Код работает следующим образом. В момент когда в запущенном приложении форма появляется на экране срабатывает ее событие OnShow. Поскольку FirstShow в этот момент истинно, то будет выполнен код, заключенный между операторными скобками begin... end. В нем значение этой переменной изменится на противоположное с тем, чтобы при всяком новом появлении формы на экране операторы, заключенные в этих скобках больше не выполнялись. Далее сработают четыре оператора, которые откроют в порядке подчинения соответствующие таблицы БД, расположенные на модуле dm.

procedure TForm1.FormShow(Sender: TObject);
begin
 if FirstShow then
  begin
   FirstShow:= false;
   dm.TaList.Open;
   dm.TaInst.Open;
  end;
end;

 

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

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 dm.TaInst.Close;
 dm.TaList.Close;
end;

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

2.6.3. Ввод и редактирование записей таблиц БД

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

     Чтобы запись таблицы сохранилась достаточно двинуть клавиатурный курсор вниз или вверх к другой записи.     

2.6.4. Ввод изображения для текущей записи таблицы

     Для ввода изображения инструмента используйте процедуру, текст которой приведен ниже

procedure PictureToGraphicField(F: TField);
var
     FileName: TFileName;
     Bmp: TBitmap;
     jpg: TJPEGImage;
     D: TDataSet;
begin
 With dm, Form1 do
  begin
   D:= F.DataSet; // множество данных, которое содержит поле F
   if D.Active then // если таблица открыта, то
    if D.RecordCount > 0 then // если в таблице есть записи, то
     if OpenPictureDialog1.Execute then // если файл картинки выбран, то
      begin
       if not (D.State in [dsEdit]) then D.Edit; // перевод таблицы в режим редактирования
       FileName:= OpenPictureDialog1.FileName; // имя файла с картинкой
       try
        Bmp:= TBitmap.Create; // создаем Bitmap в памяти
        jpg:= TJPEGImage.Create; // создаем JPEG
        jpg.CompressionQuality:= 100; // качество сжатия изображения
        jpg.Compress; // сжатие
        jpg.LoadFromFile(FileName); // загрузка
        bmp.Assign(jpg); // передача из JPEG в BMP
        F.Assign(bmp); // передача картинки из Bitmap в поле "Каринка"
        D.Post; // сохранение записи
       except // в случае исключительной ситуции делать:
        ShowMessage('Не удалось загрузить картинку.'); // сообщение об ошибке
        FreeAndNil(jpg); // освобождение памяти, занятой JPEG
        FreeAndNil(bmp); // освобождение памяти, занятой Bitmap
       end;
      end;
   end;
end;

     Процедура PictureToGraphicField (буквально "картинку в графическое поле") получает на вход единственный параметр F типа TField, который является графическим полем текущей записи, в которое следует ввести изображение. Описание типа TField находится в модуле db, ссылку на который добавьте в список USES. Будем использовать изображения только формата JPEG. Чтобы приложение "понимало" этот формат, добавьте в список USES имя модуля JPEG.

     В процедуре объявлено 4 переменных FileName, Bmp, jpg, D. Первая из них потребуется для определения имени файла, содержащего изображение, вторая - для битмапа изображения (карты пискселов, из которого состоит изображение), третья - для рисунка в сжатом формате jpg, четвертая - для определения множества данных (в нашем случае это соответствующая таблица, которая содержит поле с графического типа).

     Код добавления изображения расположен в операторных скобках begin ... end. Действия, которые производятся в процедуре, пояснены соответствующими комментариями к операторам.

     Для кнопки ввода изображения инструмента создайте событие OnClick:

procedure TForm1.sbInstAddClick(Sender: TObject);
begin
 PictureToGraphicField(dm.TaInst.FieldByName('Картинка'));
end;

     Текст вышеприведенной процедуры PictureToGraphicField должен быть помещен выше текста данной процедуры.   

2.6.5. Привязка компонента отображения картинки к полю таблицы

     Чтобы компонент DbImage1 "понимал" какую картинку ему отображать для его свойства DataSource выберите источник dm.dsInst, для свойства DataField выберите поле Картинка.

    Примерный вид формы с введенными в таблицы записями показан на рис. 2.13.

Рис. 2.13. Вид формы в работающем приложении

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

 

2.7. Программирование запросов к БД

 

    Запрос (query) – это инструкция для выбора из БД или модификации БД. Запрос может быть выполнен посредством обработки некоторого программного кода, либо составлен на специальном языке SQL (Structured Query Language), который "понятен" соответствующей СУБД и поэтому может быть ею выполнен.

     Существует запросы на выборку данных, на их обновление, добавление, удаление, создание новых таблиц и многое другое. Наиболее распространенным является запрос на выборку данных из БД. Рассмотрим именно этот вид запросов.

2.7.1. Добавление новой формы для работы с запросами

     Командой File / New / VCL Form - Delphi добавьте в приложение новую форму и положите на нее компонент TMemo (закладка Standard), кнопку TButton с надписью Выполнить запрос, сетку TDbGrid и две метки TLabel с соответствующими надписями, как показано на рис. 2.14. Дайте форме имя Form2, а компоненту TMemo имя MeSQL.

     Сохраните форму под именем Query.pas.

Рис. 2.14. Форма для
выполнения запросов к БД

     Для компонента сетки dbGrid1 установите все четыре значения akLeft, akTop, akRight, akBottom свойства Anchors в true. Это позволит автоматически менять размеры сетки при изменении размеров формы, на которой она лежит.   

     Командой File / Use Unit добавьте в список подключаемых модулей DatMod. На модуль dm положите компонент TADOQuery (закладка dbGo), если его еще нет, и источник TDataSource, которому дайте имя dsQuery (см. рис. 2.15). Свяжите ADOQuery1 с ADOConnection1, как показано на рис. 2.15, свойство DataSet компонента dsQuery свяжите с ADOQuery1

Рис. 2.15. Компоненты запроса
ADOQuery1 и
dsQuery

     Перейдите к модулю Query и свяжите сетку DbGrid1 (свойство DataSource) с источником dsQuery.

     Чтобы в работающем приложении можно было получить доступ к окну запросов, внесите модуль Query в список используемых модулей для модуля Main. Создайте событие для щелчка на кнопке с изображением и внесите в его текст оператор

  Form2.Show;

     Щелчок на этой кнопке главного окна приложения позволит открывать окно рис. 2.14 для выполнения запросов к БД.

2.7.2. Подготовка и выполнение запросов

     Компонент MeSQL будем использовать для записи текста запроса, сформулированного на языке SQL. Рассмотрим простейший запрос с текстом

select * from Инструменты

    Этот запрос дает команду на выборку данных из таблицы "Инструменты" по всем ее полям (символ "*") и не ставит условий относительно того, какие записи следует выбирать. Это означает, что должны быть выбраны все записи таблицы.

     Чтобы этот текст был запросом по умолчанию введите его в редакторе свойства Lines компонента MeSQL.

     Чтобы выполнить запрос будем использовать кнопку, по щелчку на которой запрос будет передан из MeSQL в ADOQuery1 и там выполнен. Создайте событие для щелчка на кнопке с таким кодом:

procedure TForm2.bQueryClick(Sender: TObject);
begin
 With dm.ADOQuery1 do
  try
   Active:= false; // закрыть запрос
   SQL.Assign(MeSQL.Lines); // передать запрос из MeSQL в ADOQuery1
   Active:= true; // выполнить и открыть запрос
  except // в случае ошибки
   on e:Exception do
    ShowMessage('Не удалось выполнить запрос.');
  end;
end;
 

     Действия, производимые этой процедурой, снабжены комментариями.

     После щелчка на кнопке по указанному выше запросу будет сформирован набор данных, который будет выведен в сетку:

Рис. 2.16. Сетка с набором данных,
сформированных запросом

     Как видно, из рис. 2.16 результатом запроса стала таблица, в которую попали все записи со всеми полями таблицы "Инструменты".      

2.7.3. Запросы и язык SQL

     На практике чрезвычайно редко создают отчет по всей таблице БД. Обычно требуется не все, а лишь интересующие записи, которые следует отобрать из таблицы на основе запроса, записанного на специальном языке. Для этих целей используют язык SQL (Structured Query Language - язык структурированных запросов). При помощи команд, записанных на этом языке, и выполняется запрос.

     Язык SQL предназначен для управления запросами данных в реляционных БД. В процессе работы с БД чаще всего используют четыре основные команды - SELECT (выбрать), INSERT (вставить), UPADTE (обновить) и DELETE (удалить). Это значит, что при помощи SQL можно не только отбирать данные, но и вносить изменения в таблицы БД. В наших упражнениях мы будем использовать SQL только для запросов на отбор записей из таблиц данных.

2.7.4. Основные команда и ключевые слова языка SQL

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

SELECT выражения_для_выборки FROM таблицы [параметры выборки]

     В качестве выражения для выборки обычно перечисляют поля таблиц. Если требуется вывести все поля, то используют символ "*", как это имело место при выполнении запроса 

select * from Инструменты

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

SELECT Шифр, Марка, Дата, Цена FROM Инструменты

     Результат выполнения запроса показан на рис. 2.17.

Рис. 2.17. Сетка с набором данных,
по перечисленным полям таблицы
Инструменты

     При выборе можно сразу же произвести упорядочивание записей. Например, чтобы вывести все записи в порядке возрастания дат, достаточно написать следующее выражение с оператором ORDER BY:

SELECT Шифр, Марка, Дата, Цена FROM Инструменты
ORDER BY
Дата

     Если необходимо выполнить сортировку по убыванию, то в конце выражения следует добавить ключевое слово DESC:

SELECT Шифр, Марка, Дата, Цена FROM Инструменты
ORDER BY Дата DESC

     Выборка записей из таблицы производится при помощи условия, определяемого после ключевого слова WHERE. Например, если надо выбрать только те инструменты, которые были куплены после 11.03.2013, то следует написать следующий SQL-запрос:

SELECT Шифр, Марка, Дата, Цена FROM Инструменты
WHERE Дата > #11/03/2013#
ORDER BY Цена

     В случае, когда условий больше одного, то их объединяют при помощи логических операций AND или OR. Например, если необходимо отобрать только нутромеры таблицы Инструменты, то как видно из рис. 2.18, нужно в запросе указать значение поля Id = 2 таблицы Список и отбирать лишь те записи, для которых значение поля Id таблицы Список равно значению поля ListId таблицы Инструменты. При этом запросе поля могут быть составными типа Таблица.Поле. Такой запрос может иметь следующий вид

SELECT Инструменты.Шифр, Инструменты.Марка, Инструменты.Дата,
Инструменты.Цена FROM Инструменты, Список
WHERE (Список.Id = 2) AND (Список.Id = Инструменты.ListId)
ORDER BY Инструменты.Цена 

     Результат запроса приведен на рис. 2.18.

Рис. 2.18. Запрос, содержащий
логическую операцию
AND

     Аналогично могут быть выполнены другие запросы к БД.

 

2.8. Отчеты в Delphi

 

     Одним из важных разделов Delphi, которые относятся к  программированию баз данных, являются технологии и средства создания  отчетов. Отчеты представляют собой печатные документы, получаемые в результате выполнения запросов к БД.

     Для упрощения работы по созданию отчетов во ранних версиях Delphi имелись специализированные программные средства - генераторы отчетов. В первых версиях Delphi это был ReportSmith, затем, с Delphi 3 по Delphi 6 - QuickReport, начиная с Delphi 7 и заканчивая Delphi 2006 - Rave Reports. Последние версии Delphi этими инструментами не снабжаются, однако такие компоненты разрабатываются для всякой новой версии системы. Для версии Delphi XE7 (версия 15.0), под которую составлены настоящие методические указания, разработан компонент генерации отчетов QuickReport, который устанавливается посредством приложения QR506DXE7_installer.exe.

2.8.1. Установка пакета Quick Report

     Если пакет QuickReport не установлен, то следует закрыть Delphi XE7 и запустить инсталлятор QR506DXE7_installer.exe. После инсталляции этот пакет нужно установить в Delphi при помощи команды Component / Install Packages / Add / QR506DesignDXE7.bpl (файл QR506DesignDXE7.bpl обычно лежит в папке C:\Program Files (x86)\Embarcadero\Studio\15.0\bin). После этого в палитре компонентов появляется закладка QReport

Рис. 2.19. После инсталляции компонента QuickReport
в палитре компонентов появляется закладка
QReport

2.8.2. Использование пакета Quick Report для генерации отчетов

     В основе этого пакета  находится компонент QuickRep (закладка QReport). Он содержит составное свойство Bands, которое управляется логическими свойствами:

  • HasColumnHeader - отчет имеет заголовки столбцов;

  • HasDetail - отчет имеет столбцы данных;

  • HasPageFooter - отчет имеет нижний колонтитул страницы;

  • HasPageHeader - отчет имеет верхний колонтитул страницы;

  • HasSummary - отчет имеет итоговое значение по столбцам данных;

  • HasTitle - отчет имеет заголовок.

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

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

     Запустите Delphi и добавьте к приложению новую форму Form3 и сохраните модуль QR1.pas в папке, где уже хранятся модули Main, Query, DatMod.

     Перейдите на закладку QReport и положите оттуда на форму компонент QuickRep. Растяните его по ширине формы, как показано на рис. 2.20.

Рис. 2.20. Форма Form3
с компонентом
QuickRep

     Щелкните на компоненте TQuickRep и в инспекторе объектов и свяжите компонент с таблицей Список. Для этого выберите в свойстве DataSet значение dm.TaList. (т. е. таблица TaList, которая лежит на форме dm).

     Установите перечисленные выше переменные свойства Bands в true (см. рис. 2.21).

Рис. 2.21. Свойства панелей
отчета QuickRep

     При этом на отчете появятся указанные панели, как это видно на рис. 2.17 и 2.18.

     Положите на панель Title (заголовок отчета) компонент TQRLabel, измените его свойство Caption на ОТЧЁТ. Подберите для него подходящий фонт, как показано на рис. 2.22.

Рис. 2.22.
Конструирование
отчета

     Выше на панель Page Header положите компонент QRSysData и измените значение его свойства Data на qrsDateTime. Этот компонент будет показывать дату и время создания отчета.

     Такой же компонент положите на панель Page Footer и задайте свойство Data на qrsPageNumber. Компонент будет показывать номер страницы отчета.

     Положите на панель Column Header два компонента QRLabel, измените их свойства Caption на Id и Инструменты. Подберите и для них подходящий фонт, как показано на рис. 2.22. Эти компоненты будут играть роль заголовков полей отчета.

     Положите на панель Detail два компонента QRDBText. Они предназначены для вывода записей по двум полям таблицы Список. Установите с помощью свойства DataSet связь каждого из этих компонентов с таблицей dm.TaList. Для первого из них назначьте поле (свойство DataField) Id, для второго - Инструменты.

     Конструирование отчета закончено. Теперь отчет нужно создать и вывести в окно предварительного просмотра.

2.8.3. Создание отчета в Quick Report

     Вернемся к модулю Query и его форме Form2. Замените заголовок формы на текст БД "Инструменты". Запросы и отчеты, как показано на рис. 2.23.

     Выделите все находящиеся на форме компоненты и выполните команду Edit / Cut (Редактирование / Вырезать). После этого форма окажется чистой.

     Положите на форму компонент PageControl (закладка Win32) и командой контекстного меню New Page добавьте на компонент две новых страницы с ярлыками Запросы и Отчет. На первую из них положите вырезанные ранее компоненты командой Edit / Paste (Редактирование / Вставить). Форма примет вид, который показан на рис. 2.23.

Рис. 2.23. Вид формы Form2
со стороны закладки
Запросы

     Перейдите на страницу Отчеты и положите на нее кнопку с надписью QuickReport1 (см. рис. 2.24). Создайте для щелчка на ней событие и внесите в код процедуры обработчика этого события оператор

Form3.QuickRep1.Preview;

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

     Запустите приложение и перейдите к форме Form2. На ней перейдите на страницу Отчет (вид фрагмента страницы показан на рис. 2.24).

Рис. 2.24. Вид формы Form2
со стороны закладки
Запросы

      Щелкните на кнопке с надписью QuickReport1. При этом будет автоматически сформирован отчет и откроется окно предварительного просмотра отчета, вид которого показан на рис. 2.25.

Рис. 2.25. Вид окна
предварительного просмотра
отчета

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

2.8.4. Создание двухуровневого отчета в Quick Report

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

     Создайте новую форму Form4 и скопируйте на нее QuickRep1 с формы Form3. Подключите к форме модуль DatMod, установите свойство DataSet отчета QuickRep1 в значение dm.TaList.

     Положите на панель Detail компонент QRPShape (на рис. 2.23 он выделен), установите значение его свойства Shape в qrpsTopAndBottom (показывать верх и низ), при помощи контекстного меню выполните команду Control / SendToBack (переместить вниз), отрегулируйте его высоту и длину так, как показано на рис. 2.23.

     Положите на отчет компонент QRSubDetail (он автоматически ляжет под панель Detail, как показано на рис. 2.26) и установите его свойство DataSet в dm.taInst.      Это значит, что на данной панели будут выводиться записи подчиненной таблицы Инструменты.

Рис. 2.26. Вид конструктора отчета с фигурой QRPShape, панелью QRSubDetail и панелью Summary

     Теперь положим те поля подчиненной таблицы, которые нам хотелось бы видеть в отчете на панели SubDetail. Пусть это будут поля Id, ListId, Марка, Дата, Цена и Картинка. Для первых пяти полей используйте компонент QRDBText, для картинки используйте компонент QRDBImage. Привяжите все эти компоненты к таблице dm.TaInst, затем привяжите каждое из них к соответствующим полям данной таблицы.

     Если в отчет необходимо вывести итоговые результаты, то в свойстве Bands можно установить опцию HasSummary. Например, если необходимо подсчитать сумму, на которую куплены инструменты, выведенные в отчет, то на панель Summary следует положить компонент QRExpr и в его свойстве Expression (выражение) указать текст SUM(TaInst.Цена) (см. рис. 2.26).

     Перейдите на форму Form2, разместите там кнопку с надписью QuickRep2, как показано на рис. 2.27, и привяжите показ окна предварительного просмотра данного отчета к этой кнопке. 

Рис. 2.27. Вид формы Form2
со стороны закладки
Отчеты

     На рис. 2.28 показан вид двухуровневого отчета.

     Рис. 2.28. Вид окна предварительного просмотра двухуровневого отчета

 

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

2.8.5. Автоматическое создание отчета для сетки данных

     В наборе QReport имеется компонент, который позволяет автоматически создавать отчет по данным сетки DBGrid.

     Рассмотрим его работу на примере сетки DbGrid1, которая использовалась нами для вывода результатов выполнения SQL-запросов (см., например, рис. 2.29).

     Положите на форму Form2 компонент QRGridReport и кнопку с надписью QuickRep3. Привяжите компонент этого отчета к данной сетке (свойство DbGrid). Для кнопки создайте событие OnClick и вставьте туда код создания сеточного отчета

QRGridReport1.PreviewReport(Nil);

     Создайте и выполните, например, запрос, который показан на рис. 2.29.

Рис. 2.29. Запрос и сетка данных
с результатами выполнения запроса

     Теперь перейдите на закладку Отчеты и щелкните там на кнопке с надписью  QuickRep3. В результате получим окно предварительного отчета, в которое выведена сетка данных, как показано на рис. 2.30.

Рис. 2.30. Запрос и сетка данных с результатами выполнения запроса

     Недостатком рассмотренных нами отчетов является тот акт, что их нельзя отредактировать после создания. В какой-то степени этот недостаток может быть устранен с использованием Excel-отчетов.

2.8.6. Вывод сеточного отчета в Microsoft Excel

     Для составления отчетов и и вывода их в Excel пакета MS Office нам потребуется библиотека XE7Lib, которая состоит из файлов, расположенных в папке XE7Lib данных методических указаний. Для подключения этой библиотеки необходимо выполнить команду Tools/Options/Library, как показано на рис. 2.31.  Затем напротив строки Library Path нужно справа щелкнуть на кнопку с троеточием.

Рис. 2.31. Подключение библиотеки XE7Lib

     При этом откроется окно, которое показано на рис. 2.32. Далее следует щелкнуть на кнопку с изображением папки и выбрать папку XE7Lib. и кнопкой Add добавить выбранный путь в список.

Рис. 2.32. Добавление папки XE7Lib в список библиотек Delphi

     Программный аппарат для взаимодействия Delphi с Excel находится в модуле KdnExcel.pas библиотеки XE7Lib. В этом модуле имеется процедура OutReportToExcel, которая позволяет автоматически создавать отчет по данным таблиц или запросов и выводить его в Excel.

     В общем случае заголовок процедуры выглядит так

procedure OutReportToExcel(DataSet: TDataSet;
Title: String; TitleFont,HeaderFont,DataFont: TFont;
Framed,OutDataTime: boolean);

     Размещенные в скобках параметры указывают на

DataSet - множество данных, которые нужно вывести,
Title - заголовок отчета,
TitleFont,HeaderFont,DataFont - шрифты заголовка отчета, заголовков столбцов и выводимых данных,
Framed - надо ли заключать данные в рамки,
OutDataTime - надо ли выводить дату и время создания отчета. 

     Положите на форму Form2 кнопку с надписью Отчет в Excel 1, как показано на рис. 2.33.

     Под ней положите три компонента Label с именами и наименованиями, которые показаны на рис. 2.33. Эти компоненты нужны для того, чтоб в Excel была автоматически произведена разметка шрифтов заголовка отчета, наименований столбцов отчета и данных в его ячейках в соответствии с фонтом, который установлен для каждого из этих компонентов.

Рис. 2.33. Запрос и сетка данных
с результатами выполнения запроса

     Мы будем выводить в Excel несколько отчетов, в которых упомянутые шрифты будут одинаковыми, данные будем заключать в рамки и во всех отчетах будем выводить дату и время их создания. Отчеты будут отличаться лишь данными, которые будем выводить, и заголовками. Это позволяет написать новую процедуру, которая упростит обращение к алгоритму:

procedure DataSetToExcel(D: TDataSet; Header: AnsiString);
begin
 // если Excel открыт, то закрываем, иначе открываем его и выводим отчет
 if ExApp <> Nil then ExcelClose(0) else
 // вывод таблицы в Excel
 With Form2 do
 OutReportToExcel(Header, // заголовок отчета
 D, // таблица для вывода в Excel
 LHeaderFont.Font, // шрифт заголовка
 LColumnFont.Font, // шрифт заголовков стобцов
 LCellFont.Font, // шрифт данных
 true, // заключать данные в рамки
 true // выводить время создания отчета
   );
end
;

     Как видно из текста кода, процедура имеет имя DataSetToExcel, которая взывает процедуру OutReportToExcel, содержит лишь два параметра - множество данных D и заголовок отчета Header. Разместите этот код в модуле Unit2.

     Создайте для кнопки с надписью Отчет в Excel 1 событие OnClick и внесите в него код

  DataSetToExcel(dm.ADOQuery1,'Отчет по запросу');

     Этот оператор будет выводить таблицу запроса ADOQuery1, которая находится на модуле данных с именем dm. Заголовком отчета будет текст Отчет по запросу.

     Запустите приложение и выполните следующий запрос

SELECT Шифр, Марка, Дата, Цена, Картинка FROM Инструменты
ORDER BY Дата

    Щелкните на кнопке с надписью Отчет в Excel 1. В результате будет открыто окно программы Excel и в него будет выведена таблица результатов запроса, как показано на рис. 2.34.

Рис. 2.34. Отчет в Excel

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

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

     Положите на форму Form2 кнопку с надписью Отчет в Excel 2. Создайте для нее событие OnClick с кодом

 DataSetToExcel(dm.TaInst,dm.TaListDSDesigner.AsString);

     Это значит, что при щелчке на данной кнопке следует выводить таблицу dm.TaInst и в качестве заголовка отчета выводить название группы инструментов таблицы dm.TaList.

     Рассмотрим ситуацию, которая показана на рис. 2.35. В таблице Список указатель стоит на на надписи Микрометры. Ниже в таблице Инструменты показаны все имеющиеся микрометры. Их следует вывести в Excel. 

Рис. 2.35. Таблицы Список (dm.TaList)
и Инструменты (dm.TaInst)

     Щелкните на кнопке с надписью Отчет в Excel 2. В результате будет открыто окно программы Excel и в него будет выведена таблица микрометров, где заголовком будет слово Микрометры. Эта ситуация показана на рис. 2.36.

Рис. 2.36. Таблица микрометров

     Щелкните еще раз на кнопке с надписью Отчет в Excel 2. При этом Excel автоматически закроется.