Опубликован: 07.05.2010 | Уровень: специалист | Доступ: платный
Лекция 2:

ADO. Связь с таблицей MS Access

< Лекция 1 || Лекция 2: 123 || Лекция 3 >

Здесь я поступил следующим образом: установил на форму четыре панели GroupBox с вкладки Standard, на каждую таблицу свой GroupBox. Почему я так поступил, станет понятно позже. Займемся первой таблицей. В свойстве Caption компонента GroupBox впишите "Личные данные", это название отразится в заголовке панели. Далее на эту панель следует установить восемь компонентов DBEdit с вкладки DataControls палитры компонентов, два DBCheckBox для редактирования логических данных, и один компонент DBComboBox для списка. Поясняющие компоненты Label установите и настройте самостоятельно. Немного доработаем компонент DBComboBox. Щелкните дважды по его свойству Items, открыв редактор. В нем введите две строки:

муж
жен

Сохраните текст, нажав кнопку ОК. Теперь пользователь сможет указать пол сотрудника, выбрав нужную строку из списка.

Для таблицы Doljnost все еще проще: на панели GroupBox всего два компонента DBEdit и два поясняющих Label.

Для таблицы Adres используйте три DBEdit.

А вот для таблицы Telephones понадобится один DBEdit, один DBComboBox, сетка DBGrid и кнопка BitBtn. Сетка нужна для контроля введенных телефонов, ведь здесь связь один-ко-многим, и телефонов может быть несколько. В редакторе Items компонента DBComboBox введите три строки:

Рабочий
Домашний
Мобильный

Теперь займемся подключением компонентов контроля. Удерживая <Shift>, выделите все компоненты контроля на первой панели (все компоненты, кроме Label ). В их свойстве DataSource выберите fDM.DSLichData, подключив компоненты к нужному набору данных (таблице). Снимите общее выделение, и выделите первый DBEdit. В его свойстве DataField выберите поле "Фамилия". Это свойство подключает выбранный компонент к определенному полю таблицы. Таким же образом подключите к соответствующим полям остальные компоненты. Затем подключайте компоненты других таблиц, каждое к своей таблице и к соответствующему полю. Сетка DBGrid подключается к fDM.DSTelephones, и не имеет поля, разумеется. Она отображает все видимые поля таблицы.

В правой нижней части для удобства пользователя я установил навигационный компонент DBNavigator с вкладки Data Controls. Этот компонент предназначен для перемещения по записям, включения режима редактирования записи, сохранения или отмены сделанных изменений, добавления новой записи или удаления существующей. В его свойстве DataSource я выбрал fDM.DSLichData, чтобы подключить компонент к главной таблице. Нам нужна от этого компонента только возможность перехода на начало или конец таблицы, на следующую или предыдущую запись. Поэтому раскройте его свойство VisibleButtons (видимость кнопок компонента) и переведите в False все кнопки, кроме nbFirst, nbPrior, nbNext и nbLast. Нажатие на эти кнопки приведет к вызову соответствующих методов компонента ADOTable. Эти методы делают следующее:

First - переход на первую запись таблицы.

Prior - переход на предыдущую запись.

Next - переход на следующую запись.

Last - переход на последнюю запись.

Когда у DBNavigator останется всего четыре кнопки, эти кнопки окажутся вытянутыми. Уменьшите ширину компонента, чтобы кнопки приняли более привычный вид.

Теперь пришло время объяснить, почему я поместил компоненты на панели GroupBox, и почему для каждой таблицы сделал отдельную панель. Если вы прошли предыдущий курс "Введение в программирование на Delphi", то знаете, что измененная запись в таблице сохраняется в трех случаях:

  1. Применением метода Post.
  2. При переходе на другую запись.
  3. При добавлении новой записи.

Когда мы, заполнив одну таблицу, перейдем к другой, то в первой таблице запись еще не будет сохранена. Поле "Ключ" у нас автоинкрементное, на него завязаны остальные таблицы. До тех пор, пока мы не сохраним запись, в этом поле не будет никакого значения. Следовательно, данные в других таблицах не смогут привязаться к какой-то записи главной таблицы. Поэтому выделите первый GroupBox, и дважды щелкните по событию onExit на вкладке Events инспектора объектов. Это событие происходит всякий раз, когда пользователь перейдет к другой панели GroupBox, либо к кнопкам, расположенным в нижней части окна. В сгенерированной процедуре впишите код:

{Вышли из редактирования LichData}
procedure TfEditor.GroupBox1Exit(Sender: TObject);
begin
  if fDM.TLichData.Modified then
    fDM.TLichData.Post;
end;

Свойство Modified компонента ADOTable имеет логический тип - в нем содержится True, если данные были изменены, и False в противном случае. Метод Post этого компонента, как уже упоминалось, сохраняет измененную запись таблицы. При этом в поле "Ключ" попадет присвоенное автоматически значение. Таким образом, введенный код означает, что если запись была изменена, то следует ее сохранить. Сгенерируйте событие onExit для оставшихся панелей GroupBox и таким же образом сохраните изменения записей в соответствующих таблицах.

Далее сгенерируйте событие нажатия на кнопку "Добавить" в GroupBox с телефонными данными. Этой кнопкой мы будем добавлять новые записи в таблицу, ведь один сотрудник может иметь более одного телефона. Код в процедуре будет такой:

if fDM.TTelephones.Modified then
     fDM.TTelephones.Post;
  fDM.TTelephones.Append;
  DBEdit14.SetFocus;

Вначале мы сохраняем измененные значения, если они были. Затем методом Append мы добавляем в таблицу новую запись. Добавить новую запись можно двумя методами:

  1. Append - добавляет новую запись в конец таблицы.
  2. Insert - добавляет новую запись в текущее положение курсора.

После добавления новой записи таблица уже будет в режиме редактирования, поэтому можно не вызывать метод Edit, который переводит таблицу в этот режим. Далее мы переводим фокус ввода на DBEdit с телефонными номерами, чтобы пользователю не пришлось делать это самому.

В процедуре нажатия на кнопку "Сохранить и выйти" код простой:

if fDM.TLichData.Modified then
    fDM.TLichData.Post;
  if fDM.TDoljnost.Modified then
    fDM.TDoljnost.Post;
  if fDM.TAdres.Modified then
    fDM.TAdres.Post;
  if fDM.TTelephones.Modified then
    fDM.TTelephones.Post;
  Close;

Здесь мы лишь сохраняем изменения во всех таблицах, если они были, и закрываем окно. Напоследок у нас осталась кнопка "Добавить сотрудника". Что мы должны сделать, если пользователь нажмет на эту кнопку? Добавить новую запись в каждую таблицу и перевести курсор в первый DBEdit, в котором редактируется фамилия. Это и делаем:

fDM.TLichData.Append;
  fDM.TDoljnost.Append;
  fDM.TAdres.Append;
  fDM.TTelephones.Append;
  DBEdit1.SetFocus;

С этой формой мы закончили, переходим к главной форме. Не забывайте время от времени сохранять проект. Если вы еще не подключили модуль Editor к главной форме командой File -> Use Unit, то сделайте это сейчас, чтобы можно было вызывать окно редактора из главной формы. Начнем с кнопки "Новый сотрудник". Как и в предыдущем примере, нам потребуется добавить новую запись в каждую таблицу, после чего открыть окно редактора:

fDM.TLichData.Append;
  fDM.TDoljnost.Append;
  fDM.TAdres.Append;
  fDM.TTelephones.Append;
  fEditor.ShowModal;

Сгенерируйте процедуру onClick для кнопки "Редактировать". Тут будет лишь одна строчка кода:

fEditor.ShowModal;

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

Блок поиска по фамилии оставим на следующую лекцию и перейдем к программированию радиокнопок. По нашему замыслу, при открытии программы в верхней сетке DBGrid будут отображаться данные из главной таблицы, а в нижней - из таблицы Adres. Также будет выделена радиокнопка с надписью "Адрес". Если пользователю захочется посмотреть должность или телефоны текущего сотрудника, он будет щелкать соответствующую радиокнопку, и эти данные должны быть отображены в нижней DBGrid. Выделите первую радиокнопку с надписью "Адрес" и сгенерируйте для нее событие onClick, которое будет возникать, когда пользователь щелкнет по ней. В процедуре этого события впишите следующий код:

if RadioButton1.Checked then
    DBGrid2.DataSource := fDM.DSAdres;

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

Для события onClick радиокнопки с надписью "Телефоны" код будет таким:

if RadioButton2.Checked then
    DBGrid2.DataSource := fDM.DSTelephones;

А для события onClick радиокнопки с надписью "Должность", соответственно, код будет следующим:

if RadioButton3.Checked then
    DBGrid2.DataSource := fDM.DSDoljnost;

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

< Лекция 1 || Лекция 2: 123 || Лекция 3 >
Евгений Медведев
Евгений Медведев

В лекции №2 вставляю модуль данных. При попытке заменить name на  fDM выдает ошибку: "The project already contains a form or module named fDM!". Что делать? 

Анна Зеленина
Анна Зеленина

При вводе типов успешно сохраняется только 1я строчка. При попытке ввести второй тип вылезает сообщение об ошибке "project mymenu.exe raised exception class EOleException with message 'Microsoft Драйвер ODBC Paradox В операции должен использоваться обновляемый запрос'. 

Назерке Сейтсаданова
Назерке Сейтсаданова
Казахстан, Усть-Каменагорск, ВКГУ им. С.Аманжолова
Наталья Статченко
Наталья Статченко
Россия, Благовещенск