Давно известно, что лучше один раз увидеть, чем сто раз услышать. При изучении программных средств еще лучше один раз попробовать. Поэтому давайте попрактикуемся в создании простейшего приложения, работающего с базами данных, пройдя при этом все этапы - от создания псевдонима базы данных до запуска разработанного приложения.
Если Вы никогда не проектировали приложений для работы с базами данных в
Delphi, приобретенный опыт поможет Вам понять, что построение таких приложений в Delphi максимально упрощено. Есть и еще одно последствие выполнения описываемых упражнений: читая в последующих разделах о средствах разработки приложений баз данных в Delphi, Вы будете встречать уже знакомые названия и понятия.Требуется создать в среде
Delphi приложение, предназначенное для учета поступающих на склад товаров. База данных состоит из двух таблиц: справочника "Товары" и операционной таблицы "Приход товаров". Таблицы необходимо создать и хранить в формате Paradox. Отношение между таблицами "один-ко-многим", то есть одному товару в таблице "Товары" может соответствовать более одной записи в таблице "Приход товаров". Рабочая структура таблиц приведена на рис. 2.1Для таблицы "Товары" первичный ключ построен по полю Tovar. Для таблицы "Приход товаров" первичный ключ построен по полю
N_Prih Для реализации ссылочной целостности (с таблицей "Товары") необходимо построить внешний ключ по полю Tovar. Для сортировки записей при их выводе в приложении необходимо создать индекс по полям "Дата прихода", "Товар". 2.2. Создание псевдонима базы данных При работе с таблицами локальных баз данных (в число которых входят таблицы СУБД Paradox и dBase) базой данных считается каталог на диске, в котором хранятся файлы таблиц БД, индексов, примечаний (мемо-полей) и т.д. Для хранения одной таблицы создается отдельный файл. Такие же отдельные файлы создаются для хранения индексов таблицы и мемо-полей.Обращение к БД из утилит и программы осуществляется по псевдониму (алиасу,
alias) базы данных. Такой псевдоним должен быть зарегистрирован в файле конфигурации конкретного компьютера при помощи утилиты BDE Administrator.Пусть наша база данных будет находиться в каталоге "
D:\PROBA". Присвоим псевдоним создаваемой БД. Пусть имя этого псевдонима будет "PROBA". Запустим утилиту BDE Administrator. Выберем в главном меню Элемент Object \ New. В появившемся окне (рис. 2.2) оставим тип создаваемой БД без изменений (STANDARD) и нажмем Ok.В левом окне появившегося окна администратора БД мы увидим строку с именем
STANDARDl. Изменим это имя на "PROBA". Для этого щелкнем мышью на названии БД и введем новый текст.В правом окне приведены параметры БД. Оставим их без изменения, изменив лишь
PATH. Этот параметр указывает путь к каталогу, в котором будет расположена БД. Можно ввести путь вручную, но лучше воспользоваться средствами администратора: для этого нужно щелкнуть по полю PATH и нажать на появившуюся в правом углу поля кнопку. Затем следует выбрать каталог D:\PROBA и нажать кнопку Ok (рис. 2.3.).Теперь необходимо запомнить определение псевдонима. Для этого в левом окне администратора БД необходимо щелкнуть по имени псевдонима правой кнопкой мыши и во всплывающем меню выбрать элемент
Apply. В появившемся диалоговом окне, в котором спрашивается, собираемся ли мы запоминать изменения для псевдонима, необходимо нажать кнопку Ok. Затем следует выйти из утилиты BDE Administrator. Теперь создание псевдонима завершено и к нему можно обращаться из других утилит и приложений. Однако каталог, на который ссылается псевдоним БД, еще пуст. Необходимо создать таблицы базы данных.2.3. Создание таблиц базы данных
Для создания таблиц базы данных необходимо запустить утилиту Database Desktop (DBD). После запуска утилиты установим рабочий псевдоним утилиты. Это псевдоним, с которым утилита работает по умолчанию. Если рабочий псевдоним не установлен, придется при работе с DBD всякий раз указывать псевдоним, что отнимает время.Для установки рабочего псевдонима нужно выбрать элемент главного меню
File | Working Directory и в выпадающем списке A liases выбрать имя псевдоним PROBA, после чего нажать кнопку Ok.Для создания таблицы БД нужно выбрать элемент главного меню
File \ New | Table. В появившемся окне Create Table оставляем без изменения тип создаваемой таблицы (Paradox 7) и нажимаем кнопку Ok. После этого появится окно определения структуры таблицы БД (рис. 2.4).Каждая строка таблицы соответствует полю. Назначения столбцов:
• Fields Name -
имя поля;• Type -
тип поля;• Si:e -
размер поля (для строковых полей, поскольку иные поля подразумевают размер, определяемый типом поля);• Key -
содержит звездочку '*', если поле входит в состав первичного ключа. Если в первичный ключ входит несколько полей, они должны определяться в той последовательности, в которой они присутствуют в первичном ключе. Кроме того, все поля, входящие в состав первичного индекса, должны определяться перед иными полями, то есть быть в списка полей наверху.Определим поля, входящие в таблицу "Товары". Введем
Tovary в столбец Field Name. Для того, чтобы определить тип поля, щелкните по столбцу Type и нажмите клавишу пробела. В ответ на это будет выдан список типов полей, из которых необходимо произвести выбор нужного типа (рис. 2.5).Рис. 2.5. Выбор типа поля
Рассмотрим возможные типы полей СУБД Paradox:
Тип поля |
Обозначение |
Хранимые значения |
Alpha |
A |
Символьные значения длиной до 255 символов. |
Number |
N |
Числовые значения с плавающей точкой в диапазоне -10 307...+10308. Точность до 15 значащих цифр. |
Money |
$ |
Аналогичен типу Number, но предназначен для хранения денежных сумм. Число знаков после запятой по умолчанию - 2. При показе значения выводится знак денежной единицы. |
Short |
S |
Целочисленные значения в диапазоне -32 767..32 767. |
LongInteger |
I |
Целочисленные значения в диапазоне -2 147 483 648 ..2 147 483 647. |
BCD |
# |
Числовые значения, в том числе и дробные, в двоично-десятичном формате. Обеспечивает исключительную точность при работе с большим числом знаков в дробной части. Применяется в вычислениях, где важна точность (финансовые, научные приложения). Для проведения вычислений требует больше времени, чем для числовых полей иных типов. |
Date |
D |
Значения даты (в диапазоне от 01.01.9999 до н.э. до 31.12.9999). |
Time |
T |
Значения времени. |
Timestamp |
@ |
Значения даты и времени. |
Memo |
M |
Строковые значения длиной более 255 символов. Максимальная длина не ограничена. От 1 до 240 символов могут храниться вместе с таблицей БД; остальные хранятся в виде Memo-файла (расширение . MB) |
Formatted Memo |
F |
Аналогично мемо-полю, но, может хранить форматированные тексты, в которых фрагменты текста представлены разным шрифтом, цветом и стилями. |
Graphic Fields |
G |
Графические изображения в формате файлов - BMP, .PCX, -TIF, .GIF, .EPS, которые при хранении преобразуются к формату .BMP. Хранятся отдельно от основной таблицы БД. |
OLE |
0 |
Информация в форматах, поддерживаемых технологией OLE (Object Linking and Embedding) фирмы Microsoft |
Logical |
L |
Логические значения (" True", "False"). Высота букв не имеет значения. |
Autoincrement |
± |
Автоинкрементное поле. Значения доступны только для чтения. Обычно - ключевое поле в составе первичного ключа. При добавлении новой записи значение поля вычисляется автоматически таким образом, чтобы в одной и той же таблице не было одинаковых значений. Значения поля из удаленных записей повторно не используются |
Binary |
В |
Произвольные двоичные значения. Должны интерпретироваться приложениями пользователя. DBD не интерпретирует значения этих полей. Хранятся в отдельных от основной таблицы .МВ-файлах. Длина не определена |
Bytes |
Y |
Произвольные двоичные значения, интерпретируемые приложениями пользователя, длиной от 1 до 240 байт. Хранятся вместе с таблицей БД. |
Введем определения и других столбцов таблицы
Tovary (рис. 2.6). Для каждого поля определим требование обязательного заполнения поля значением. Для этого, переходя от поля к полю, включим переключатели Required Field. Другие поля служат для наложения ограничений на значение поля:• Minimum value -
определяет минимальное значение поля, Maximum value - определяет максимальное значение поля;Default value -
определяет значение поля по умолчанию;• Picture -
определяет шаблон изображения поля. Для формирования шаблона следует нажать кнопку Assist.Отсутствие значения в одном из полей означает отсутствие ограничений на значение поля.
Чтобы запомнить сохраненную таблицу на диске, следует нажать кнопку Save As. Затем в появившемся окне следует указать имя таблицы (рис. 2.7). При желании можно указать каталог или псевдоним, отличные от принятых по умолчанию. Напомним, что по умолчанию принимается рабочий каталог или каталог, определяемый рабочим псевдонимом.
После того, как мы определим имя создаваемой таблицы (
Tovary), в каталоге С \PROBA (он назначен псевдониму PROBA, используемому нами в качестве рабочего псевдонима) будет создан файл Tovary.DB и файлы индексов с соответствующими расширениями.2.3.3. Изменение структуры существующей таблицы
Если в структуру существующей таблицы БД необходимо внести изменения, следует выбрать элемент меню File | Open | Table, в появившемся диалоговом окне выбрать имя таблицы и нажать кнопку Ok. Будет показано содержимое таблицы (на рис. 2.8: в таблице Tovary отсутствуют записи, что не удивительно, поскольку мы их еще не вводили).В том случае, когда мы хотим ввести новые записи в таблицу прямо в
DBD (а также изменить значения в некоторых записях или произвести удаление), следует нажать кнопку F9. После этого таблица будет переведена в режим внесения изменений.Чтобы изменить структуру таблицы, выберите элемент меню
Table | Restructure. Вслед за этим будет показано диалоговое окно для определения структуры таблицы. 2.3.4. Определение индексовОпределим структуру таблицы "Приход товаров" (рис. 2.9).
Всем полям назначим атрибут Required (требование обязательного существования значения у поля на момент его запоминания в БД), кроме поля N_Prih:, поскольку это поле автоинкрементное, заполнение его значением производится автоматически при запоминании новой записи.Создадим индекс по полям "Дата прихода", "Товар". Для этого в комбинированном списке
Table Properties (в правом верхнем углу окна) выберем элемент Secondary Indexes. После этого диалоговое окно приобретет вид, показанный на рис. 2.10.Чтобы определить новый индекс, нажмем кнопку
Define. В появившемся диалоговом окне в поле Fields содержится список полей определяемой нами таблицы. Поле Index Fields предназначено для хранения полей, входящих в создаваемый индекс. Чтобы скопировать конкретное поле из списка Fields в список Index Fields, нужно нажать кнопку с изображением правой стрелки. Последовательность добавления полей в список важна, она определяет порядок чередования полей в списке. После того, как мы поместили нужные поля в список Index Fields (рис. 2.11), нажмем кнопку Ok.В появившемся окне запрашивается имя индекса (рис. 2.12) Следует ввести имя и нажать Ok.
Не рекомендуется составлять название индекса только из имен полей, поскольку такой способ именования индексов используется автоматически при создании ссылочной целостности между таблицами (см следующий раздел).
Как видно на рис.2.13, после добавления нового индекса его имя появилось в списке индексов.
Впоследствии, щелкнув по имени индекса, мы можем его удалить (кнопка
Erase) или изменить (кнопка Modify).Сохраним созданную нами таблицу под именем Pnhod.
2.3.5. Определение ссылочной целостности между таблицами
Как известно из постановки задачи, таблицы "Товары" и "Приход товаров" находятся в отношении "один-ко-многим", то есть с одной записью в таблице Tovary может быть связано несколько записей по приходу того же товара в таблице Prihod. В качестве поля связи выступает поле Tovar, присутствующее в обеих таблицах.Определим ссылочную целостность между данными таблицами. Ссылочная целостность в
Paradox определяет, во-первых, связь между таблицами, а во-вторых, вид каскадных воздействий.Откроем таблицу Prihod (элемент меню
File \ Table \ Open) и затем войдем в режим изменения структуры таблицы (Table \ Restructure). В выпадающем списке Table Properties выберем элемент Refrential Integrity и нажмем кнопку Define. В появившемся диалоговом окне (рис. 2.14) в списке Fields показаны поля таблицы Prihod, а в списке Tables - таблицы базы данных PROBA.Выберем в списке
Fields поле Tovar и нажмем кнопку с изображением стрелки вправо. Название Tovar будет записано в поле Child Fields (поле внешнего ключа дочерней таблицы).Выберем в списке
Tables таблицу Prihod и нажмем кнопку с изображением стрелки влево. В поле Parents Key (ключ родительской таблицы) будут показаны поля из первичного ключа таблицы Tovary В данном случае это поле Tovar.Переключатели
Update rules определяют вид каскадных воздействий на таблицу Prihod при изменении значения поля связи в таблице Tovary или при удалении записи в таблице Tovary:• Cascade -
каскадные изменения и удаления подчиненных записей в таблице Prihod;• Prohibit -
запрет на изменение поля связи или удаление записи в таблицеTovary
, если для данной записи есть связанные записи в таблице Prihod. Выберем Cascade (рис. 2.15) и нажмем кнопку Ok.Будет запрошено имя - в Paradox ссылочные целостности именуются. Введем имя, например Tovary_Prihod_Integnty, и нажмем кнопку Ok. Теперь имя созданной ссылочной целостности будет помещено в список.
Запомним изменения в таблице Prihod (кнопка Save) и заново войдем в режим реструктуризации таблицы Prihod (Table | Restructure). В выпадающем списке Table properties выберем элемент Secondary Indexes (индексы таблицы, кроме индекса, построенного по определению первичного ключа). В списке индексов увидим, что появился новый индекс с именем Tovar (по полю Tovar). Этот индекс построен автоматически по неявному определению внешнего ключа при создании ссылочной целостности (рис. 2.16).
Выйдем из режима реструктуризации и покинем DBD. После этого перейдем к разработке простейшего приложения для работы с созданными таблицами.2.4. Создание простейшего приложения
Создадим в каталоге
CAPROBA подкаталог АРР. В нем мы будем хранить разработанные приложения. Запустим Delphi. По умолчанию Delphi при своем запуске создает форму для нового приложения. Воспользуемся ею. В палитре компонентов Delphi на странице Data Access выберем мышью невизуальный компонент TTable (рис. 2.17), щелкнем на нем мышью и затем щелкнем мышью в форме. После этого, изображение компонента останется в форме.Невизуальным компонент
TTable (как и другие компоненты, например, TQuery, TDataSource) называется потому, что он применяется для хранения и доступа к данным, а не для их визуализации - для этой цели применяются визуальные компоненты (TDBGrid, TEdit и другие).После того, как мы разместили в форме компонент
TTable, установим его свойства. Для этой цели воспользуемся инспектором объектов (Object Inspector), который обычно помещается слева от формы. Если он не видим, его можно вызвать, нажав кнопку F11. Инспектор объектов позволяет устанавливать свойства того компонента в форме, который выделен при помощи мыши. Выделим мышью компонент TTable.Установим значение свойства
DatabaseName (псевдоним БД) в PROBA при помощи выпадающего списка или введя его вручную. Установим значение свойства TableName (имя таблицы БД) в Tovary.DB при помощи выпадающего списка. После этого установим значение свойства Active в True. После этого произойдет реальное связывание компонента TTable (он по умолчанию имеет имя Tablel) с реально существующей таблицей Tovary.DB.Компонент
TTable и компонент TQuery (его мы рассмотрим позже) служат для хранения наборов данных. Понятие набора данных несколько шире, чем понятие таблицы БД, поскольку набор данных может содержать:• подмножество записей или полей таблицы БД (компоненты
TTable, TQuery);• записи, сформированные из нескольких таблиц БД (компонент
TQuery). Расположим в форме компонент TDataSource. Он служит в качестве связующего звена между невизуальными компонентами (в данном случае Tablel) и визуальными компонентами, которые мы добавим в форму позднее. Поэтому компоненты TDataSource часто называют источниками данных. Установим свойство DataSef (имя набора данных) компонента TDataSource в значение Tablel путем выбора из выпадающего списка.Расположим в форме компонент
TDBGrid, взяв его из палитры компонентов (страница Data Controls). Установим свойство DataSource компонента TDBGrid в значение DataSource1 (это имя, присвоенное Delphi по умолчанию созданному нами перед этим компоненту TDataSource). Компонент TDBGrid служит для отображения записей набора данных в табличной форме. Вид разрабатываемой формы представлен на рис. 2.18.Выберем элемент меню
File \ Save Project As и сохраним проект. Сначала запрашивается имя формы проекта (у нас форма одна, с именем Form1). Сохраним форму под именем 'appll.pas'. Затем запрашивается имя проекта. Сохраним проект под именем 'appl.dpr'.После этого выполним приложение. (Чтобы выполнить приложение, не выходя из среды
Delphi, достаточно нажать кнопку F9. Чтобы создать приложение и запустить его вне среды Delphi, следует нажать комбинацию кнопок Ctrl+F9 и затем запустить созданный файл с расширением .ехе и именем, совпадающим с именем проекта. В нашем случае следует запускать файл 'appl.exe').Добавлять записи в набор данных (и, следовательно, в таблицу
Tovary.DB) можно прямо из компонента TDBGrid.Для добавления записи нужно нажать на клавиатуре кнопку
Insert или, находясь на последней записи набора данных, кнопку "стрелка вниз". Набор данных автоматически перейдет в режим добавления новой записи. После ввода значений в поля записи запомнить запись в наборе данных можно, перейдя на другую запись при помощи клавиш управления курсором. Отказаться от запоминания записи можно, нажав кнопку Esc.Для изменения записи следует переместить указатель текущей записи в нужное место и изменить значения там, где это необходимо. Набор данных автоматически перейдет в режим редактирования.
Для удаления записи следует установить на нее указатель текущей записи и нажать комбинацию кнопок
Ctrl+Del.На рис.2.19 показан вид приложения в момент добавления в таблицу
Tovary новой записи.2.5. Создание приложения для работы с двумя таблицами
Покажем, как в одной форме можно связать два набора данных (родительский и подчиненный) так, чтобы в подчиненном наборе данных всегда показывались записи, соответствующие текущей записи в родительском НД
Сохраним форму приложения в файле 'app21.pas', а проект приложения - в файле 'арр2 drp' Добавим в приложение компонент TTable (с именем Table2) для работы с таблицей Prihod базы данных PROBA (значения свойств такие же, как у компонента Tablel, но свойство TableName ссылается на имя таблицы Prihod DB) Установим свойство Table2 Avtive в True Добавим в форму компонент TDataSource (имя по умолчанию DataSource2). Установим свойство DataSet этого компонента в значение Table2. Разместим в форме компонент TDBGnd (имя по умолчанию DBGrid2) и установим его свойство DataSource в значение DataSource2 (рис 2 20).Запустим приложение на выполнение. Ввод и изменение данных в таблицу Prihod будем производить также из компонента
TDBGnd (рис 2 21)Обратите внимание, значение поля
N_Prih формируется автоматически2.6. Уточнение списка полей и настройка параметров столбцов в
TDBGnd. Смена активного индекса Как можно заметить, значение поля N_Prih необходимо для обеспечения уникальности в таблице Prihod и не несет никакой иной нагрузки. Поэтому данное поле лучше не показывать в составе столбцов DBGrid2. Для этой цели сформируем список полей таблицы Prihod В Delphi имеются две возможности указать, какие из полей таблицы БД следует использовать в приложении для набора данных (в нашем случае для компонента Table2)Первый способ состоит в использовании по умолчанию всех полей из таблицы БД, с которой ассоциирован этот набор данных Этот способ всегда используется по умолчанию и, следовательно, был неявно использован и нами при создании наборов данных
Tablel и Table2Второй способ состоит в использовании подмножества полей таблицы
БД, с которой ассоциирован набор данных Для этой цели используется редактор полей набора данных, который позволяет включить в состав обрабатываемых для набора данных полей все поля или подмножество полей таблицы БДСохраним форму приложения как 'арр31.
pas', а проект приложения как 'аррЗ.drp'. Выберем при помощи мыши компонент Table2 и нажмем правую кнопку мыши В появившемся на экране всплывающем меню выберем элемент Fields Editor В появившемся списке редактора полей (пока он пуст, рис 2 22 а) нажмем правую кнопку мыши и во всплывающем меню выберем элемент меню Add Fields Будет показан список всех полей таблицы БД Prihod.DB Отметим (при помощи мыши и кнопки Shift) все поля, кроме N_Prih (рис 2 22 б) и нажмем кнопку Add Теперь список редактора полей будет включать все отмеченные поля (рис 2 22 в)Как можно заметить, в составе столбцов в компоненте
DBGrid2 теперь присутствуют только те поля, которые добавлены для набора данных Table2 в редакторе полей (рис 2.23)Определение для набора данных списка полей в редакторе полей приводит к тому, что для каждого добавленного таким образом поля в приложении
Delphi автоматически создает компонент TField (поле набора данных) Каждый такой компонент по умолчанию именуется уникальным именем - в качестве первой составляющей имени поля берется имя набора данных (Table2), а в качестве второй составляющей - имя поля в таблице БД Так, компонент TField, соответствующий полю Tovar, будет поименован как Table2Tovar Если в редакторе полей щелкнуть по имени соответствующего поля, в инспекторе объектов можно установить или изменить свойства поля, а также определить обработчики события для конкретного поля Более подробно об этом сказано ниже в разделе, посвященном работе с полями.Изменим параметры компонента DBGrid2 так, чтобы названия его столбцов содержали русские наименования Для этого щелкнем правой кнопкой мыши на компоненте DBGrid2, и во всплывающем меню выберем элемент
Columns Editor На экране появится окно редактора столбцов компонента (рис 2 24 а) Для того, чтобы изменить характеристики столбцов в TDBGrid, нужно перейти от неявно определяемых столбцов к явно определяемым Для этого нужно щелкнуть по кнопке Add All Fields, в результате чего будут добавлены столбцы, каждый из которых соответствует полю, определенному в редакторе полей компонента Table2 (рис 2 24 б) Чтобы изменить заголовок каждого столбца, следует выбрать при помощи мыши имя столбца в редакторе столбцов, и в инспекторе объектов раскрыть список свойства Title (для чего следует щелкнуть мышью по крестику рядом с именем свойства) В элементе Caption этого списка содержится заголовок столбца, изменим соответствующим образом заголовки и затем выйдем из редактора столбцов DBGrid2 То же проделаем для набора данных Tablel (рис 2.25)Изменим также порядок сортировки записей в наборе данных
Tdble2. Для этого в инспекторе объектов установим свойство Table2 Index FieldNames в значение 'DatPnh,Tovar' путем выбора из выпадающего списка, содержащего названия индексных полей, определенных для каждого существующего индекса таблицы Prihod DB. После этого войдем еще раз в редактор колонок DBGnd2 и при помощи мыши "перетащим" столбец DatPrih так, чтобы он предшествовал столбцу Tovar. Откомпилируем приложение и запустим его на выполнение. Как видно из рис. 2.26, набор данных Table2, ассоциированный с таблицей БД Prihod.DB, в приложении отсортирован по дате прихода, а внутри каждой даты прихода - по наименованию товара.2.7. Определение визуальных компонентов для работы с полями записи набора данных
Сохраним форму приложения как 'арр4
1.pas', а приложение как 'app4.drp'. Теперь сделаем так, чтобы к полям записи в наборе данных Table2 можно было обращаться не только из сетки компонента DBGnd2, а из отдельных визуальных компонентов, позволяющих осуществлять доступ к отдельным полям записи набора данных.Добавим в форму два компонента
TDBEdit (палитра компонентов Data Controls). Разместим компонент DBEdit1 под столбцом "Дата прихода", а компонент DBEdit2 под столбцом "Количество" Определим поле, к которому можно иметь доступ через компонент DBEditl. Для этого установим значение его свойств - DataSource в DataSource2 и DataField в DatPrih. Определим поле, к которому можно иметь доступ через компонент DBEdit2 Для этого установим значение его свойств - DataSource в DataSource2 и DataField в Kolvo.Для доступа к полю Tovar нам нужен более сложный компонент, который позволял бы вводить в поле Tovar таблицы Prihod.DB значения полей Tovar из таблицы
Tovary.DB, и никакие другие значения. Для этой цели под столбцом "Товар" компонента DBGnd2 разместим компонент TDBLookupComboBox с именем по умолчанию DBLookupComboBox1. Установим свойства этого компонента.• DataSource -
в значение DataSource2,• DataFiled -
в значение Tovar,• List Source -
в значение DataSource 1• LislField -
в значение Tovar;• Key Field -
в значение TovarДобавим в приложение 5 компонентов кнопок
TButton (страница Standard палитры компонентов). Изменим имена этих компонентов (свойство Name), используя инспектор объектов, соответственно на InsertButton, EditButton, DeleteButton, PostButton, EditButton. Изменим заголовки этих кнопок (свойство Caption), используя инспектор объектов, соответственно на "Добавить", "Изменить", "Удалить", "Запомнить", "Отменить" (рис. 2.27).Выберем при помощи мыши кнопку
InsertButton и два раза щелкнем на ней После этого мы перейдем в редактор кода и определим для кнопки InsertButton обработчик события нажатия кнопки, OnClickprocedure TForm1.InsertButtonClick(Sender: TObject);
begin
IF Table2.State = dsBrowse THEN
Table2.Insert; end;
Метод
Insert переводит набор данных Table2 в состояние добавления записи dslnsert. Ввод значений полей осуществляется в компонентах DBEditl, DBLookupComboBoxl, DBEdit2 Для этого необходимо, чтобы набор данных находился в режиме просмотра dsBrowse.Определим обработчик нажатия кнопки
EditButtonprocedure TFormI.EditButtonClick(Sender: TObject);
begin
IF Table2.State = dsBrowse THEN Table2.Edit;
end;
Метод
Edit переводит набор данных Table2 в состояние добавления записи dsEdit. Редактирование значений полей осуществляется в компонентах DBEditl, DBLookupComboBoxl, DBEdit2 Для этого необходимо, чтобы набор данных находился в режиме просмотра dsBrowseОпределим обработчик нажатия кнопки
DeleteButtonprocedure TForm1.DeleteButtonClick(Sender: TObject);
begin
IF Table2.State = dsBrowse THEN
IF MessageDIg('
Подтвердите удаление записи', mtConfirmation,[mbYes, mbNo],0) = mrYes THEN Table2.Delete/- end;Если набор данных Table2 находится в режиме просмотра записей
dsBrowse, вызывается окно диалога (при выполнении функции MessageDIg), если пользователь нажимает кнопку Yes, происходит удаление текущей записи в наборе данных Table2Определим обработчик нажатия кнопки
PostButtonprocedure TFormI.PostButtonClick(Sender: TObject);
begin
IF Table2.State in [dsInsert,dsEdit] THEN Table2.Post;
end;
Если набор данных находится в режиме добавления новой записи или редактирования, происходит выполнение метода набора данных
Post, который запоминает текущее состояние записи в таблице БД После запоминания набор данных переводится в режим просмотра dsBrowseОпределим обработчик нажатия кнопки
CancelButtonprocedure TFormI.CancelButtonClick(Sender: TObject);
begin
IF Table2.State in [dslnsert,dsEdit] THEN Table2.Cancel;
end;
Если набор данных находится в режиме добавления новой записи или редактирования, происходит выполнение метода набора данных Cancel, который отменяет запоминание записи в таблице БД и переводит набор данных в режим просмотра dsBrowseДля того чтобы набор данных нельзя было переводить в состояние добавления и изменения данных, а также удалять записи непосредственно из компонента
DBGrid2, установим свойство DBGrid2 ReadOnly в значение TrueПосле этого запустим приложение на выполнение. При добавлении новой записи или при корректировке существующей в поля можно заносить значения, используя ввод в компоненты DBEdit1, DBEdit2 и путем выбора из списка значений в компоненте DBLookupComboBoxl (рис 2.28). То же происходит при изменении записи. При удалении записи выдается окно диалога (рис 2.29)
Master-Detail между наборами данных Нам известно, что таблицы базы данных Tovary.DB и Prihod.DB находятся в отношении "один-ко-многим". Поскольку мы определили ссылочную целостность между этими таблицами, можно сделать так, чтобы при установке указателя на запись в наборе данных Table1 (ассоциированном с Tovary. DB) в наборе данных Table2 (ассоциированном с Prihod.DB) показывались только записи прихода текущего товара в Table1. Это реализуется через механизм связи наборов данных Master-Detail.
Для этого откроем проект 'аррЗ.' В редакторе столбцов
DBGrid2 сделаем столбец, соответствующий полю Tovary, первым по счету в DBGrid2. В инспекторе объектов для компонента Table2 установим значение свойства MasterSource в DataSourcel. Переместимся на значение свойства MasterFields и нажмем кнопку эллипса. В появившемся окне Field Link Designer установим параметры связи. В -поле Available Indexes выберем в качестве текущего индекса по полю 'Tovar'. В списке Detail Fields выберем поле Tovar, в списке Master Fields выберем поле Tovar и нажмем кнопку Add. В поле Joined Fields будет сформировано выражение 'Tovar -> Tovar' (рис. 2.30). Нажмем кнопку Ok.Как можно заметить, в компоненте Table2 текущий индекс (свойство
Fieldlndex Names) заменен на индекс, построенный по полю 'Tovar'.Выполним приложение. Теперь в наборе данных Table2 показываются только записи по приходу товара, текущего в наборе данных
Table 1 (рис. 2.31). Мало того, при добавлении записи в набор данных Table2 значение поля Tovar по умолчанию берется равным значению поля Tovar из текущей записи в наборе данных Table1 (рис. 2.32). 2.9. Использование компонента TQuery для формирования набора данных из нескольких таблицСоздадим новое приложение, выбрав в меню
Delphi элемент File | New Application. Сохраним форму нового приложения как 'app51.pas', а само приложение как 'app5.dpr'.Расположим в форме компонент
TQuery (страница Data Access палитра компонентов). По умолчанию его имя Query1. Установим его свойство DatabaseName в PROBA. Расположим в форме компонент TDataSource (имя DataSource1). Установим его свойство DataSet в значение Queryl. Расположим в форме компонент TDBGrid. Установим его свойство DataSource в значение DataSourcel.В инспекторе объектов для компонента
Queryl найдем свойство SQL и нажмем кнопку эллипса. Затем в появившемся окне редактора наберем текст SQL-запросаSELECT P.DatPrih, P.Tovar, P.Kolvo,
Т.Zena, (P.Kolvo * Т.Zena) As StoimFROM Tovary T, Prihod P WHERE T.Tovar = P.Tovar ORDER BY P.DatPrih, P.Tovar
и нажмем кнопку
Ok.После этого установим свойство
Queryl.Active в значение True. Набор данных Queryl содержит сведения о приходе товара со склада. В составе записи этого набора присутствуют поля DatPrih (дата прихода), Tovar (название товара), Kolvo (количество прихода), Zena (цена за ед. измерения данного товара), Stoim (стоимость прихода товара). Как видно из текста запроса в свойстве SQL, набор данных "собирается" из двух таблиц БД PROBA, Tovary.DB и Prihod.DB. При этом соединяются записи из этих таблиц БД, имеющие одинаковое значение поля Tovar (рис. 2.33) Однако, стоит нам выполнить это приложение, и мы увидим, что в набор данных Queryl нельзя добавить новые записи и нельзя изменить или удалить существующие записи в наборе данных. Это происходит потому, что тип набора данных, "собираемого" более чем из одной таблицы БД, является доступным только для чтения.* * *
Теперь, когда Вы попрактиковались в создании приложений
Delphi, работающих с базами данных, перейдем к более детализированному рассмотрению визуальных и невизуальных компонентов Delphi для работы с данными. В следующем разделе показаны средства Delphi, доступные при разработке таких приложений, а также рассматриваются различные архитектуры приложений для работы с базами данных.