В лекции №2 вставляю модуль данных. При попытке заменить name на fDM выдает ошибку: "The project already contains a form or module named fDM!". Что делать? |
ADO. Связь с таблицей MS Access
Практика работы с БД MS Access из Delphi
Базу данных мы спроектировали, таблицы сделали. Осталась еще половина работы - проект Delphi, работающий с этой базой данных. Загружаем Delphi, делаем новый проект. Главная форма нашей программы будет выглядеть так:
Здесь я поместил три обычных панели. Свойству Align верхней панели присвоил значение alTop (весь верх). Затем свойству Align нижней панели присвоил значение alBottom. Затем поместил компонент Splitter с вкладки Additional панели инструментов, и его свойству Align также присвоил alBottom, после чего он прижался к нижней панели. Splitter - это разделитель между панелями. С его помощью пользователь мышью сможет передвигать нижнюю панель, меняя ее размеры. И, наконец, свойству Align средней панели присвоил значение alClient, чтобы она заняла все оставшееся место на форме. Не забудьте очистить свойство Caption всех трех панелей.
Далее на верхнюю панель я поместил три компонента RadioButton с вкладки Standard палитры компонентов. В их свойствах Caption я написал, соответственно, "Адрес", "Телефоны" и "Должность". Переключаясь между ними, пользователь сможет выводить в нижнюю, подчиненную сетку DBGrid нужные данные. Свойству Checked первой радиокнопки присвоил значение True, чтобы включить ее. Раздел с переключателями я разделил компонентом Bevel с вкладки Additional палитры компонентов. Его ширину (свойство Width ) сделал равным 2 пикселям, превратив его в вертикальную разделительную полосу.
Далее я сделал раздел поиска, поместив в него обычные Label, Edit и кнопку BitBtn. Этот раздел понадобится на следующей лекции.
В последнем разделе верхней панели находятся еще две кнопки BitBtn. Одна из них предназначена для редактирования текущей записи, другая - для добавления новой.
Вторая и третья панели содержат только по одному компоненту DBGrid из вкладки DataControls палитры компонентов, свойствам Align которых присвоено значение alClient.
Свойству Name формы присвоено значение fMain, свойство Caption формы имеет текст "Отдел кадров", модуль сохранен под именем Main.pas, а проект в целом называется ok (отдел кадров).
Далее в проект добавлен модуль данных (File -> New -> Data Module). Модуль данных - это не визуальный контейнер для размещения на нем невизуальных компонентов. В основном, он предназначен для размещения в нем компонентов подключения к данным ( TDataBase, ADOConnection и т.п.), компонентов - наборов данных ( TTable / ADOTable, TQuery / ADOQuery, TStoredProc / ADOStoredProc ) и компонентов DataSource, которые обеспечивают связь наборов данных и компонентов отображения/редактирования данных. Также модуль данных часто используют и для хранения глобальных переменных, общих функций и процедур, которые должны быть видны по всей программе. Модуль данных не имеет формы, но сохраняется как модуль в файле *.pas.
Свойству Name модуля данных мы присвоим имя fDM, а модуль сохраним как DM.pas. Теперь самое интересное. Добавляем в модуль компонент ADOConnection с вкладки ADO палитры компонентов. Этот компонент обеспечит связь других компонентов с базой данных при помощи механизма ADO. Связь обеспечивается свойством компонента ConnectionString. В общем-то, у таких компонентов, как ADOTable тоже есть это свойство, однако, имея четыре таблицы, придется четыре раза устанавливать связь. Проще единожды соединиться компонентом ADOConnection и использовать его для связи других компонентов.
Приступим к делу. Щелкните дважды по свойству ConnectionString компонента ADOConnection. Откроется окно подключения компонента к ADO:
Здесь мы можем подключиться тремя способами:
- Использовать для связи созданный ранее link-файл.
- Вписать в поле "Use Connection String" строку для связи с ADO.
- Сгенерировать эту строку, нажав кнопку Build.
Воспользуемся третьим способом - нажмем кнопку Build. Открывается новое окно, содержащее настройки подключения:
Вначале нам предлагается выбрать поставщика OLE DB, или иначе, указать нужный для подключения драйвер. Для связи с базой данных MS Access больше всего подходит " Microsoft Jet 4.0 OLE DB Provider ". Jet - это название механизма работы с СУБД, встроенного в MS Access. Этот механизм поддерживает как собственные БД MS Access, имеющие расширение *.mdb, так и ODBC. Его и выделяем в списке.
Нажимаем на кнопку "Далее", либо переходим к вкладке "Подключение". Здесь нам нужно выбрать или ввести базу данных. Тут есть одно замечание. Если мы выберем базу данных, то есть, нажмем на кнопку с тремя точками, откроем диалог выбора и найдем там наш файл, то база данных будет привязана к указанному адресу. Если вы желаете поместить базу данных в какой-то определенной папке, то так и поступите. Однако если вы поместили файл с базой данных (в нашем случае ok.mdb) там же, где находится программа, и не желаете зависеть от определенной папки (ведь пользователь может переместить вашу программу), то нужно вручную вписать только имя файла с БД, без всякого адреса. В этом случае вы не сможете проверить подключение, нажав на кнопку "Проверить подключение". Ну и не надо, обойдемся без проверки. Укажите только имя файла - ok.mdb (вы ведь уже поместили этот файл в папку с проектом?). Нажмите на кнопку "ОК".
Закрываем окно редактора связей, и нам остается открыть подключение. Однако перед этим переведите свойство LoginPrompt компонента ADOConnection в False. Если этого не сделать, то при каждой попытке соединиться с базой данных будет выходить запрос на пользовательское имя и пароль, нам это не нужно, наша база данных без пароля. Теперь свойство Connected переведите в True. Если вам удалось это сделать, и не вышло никаких сообщений об ошибке, то подключение состоялось.
Пойдем дальше. Установите в модуль данных четыре компонента ADOTable, по одному на каждую таблицу из нашей базы данных. Компонент ADOTable (также как и TTable из вкладки BDE ) предназначен для создания набора данных.
Набором данных (НД) называется группа записей, полученных такими компонентами, как TTable/ADOTable, TQuery/ADOQuery, TStoredProc/ADOStoredProc из одной или нескольких таблиц базы данных. Все компоненты наборов данных являются потомками класса TDBDataSet, и имеют много общих свойств, методов и событий. Эти компоненты также называют наборами данных.
Табличные компоненты (TTable/ADOTable) являются наборами данных, которые получают из базы данных полную копию одной из таблиц, и предоставляют полученный набор данных визуальным компонентам отображения данных ( DBGrid, DBEdit, DBMemo и проч.).
Компоненты запросов ( TQuery/ADOQuery ) для получения набора данных из базы данных используют SQL -запрос. Компоненты позволяют получить из одной или нескольких таблиц только те данные, которые удовлетворяют запросу.
Выделите все четыре ADOTable (удерживая клавишу <Shift>), и в их свойстве Connection выберите нашу связь ADOConnection1. Таким образом, все четыре ADOTable мы подключили к базе данных.
Выделите первый компонент ADOTable. Переименуйте его свойство Name в TLichData, а в свойстве TableName выберите главную таблицу базы - LichData. Буква "Т" в начале названия компонента укажет нам в дальнейшем, что это таблица. Рядом с компонентом установите компонент DataSource из вкладки Data Access палитры компонентов. Компонент DataSource предназначен для организации связи с наборами данных, и служит посредником между такими компонентами НД, как ADOTable, ADOQuery и между компонентами отображения данных, например, DBGrid, DBEdit и т.п. Свойство Name компонента DataSource переименуйте в DSLichData ( DS - DataSource ). В свойстве DataSet выберите таблицу TLichData.
То же самое нужно проделать еще три раза, подключая аналогичным образом компоненты DataSource к другим таблицам:
Затем свойство Active таблиц переведите в True, открыв их. Для тех, кто пропустил предыдущий курс, напомню, что таблицы можно открывать и закрывать не только в Инспекторе Объектов, но и программно. Как открыть, так и закрыть таблицы можно двумя абсолютно равноценными способами:
//Открываем таблицы: fDM.TLichData.Open; fDM.TDoljnost.Active := True; //Закрываем их: fDM.TLichData.Close; fDM.TDoljnost.Active := False;
Пойдем далее. Перейдите на главную форму. Выберите команду File -> Use Unit и подключите к ней модуль DM. Теперь мы сможем видеть таблицы из главной формы.
На вкладке DataControls сосредоточены визуальные (видимые пользователю) компоненты отображения данных, такие как DBGrid (сетка, отображающая все данные НД в виде таблицы, и позволяющая редактировать их), DBEdit (поле редактирования данных, предназначенная для ввода или редактирования одного поля записи, то есть, ячейки таблицы), DBMemo (для редактирования MEMO -полей) и т.д. Единственным исключением является компонент DBNavigator. Этот компонент предназначен не для отображения данных, а для перемещения по записям набора данных, для вставки новой записи или удаления старой, для перевода НД в режим редактирования или для подтверждения сделанных изменений в наборе данных.
Выделите верхнюю сетку DBGrid, в ее свойстве DataSource выберите fDM.DSLichData. В таком же свойстве нижней сетки выберите fDM.DSAdres. Сетки среагировали, и вы можете видеть названия полей. Разумеется, таблица еще пуста, данных пока нет. Кстати, выделите обе сетки, и установите в True их свойства ReadOnly - только чтение. Таблицы ведь будут связаны, и нам не нужно, чтобы пользователь вводил данные фрагментарно. Мы для этого сделаем отдельную форму, а эти сетки нужны только для просмотра.
Теперь нужно между таблицами установить связь. Это требуется не только для того, чтобы в нижней сетке выходили данные только на сотрудника, выделенного в верхней сетке, но и для того, чтобы мы смогли в дальнейшем вводить связанные данные в окне редактора. Снова выделите модуль данных. Щелкните дважды по первой таблице, чтобы открыть редактор полей. Правой кнопкой щелкните по этому редактору и выберите команду Add all fields (добавить все поля). В окне редактора полей появились все поля таблицы:
Редактор полей предназначен для настройки параметров каждого поля, для добавления новых полей или удаления имеющихся. Если в редакторе полей нет ни одного поля, то в компоненте DBGrid будут отображены все поля таблицы, имеющие параметры по умолчанию. Если же мы добавили в редактор полей хотя бы одно поле, то сетка DBGrid его и отобразит. В редакторе мы можем для каждого поля изменить различные параметры, например, ширину колонки, название колонки, видимое это поле или нет, и т.п. Кроме того, редактор полей предоставляет возможность добавлять в набор данных новые поля, например вычисляемые или просматриваемые ( lookup ). Но эту возможность мы будем рассматривать в других лекциях.
Поле "Ключ" у нас автоинкрементное, предназначено для связи с другими таблицами. Пользователю его видеть не обязательно. Выделите его, и в свойстве Visible установите False. Теперь для пользователя оно будет невидимым. Здесь у нас есть два логических поля - "Сем_Полож" и "Военнообязанный". Чтобы True и False выходили на экране так, как нам нужно, свойству DisplayValues первого из этих полей присвойте значение "Женат;Холост" (разумеется, без кавычек), а второго - "Да;Нет". Первым здесь идет значение, которое будет обозначать True, вторым - False. Эти значения разделяются точкой с запятой, пробелы не нужны.
Таким же образом добавьте все поля в остальные три таблицы. У них невидимым следует сделать поле "Сотрудник" - этому полю автоматически будет присвоено такое же число, как у поля Ключ соответствующей записи. Логических полей у них нет. Однако для поля "Телефон" таблицы Telephones следует изменить свойство EditMask. Щелкните по нему дважды, открыв редактор маски, и в поле Input Mask введите маску "#(###)-###-##-##". Сохраните ее, нажав кнопку ОК. Для полей типа Дата в этом свойстве (в таблице LichData два таких поля) введите маску "##.##.####".
Далее кнопкой <F12> перейдите в редактор кода. В нижней части окна вы можете увидеть вкладку Diagram, перейдите на нее. Нам с вами потребуется сделать такие связи:
Для начала в окно диаграмм нужно добавить наши таблицы. Найдите их в окне дерева объектов Object TreeView. Если у вас это окно закрыто, откройте его клавишами <Shift+Alt+F11> либо командой меню View -> Object TreeView. Ухватитесь в этом окне мышью за название главной таблицы
LichData {TLichData}
и перетащите ее в окно диаграмм. Таблица вместе с полями отобразится в окне. Если бы ранее мы не добавили все поля в окне редактора полей компонента ADOTable, то здесь мы не увидели бы полей. Точно также перетащите остальные таблицы, как на рисунке. Связи главная - подчиненная делают кнопкой Master / Detail Connector, которую вы можете увидеть в верхней части окна диаграмм (предпоследняя). Нажмите на кнопку, затем подведите указатель мыши к боковой границе главной таблицы, нажмите левую кнопку и, удерживая ее, проведите линию к боковой границе таблицы Adres. Как только вы отпустите кнопку, появится окно связей:
Здесь в поле Detail Fields нужно выбрать поле, по которому будет осуществляться связь, в нашем случае это поле "Сотрудник". В поле Master Fields выбираем ключевое поле "Ключ". Затем нажимаем кнопку Add и кнопку OK. Связь установлена.
При установке связей главный / подчиненный важно начинать вести линию с главной таблицы к подчиненной. Если бы мы сделали иначе, то главной таблицей стала бы TAdres. Такую же связь установите и с остальными таблицами. Просто, не правда ли?
Сохраните проект, скомпилируйте его и запустите на выполнение. Если в сетках главного окна вы видите открытые таблицы, то все хорошо. Если нет, возможно, при изменении настроек ваши таблицы закрылись. В таком случае закройте программу (но не проект!), выделите таблицы, и их свойству Active снова присвойте значение True. Таблицы должны появиться в сетках главного окна, даже на этапе проектирования.
Пойдем дальше. Теперь нам нужно сделать окно редактора данных. Создайте новую форму (File -> New -> Form). Ее свойство Name переименуйте в fEditor, а при сохранении формы дайте модулю имя Editor. Командой File -> Use Unit подключите к форме модуль данных DM. Теперь нам нужно установить на форму такие компоненты: