страница 1 страница 2
-
Методические указания к выполнению самостоятельных работ студентом
|
|
Ф
ФСО ПГУ 7.18.2/07
| Министерство образования и науки Республики Казахстан Павлодарский государственный университет им. С. Торайгырова
Факультет физики, математики и информационных технологий
Методические указания
к выполнению курсовых работ студентом
по дисциплине «Системы базы данных»
для специальности 0500703«Информационные системы»
Павлодар
-
Лист утверждения МУ к самостоятельным работам студентов
|
|
Ф
ФСО ПГУ 7.18.2/11
|
УТВЕРЖДАЮ
Декан факультета ФМ иИТ
_____________ Тлеукенов С.К.
«__»_________2008г.
Кафедра информатики и информационных систем
Составитель: старший преподаватель Аканова А.С.
Методические указания
к выполнению курсовых работ студентом
по дисциплине «Системы базы данных»
для специальности 0500703«Информационные системы»
Методические указания к выполнению курсовых работ студентом разработаны на основании рабочей программы дисциплины
Рекомендована на заседании кафедры от «__» ____________200 протокол №__
Зав. кафедрой __________________________Ж.К. Нурбекова
(подпись, Ф.И.О.)
Одобрено методическим советом факультета ФМиИТ
«______»____________200__г., протокол № ___________________
Председатель МС___________________ Ж.Г.Муканова
(подпись)
Теоретические сведения
Современные инструментарии создания программных средств и delphi
Среди существующих инструментов создания приложений Delphi является самым эффективным. Поэтому для создания нашей системы в качестве инструмента берем Delphi. В наше время уже имеется 5-ая версия этого популярного продукта, но, начиная с 3-ей, технология создания примерно идентичны. В данном учебнике создание системы ведется в среде Delphi-3.
Для начала работы предполагается, что на Вашем компьютере Delphi уже установлен. Поэтому покажем только схему запуска Delphi.
Основная схема запуска Delphi.
Пусть на Вашем компьютере (т.е. компьютер включен, Windows загружен) загружен рабочий стол одной из версии Windows, т.е. Windows 95/98/2000. Будем считать, что читатель умеет загружать Windows. Тогда запуск Delphi с рабочего стола Windows происходит по схеме:
Пуск/Программы/Borland Delphi 3.
После подачи этой команды через некоторое время полностью запускается Delphi и на экране компьютера появляется интерфейс Delphi или точнее интерфейс интегрированной среды разработки (IDE -Integrated Development Environment). Структура IDE Delphi приведена на рис.1.
Отметим, что Delphi можно запустить с ярлыка, если на рабочем столе Windows создан его ярлык.
Вкратце опишем элементы IDE Delphi.
Назначение IDE Delphi.
Интегрированная среда разработки Delphi предназначена для простого, логичного представления на экране объектов, используемых при разработке приложения, в нашем примере системы базы данных. Через ряд окон интерфейса можно, в частности, выполнять следующие процедуры разработки (в режиме RAD): добавлять, изменять и удалять объекты в приложениях и компонентах.
Поэтому уместно напомнить, что при работе с Delphi можно получить достаточно полную информацию об активном в данный момент средстве программирования, нажав клавишу F1.
Создание системы базы данных в DELPHI
1. Выбор задачи автоматизации и ее формулировка
Пусть предприятие намерено автоматизировать учет складского хозяйства. Тогда из всевозможных задач выберем задачу складского учета. Причем из всего процесса учета – учет поступление материалов.
Характер процесса складского учета следующий. В складском хозяйстве учет материалов начинается с начала месяца и состоит из следующих операций и процессов:
-
перенос остатка с предыдущего месяца на текущий;
-
учет и регистрация поступления материалов в течение месяца;
-
учет и регистрация расхода материалов в течение месяца;
-
определение остатка в конце месяца.
Для учебной цели из всего набора процессов учета материалов на складе выберем процесс учета поступлений.
Описание задачи. На склад ежемесячно поступают материалы, перечень материалов может меняться. Поступление этих материалов происходит поэтапно.
Требуется автоматизировать учет поступающих на склад материалов и хранение данных о них. Основным требованиям к решению данной задачи является:
-
минимальность размера системы;
-
максимальность быстродействие;
-
максимальность удобства для работы оператора.
Для автоматизации данной задачи необходимо создать систему. Данная система будет работать с данными о материалах, поступающих на склад. Поэтому тип системы является системой базы данных. Она состоит из главных компонентов БД и СУБД, которая будет работать с БД.
2. План работы по созданию СБД.
Исходя из технологии создания СБД, вытекает следующий порядок:
1. Определить архитектуру СБД, а также среду и технологию ее создания;
2. Создать БД;
3. Создать СУБД.
Согласно данному плану начнем создание БД.
Однако в связи с тем, что и БД и СУБД состоят из ряда компонентов, прежде чем программировать систему необходимо предварительно определить основные компоненты будущей системы и их назначения, а затем планировать последовательность создаваемых компонентов по каждому разделу, т.е. БД и СУБД.
Таким образом, для БД следует определить необходимое количество баз данных и их состав, которые необходимы для эффективности функционирования СБД.
Для СУБД определяем, сколько потребуется экранных форм и отчетов, которые необходимы для удобной работы пользователя.
Наиболее правильный путь создания системы базы данных является построение БД, а затем программирование форм просмотра базы.
Итак, проектирование (т.е. изготовление) системы начнем с создания БД.
Изучение процессов приема, регистрации и хранения материалов на складе показывает, что для работы удобно данные о материалах и процессах представить в виде двух взаимосвязанных таблиц.
В одной таблице представим данные о материалах, с которыми склад работает. Это список материалов (ассортимент материалов), которые на текущий момент, либо имеются на складе, либо поступят на склад. Каждый материал, в этой таблице, задается названием, единицей измерения и ценой. Данную таблицу назовем таблицей материалов – «Материалы», ее структура представлена на рис.2.
В другой таблице будут фиксироваться данные о тех материалах, которые поступили на склад. Каждый материал, в этой таблице, задается также названием, номером приходного ордера, датой поступления и количеством поступления по данному приходному ордеру. Цена и единица измерения материалов в данной таблице не задается, так как эти данные зафиксированы в первой таблице. Эту таблицу назовем таблицей поступление материалов – «Поступление материалов» и структура приведена на рис.2.
В данном варианте формализации процесса поступления и учета материалов на склад таблица «Материалы» выполняет первичную функцию (ведущая), а таблица «Поступление материалов» – вторичную функцию (подчиненная).
В состав данных о материалах и об их поступлениях в соответствующие таблицы можно включить информацию о других особенностях материалов. Например, в состав второй таблицы можно включить стоимость поступивших материалов.
Отметим, что эти недостающие данные могут быть вычислены позже из имеющихся в таблицах данных.
Таким образом, для учебной цели состав данных достаточен.
Один и тот же материал может поступать по частям несколько раз в течение месяца или года. Поэтому одной строке первой таблицы может соответствовать несколько строк во второй таблице. В связи с этим при проектировании физической модели необходимо показать тип отношения между этими таблицами.
3.1.2. Проектирование физической модели (представления) БД
Теперь рассмотрим вариант физического представления таблиц БД или физическую модель БД.
При переводе таблицы с реального на физическое представление структура остается инвариантной. Т.е. структура таблицы остается неизменной, однако параметры реальной таблицы приобретают конкретные значения, т.е. интуитивно понятные свойства и характеристики таблицы на физическом уровне представления получают однозначное значение (рис.3).
Соответствие между реальной и физической структурой таблиц БД является однозначной.
Структуру и параметры таблицы БД продемонстрируем на примере вышеприведенных таблиц.
Связь или отношения между таблицами "один – ко - многим", то есть одному материалу в таблице "Материалы" может соответствовать более одной записи в таблице "Поступление материалов".
3.2. Создание базы данных
1)C:\Primer;
2)C:\SYSTEMA\STUDENT\…..\Primer.
Обычно в режиме локальных баз данных работают БД (или таблицы БД), созданные в формате СУБД Paradox, dBase и FoxPro.
Присвоение БД псевдонима. Как было отмечено, что БД состоит из совокупности компонентов. Поэтому они должны имеет общее название. В технологии СУБД принято в качестве названия БД присвоить к ней псевдоним (или еще называют: алиас, alias) и тогда обращение из утилит и программы СУБД к БД будет осуществляться через ее псевдоним.
В связи с отмеченным, в утилите BDE Administrator Delphi должен быть:
-зарегистрирован псевдоним БД и
-указан адрес (путь) к БД.
Создание БД в Delphi или для работы в Delphi начинается с задания места расположения и хранения.
Таким образом, первый шаг процесса создания БД.
Для нашего примера выполним этот шаг процесса создания БД.
Пусть наша база данных будет находиться в директории в корневом каталоге диска "C:" на нашем компьютере (или самого пользователя). Название директории (или папки) - "PRIMER". Тогда полное название созданной директории, вместе с путем папки будет называться: "С:\PRIMER". Если БД была бы создана на диске D:, то она имела бы название "D:\PRIMER".
Базе данных, размещенной в "С:\PRIMER" для удобства можно присвоить любое рабочее название, например, "BD", но мы назовем (присвоим псевдоним создаваемой БД) создаваемую БД с тем же именем, т.е. "С:\PRIMER".
Таким образом, псевдоним (или алиас) БД "PRIMER".
Регистрация БД. Регистрация БД в Delphi осуществляется с помощью его утилиты (или модуля) BDE Administrator. Поэтому для регистрации нашей БД "С:\PRIMER" необходимо запустить BDE Administrator.
Запуск утилиты BDE Administrator осуществляется в одном из двух вариантах таким образом:
1.Непосредственно с рабочего стола Windows:
(Пуск/Программы/Borland Delphi 3/BDE Administrator).
В данном случае приведена последовательность открытия меню и подменю (или подача команд из меню).
2.Сначала запускается главный модуль Delphi, который на экран отображает IDE. Структура IDE запущенного Delphi приведена на рис.1.
В самом верхнем ряду IDE имеется главное меню Delphi. В нем открываем меню DateBase и в нем выберем команду Exproler. По этой команде запускается утилита BDE Administrator.
После запуска утилиты BDE Administrator, в нем выполняется следующие действия.
Выберем в главном меню элемент Object|New. В появившемся окне (рис. 4) оставим тип создаваемой БД без изменений (STANDARD) и нажмем OK.
В левом окне появившегося окна администратора БД мы увидим строку с именем STANDARD1. Изменим это имя на "PRIMER". Для этого щелкнем мышью на названии БД и введем новый текст.
В правом окне приведены параметры БД. Оставим их без изменения, изменив лишь PATH. Этот параметр указывает путь к каталогу, в котором будет расположена БД. Можно ввести путь вручную, но лучше воспользоваться средствами администратора: для этого нужно щелкнуть по полю PATH и нажать на появившуюся в правом углу поля кнопку следует выбрать каталог С:\PRIMER и нажать кнопку Ok (рис. 5).
Теперь необходимо запомнить определение псевдонима. Для этого в левом окне администратора БД необходимо щелкнуть по имени псевдонима правой кнопкой мыши и во всплывающем меню выбрать элемент Apply. В появившемся диалоговом окне, в котором спрашивается, собираемся ли мы запоминать изменения для псевдонима, необходимо нажать кнопку Ok. Затем следует выйти из утилиты BDE Administrator. Теперь создание псевдонима завершено и к нему можно обращаться из других утилит и приложений. Однако каталог, на который ссылается псевдоним БД, еще пуст. Необходимо создать таблицы базы данных.
3.2.3. Создание таблиц базы данных
Создание БД представим таким образом.
Согласно концептуальному проекту база данных состоит из 2 взаимосвязанных таблиц. Причем первая таблица является главной. Поэтому БД создадим в следующей последовательности:
-формирование структуры таблицы 1;
-формирование структуры таблицы 2;
-установление связи между таблицами.
А. Конструирование мастер-таблицы
Для создания таблиц базы данных необходимо запустить утилиту Database Desktop (DBD) (Пуск/Программы/Borland Delphi 3/Database Desktop). После запуска утилиты установим рабочий псевдоним утилиты. Это псевдоним, с которым утилита работает по умолчанию. Если рабочий псевдоним не установлен, придется при работе с DBD всякий раз указывать псевдоним, что отнимает время.
Для установки рабочего псевдонима нужно выбрать элемент главного меню File|Working Directory и в выпадающем списке Aliases выбрать имя псевдонима PRIMER, после чего нажать кнопку Ok.
Конструирование структуры таблицы. Для создания таблицы БД нужно выбрать элемент главного меню File|New|Table. В появившемся окне Create Table оставляем без изменения тип создаваемой таблицы (Paradox 7) и нажимаем кнопку Ok. После этого появится окно определения структуры таблицы БД (рис. 6).
Каждая строка таблицы соответствует полю. Назначения столбцов:
-
Fields Name - имя поля;
-
Type - тип поля;
-
Size - размер поля (для строковых полей, поскольку иные поля подразумевают размер, определяемый типом поля);
-
Key - содержит звездочку '*', если поле входит в состав первичного ключа. Если в первичный ключ входит несколько полей, они должны определяться в той последовательности, в которой они присутствуют в первичном ключе. Кроме того, все поля, входящие в состав первичного индекса, должны определяться перед иными полями, то есть быть в списке полей наверху.
Определим поля, входящие в таблицу "Материалы". Введем Material в столбец Field Name. Для того, чтобы определить тип поля, щелкните по столбцу Type и нажмите клавишу пробела. В ответ на это будет выдан список типов полей, из которых необходимо произвести выбор нужного типа (рис. 7).
Всевозможные типы полей СУБД Paradox приведены на рис. 8.
Для того чтобы определить тип поля Material, выберем Alpha и затем в столбце Size укажем значение 20. В столбце Key поместим звездочку, означающую, что данное поле входит в состав первичного ключа. Для этого нажмем любой символ на клавиатуре. Повторное нажатие любого символа снимает отметку звездочкой в столбце Key.
Мастер таблица по первичному ключу индексируется.
Введем определения и других столбцов таблицы Materialу (рис. 9).
Согласно условиям задачи все поля данной таблицы должны заполнятся. Поэтому для каждого поля определим требование обязательного заполнения поля значением. Для этого, переходя от поля к полю, включим переключатели Required Field. Другие поля служат для наложения ограничений на значение поля:
-
Minimum value - определяет минимальное значение поля
-
Maximum value - определяет максимальное значение поля
-
Default value - определяет значение поля по умолчанию
-
Picture – определяет шаблон изображения поля. Для формирования шаблона следует нажать кнопку Assist.
Отсутствие значения в одном из полей означает отсутствие ограничений на значение поля.
Заполнение и запомнить таблицы. После конструирования структуры таблицы в Database Desktop можно заполнить таблицу. Отметим, что заполнение таблицы в русском алфавите может не удасться, тогда следует использовать латинский алфавит.
Чтобы запомнить сохраненную таблицу на диске, следует нажать кнопку Save As. Затем в появившемся окне следует указать имя таблицы (рис. 10) При желании можно указать каталог или псевдоним, отличные от принятых по умолчанию. Напомним, что по умолчанию принимается рабочий каталог или каталог, определяемый рабочим псевдонимом.
После того как мы определим имя создаваемой таблицы (Materialу) в каталоге С:\PRIMER (он назначен псевдониму PRIMER, используемому нами в качестве рабочего псевдонима) будет создан файл Materialу.DB и файлы индексов с соответствующими расширениями.
Реструктурирование созданной таблицы. Если в структуру существующей таблицы БД необходимо внести изменения следует выбрать элемент меню File | Open | Table, в появившемся диалоговом окне выбрать имя таблицы и нажать кнопку Ok. Будет показано содержимое таблицы (на рис. 11, в таблице Materialу отсутствуют записи, что не удивительно поскольку мы их еще не вводили).
В том случае, когда мы хотим ввести новые записи в таблицу прямо в DBD (а также изменить значения в некоторых записях или произвести удаление) следует нажать кнопку F9. После этого таблица будет переведена в режим внесения изменений.
Чтобы изменить структуру таблицы, выберите элемент меню Table | Restructure. Вслед за этим будет показано диалоговое окно для определения структуры таблицы.
Б. Конструирование деталь таблицы
Определим структуру второй таблицы "Поступление материалов" (рис. 12), которая является деталь-таблицей. Способ конструирования структуры этой таблицы почти аналогично мастер таблице. Кроме следующих отличий.
Всем полям назначим атрибут Required (требование обязательного существования значения у поля на момент его запоминания в БД), кроме поля N_Prih, поскольку это поле автоинкрементальное, заполнение его значением производится автоматически при запоминании новой записи.
Создадим индекс по полям «Дата прихода», «Материал». Для этого в комбинированном списке Table Properties (в правом верхнем углу окна) выберем элемент Secondary Indexes. После этого диалоговое окно приобретет вид, показанный на рис. 13.
Чтобы определить новый индекс, нажмем кнопку Define. В появившемся диалоговом окне в поле Fields содержится список полей определяемой нами таблицы. Поле Index Fields предназначено для хранения полей, входящих в создаваемый индекс. Чтобы скопировать конкретное поле из списка Fields в список Index Fields, нужно нажать кнопку с изображением правой стрелки. Последовательность добавления полей в список важна, она определяет порядок чередования полей в списке. После того как мы поместили нужные поля в список Index Fields (рис. 14), нажмем кнопку Ok.
В появившемся окне запрашивается имя индекса (рис. 15) Следует ввести имя и нажать Ok.
Не рекомендуется составлять название индекса только из имен полей, поскольку такой способ именования индексов используется автоматически при создании ссылочной целостности между таблицами (см. следующий раздел).
Как видно на рис. 16, после добавления нового индекса его имя появилось в списке индексов.
Впоследствии, щелкнув по имени индекса, мы можем его удалить (кнопка Erase) или изменить (кнопка Modify).
Сохраним созданную нами таблицу под именем Prihod.
В. Конструирование базы данных
Теперь конструируем БД в целом из таблиц, структура которых созданы, т.е. из конструированных таблиц.
Как известно из постановки задачи, таблицы "Материалы" и "Приход материалов" находятся в отношении "один - ко - многим", то есть с одной записью в таблице Materialy может быть связано несколько записей по приходу того же материала в таблице Prihod. В качестве поля связи выступает поле Material, присутствующее в обеих таблицах.
Определим ссылочную целостность между данными таблицами. Ссылочная целостность в Paradox определяет, во-первых, связь между таблицами, а во-вторых, вид каскадных воздействий.
Откроем таблицу Prihod (элемент меню File | Table | Open) и затем войдем в режим изменения структуры таблицы (Table | Restructure). В выпадающем списке Table Properties выберем элемент Refrential Integrity и нажмем кнопку Define. В появившемся диалоговом окне (рис. 17) в списке Fields показаны поля таблицы Prihod, а в списке Tables - таблицы базы данных PRIMER.
Выберем в списке Fields поле Material и нажмем кнопку с изображением стрелки вправо. Название Material будет записано в поле Child Fields (поле внешнего ключа дочерней таблицы).
Выберем в списке Tables таблицу Materialy и нажмем кнопку с изображением стрелки влево. В поле Parents Key (ключ родительской таблицы) будут показаны поля из первичного ключа таблицы Materialy. В данном случае это поле Material.
Переключатели Update rules определяют вид каскадных воздействий на таблицу Prihod при изменении значения поля связи в таблице Materialy или при удалении записи в таблице Materialy:
-
Cascade - каскадные изменения и удаления подчиненных записей в таблице Prihod;
-
Prohibit - запрет на изменение поля связи или удаление записи в таблице Materialy, если для данной записи есть связанные записи в таблице Prihod. Выберем Cascade (рис. 18) и нажмем кнопку Ok.
Будет запрошено имя - в Paradox ссылочные целостности именуются. Введем имя, например Materialy_Prihod_Integrity, и нажмем кнопку Ok. Теперь имя созданной ссылочной целостности будет помещено в список.
Запомним изменения в таблице Prihod (кнопка Save) и заново войдем в режим реструктуризации таблицы Prihod (Table|Restructure). В выпадающем списке Table properties выберем элемент Secondary Indexes (индексы таблицы, кроме индекса, построенного по определению первичного ключа). В списке индексов увидим, что появился новый индекс с именем Material (по полю Material). Этот индекс построен автоматически по неявному определению внешнего ключа при создании ссылочной целостности (рис. 19).
На этом процесс построение БД закончится, поэтому можно выйти из режима реструктуризации и покинем DBD. После этого перейдем к разработке простейшего приложения для работы с созданными таблицами.
Заключение по разделу
Структура материала по созданию БД следующая:
1.Формирование структуры первой таблицы. Ее характеристики таковы:
Она является мастер таблицей и для неё создан первичный ключ, первичная индексация по первичному ключу.
2.Формирование структуры второй таблицы. Ее характеристики таковы:
Она является деталь таблицей, создан вторичный ключ, вторичная индексация.
3. Между таблицами установлено отношение “один ко многим”.
СОЗДАНИЕ СУБД В DELPHI
СУБД состоит из совокупности экранных и отчетных форм и процедур обработки данных вводимых в БД и выводимых из БД. При программировании СБД в среде Windows СУБД называют приложением.
Таким образом, из описанной выше схемы работы системы «пользователь – система» видно, что для работы системы необходимо следующие формы:
-
Форма для меню;
-
Форма для ввода данных в базу;
-
Форма для просмотра БД;
-
Форма для отчета №1;
-
Форма для отчета №2;
-
Форма для отчета №3.
Выше было указано внешняя форма проявления СБД. Для того чтобы обеспечить работоспособность СБД необходимо обеспечить связь форм с БД: обработку данных БД из экранной формы. Что и будет сделано в следующих пунктах.
В Delphi информационная связь форм СУБД с БД осуществляется через определенные невизуальные компоненты. Поэтому для обеспечения связи экранных форм с БД в проекте используется специальный невизуальный компонент (контейнер) TDataModule, который также должен создаваться отдельно.
Таким образом, исходя из описанных эвристических предпосылок, установим перечень необходимых для нашей задачи форм:
-
Форма для меню;
-
Форма для ввода данных в базу;
-
Форма для просмотра БД;
-
Форма для отчета №1.
-
Форма для отчета №2.
-
Форма для отчета №3.
-
Компонента TDataModule
Опыт подсказывает, что одним из наиболее удобных для разработчика порядка формирования форм и их компонентов является следующий.
-
Компонента TDataModule
-
Форма для меню;
-
Форма для просмотра БД;
-
Форма для ввода данных в базу;
-
Форма для отчета №1.
-
Форма для отчета №2.
-
Форма для отчета №3.
Формы, необходимые для создания СУБД можно задать двумя способами:
1. Если заранее известно их количество, то на экране монитора и соответственно в хранилище (repository) проекта IDE Delphi заранее можно вывести нужное количество визуальных и невизуальных форм, т.е. в проект можно добавить столько форм, сколько требуется. С помощью команды File|New Form добавляются визуальные формы, а командой File|New Data Module - невизуальная. Отметим, что для нашей системы требуется всего шесть визуальных форм и одна компонента TDataModule.
2. Если заранее количество нужных форм для проекта не известно, то на экране монитора и соответственно в хранилище (repository) проекта IDE Delphi добавляется та форма, которая нужна для проекта на текущем этапе создания СУБД. Установление форм на экране осуществляется через команды File|New Form или File|New Data Module. Другими словами каждая форма в проект добавляется по мере необходимости.
В данном случае добавление новых форм в хранилище проекта происходить с помощью команды добавления (File|Add to Project).
Таким образом, исходя из проекта, представим план работы по созданию СУБД для поставленной выше задачи автоматизации из экранных и отчетных форм и процедур обработки данных.
Сначала будем считать, что на экране выведено столько форм, сколько требуется для создания всех форм СУБД. Если форм не хватает, то доводим их до необходимого количества. Это делается путем повторение действия (File|New Form) столько раз, сколько требуется количеств форм и один контейнер командой File|New Data Module.
Теперь определим последовательность проектирования (конструирования) форм. Последовательность создание форм в общем случае произвольный, но мы все таки выбираем вышеизложенную последовательность.
Данная последовательность оформления и создания форм упрощает процесс создания СУБД.
Создание СУБД начнем с построения контейнера TDataModule для связи с БД. Проектирование форм СУБД начнем с экранной формы, на которой будет отображено содержимое БД.
Проектирование СУБД происходит по каждой форме по отдельности путем установления связи с БД и созданием процедур обработки данных, вводимые с экранной формы или получаемые из БД.
Кроме того, требуется установление связи между компонентами различных форм. В одной из экранных форм следует предусмотреть команду завершения работы системы.
После определения набора компонентов и их размещения на форме, устанавливается их доступ к БД и создается процедура обработки данных для каждого компонента формы.
Из вышеприведенного определения видно, что СУБД также как БД состоит из множества компонентов. Все эти компоненты СУБД требуют формирования и программирования. Поэтому их также как и БД следует хранить в определенном месте. Поэтому для этой цели создадим в каталоге C:\PRIMER подкаталог АРР. В нем мы будем хранить разработанные приложения.
В общем случае приложение можно хранить в любом месте, однако, хранение его вместе с БД в одной папке, но все же отельной поддиректории удобно для работы разработчика. Так и будем делать.
4.3. Создание СУБД
4.3.1. Создание контейнера TDataModule
Связь экранной формы с БД обеспечивается специальными компонентами, которые называются невизуальными компонентами. Эти элементы видны только в режиме конструирования, а в режиме работы системы на экране невидимы.
Если СУБД состоит из одной экранной формы, то не нужно специального хранилища в виде контейнера для хранения невизуальных компонентов. В этом случае невизуальные компоненты можно расположить на той же экранной форме, которая является единственной. В случае множества экранных форм, каждая из которых должна иметь доступ к БД, доступ организовывается следующим образом.
Для всех экранных и отчетных форм необходим доступ (связь) к БД. Причем когда СУБД имеет несколько экранных форм их доступ к БД можно осуществить двумя способами.
1. Доступ каждой формы (и ее компонентов) к БД можно осуществить автономно, независимо от остальных форм.
2. Второй способ предполагает не повторять для каждой формы организацию доступа к БД, а для всех экранных и отчетных форм организовать единый доступ через специальный компонент типа TDataModule. Компонент типа TDataModule представляет собой контейнер, в который можно помещать невизуальные компоненты TTable, TQuery, DataSource, которые необходимы для доступа к БД и т.д. Тогда все те формы, для которых потребуется доступ к БД, доступ получат через компонент TdataModule. Поэтому при создании СУБД для каждой экранной формы необходимо установить связь с компонентой типа TdataModule.
Таким образом, для работы СУБД необходимо создать компонент типа TDataModule.
Создание экземпляра TDataModule в среде Delphi осуществляется через пункт меню File|New Data Module.
Компонент TDataModule служит контейнером компонентов для работы с базами данных. В палитре компонентов Delphi на странице Data Access выберем мышью невизуальный компонент ТТаblе (рис. 20), щелкнем на нем мышью и затем щелкнем мышью в контейнере. После этого, изображение компоненты останется в контейнере.
Невизуальным компонент TTable (как и другие компоненты, например, TQuery, TDataSource) называется потому, что он применяется для хранения и доступа к данным, а не для их визуализации - для этой цели применяются визуальные компоненты (TDBGrid, TEdit и другие).
После того, как мы разместили компонент TTable, установим его свойства. Для этой цели воспользуемся инспектором объектов (Object Inspector), который обычно помещается слева от формы. Если он не видим, его можно вызвать, нажав кнопку F11. Инспектор объектов позволяет устанавливать свойства того компонента, который выделен при помощи мыши. Выделим мышью компонент TTable.
Установим значение свойства DatabaseName (псевдоним БД) в PRIMER при помощи выпадающего списка или введя его вручную. Установим значение свойства TableName (имя таблицы БД) в Materialy.DB при помощи выпадающего списка. После этого установим значение свойства Active в True. После этого произойдет реальное связывание компонента TTable (он по умолчанию имеет имя Table1) с реально существующей таблицей Materialy.DB.
Компонент TTable и компонент TQuery (его мы рассмотрим позже) служат для хранения наборов данных. Понятие набора данных несколько шире, чем понятие таблицы БД, поскольку набор данных может содержать:
-
подмножество записей или полей таблицы БД (компоненты TTable, TQuery);
-
записи, сформированные из нескольких таблиц БД (компонент TQuery).
Расположим в контейнере DataModule компонент TDataSource. Он служит в качестве связующего звена между невизуальными компонентами (в данном случае Table1) и визуальными компонентами, которые мы добавим в форму №3 позднее. Поэтому компоненты TDataSource часто называют источниками данных. Установим свойство DataSet (имя набора данных) компонента TDataSource в значение Table1 путем выбора из выпадающего списка.
TDataModule нужно сохранить под каким-либо именем (по умолчанию Unit5.pas). Имя модуля Unit, в котором описан TDataModule, добавляется в текст модулей unit всех иных форм приложения, которые будут использовать БД и TDataSource, расположенные в этом TDataModule. Это производится в главном меню среды Delphi, в элементе меню File|Use Unit.
В дальнейшем визуальные компоненты, работающие с данными набора данных (НД), должны в своем свойстве DataSource содержать имя соответствующего компонента TDataSource из TDataModule. При этом имя является составным: сначала идет имя компонента TDataModule и затем через точку – имя компонента TDataSource, например DataModule5.DataSource1.
4.3.2. Создание экранных форм, установление их доступа к БД и организация обработки данных (простой вариант)
А. Создание экранной формы для меню СУБД
Перейдем в форму №1 (элемент меню View|Forms), выбрав из диалогового окна Form1 нажмем на кнопку Ok. Расположим в форме компонент MainMenu из страницы Standard палитры компонентов. Затем вызовем средства разработки меню (это можно сделать двумя способами):
-
Двойное нажатие на компонент MainMenu внутри формы №1
-
Переходим в окно Object Inspector при выделенном компоненте на форме. Щелкнем на свойстве Items и нажмем кнопку .
Находясь в Конструкторе меню Form1.MainMenu1 (это имя, присвоенное Delphi по умолчанию созданному нами перед этим компоненту TMainMenu), дадим названия пунктам меню (свойства Caption в Object Inspector) «Файл/Ввод/Просмотр/Отчет/Выход». Для перехода на следующий уровень нажимаем на <Enter>. Для визуального разделения пунктов меню на отдельные группы после Отчет используем несколько символов минус (-), назначать имя разделителю необязательно. Для пункта меню «Ввод» создадим подменю «Название материала/Поступление материала». Для этого выделим его и щелкнем правой кнопкой мыши, в появившемся окне выберем пункт Create Submenu.
Теперь, когда меню создано, можно связать с каждым пунктом меню код, который будет выполняться при выборе данного пункта пользователем. Для создания процедуры обработки этого события – OnClick, находясь в Конструкторе меню, дважды щелкнем мышью на пункте меню. В появившемся окне Редактора кода процедуре обработки события OnClick напишем код, который будет выполняться при выборе этого пункта меню. Такого же результата можно достичь при помощи двойного щелчка мышью на имени процедуры обработки, которое находится на странице Events окна Object Inspector.
Например, в пункт Просмотр введем следующий код:
Form1.Visible := False;
Form3.Visible := True;
элемент меню Поступление материала:
Form1.Visible := False;
Form2.Visible := True;
элемент меню Выход: Сlose;
Выберем элемент меню File|Save Project As и сохраним проект. Сначала запрашивается имя формы проекта (у нас пять форм, с именами Form1 … Form4, DataModule5). Сохраним формы под именами 'Unit*.pas'. Затем запрашивается имя проекта. Сохраним проект под именем 'appl.dpr'.
Добавим имена модулей Unit2 и Unit3 в текст модулей unit формы №1.
После этого выполним приложение. (Чтобы выполнить приложение не выходя из среды Delphi, достаточно нажать кнопку F9. Чтобы создать приложение и запустить его вне среды Delphi, следует нажать комбинацию кнопок Ctrl+F9 и затем запустить созданный файл с расширением .ехе и именем, совпадающим с именем проекта. В нашем случае следует запускать файл 'appl.exe'.
Остановить работающее приложение можно командой Run|Program Reset.
Б. Создание экранной формы для представления содержания БД
1) Представление содержания одной таблицы БД на экранной форме.
Сначала построим простую экранную форму, которая имеет доступ только к одной таблице БД.
Перейдем в форму №3 путем выбора элемента (или команды) меню View|Forms, нажмем на кнопку Ok выбрав из диалогового окна Form3. Расположим в форме компонент TDBGrid, взяв его из палитры компонентов (страница Data Controls). Установим свойство DataSource компонента TDBGrid в значение DataSource1 (это имя созданного нами выше компонента TDataSource, присвоенное Delphi по умолчанию) предварительно добавив имя модуля Unit5, в котором описан TDataModule, в текст модулей unit формы №3. Компонент TDBGrid служит для отображения записей набора данных в табличной форме.
Добавим в форму компонент кнопки TButton (страница Standard палитры компонентов), дадим имя этому компоненту (свойство Name), используя инспектор объектов, CancelButton. Изменим заголовок кнопки (свойство Caption) на Отмена.
Вид разрабатываемой формы представлен на рис. 21.
Свяжем с кнопкой код, который будет выполняться при нажатии на кнопку пользователем. Для создания процедуры обработки этого события – OnClick, находясь в форме, дважды щелкнем мышью на кнопку Отмена. В появившемся окне Редактора кода процедуре обработки события OnClick напишем код
Сlose;
Form1.Visible := True;
Запустим приложение на выполнение из Delphi, выбрав команду Run из меню Run (или F9). Из меню Файл/Ввод приложения выберем команду Просмотр.
Вид работающего приложения показан на рис.22.
Добавлять записи в набор данных (и, следовательно, в таблицу Materialy.DB) можно прямо из компонента TDBGrid.
Для добавления записи нужно нажать на клавиатуре кнопку Insert или, находясь на последней записи набора данных, кнопку "стрелка вниз". Набор данных автоматически перейдет в режим добавления новой записи. После ввода значений в поля записи запомнить запись в наборе данных можно, перейдя на другую запись при помощи клавиш управления курсором. Отказаться от запоминания записи можно, нажав кнопку Esc.
Для изменения записи следует переместить указатель текущей записи в нужное место и изменить значения там, где это необходимо. Набор данных автоматически перейдет в режим редактирования.
Для удаления записи следует установить на нее указатель текущей записи и нажать комбинацию кнопок Ctrl+Del.
2) Представление содержания двух таблиц БД
Теперь работу усложним. Представим содержание двух таблиц БД. Причем в двух вариантах:
а) без установления связи между таблицами на экранной форме;
б) отобразим данные таблицы с учетом связи между таблицами.
2.1) Отображение данных таблиц БД на экранной форме без установления связи между ними
Покажем, как в одной форме можно связать два набора данных (родительский и подчиненный) так, чтобы в подчиненном наборе данных всегда показывались записи, соответствующие текущей записи в родительском НД.
Добавим в контейнер DataModule5 компонент ТТаblе (с именем Таblе2) для работы с таблицей Prihod базы данных PRIMER (значения свойств такие же, как у компонента Table1, но свойство TableName ссылается на имя таблицы Prihod.DB). Добавим в форму компонент TDataSource (имя по умолчанию DataSource2). Установим свойство DataSet этого компонента в значение Таblе2. Разместим в форме №3 компонент TDBGrid (имя по умолчанию DBGrid2) и установим его свойство DataSowce в значение DataSource2 (рис.23). Установим свойство Таbl2.Аvtive в True. После этого произойдет реальное связывание компонентов TTable с реально существующими таблицами Materialy.DB и Prihod.DB.
Чтобы при просмотре нельзя было изменять данные о материалах (таблица Materialy.DB), установим свойства ReadOnly компонента DBGrid1 в положение True.
Запустим приложение на выполнение. Добавим несколько записей в таблицу Prihod.DB из компонента TDBGrid2. Обратите внимание, значение поля N_Prih формируется автоматически (рис. 24).
2.2) Отображение данных таблиц БД на экранной форме с учетом связи между ними, т.е. реализация связи Master-Detail между наборами данных
Нам известно, что таблицы базы данных Materialy.DB и Prihod.DB находятся в отношении "один-ко-многим". Поскольку мы определили ссылочную целостность между этими таблицами, можно сделать так, чтобы при установке указателя на запись в наборе данных Table1 (ассоциированном с Materialy.DB) в наборе данных Таblе2 (ассоциированном с Prihod.DB) показывались только записи прихода текущего материала в Table1. Это реализуется через механизм связи наборов данных Master-Detail.
В инспекторе объектов для компонента Таblе2 установим значение свойства Master Source в DataSource1. Переместимся на значение свойства Master Fields и нажмем кнопку . В появившемся окне Field Link Designer установим параметры связи. В поле Available Indexes выберем в качестве текущего индекса по полю 'Material'. В списке Detail Fields выберем поле Material, в списке Master Fields выберем поле Material и нажмем кнопку Add. В поле Joined Fields будет сформировано выражение 'Material Material' (рис. 25). Нажмем кнопку Ok.
Как можно заметить, в компоненте Таblе2 текущий индекс (свойство FieldIndexNames) заменен на индекс, построенный по полю 'Material'.
Теперь в наборе данных Table2 показываются только записи по приходу материала, текущего в наборе данных Table1 (рис. 26).
В. Создание экранной формы для ввода данных в БД
Для дальнейшей работы подготовим контейнер DataModule5. Из палитры компонентов Delphi на странице Data Access добавим невизуальный компонента TTаblе, установим значения свойств DatabaseName (псевдоним БД) в PRIMER при помощи выпадающего списка или введя его вручную. В Tаblе3 установим значение свойства TableName (имя таблицы БД) в PRIHOD.DB. После этого установим значение свойства Active в True. Расположим компонента TDataSource, установим свойство DataSet (имя набора данных) компонента DataSource3 в значение Table3. Добавление невизуальных компонентов для связи с таблицей PRIHOD.DB в контейнер обязательно, т.к. аналогичные компоненты в контейнере DataModule взаимно связаны и в дальнейшем может произойти циклическое обращение.
Добавим в форму №2 компонент TDBGrid из палитры компонентов Data Controls. Установим свойство DataSource компонента TDBGrid в значение DataSource3, предварительно добавив имя модуля Unit5 в текст модулей unit формы №2.
Теперь сделаем так, чтобы к полям записи в наборе данных Table3 можно было обращаться не только из сетки компонента DBGrid1, а из отдельных визуальных компонентов, позволяющих осуществлять доступ к отдельным полям записи набора данных.
Добавим в форму №2 два компонента TDBEdit (палитра компонентов Data Controls). Определим поле, к которому можно иметь доступ через компонент DBEdit1. Для этого установим значение его свойств - DataSource в DataSource3 и DataField в DatPrih. Определим поле, к которому можно иметь доступ через компонент DBEdit2. Для этого установим значение его свойств - DataSource в DataSource3 и DataField в Kolvo.
Для доступа к полю Material нам нужен более сложный компонент, который позволял бы вводить в поле Material таблицы Prihod.DB значения полей Material из таблицы Materialy.DB, и никакие другие значения. Для этой цели разместим компонент TDBLookupComboBox с именем по умолчанию DBLookupComboBox1. Установим свойства этого компонента:
-
DataSource - в значение DataModule5.DataSource3;
-
DataFiled - в значение Material;
-
List Source - в значение DataModule5.DataSource1
-
ListField - в значение Material;
-
KeyField - в значение Material.
Добавление кнопок управления данными БД на экранной форме
Далее на экранной форме можно создать набор кнопок, которые позволят проводить навигацию по таблицам БД и управлять ее состоянием, т.е. ее записями.
Для этого в приложение добавим пять компонентов кнопок TButton (страница Standard палитры компонентов). Изменим имена этих компонентов (свойство Name), используя инспектор объектов, соответственно на InsertButton, EditButton, DeleteButton, PostButton, CancelButton. Изменим заголовки этих кнопок (свойство Caption), используя инспектор объектов, соответственно на "Добавить", "Изменить", "Удалить", "Запомнить", "Закрыть" (рис. 27).
Выберем при помощи мыши кнопку InsertButton и два раза щелкнем на ней. После этого мы перейдем в редактор кода и определим для кнопки InsertButton обработчик события нажатия кнопки, OnClick:
procedure TForm2.InsertButtonClick(Sender: TObject);
begin
DataModule5.Table3.Insert;
end;
Метод Insert переводит набор данных Table1 в состояние добавления записи dsInsert. Ввод значений полей осуществляется в компонентах DBEdit1, DBLookupComboBox1, DBEdit2. Для этого необходимо, чтобы набор данных находился в режиме просмотра dsBrowse.
Определим обработчик нажатия кнопки EditButton:
procedure TForm2.EditButtonClick(Sender: TObject);
begin
DataModule5.Table3.Edit;
end;
Метод Edit переводит набор данных Table1 в состояние добавления записи dsEdit. Редактирование значений полей осуществляется в компонентах DBEdit1,
DBLookupComboBox1, DBEdit2. Для этого необходимо, чтобы набор данных находился в режиме просмотра dsBrowse.
Определим обработчик нажатия кнопки DeleteButton:
procedure TForm2.DeleteButtonClick(Sender: TObject);
begin
IF MessageDlg('Подтвердите удаление записи', mtConfirmation,[mbYes, mbNo],0) = mrYes THEN DataModule5.Table3.Delete;
end;
Если набор данных Table1 находится в режиме просмотра записей dsBrowse, вызывается окно диалога (при выполнении функции MessageDlg); если пользователь нажимает кнопку Yes, происходит удаление текущей записи в наборе данных Table1.
Определим обработчик нажатия кнопки PostButton:
procedure TForm2.PostButtonClick(Sender: TObject);
begin
DataModule5.Table3.Post;
end;
Если набор данных находится в режиме добавления новой записи или редактирования, происходит выполнение метода набора данных Post, который запоминает текущее состояние записи в таблице БД. После запоминания набор данных переводится в режим просмотра dsBrowse.
Определим обработчик нажатия кнопки CancelButton:
procedure TForm2.CancelButtonClick(Sender: TObject);
begin
close;
Form1.Visible:=true;
end;
Если набор данных находится в режиме добавления новой записи или редактирования, происходит выполнение метода набора данных Cancel, который отменяет запоминание записи в таблице БД и переводит набор данных в режим просмотра и переходит на форму меню.
Для того чтобы набор данных нельзя было переводить в состояние добавления и изменения данных, а также удалять записи непосредственно из компонента DBGrid1, установим свойство DBGrid1.ReadOnly в значение True. После этого запустим приложение на выполнение. При добавлении новой записи или при корректировке существующей в поля можно заносить значения, используя ввод в компоненты DBEdit1, DBEdit2 и путем выбора из списка значений в компоненте DBLookupComboBox1 (рис. 28). То же происходит при изменении записи. При удалении записи выдается окно диалога (рис. 29).
4.3.3. Создание более сложной экранной формы
для представления содержания БД
Варианты модификации TDBGrid на экранной форме.
Как можно заметить, значение поля N_Prih необходимо для обеспечения уникальности в таблице Prihod и не несет никакой иной нагрузки. Поэтому данное поле лучше не показывать в составе столбцов DBGrid2. Для этой цели сформируем список полей таблицы Prihod. В Delphi имеются две возможности указать, какие из полей таблицы БД следует использовать в приложении для набора данных.
Первый способ состоит в использовании по умолчанию всех полей из таблицы БД, с которой ассоциирован этот набор данных. Этот способ всегда используется по умолчанию и, следовательно, был неявно использован и нами при создании наборов данных Table1 и Table2.
Второй способ состоит в использовании подмножества полей таблицы БД, с которой ассоциирован набор данных. Для этой цели используется редактор полей набора данных, который позволяет включить в состав обрабатываемых для набора данных полей все поля или подмножество полей таблицы БД.
Выберем в контейнере DataModule5 при помощи мыши компонент Таblе2 и нажмем правую кнопку мыши. В появившемся на экране всплывающем меню выберем элемент Fields Editor. В появившемся списке редактора полей (пока он пуст, рис. 30.а) нажмем правую кнопку мыши и во всплывающем меню выберем элемент меню Add Fields. Будет показан список всех полей таблицы БД Prihod.DB. Отметим (при помощи мыши и кнопки Shift) все поля, кроме N_Prih (рис. 30.6) и нажмем кнопку Add. Теперь список редактора полей будет включать все отмеченные поля (рис. 30.в).
Как можно заметить, в составе столбцов в компоненте DBGrid2 на форме №3 теперь присутствуют только те поля, которые добавлены для набора данных Table2 в редакторе полей (рис. 31).
Определение для набора данных списка полей в редакторе полей (нажатие правой кнопки мыши по компоненту Таblе2) приводит к тому, что для каждого добавленного таким образом поля в приложении Delphi автоматически создает компонент TField (поле набора данных). Каждый такой компонент по умолчанию именуется уникальным именем - в качестве первой составляющей имени поля берется имя набора данных (Таblе2), а в качестве второй составляющей - имя поля в таблице БД. Так, компонент TField соответствующий полю Material, будет поименован как Table2Material. Если в редакторе полей щелкнуть по имени соответствующего поля, в инспекторе объектов можно установить или изменить свойства поля, а также определить обработчики события для конкретного поля.
Изменим параметры компонента DBGrid2 так, чтобы названия его столбцов содержали русские наименования. Для этого нажмем правой кнопкой мыши на компоненте DBGrid2, и во всплывающем меню вые элемент Columns Editor. На экране появится окно редактора стол компонента (рис. 32.а). Для того чтобы изменить характеристики стол в TDBGrid, нужно перейти от неявно определяемых столбцов к определяемым. Для этого нужно щелкнуть по кнопке Add All Fields, в результате чего будут добавлены столбцы, каждый из которых соответствует полю, определенному в редакторе полей компонента Table2 (рис. 32.б). Что бы изменить заголовок каждого столбца, следует выбрать при помощи мыши имя столбца в редакторе столбцов, и в инспекторе объектов раскрыть список свойства Title (для чего следует щелкнуть мышью по крестику рядом с именем свойства). В элементе Caption этого списка содержится заголовок столбца; изменим соответствующим образом заголовки и затем выйдем из редактора столбцов DBGrid2. То же проделаем для набора данных Table1 (рис. 33).
Аналогичные изменения проделаем и в форме №2.
Изменим также порядок сортировки записей в наборе данных Таblе3 в форме №2. Для этого в инспекторе объектов компонента Table3 (в DataModule5) установим свойство IndexFieldNames в значение "DatPrih;Material" путем выбора из выпадающего списка, содержащего названия индексных полей, определенных для каждого существующего индекса таблицы Prihod.DB. После этого войдем еще раз в редактор колонок DBGrid и при помощи мыши "перетащим" столбец DatPrih так, чтобы он предшествовал столбцу Material. Откомпилируем приложение и запустим его на выполнение. Как видно из рис. 34, набор данных Table2, ассоциированный с таблицей БД Prihod.DB, в приложении отсортирован по дате прихода, а внутри каждой даты прихода - по наименованию материала.
Создание вычисляемых полей на экранной форме
Если необходимо в форме №3 создать вычисляемое поле, значение которого вычисляется по значениям других полей, поступают так:
-
В редакторе полей необходимо создать новое поле, пометив его как Calculated. Для этого нужно перейти в DataModule5, сделать текущим (при помощи мыши) необходимый НД (Table2), нажать правую кнопку мыши, выбрать в меню Field Editor и снова нажать правую кнопку мыши и выбрать в меню New Field. Затем в окне диалога необходимо указать имя поля, его тип и для строковых полей – длину (рис. 35).
Для нового поля будет создан компонент TField, доступ к которому отныне можно осуществлять в редакторе полей.
-
Для компонента НД (Table2), к которому принадлежит вычисляемое поле, необходимо определить обработчик события OnCalcFields.
Например, для НД Table2, ассоциированному с ТБД «Приход», будем заносить в вычисляемое поле Table2Vychisl значение «Да», если в поле Table2Kolvo этой записи содержится значение больше 100. В противном случае в поле Table2Vychisl будем заносить пустое значение:
procedure TDataModule5.Table2CalcFields(DataSet: TDataSet);
begin
IF Table2Kolvo.Value > 100 Then
Table2Vychisl.AsString := 'Да'
ELSE
Table2Vychisl.AsString := ' ';
end;
Если свойство набора данных AutoCalcFields установлено в True, событие OnCalcFields наступает и при модификации значений невычисляемых полей в режимах dsInsert и dsEdit данного НД или НД, реляционно с ним связанного (когда установлены ограничения целостности в самой ТБД, а не тогда, когда они подразумеваются).
Процедура-обработчик события OnCalcFields содержит реализацию алгоритма вычисления значения вычисляемого поля или группы полей. Необходимо помнить, что в этом обработчике значение может быть присвоено только вычисляемому полю и не может – полю, определенному в структуре БД (приложение показано на рис. 36).
Замечание. Иногда бывает необходимым присваивать вычисляемым полям значения, не содержащиеся в полях других таблиц. Иными словами, иногда бывает полезным записывать в вычисляемые поля значение некоторых переменных формы. Например, пусть мы добавляем записи в НД Tbl, по некоторому алгоритму рассчитывая значения поля Summa. Пусть для расчета значения поля Summa используется переменная TekOstatok. И мы хотим значение TekOstatok для каждой записи занести в вычисляемое поле TblTO.
И здесь встречается одна сложность: занесение значения в вычисляемое поле производится в обработчике события OnCalcFields и это происходит в то время, когда значения локальной переменной TekOstatok уже утрачены.
В этой ситуации в процессе выполнения алгоритма, добавляющего записи в Tbl, приходится запоминать значения локальной переменной в каком-либо динамическом списке, а затем извлекать из него соответствующие элементы в обработчике события OnCalcFields, присваивая значения этих элементов полю TblTO.
Использования SQL-запроса для отображения данных из разных таблиц на экранной форме
Создадим форму для отображения данных из нескольких таблиц. Для этого в контейнере TDataModule5 расположим компонент TQuery (страница Data Access палитра компонентов). По умолчанию его имя Query1. Установим его свойство DatabaseName в PRIMER. Расположим компонент TDataSource (имя DataSource4). Установим его свойство DataSet в значение Query1.
Расположим в форме №4 компонент TDBGrid. Установим его свойство DataSource в значение DataSource4.
В инспекторе объектов для компонента Query1 найдем свойство SQL и нажмем кнопку . Затем в появившемся окне редактора наберем текст SQL-запроса
SELECT P.DatPrih, P.Material, P.Kolvo,Т.Zena,
(P.Kolvo * T.Zena) As Stoim
FROM Materialy T, Prihod P
WHERE T.Material = P.Material
ORDER BY P.DatPrih, P.Material
и нажмем кнопку Ok.
После этого установим свойство Query1.Active в значение True. Набор данных Query1 содержит сведения о приходе материала на склад. В составе записи этого набора присутствуют поля DatPrih (дата прихода), Material (название материала), Kolvo (количество прихода), Zena (цена за ед. измерения данного материала), Stoim (стоимость прихода материала). Как видно из текста запроса в свойстве SQL, набор данных "собирается" из двух таблиц БД PRIMER, Materialy.DB и Prihod.DB. При этом соединяются записи из этих таблиц БД, имеющие одинаковое значение поля Material (рис. 37).
В форме №1 в пункт Отчет введем следующий код:
Form1.Visible := False;
Form4.Visible := True;
Заметим, что в набор данных Query1 нельзя добавить новые записи и нельзя изменить или удалить существующие записи в наборе данных. Это происходит потому, что тип набора данных, "собираемого" более чем из одной таблицы БД, является доступным только для чтения.
4.3.4. Создание отчетных форм и установление их
доступа к БД и организация обработки данных
Создание отчетных форм можно представить как всякая форма и рассмотреть в данной главе вместе с экранными формами. Однако формирование отчета имеет свои особенности. Кроме того, процесс формирование отчетов можно рассмотреть отдельно от вопросов СУБД. Формирование отчетных форм более или менее отдельный вопрос из-за того, что отчет включает три вида компонентов. Это экранная форма отчета в виде текста и таблицы, форма отчета выводимые на бумажные носители, графические материалы и материалы, формируемые в виде электронных файлов.
Поэтому все эти вопросы вынесем в отдельную главу и в ней рассмотрим вопросы формирования отчетов различного вида.
4.3.5. Запуск и проверка работы системы
Разрабатываемую систему время от времени следует запускать на исполнение и проверять ее работоспособность. Причем проверка работоспособности системы можно проводить на любой стадии создания, не обязательно полностью завершать ее создание, достаточно получить минимальную конфигурацию. Минимальную конфигурацию составляет БД и одна экранная форма, которая обращается к БД.
Для запуска системы предварительно следует запомнить все созданные компоненты.
Запуск системы осуществляется по команде: Rиn|Rиn. Запуск системы можно осуществить и с помощью горячей клавиши F9.
В случае зависания системы или при отсутствии выхода из системы прерывание работы осуществляется по команде Rиn|Program Reset.
После прерывания работы системы можно продолжать ее разработку или отладку.
Работа полного варианта системы, без отчетной части системы, начинается с отображения на экране формы меню. Далее пользователь системы может с помощью меню переходить на любую другую экранную форму и вернуться на главное меню системы.
Если порядок отображения экранных форм не соответствует желаемому варианту, то его можно менять в поле Main Form с помощью элемента меню Proect|Options закладка Forms.
Заключение по разделу
Создание СУБД для решения поставленной задачи сводится к следующему:
1. Формирование экранной формы для меню.
2. Формирование экранной формы для отображения БД. Причем:
-формирование экранной формы для отображения данных одной таблицы;
-формирование экранной формы для отображения 2-х таблиц (отображение данных двух таблиц без учета связи между ними; отображение данных таблиц с учетом связи между таблицами);
-включение в состав экранной формы вычисляемого поля;
-создание экранной формы с использованием SQL-запроса.
3. Формирования экранной формы для ввода данных в БД с кнопками навигации и управления состоянием БД.
Создание отчетных форм в delphi
Результаты работы системы необходимо распечатать на принтере или хранить в виде файла. Для этой цели создается отчетная форма.
Создание отчетной формы и организация отчета процедура, несколько отличающая от процедуры создания экранной формы, поэтому эти материалы рассмотрим в отдельной главе.
Возможны различные варианты создания отчетов с предварительным отображением на экране:
- отображение таблицы на экране, а затем выбор записи из нее для отчета;
- отображение отчета на экране с выбранной строки;
- отображение отчета.
5.1. Компоненты для построения отчетов
На странице палитры компонентов QReport Delphi имеется более двадцать компонентов, применяемых для построения отчетов. Основными из, которых являются следующие:
TQuickRep, TQRBand, TQRSubDetail, TQRGroup, TQRLabel,
TQRDBText, TQRExpr, TQRSysDat, TQRMemo, TQRRichText,
TQRDBRich Text, TQRShape, TQRImage, TQRChart.
Назначение этих компонентов следующие.
-
TQuickRep – является базовым для всех остальных, определяющий поведение отчета в целом. Другие компоненты определяют составные части отчета:
-
TQRBand – заготовка для расположения данных, заголовков, титула отчета и др.; отчет, в основном, строится из компонентов TQRBand, которые реализуют:
-
область заголовка отчета;
-
область заголовка страницы;
-
область заголовка группы;
-
область названий столбцов отчета;
-
область детальных данных, предназначенную для отображения данных самого нижнего уровня детализации;
-
область подвала группы;
-
область подвала страницы;
-
область подвала отчета.
-
TQRSubDetail - определяет область, в которой располагаются данные подчиненной таблицы при реализации в отчете связи Master-Detail н основе существующей связи между ТБД;
-
TQRGroup - применяется для группировок данных в отчете;
-
TQRLabel - позволяет разместить в отчете статический текст;
TQRDBText - позволяет разместить в отчете содержимое поля набора данных;
-
TQRExpr - применяется для вывода значений, являющихся результатом вычисления выражений; алгоритм вычисления выражений строится при помощи редактора формул данного компонента;
-
TQRSysDate - служит для вывода в отчете даты, времени, номера страницы, счетчика повторений какого-либо значения и т.д.;
-
TQRMemo - служит для вывода в отчете содержимого полей комментарии
-
TQRRichText - служит для вывода в отчете содержимого полей форматированных комментариев;
-
TQRDBRich Text - служит для вывода в отчете содержимого полей форматированных комментариев, источником которых является поле набора данных;
-
TQRShape - служит для вывода в отчете графических фигур, например, прямоугольников;
-
TQRImage - служит для вывода в отчете графической информации, источником которой является поле набора данных;
-
TQRChart - служит для встраивания в отчет графиков.
Компонент TQuickRep
Компонент TQuickRep определяет поведение и характеристики отчета в целом. При размещении этого компонента форме в ней появляется сетка отчета (рис. 38). В дальнейшем в этой сетке располагаются составные части отчета, например, группы TQRBand (рис. 39).
Перечислим важнейшие свойства, методы и события компонента TQuickRep.
Свойства данного компонента таковы.
1.Property Bands: TquickRepBands.
Данное свойства состоит из множества логических значений (False/True), которые определяют включение в отчет отдельных видов составляющих:
-
HasColumnHeader - заголовка столбцов отчета;
-
HasDetail - детальной информации;
-
HasPageFooter - подвала страницы;
-
HasPageHeader - заголовка страницы;
-
HasSummary - подвала отчета;
-
HasTille - заголовка отчета.
2.Property DataSet: TdataSet.
Оно указывает на набор данных, на основе которого и создается отчет. Обычно для выдачи отчета используется один НД.
Если нужно вывести связанную информацию из нескольких таблиц БД, ее объединяют в одном НД при помощи оператора SELECT. В этом случае в качестве НД для отчета может использоваться компонент TQuery. Информацию из нескольких связанных НД можно включать в отчет, если эти наборы данных связаны в приложении отношением Master-Detail. В этом случае в качестве НД отчета указывается Master-набор, а ссылка на соответствующие Detail-наборы осуществляется в компонентах TQRSubDetail.
Если в отчет нужно включить информацию из несвязанных наборов данных применяют композитный отчет, то есть отчет, составленный из группы других отчетов.
3.Property Frame: TQRFrame.
Данное свойства определяет параметры рамки отчета:
-
Color - цвет линии рамки;
-
DrawBottom - определяет, следует ли выводить линию снизу;
-
DrawLeft- определяет, следует ли выводить линию слева;
-
DrawRight- определяет, следует ли выводить линию справа;
-
DrawTop- определяет, следует ли выводить линию сверху;
-
Style - определяет стиль линии;
-
Width • определяет ширину линии в пикселях.
4.Property Page: TQRPage - определяет параметры страницы.
5.Property PrinterSettings: TquickRepPrinterSettings - определяет параметры принтера.
6.Property PrintIfEmpty: Boolean - указывает (True), что следует печатать отчет даже в том случае, если он не содержит данных.
Методы данного компонента следующие.
7.Procedure NewPage;
Данный метод выполняет переход на новую страницу. Может использоваться в обработчиках событий компонентов отчета BeforePrint или AfterPrint и не может - в обработчиках событий OnPrint, OnStartPage и OnEndPage.
8.Procedure Preview - выводит отчет в окно предварительного просмотра.
Чтобы во время разработки отчета просмотреть в окне предварительного просмотра содержимое отчета в том виде, как он будет выводиться на печать, необходимо:
-
выбрать отчет при помощи мыши;
-
нажать правую кнопку мыши;
-
во всплывающем меню выбрать элемент Preview.
Следует заметить, что при этом не будут видны некоторые данные, например, значения вычисляемых полей наборов данных. Они будут выводиться только во время выполнения.
9.Procedure Print - печатает отчет на принтере.
10.Procedure PrinterSetup -обеспечивает установки параметров принтера.
События данного компонента таковы.
11.Property AfterPreview : TQRAfterPreviewEvent -наступает после закрытия окна предварительного просмотра отчета.
12.Property AfterPrint: TQRAfterPrintEvent -наступает после вывода отчета на печать.
13.Property BeforePrint: TQRBeforePrintEvent - наступает в момент генерации отчета, до выдачи окна предварительного просмотра отчета и до вывода отчета на печать.
14.Property OnEndPage : procedure(Sender : TObject) - наступает в момент подготовки к генерации последней страницы отчета
15.Property OnStartPage : procedure(Sender : TObject) - наступает в момент подготовки к генерации первой страницы отчета.
Компонент TQRBand
Компоненты TQRBand являются основными составными частями отчета и используются для размещения в них статического текста и данных.
Данный компонент имеет следующие свойства.
1.Рroperty BandType: TQRBandType - определяет месторасположение компонента в отчете и его поведение.
Возможные значения этого свойства таковы.
-
rbTitle - определяет компонент заголовка отчета. Информация, размещенная в компоненте TQRBand, располагается перед всеми другими частями отчета. Этот вид компонента TQRBand используется для bi заголовочной информации отчета.
-
rbPageHeader - определяет компонент заголовка страницы. Информация, размещенная в компоненте с этим значением свойства Band выводится всякий раз при печати новой страницы отчета прежде всех иных частей отчета (но после информации, размещенной в компоненте заголовка отчета - для первой страницы).
-
rbDetail - компонент детальной информации. Выводится всякий раз при переходе на новую запись в НД отчета. Отчет печатается для всех записей НД, определяемого свойством отчета DataSet, начиная с первой и заканчивая последней. Позиционирование на первую запись и последовательный перебор записей в НД осуществляется компонентом TQuickRep автоматически.
-
rbPageFooter - компонент подвала страницы. Выводится для каждой страницы отчета после всех иных данных на странице.
-
rbSummary - компонент подвала отчета. Выводится на пост странице отчета после всей иной информации, но перед под последней страницы отчета.
-
rbGroupHeader - компонент заголовка группы. Применяется при группировках информации в отчете. Выводится всякий раз при выводе новой группы.
-
rbGroupFooter - компонент подвала группы. Применяется при группировках информации в отчете. Выводится всякий раз при окончании вывода группы, после всех данных группы.
-
rbSubDetail - компонент для выдачи детальной информации из подчиненного набора данных, при выводе в отчете информации из двух или более наборов данных, связанных в приложении при помощи механизма Master-Detail. Это значение присваивается компоненту автоматически, когда генерируется компонент TQRBand при размещении в форме компонента TQRSubDetail. Программа не должна устанавливать это значение в свойство BandType.
-
rbColumnHeader - компонент для размещения заголовков столбцов. Размещается в отчете на каждой странице после заголовка страницы.
-
rbOverlay - используется для совместимости с более ранними версиями отчетов.
2.Рroperty Enabled: Boolean - указывает, печатается в отчете (True) или нет (False) информация, содержащаяся в компоненте TQRBand.
3.Рroperty ForceNewPage: Boolean - указывает, должна ли информация в составе TQRBand всегда печататься с новой страницы (True) или нет (False).
Компонет TQRBand имеет следующее событие.
Рroperty BeforePrint: TQRBeforePrintEvent - наступает перед печатью информации, размещенной в области компонента TQRBand.
5.2. Способ создания простейшего отчета с помощью
компонентов TQuickRep и TQRBand
Компоненты TQuickRep и TQRBand являются минимально достаточными для создания простого отчета, не содержащего внутри себя группировок информации.
Таблица БД Prihod.DB содержит сведения о поступлении материалов на склада. В состав ТБД входят поля
-
N_Prih - уникальный номер события прихода материала;
-
DataPrih – дата поступления;
-
MATERIAL - наименование материала;
-
KOLVO - количество единиц поступившего материала.
Создадим простейший отчет, состоящий из заголовка и сведений о поступлении материала. В отчет включаются все факты поступления материала. Сортировка производится по номеру события поступления материала.
Разместим в форме №6 компонент TTable (имя Table1), свяжем с таблицей БД Prihod.DB и откроем его (Active = True). Разместим в форме компонент TQuickRep (имя QuickRep1) из страницы QReport палитры компонентов. Установим в свойство DataSet отчета значение Table1, назначив, таким образом, отчету набор данных, записи из которого будут выводиться в отчет. Добавим в отчет компонент TQRBand (имя QRBand1). Свойство BandType компонента QRBandl по умолчанию установлено значение rbTitle, то есть компонент QRBand1 определяет заголовок отчета. Разместим в пространстве отчета, занимаемом компонентом QRBand1, компонент TQRLabel (статический текст) с именем QRLabel1. Установим свойство Caption этого компонента значение 'Поступление материалов на склад', установим в свойстве Font жирный наклонный шрифт высотой 16 пунктов. Вид отчета показан на рис. 40.
Теперь разместим в отчете данные, соответствующие текущей записи таблицы Prihod. Для этого поместим в отчет новый компонент TQRBand (имя QRBand2) и установим в его свойство BandType значение rbDetail. Затем разместим в группе четыре компонента TQRDBText с именами QRDBText1 ... QRDBText4. Свяжем данные компоненты соответственно с полями НД - N_Prih, MATERIAL, DataPrih, KOLVO. Для этого в свойство DataSet каждого компонента QRDBText установим значение Table1, а в свойство DataField - значение имени соответствующего поля. Вид отчета показан на pис. 41.
Для просмотра получившегося отчета щелкнем по нему правой кнопкой мыши и из всплывающего меню выберем элемент Preview. Получим окно предварительного просмотра отчета (рис. 42).
Вызов окна предварительного просмотра организуем при нажатии на кнопку «Просмотр» из формы №4.
Для этого добавим в форму №4 компонент TButton. Изменим заголовок этой кнопки (свойство Caption), используя инспектор объектов, на «Просмотр». Определим для кнопки обработчик события нажатия кнопки, OnClick:
Form6. QuickRep1.Preview;
Представление заголовков столбцов с помощью компонента TQRBand
Компонент TQRBand, у которого в свойство BandType установлено значение rbColumnHeader, используется для представления заголовков столбцов. Заголовки столбцов определяются при помощи компонетов TQRLabel.
В отчете, рассмотренном в предыдущих разделах, добавим компонент TQRBand (имя QRBand3) и установим в его свойство BandType значение rbColumnHeader. Разместим в пространстве отчета, определяемом QRBand3, четыре компонента TQRLabel (имена QRLabel2 ... QRLabel5) и установим в свойства Caption этих компонентов соответственно значения «№ Прихода», «Наименование материала», «Дата», «Количество». В свойстве Font данных компонентов установим режим подчеркивания шрифта, а сам шрифт определим как наклонный.
Выйдем в окно предварительного просмотра отчета. Для каждой страницы отчета вверху страницы будут выводиться названия столбцов (рис. 43).
Оформление заголовки и подвала страницы отчета с помощью компонента TQRBand
Компонент TQRBand, у которого в свойство BandType установлено значение rbPageHeader, используется для показа заголовка страницы. Он выводится для каждой новой страницы перед выводом другой информации. Компонент TQRBand, у которого в свойство BandType установлено значение rbPageFooter, используется для показа подвала страницы. Он выводится для каждой страницы после вывода любой иной информации.
Информация в заголовке и подвале страницы может формироваться на основе статического текста (компоненты TQRLabel), значений полей (компоненты TQRDBText) и результатов вычисления выражений (компонеты TQRExpr).
В отчете, рассмотренном в предыдущих разделах, разместим компонент TQRBand (имя QRBand4) и установим в его свойство BandType значение rbPageHeader. Не будем размещать в заголовке страницы никакого текста, просто отчеркнем линию вверху страницы. Для этого установим в свойство компонента заголовка страницы Frame. DrawTop значение True, что обеспечивает вывод линии по верхнему краю области, занимаемой компонентом.
Аналогичным образом определим в отчете компонент подвала страницы (имя QRBand5) и установим в его свойство BandType значение rbPageFooter, а в Frame. DrawBottom значение Тrue, что обеспечивает вывод линии по нижнему краю области, занимаемой компонентом.
Войдя в режим предварительного просмотра отчета, увидим, что вверху и внизу каждой страницы отчета выводятся линии.
Представление в отчете вспомогательной и системной информации с помощью
компонента TQRSysData
Компонент TQRSysData используется для показа вспомогательной и системной информации. Вид показываемой информации определяется свойством
property Data : TQRSysDataType;
Ниже указаны возможные значения этого свойства.
-
qrsColumnNo - номер текущей колонки отчета (для одноколоночного отчета всегда 1).
-
qrsDate - текущая дата.
-
qrsDate Time - текущие дата и время.
-
qrsDetailCount - число записей в НД; при использовании нескольких НД - число записей в master-наборе. Для случая, когда НД представлен компонентом TQuery, эта возможность может быть недоступной, что связано с характером работы компонента TQuery, который возвращает столько записей, сколько необходимо для использования в текущий момент, а остальные предоставляет по мере надобности;
-
qrsDetaUNo - номер текущей записи в НД. При наличии нескольких наборов - номер текущей записи в master-наборе.
-
qrsPageNumber - номер текущей страницы отчета.
-
qrsPageCount - общее число страниц отчета.
-
qrsReport Title - заголовок отчета.
-
qrsTime - текущее время.
Разместим в компоненте подвала отчета QRBand5 два компонента TQRSysData (имена QRSysDatal... QRSysData2). В свойство Data первого из них установим значение qrsDate (текущая дата), второго - значение qrsPageNumber (номер текущей страницы отчета). Войдем в режим предварительного просмотра результатов отчета. Теперь в подвале каждой страницы отчета выводятся номер страницы и текущая дата.
5.3. Способы группировки данных в отчете
Выше мы рассмотрели отчет, в котором информация о поступлении материалов из ТБД Prihod.DB на склад выводилась "как есть". Такое представление информации в отчете не всегда информативно. Пусть, например, в нашем случае требуется сгруппировать информацию по материалам.
Для группировки информации используется компонент TQRGroup. Его свойство Expression указывает выражение. В группу входят записи НД, удовлетворяющие условию выражения. При смене значения выражения происходит смена группы. Для каждой группы, если определены, выводятся заголовок группы и подвал группы. В качестве заголовка группы служит компонент TQRBand со значением свойства ВапаТуре, равным rbColumnHeader. В качестве подвала группы служит компонент TQRBand со значением свойства ВапаТуре, равным rbGroup Footer.
Свойство FooterBand компонента TQRGroup содержит ссылку на компонент подвала группы.
В заголовке группы, как правило, выводится выражение, по которому происходит группировка, и различные заголовки, если они нужны. В подвале группы обычно выводится агрегированная информация - суммарные, средние и т.п. значения по группе.
Пример. Построим новый отчет о поступлении материала на склад, в котором информация группируется по наименованию материала. Для этого в форме №7 определим набор данных отчета (компонент ТТаblе, имя Table1, свойства TablelName - Prihod.DB, Active - True). Установим у НД текущим индекс по полю Material (в свойстве FieldIndexNames или IndexName). Разместим в отчете:
-
заголовок отчета - компонент TQRBand с именем QRBand1, свойство ВапаТуре = rbTitle;
-
заголовок столбцов - компонент TQRBand с именем QRBand2, свойство ВапаТуре = rbColumnHeader;
-
группу - компонент TQRGroup с именем QRGroup1.
-
область детальной информации - компонент TQRBand с именем QRBand3, свойство ВапаТуре = rbDetail;
-
подвал группы - компонент TQRBand с именем QRBand4, свойство ВапаТуре = rbGroupFooter.
В компоненте QRGroup1 установим:
-
в свойство FooterBand значение QRBand4;
-
в свойство Expression значение Table1.MATERIAL, которое является формулой и строится в редакторе формул.
Поскольку свойство Expression не визуализирует значения выражения, необходимо разместить в группе компонент TQRExpr (имя QRExpr1) и определить значение его свойства Expression так, чтобы оно содержало Table1.MATERIAL (Рис. 44).
В компоненте подвала группы QRBand4 будем подсчитывать сумму по полю Kolvo (сумму поступившего конкретного материала). Для этого разместим в подвале группы компонент TQRExpr (имя QRExpr2) и определим значение его свойства Expression так, чтобы оно содержало формулу SUM(Table1.KOLVO).
В группе детальной информации разместим компоненты TQRDBText, связанные с полями N_Prih, Material, DataPrih и Kolvo набора данных (свойства DataSet и DataField).
Заполним другие области отчет статическим текстом, как это показано на рис. 45.
На рис. 46 показан отчет в режиме предварительного просмотра.
Вызов окна предварительного просмотра отчета организуем при нажатии на кнопку "Группа" из формы №4. Добавим в форму №4 компонент TButton, Определим для кнопки обработчик события нажатия кнопки, OnClick:
Form7. QuickRep1.Preview;
На рис. 46 показан подвал одной из групп - там выводится информация о суммарном приходе материала.
5.4. Формирование отчета с использованием фильтра
Свойство Filtered, установленное в True, инициирует фильтрацию, условие которой записано в обработчике события OnFilterRecord. Например, если в НД установлен фильтр
begin
Accept := DataSet['KOLVO'] >= 500;
End;
то установка Table1.Filtered в True приведет к фильтрации; в результирующем наборе данных будут показаны только записи, у которых поле 'KOLVO' содержит значение 500 и более.
Установка Filtered в False приведет к отмене фильтрации, условия которой указаны в событии OnFilterRecord.
Тестирование и доработка приложения. Для выявления недоработок необходимо провести испытания приложения во всех режимах функционирования.
После тестирования выяснилось, что у нас остался не задействованным пункт меню Ввод/Название материала. Создадим форму для добавления новых материалов и их характеристик в существующий список материалов. Разместим на нем компонент TDBGrid, установим свойство DataSource в значение DataSource1. Добавим в форму компонент кнопки TButton, дадим имя этому компоненту (свойство Name) CancelBtn, изменим заголовок кнопки (свойство Caption) на "Закрыть". Свяжем с кнопкой код, который будет выполняться при нажатии на кнопку пользователем. Для создания процедуры обработки этого события – OnClick, находясь в форме, дважды щелкнем мышью на кнопку "Закрыть". В редакторе кода напишем следующий код
Сlose;
Form1.Visible := True;
Перейдем на форму № 1 и напишем код для пункта меню Ввод/Название материала код вызова формы № 8:
Form1.Visible := False;
Form8.Visible := True;
На этом подготовка приложения считаем завершенной.
Сопровождение системы. Но, как говорится жизнь не стоит на месте, так и наше разработанное приложение может претерпевать изменения в связи с изменившимися внешними условиями. Для какого-то момента времени может потребоваться отчет другой формы, например, показать на какую сумму поступило материалов на склад.
Доработаем наше приложение с учетом новых требований.
Доработка №1.
Создадим новую форму отчета (форма №9). Разместим в форме компонент TQuickRep (имя QuickRep1), но обращение к набору данных организуем через Query1. Для этого свойство DataSet установим как DataModule5.Query1. Добавим другие компоненты и области отчета заполним статическим текстом, как это показано на рис. 47.
В конце отчета добавим итоговую сумму всех поступивших материалов в словесном виде. Для этого добавим компонент TQRBand с именем QRBand4, свойство ВапаТуре = rbSummary.
Разместим в QRBand4 компонент TQRLabel (имя QRLabel7).
Перейдем в Unit4 и добавим в обработчик события OnClick кнопки "Итог" такой код:
procedure TForm4.Button5Click(Sender: TObject);
var ss: String;
begin
Str(TempTotal,ss);
Form9.QRLabel7.Caption := SumNumToFull(TempTotal);
Form9.QuickRep1.Preview;
end;
В Unit5 определим переменную TempTotal и добавим код вычисления итоговой суммы поступивших на склад материалов TempTotal.
var
DataModule5: TDataModule5;
TempTotal: Integer;
implementation
Двойным нажатием мыши на свойство AfterOpen в инспекторе объектов откроем Unit5 и добавим следующий код:
procedure TDataModule5.Query1AfterOpen(DataSet: TDataSet);
begin
Query1.First;
TempTotal := 0; { use temp for efficiency }
while not Query1.EOF do
begin
TempTotal := TempTotal + Query1Stoim.Value;
Query1.Next;
end;
SumNumToFull(TempTotal);
end;
Добавим в проект модуль перевода числа в запись прописью Writesum.pas, используя меню Project|Add to Project . Листинг модуля приведен в Приложении.
Продолжим формирование отчета. В поле QRBand4 разместим компонент TQRLabel (имя QRLabel8), свойство Caption изменим на "Итого:". Добавим еще компонент TQRExpr (имя QRExpr1) и определим значение его свойства Expression так, чтобы оно содержало формулу SUM(Table1.Stoim). На Рис.48 показан итоговый отчет в окне предварительного просмотра.
Доработка №2.
Для подготовки отчета Excel имеет большие возможности (графические представления и т.д.). Кроме того иногда бывают для бизнес-процесса удобно ряд операции выполнить в среде Excel. Поэтому, чтобы использовать этот ресурс с помощью процедуры OLE необходимо передать данные в Excel.
Чтобы продемонстрировать это приведем пример-задачу, который на этапе сопровождения необходимо выпольнить.
ПРИЛОЖЕНИЯ
П1. Графические материалы этапов создания системы в среде Delphi
Рис.1 Интегрированная среда разработки Delphi
Таблица «Материалы»
Название материала
|
Единица измерения материала
|
Цена материала
|
|
|
|
|
|
|
Таблица «Поступление материалов»
Номер приходного материала
|
Название материала
|
Дата поступления
|
Количества поступившего материала
|
|
|
|
|
|
|
|
|
Рис. 2. Структура таблиц, разрабатываемой базы данных
Таблица "Материалы"
Назначение поля таблицы
|
Конструкция поля таблицы
|
Название
|
Тип
|
Длина
|
Заносится название материалов, которые на склад поступили или поступят
|
Material
|
Строка
|
20
|
Единица измерения материала
|
Edizm
|
Строка
|
10
|
Цена единицы материала
|
Price
|
Целочисленный
|
|
Таблица "Поступление материалов"
Назначение поля таблицы
|
Конструкция поля таблицы
|
|
Название
|
Тип
|
Длина
|
Номер прихода, материала подтупленного на склад
|
N_Prih
|
Автоинкремент
|
|
Название материала
|
Material
|
Строка
|
20
|
Дата поступления материала
|
DatPrih
|
Дата
|
|
Количество материала
|
Kolvo
|
Целочисленный
|
|
Рис.3. Структура физической модели таблиц разрабатываемой базы данных
Рис. 4 Окно выбора типа драйвера базы данных
Рис. 5. Окно параметров псевдонима базы данных
Рис. 6. Утилита Database Desktop: окно определения структуры таблицы БД
Рис. 7. Выбор типа поля
страница 1 страница 2
|