Шаг 38.
Работа с локальными БД в Delphi.
Режимы набора данных (продолжение)

    На этом шаге мы рассмотрим использование свойства State при разработке приложения.

    Очень важно знать, в каком режиме находится НД, иначе некоторые методы НД, могут привести к ошибке в процессе выполнения программы. Для примера вернемся к нашей предыдущей программе с двумя таблицами. Поместим на форму компонент TButton, который расположен на вкладке Standard, и напишем обработчик события OnClick для этого компонента.

procedure TForm1.Button1Click(Sender: TObject);
begin
  Table1.Cancel;
  Table1.Post;
end;

    Запустим нашу программу и нажмем кнопку Button1. Delphi выдаст критическую ошибку с сообщением: "Таблица не находится в режиме редактирования либо добавления новой записи" (рисунок 1).


Рис.1. Ошибка приложения

    Давайте разберемся, из-за чего она возникла. Рассмотрим текст приведенной процедуры. Действием Table1.Cancel мы отменяем последние несохраненные изменения, то есть, если наш набор данных находился в режиме dsEdit (режим редактирования), или dsInsert (добавление записи), то отменяются последние изменения и НД переходит в режим dsBrowse (режим просмотра), если же НД уже находился в режиме dsBrowse, то ничего не происходит. Затем вызывается метод Post (Table1.Post) - сохранение внесенных изменений, но так как НД находиться в режиме просмотра, этот метод создает критическую ошибку, потому что он может применяться только в режиме редактирования, либо добавления новой записи. Чтобы избегать подобных ошибок, необходимо перед использованием того или иного метода проверять, в каком режиме находится НД.

    Используем все то же приложение с двумя таблицами, удалив процедуру Button1Click и кнопку с формы.

    Разорвем связь между таблицами, удалив значения свойств компонента Table2, MasterSource и MasterFields.

    Поместим на форму три компонента TDBEdit (вкладка Data Controls). Чтобы связать эти компоненты с полями, поместите в их свойства DataSource значение DataSource2 и в свойства DataField соответственно Model, Kolvo, Zena. Для доступа к полю Naim нам нужен более сложный компонент, который позволял бы вводить в это поле только те значения, которые уже введены в поле Naim в таблице Naim.db, и никакие другие. Для этой цели мы воспользуемся компонентом TDBLookupComboBox. Установите у этого компонента следующие свойства:

Таблица 1. Значения свойств компонента TDBLookupComboBox
Свойство Значение Описание
DataSource DataSource2 Указывает на компонент TDataSource, связанный с НД2
DataField Naim Содержит поле НД2, в которое будет помещаться значение из НД1
ListSource DataSource1 Указывает на компонент TDataSource, связанный с НД1
ListField Naim Определяет список полей из НД1, значение которых будет показываться в списке выбора. Соседние поля в списке разделяются точкой с запятой. Если значение не заполнено, берется значение свойства KeyFields
KeyField Naim Устанавливает поле связи между НД1 и НД2

    Теперь на форме есть специальные компоненты для доступа к полям записи. Чтобы обращение к полям шло только с помощью этих компонентов, запретим доступ к полям из компонента DBGrid2: установите в его свойство ReadOnly значение True.

    Добавьте на форму пять компонентов TButton (вкладка Standard). Измените имена этих компонентов (свойство Name) соответственно на InsertButton, EditButton, PostButton, CancelButton, DeleteButton. Измените надписи на кнопках соответственно на "Добавить", "Изменить", "Запомнить", "Отменить", "Удалить".

    Напишите обработчик события OnClick для каждой из кнопки. Для кнопки InsertButton:

procedure TForm1.InsertButtonClick(Sender: TObject);
begin
  if Table2.State = dsBrowse then Table2.Insert;
end;

    Если НД Table2 находится в режиме просмотра dsBrowse, метод Insert переводит его в режим добавления записи dsInsert.

    Для кнопки EditButton:

procedure TForm1.EditButtonClick(Sender: TObject);
begin
  if Table2.State = dsBrowse then Table2.Edit;
end;

    Метод Edit переводит НД в режим редактирования записи dsEdit.

    Для кнопки PostButton:

procedure TForm1.PostButtonClick(Sender: TObject);
begin
  if (Table2.State = dsInsert) or
     (Table2.State = dsEdit) then Table2.Post;
end;

    Если НД находится в режиме добавления новой записи или редактирования, вызывается метод Post набора данных Table2, который запоминает текущее состояние записи в таблице БД. После запоминания НД автоматически переводится в режим просмотра dsBrowse.

    Для кнопки CancelButton:

procedure TForm1.CancelButtonClick(Sender: TObject);
begin
  if Table2.State in [dsInsert,dsEdit] then Table2.Cancel;
end;

    Метод Cancel отменяет сделанные изменения и переводит НД в режим dsBrowse.

    Для кнопки DeleteButton:

procedure TForm1.DeleteButtonClick(Sender: TObject);
begin
   if Table2.State = dsBrowse then
     if MessageDlg('Вы действительно хотите удалить запись?',
             mtConfirmation,[mbYes,mbNo],0) = mrYes then
       Table2.Delete;
end;

    Если НД находится в режиме dsBrowse, вызывается диалоговое окно MessageDlg с предложением подтвердить удаление записи. Если пользователь нажимает кнопку Yes, текущая запись в наборе данных Table2 удаляется методом Delete.

    Запустите программу. При добавлении новой записи или при корректировке существующей, в поля можно заносить значения, используя компоненты TDBEdit и TDBLookupComboBox. Использование таких компонентов дает множество преимуществ, например, с помощью них можно контролировать и редактировать данные, введенные пользователем.


Рис.2. Пример работы приложения

    Созданное приложение можно взять здесь.

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг