вторник, 27 декабря 2011 г.

Урок 28. Организация ввода и редактирования данных


В предыдущем уроке мы много говорили на тему оформления интерфейса. Теперь настало время заглянуть внутрь - организовать процедуры ввода информации в главную таблицу и редактирования ее.
Для начала, добавьте в раздел частных объявлений декларацию следующей процедуры:
Procedure TMainFrm.MyEdits();
Begin
DataEdit.Value:=ADOTableMain.FieldByName('MyDate').value;
DEdit.KeyValue:=ADOTableMain.FieldByName('D').value;
KEdit.KeyValue:=ADOTableMain.FieldByName('K').value;
SEdit.Value:=ADOTableMain.FieldByName('Summa').value;
PEdit.Text:=ADOTableMain.FieldByName('Rem').Text;
Panel3.Visible:=True;
end;
Panel3 - это верхняя панелька на главной форме, где расположены несколько элементов управления для ввода.
В этой процедуре,  элементам управления (контролам) присваиваются значения из соответствующих полей таблицы "Main".
Аналогично объявите и создайте процедуру InsEdit:
Procedure TMainFrm.InsEdit();
Begin
// Процедура подготоавливает ввод новой записи
ADOTableMain.Edit;                                // Переводит таблицу в режим редактирования
MyEdits;                                          // Вызывает процедуру, переприсваивающую данные из записи в таблице в элементы управления на форме
if DataEdit.CanFocus                              // Устанавливает фокус на первое слева поле, если это возможно
then
DataEdit.SetFocus;
DBGridEh1.Enabled:=False;                         // Делает недоступной Grid
end;




Теперь для компонента ADOTableMain необходимо прописать обработчики четырех событий:
до вставки (BeforeInsert),
до редактирования (BeforeEdit),
после записи (отправки данных в источник - AfterPost),
после вставки (AfterInsert).
Эти процедуры будут выглядеть следующим образом:

procedure TMainFrm.ADOTableMainAfterInsert(DataSet: TDataSet);
begin
// Присвоение некоторых стартовых значений полям таблицы
ADOTableMain.FieldByName('MyDate').Value:=FormatDateTime('dd/mm/yyyy',now());
ADOTableMain.FieldByName('D').Value:=1;
ADOTableMain.FieldByName('K').Value:=1;
ADOTableMain.FieldByName('MO').Value:=MySelect.MySel_IDMO;
ADOTableMain.FieldByName('MO_Name').Text:=MySelect.MySel_MOName;
// Поднять запись на верхнюю панель
InsEdit;
end;
procedure TMainFrm.ADOTableMainAfterPost(DataSet: TDataSet);
begin
DBGridEh1.ReadOnly:=True;                         // Делает Grid НЕдоступной для редактирования
end;
procedure TMainFrm.ADOTableMainBeforeEdit(DataSet: TDataSet);
begin
MyEdits;                                          // Переписывает значения из источника базы данных в поля формы
end;
procedure TMainFrm.ADOTableMainBeforeInsert(DataSet: TDataSet);
begin
DBGridEh1.ReadOnly:=False;                        // Делает Grid доступной для редактирования
end;



Пояснения я постарался задать в //комментариях :-)
Теперь настало время вспомнить про разработанный нами несколько уроков назад навигатор. Пора его "приспособить" к главной таблице. Расположите его на нижней панельке и назначьте в качестве источника данных DataSource = DataSourceMain. Не забудьте установить "якоря" (Anchors), привязывающие его справа внизу:
akRight = True;
akBottom = True,
(другие два значения = False).
Если сейчас запустить проект и нажать на навигаторе кнопку "Добавить", то возникнет следующая ошибка:





Вообще-то, о способах и методах отладки я планирую поговорить в будущем. Тема эта неисчерпаема и довольно сложна. А сейчас, просто избавимся от лишнего поля, о котором идет речь в сообщении. Откуда оно взялось? Да, Бог его знает...
удалите строку кода:
ADOTableMain.FieldByName('MO_Name').Text:=MySelect.MySel_MOName;
После запуска проекта и попытке добавить новую запись Вы обнаружите, что:





1.  Новая запись со значениями по умолчанию добавлена в таблицу Main. Ура!
2. Остается активным меню. Правильно ли это?
3. Не работают элементы управления с выпадающими списками на верхней панельке.
4. Запись невозможно сохранить.
5. Невозможно вернуть форму к стартовому виду.
Давайте добавим для начала обработчики событий для кнопок Cancel и Post навигатора




procedure TMainFrm.PrDNavigator1nbCancelClick(Sender: TObject);
begin
DBGridEh1.Enabled:=True;                // После нажатия кнопки Cancel на навигаторе, сетка должна стать доступной
Panel3.Visible:=False;                            // Верхняя панелька становится не нужна, скроем ее
end;
procedure TMainFrm.PrDNavigator1nbPostClick(Sender: TObject);
begin
// Переприсвоение значений из контролов формы в поля таблицы
ADOTableMain.FieldByName('MyDate').Value:=DataEdit.Value;
ADOTableMain.FieldByName('D').Value:=DEdit.KeyValue;
ADOTableMain.FieldByName('K').Value:=KEdit.KeyValue;
ADOTableMain.FieldByName('Summa').Value:=SEdit.Value;
ADOTableMain.FieldByName('Rem').Text:=PEdit.Text;
DBGridEh1.Enabled:=True;               // После нажатия кнопки Post на навигаторе, сетка должна стать доступной
Panel3.Visible:=False;                           // Верхняя панелька становится не нужна, скроем ее
end;

Теперь по нажатию кнопки Post (сохранить) на навигаторе, форма возвращается к первоначальному виду, а данные из полей формы переписываются в таблицу базы данных.
Разберемся с элементами управления (DEdit, KEdit), которые должны содержать списки.
Прежде всего, для каждого из них нужно задать источник строк ListSource:





Элементы управления со списками работают так, что пользователю показывается понятное ему значение из списка (ListField), а программа записывает в элемент управления (и далее - в базу данных) соответствующий ему код (KeyField).
Исправив эту некорректность, Вы получите практически работающую программу.


Останутся такие мелочи, как быстрые клавиши, обработка двойных и одинарных кликов на DBGridEh и т.п.







Комментариев нет:

Отправить комментарий