Задания к самостоятельной работе
1. Создать компонент, позволяющий в строке ввода задавать целые числа. В компоненте предусмотреть возможность задания допустимого диапазона значений, количества позиций, выравнивания внутри строки ввода.
2. Создать компонент, позволяющий в строке ввода задавать вещественные числа. В компоненте предусмотреть возможность задания допустимого диапазона значений, количество позиций на целую и дробную части.
3. Создать компонент, позволяющий вводить данные в следующем виде:
Второе число должно быть всегда больше первого!
4. Создать компонент, который бы позволял перевести курсор в место начала подстроки, которая задается в программе, использующей новый компонент. Если такой фрагмент отсутствует, курсор перевести в конец текста.
5. Написать компонент, который предоставлял бы пользователю следующую возможность: при двойном щелчке мыши над панелью панель разворачивается на .
6. Написать компонент, который бы позволял ввести вещественное число, а при выходе из поля редактирования в нем отображалось (или или или ).
7. Редактор текста: выполнить компонент, который бы предоставлял следующую возможность: по желанию пользователя автоматически каждое слово начинать с большой буквы, а все другие буквы слова должны быть маленькими.
Лабораторная работа №7 (10 баллов).
Создание базы данных
Данная лабораторная работа предназначена для знакомства с основами работы с реляционными базами данных. Условно можно считать, что реляционная база данных состоит из набора таблиц, которые в свою очередь состоят из однотипных записей с несколькими полями. Обычно записи в таблицах представляют в виде горизонтальных рядов, а в колонках -значения соответствующих полей.
Базы данных бывают серверного типа, когда они хранятся в специальном формате, и обращение к ним производится только через специальные программы-серверы баз данных, а также бывают локальные базы. В локальных базах обычно отдельные таблицы хранятся в виде одного или нескольких файлов, при этом базой данных считается каталог на диске, содержащий все эти файлы. В нашей работе мы будем работать с локальной базой данных в формате Paradox 7.
В данной работе будет необходимо создать простое приложение для ведения учета книг в домашней библиотеке. Для каждой книги в библиотеке должна быть создана запись в базе данных со следующими полями: фамилия автора, название книги, ее тип и фамилия того, кто взял книгу. Тип книг и список читателей необходимо оформить в виде таблиц-справочников, которые можно будет наполнять по мере необходимости. Просмотр списка книг должен производиться в одном из трех режимов: просмотреть все книги, книги заданного типа, либо книги, находящиеся у выбранного читателя.
В рамках работы необходимо будет освоить программу Database Desktop, предназначенную для создания и редактирования таблиц баз данных. Используя эту программу, нужно будет создать 3 таблицы, которые затем будут подключены к нашей программе в среде Delphi.
Описание работы
Разработка любой базы данных начинается с проектирования её' логической и физической структур. Физическая схема нашей базы изображена на рис. 24. На ней слева представлена главная таблица, имеющая 4 поля: имя автора, название книги, код типа книги и код читателя
Рис. 24. Физическая схема БД домашней библиотеки
Справа представлены две таблицы-справочника, в которых хранится соответствие кода типа книги с текстовым описанием типа и кода читателя с его текстовым именем. Для быстрого поиска и сортировки содержимого таблиц они должны быть проиндексированы по полям, отмеченным звездочками. В первой таблице по полям Author и Name должен быть создан первичный индекс, а по полям Туре и User два вторичных. В таблицах-справочниках индекс должен быть создан по полям ID. Он будет использоваться для быстрого поиска текстового описания по коду.
В таблицах-справочниках для полей ID необходимо указать тип данных Autoincrement, что означает, что при добавлении новой записи в таблицу для значения этого поля будет автоматически браться уникальное целочисленное значение. Тип данных Alpha означает текстовую строк)'. Этот . тип имеет целочисленный параметр, означающий максимальную длину строки, которую можно поместить в это поле.
Для физического создания таблиц нашей базы данных можно воспользоваться программой Database Desktop, входящей в состав Delphi. Её можно запустить из Delphi с помощью команды меню Tools {Database Desktop. После ее запуска необходимо выбрать команду меню Filej Working Directory... и затем в диалоге указать каталог, в котором мы будем сохранять таблицы. Пусть это будет тот же каталог, в котором мы сохраняем файлы проекта Delphi.
Затем с помощью команды меню FiJe|New|Table... необходимо создать 3 таблицы, указав список полей таблиц, их типы, а также создать индексы. При выборе этой команды, в первую очередь, в диалоговом окне (рис. 25) необходимо выбрать тип таблицы. Для нашей задачи лучше всего выбрать тип «Paradox 7», т.к. он обладает максимальными возможностями среди других доступных форматов не серверного типа.
После выбора типа таблицы откроется окно создания таблицы формата «Paradox 7», в котором в первую очередь необходимо сформировать список всех полей таблицы. На рис. 25. приведен внешний вид программы Database Desktop в процессе создания новой таблицы, которую мы потом должны сохранить под именем Books.db. В первой колонке списка полей указывается имя поля, во второй — его тип. Для выбора нужного типа можно либо нажать клавишу с первой буквой нужного типа, либо нажать пробел и на экране появится полный список всех доступных типов. В нашей работе нам понадобятся только типы Alpha для представления строковых значений, Long Integer для представления целочисленных кодов типа книги и кода читателя, а также тип + (Autoincrement).
|
Рис. 25. Создание новой таблицы в Database Desktop
Третья колонка списка полей предназначена для задания размера поля. В нашем случае она имеет смысл только для строковых полей. Размер поля определяет максимальную длину строки, которую можно поместить в данное поле.
Четвертая колонка позволяет указать поля, которые будут входить в первичный индекс. Для его задания необходимо просто нажать пробел. Индекс (ключ) используется при отображении данных в таблице в качестве критерия сортировки записей.
В нашей задаче для таблицы . Books.db понадобятся также еще 2 вторичных индекса, в которые будет входить только одно поле, - Туре и User соответственно. Для этого в правой верхней части окна создания таблицы необходимо выбрать в выпадающем списке пункт Secondary Indexes. Затем необходимо нажать . на появившуюся кнопку Define, после чего на экране появится диалог создания вторичного индекса — (рис. 27).
|
Рис. 27. Создание индекса в Database Desktop
В диалоге создания вторичного индекса необходимо выбрать в левом списке имя поля, по которому необходимо создать индекс, и нажать кнопку . При этом в правом списке отображается список полей, которые будут участвовать во вторичном индексе. В нашем случае необходимо выбрать для индекса поле Туре и нажать клавишу ОК. При этом появится окно, в котором необходимо указать имя созданного индекса. Обычно для имени индекса указывают имя поля, составляющего индекс, с добавлением слова Index. В нашем случае укажем имя Typelndex.
После этого необходимо создать еще один вторичный индекс, но уже по полю User. Аналогично сохраним этот индекс под именем UserIndex.
В дальнейшем для изменения структуры уже созданной таблицы в программе Database Desktop необходимо будет открыть её с помощью команды меню File|Open]Table, а затем выбрать команду меню Та-ble|Restructure...
После физического создания таблиц базы данных можно переходить к созданию пользовательского интерфейса к базе данных в среде Delphi.
В Delphi для подключения к таблице базы данных используется невизуальный компонент типа ТТаblе, находящийся на закладке «Database Access» палитры компонентов. В простейшем случае для обращения к реальной таблице необходимо указать только 3 свойства, приведенные в табл. 1.
Таблица 1. Основные свойства компонентов типа ТТаblе
Свойство | Тип | Комментарий |
DatabaseName | String | Имя базы данных, указанной в компоненте Database, зарегистри-рованном на компьютере в программе BDE Administrator или каталог, содержащий таблицы форматов DBase, FoxPro или Paradox |
TableName | String | Имя таблицы указанной базы данных |
Active | Boolean | Открыта ли таблица. Для открытия можно также воспользоваться методом Open, а для закрытия- Close |
Для удобства разработки компоненты баз данных обычно размещают в отдельных модулях (чтобы компоненты для доступа к базам не путались с остальными): это может быть отдельная пустая невидимая форма или специальный модуль данных (Data Module), который можно создать с помощью пункта меню File! New... В этом модуле необходимо разместить компоненты типа ТТаblе, соответствующие таблицам нашей базы данных.
|
Рис. 29. Создание подстановочного поля
Для каждого компонента TTable определен так называемый «курсор», определяющий текущую запись в таблице. Отметим особую роль таблиц-справочников в нашем приложении. Их необходимо будет редактировать при появлении новых читателей и типов книг, а также независимо перемещаться по ним для подмены кодов полей их строковыми значениями. Поэтому для этих таблиц необходимо будет поместить в модуль данных по два компонента TTable, каждый из которых имеет независимые курсоры.
Список полей таблицы представляется в свойстве таблицы Fields. Для его изменения необходимо вызвать редактор списка полей таблицы, который появляется при двойном щелчке мышкой на компоненте TTable. По умолчании список полей пуст, что означает, что он будет формироваться автоматически при открытии таблицы базы данных. Если же мы хотим каким-то образом переопределить свойства полей, то необходимо в локальном меню редактора списка полей вызвать вначале команду Add all fields для получения полного списка полей. Для создания в главной таблице подстановочных полей необходимо выбрать команду локального меню New field...
В главной таблице TableBooks для подстановки текстовых значений вместо кодов типов книг и кодов читателей будем использовать компоненты с именами TableTypesLookup и TableUsersLookup. Поэтому в главной таблице кроме реальных физических полей необходимо создать два дополнительных подстановочных (lookup) поля строкового типа: поля же с кодами необходимо скрыть от пользователя.
На рис. 29 приведен пример создания подстановочного поля типа книги LookupType, подменяющего числовой код типа книги его текстовым описанием с помощью другой таблицы-справочника TableTypesLookup.
Таблица 2. Основные свойства компонентов типа Т Field
Свойство | Тип | Комментарий | |
Alignment | TAligranent | Выравнивание текста поля при просмотре: по левой стороне, по правой или по центру | |
DisplayLabel | String | Текст метки поля, используемый, например, в качестве заголовка столбца таблицы | |
DisplayWidth | Integer | Ширина колонки таблицы по умолчанию в символах | |
FieldKind | TFieldKind | Определяет, является ли поле отражением реальных данных в физической таблице (f kData), является ли поле подстановочным (f kLookup), вычисляемым (fkCalculated) и т.д. | |
FieldName | String | Физическое имя поля для типа fkData, либо логическое для других типов | |
Readonly | Boolean | Разрешено ли изменение поля пользователем | |
Required | Boolean | Обязательно ли заполнять значение поля при модификации записи | |
Visible | Boolean | Видно ли поле в таблице по умолчании | |
LookupDataset | TDataset | Указывает на набор данных (например на таблицу), являющийся справочником | |
KeyFields | String | Имя поля таблицы, где хранится код, который надо подменить по справочнику | |
LookupKeyFields | String | Имя поля справочника с кодом | |
LookupResultField | Spring | Имя поля справочника, возвращаемого как результат подмены кода |
Создаваемые поля компонента ТТаble являются потомками класса TField. Любое поле в списке можно выбрать, и затем изменить его настройки с помощью инспектора объектов. Список основных свойств объектов типа TField приведен в табл. 2.
Рис. 30. Связывание компонент для работы с базами данных
После того как таблицы открыты, к ним можно подключать визуальные компоненты для отображения содержимого и перемещения по записям. Для этого в Delphi используется двухступенчатая схема, по которой к таблицам присоединяется один компонент типа TDataSource, а к нему, в свою очередь, все необходимые визуальные компоненты. В Delphi, как правило, имена типов визуальных компонентов для работы с базами данных начинаются с букв TDB, например, BGrid для отображения всей таблицы в виде сетки, TDBNavigator для навигации по таблице и т.д. Условно иерархия связывания визуальных и невизуальных компонентов для работы с базами данных приведена на рис. 30. В нашем приложении, таким образом, необходимо для всех отображаемых таблиц (кроме тех, которые используются в подстановочных полях) создать компоненты типа TDataSource и связать их с таблицами с помощью их свойства Dataset.
|
Рис. 31. Внешний вид главной формы приложения
Рис. 31. Внешний вид главной формы приложения
|
Рис. 32. Форма для редактирования справочника типов книг
В главной форме нашего приложения необходимо разместить компоненты с соответствии с рис. 31. В правой части надо разместить компонент TDBGrid для отображения таблицы в виде сетки. С его помощью можно редактировать содержимое таблицы, добавлять новые записи с помощью клавиши Insert, а также удалять записи с помощью комбинации клавиш Ctrl+Delete. В верхней части формы необходимо разместить компонент TDBNavigator, помогающий перемещаться по таблице, редактировать ее, вставлять и удалять записи. Обоим этим компонентам надо указать ис-. точник данных - свойство DataSource - с помощью выпадающего списка в инспекторе объектов. Но т.к. наши источники данных находятся в другом модуле, то перед этим необходимо указать, что данный модуль (главная форма) использует другой (модуль данных). Это делается в Delphi с помощью команды меню File|Use Unit..., которая по сути добавляет в секцию uses раздела implementation выбранный модуль проекта.
В левой части главной формы необходимо разместить кнопку выхода из программы и две кнопки для редактирования справочников, которые просто должны выводить на экран две другие формы простого содержания, как на рис. 32. В этих формах также необходимо указать, что надо использовать модуль данных Data, и затем просто выставить свойства DataSource. Обратите внимание, что в этих формах видно только одно строковое поле, а поле ID скрыто. Просто у этого поля в редакторе списка полей свойство Visible установлено равным False.
В левой верхней части формы необходимо разместить компоненты, позволяющие фильтровать записи в таблице в соответствии с некоторым критерием. Нам необходимо сделать три варианта: все книги, книги заданного типа и книги, находящиеся у заданного пользователя. Для извлечения данных из таблиц в соответствии с некоторым критерием в Delphi возможны несколько вариантов.
Один из вариантов заключается в задании выражения фильтра на записи в свойствах Filter и Filtered компонента TTable. Например, выражение фильтра «Type<>l and Author='Стругац*'» для главной таблицы нашего приложения позволяет выбрать только те книги, код которых отличается от 1 и имя автора начинается с букв ' Стругац'.
Другой вариант заключается в создании связки таблиц «главная-подчиненная» (master-detail) по некоторым полям. Тогда при выборе записи в главной таблице в подчиненной таблице будут отображаться только те, код связи которых совпадает с текущей записью в главной. Эта связка аналогична той, что используется в подстановочных полях: там главной таблицей являлась TableBcoks, а подчиненными - справочники TableTypes HTableUsers.
В данном случае необходимо, чтобы, наоборот, таблицы TableTypes и Tablellsers были главными, a TableBooks - подчиненной. При выборе типа книги или пользователя в таблице книг должны выбираться только определенные записи. Для организации такой связи а подчиненной таблице необходимо указать три свойства, краткое описание которых приведено в табл. 24.
Таблица 24. Свойства компонентов типа ТТаble для организации связи с главной таблицей в режиме подчиненной
Свойство | Тип | Комментарий . |
MasterSource | TDataSource | Источник данных с главной таблицей |
IndexFieldNames | String | Имя индексированного поля подчиненной таблицы, по которому осуществляется связь |
MasterFields | String | Имя поля главной таблицы, текущее значение которого используется для фильтрации записей в подчиненной |
Итак, вернемся к нашему приложению. В левой верхней части главной формы следует разместить три радио-кнопки, при выборе которых необходимо динамически менять свойства MasterSource, IndexFieldNames и MasterFields компонента TableBooks. Для выбора типа книг или пользователя для фильтрации необходимо разместить около радио-кнопок компоненты типа TDBLookupComboBox, при раскрытии которых в ниспадающем списке будут отображаться записи таблиц TableTypes и TableUsers. Для этого нужно у компонентов TDBLookupComboBox установить свойства ListSource в значение DataSourceType (или DataSourceUsers); ListFields равным «Booktype» (или «UserName») и свойство KeyField равным ID.