Формирование списка возможных значений столбца
Если значения постоянного столбца должны выбираться из некоторого фиксированного множества и Вы хотите получать список значений при редактировании столбца непосредственно в TDBGrid, этот список должен содержаться в свойстве PickList данного постоянного столбца.
При этом возможны 2 варианта - список возможных значений столбца является фиксированным и переменным.
Вариант 1. Список возможных значений столбца является фиксированным, т.е. не изменяется во времени. Тогда достаточно на этапе конструирования программы заполнить список свойства PickList (этот список имеет тип TStrings) постоянного столбца. В свойство ButtonSty/e необходимо установить значение cbsAuto. Тогда Delphi, обнаружив, что список PickList заполнен, автоматически будет помещать в столбце при редактировании его ячейки кнопку типа ComboBox (стрелка вниз).
Например, пусть для рассматриваемого примера сотрудники кафедры могут обладать учеными степенями доктора физико-математических наук (д.ф.-м.н.), доктора технических наук (д.т.н.), кандидата физико-математических наук (к.ф.-м.н.) и кандидата технических наук (к.т.н.). Предположим, что на работу не принимаются обладатели иных ученых степеней (например, доктора и кандидаты химических или социологических наук). Таким образом, список возможных значений столбца "Уч. степень" состоит из 4 значений (рис. 10.13).
При работе приложения, если мы корректируем ячейку столбца "Уч. степени", на экране появляется кнопка типа "Стрелка вниз" (рис.10.14).
Нажатие данной кнопки приведет к появлению выпадающего списка с фиксированными значениями (рис. 10.15).
При этом выбор значения в списке приведет к копированию его в текущую ячейку столбца, и, если данный столбец связан с полем ТБД, к последующему запоминанию в качестве значения поля ТБД в текущей записи.
Заметим, что наличие выпадающего списка не препятствует пользователю занести в столбец и иную информацию (рис. 10.16).
Рассмотрим второй вариант, когда список возможных значении столбца не является фиксированным, т.е. может изменяться во времени. Почти всегда в
таком случае источником значений служит другая, справочная ТБД В процессе работы справочная ТБД может меняться, записи в ней могут корректироваться, добавляться или удаляться Все внесенные изменения должны отображаться в списке PickList для рассматриваемого столбца TDBGnd
Пусть для рассматриваемого примера список возможных должностей находится в ТБД "UCHSTEP DB" (в поле UchStepen) Тогда проблема решается, если при всякой активизации формы, на которой расположен TDBGnd с постоянным столбцом, произвести следующие действия
1 Очистить список PickList для постоянного столбца "Уч степени",
2 Поместить все значения из поля UchStepen таблицы БД "UCHSTEP DB" в список PickList для постоянного столбца "Уч степени"
procedure TForm1.FormActivate(Sender: TObject);
begin
DBGrid1.Columns.Items[3].PickList.Clear;
WITH Table2 do begin
First;
WHILE not EOF do begin
DBGrid1.Columns.Items[3].PickList.Add (FieldByName('UchStepen').Value) ;
Next;
END; {while}
END; {with}
end;
Результат работы показан на рис 1017
ЗАМЕЧАНИЕ 1. Поле UchStepen в ТБД "UCHSTEP DB" должно быть уникальным, иначе в списке PickList появятся дублирующие друг друга значения Если поле, по которому строится PickList, неуникально, нужно программно предусмотреть дополнительный анализ дублирования в списке PickList
ЗАМЕЧАНИЕ
2. Аналогичного или сходного результата можно добиться путем использования поля, возвращающего значение (lookup-поля) Более подробно см раздел "Использование компонента TField"ЗАМЕЧАНИЕ
3. Если таблица-справочник содержит больше 10-15 записей, в список PickList ее заносить нерационально, поскольку пользователю весьма трудно будет искать нужное значение К другим недостаткам описываемого подхода можно отнести то, что список PickList не позволяет редактировать таблицу-источник (представим, что в процессе работы с кадровым составом кафедры нам понадобилось внести в справочник ученых степеней степень "кандидата философских наук")Два этих обстоятельства делают работу с выпадающим списком не очень удобной Поэтому, на взгляд автора, более рационально не формировать список PickList вручную или программно, а установить в свойство ButtonStyle постоянного поля значение cbsElhps и написать в обработчике нажатия кнопки (. .) OmtButtonChck вызов модальной формы, содержащей НД справочника После этого следует определить код занесения выбранного в справочнике значения в текущую ячейку постоянного столбца. Пример Для рассмотренной выше формы
1 Добавим в приложение форму Form2 (рис. 10.18), содержащую компонент TDBGnd, в котором показываются значения из ТБД "UCHSTEP DB" с возможностью их корректировки, а также 2 экранные кнопки - "Выбрать" (со свойством Moda/Result = mrOk) и "Отменить" (со свойством ModalResult = mrCancel);
2 Установим у постоянного столбца "Уч степень" в свойство ButtonStyle значение cbsElhps,
3. Напишем такой обработчик нажатия кнопки:
procedure TForm1.DBGridlEditButtonClick(Sender: TObject);
begin
// модальный вызов справочной ТБД "Ученые степени"
Form2.ShowModal;
// Если выбрана клавиша с модальным результатом mrOk // (т.е. клавиша "Выбрать" в Form2)
IF Form2.ModalResult = mrOK THEN
begin
// если НД сотрудников кафедры не находится в режиме dsEdit или dslnsert, переводим НД в режим dsEdit,
// поскольку иначе мы не сможем изменить значения поля UchStepen
IF Tablel.State = dsBrowse THEN TableI.Edit;
// производим присваивание значения поля
Formi.Tablel.FieldByName('UchStepen').Value := Form2.Tablel.FieldByName('UchStepen').Value;
end;
end;
Результат работы показан на рис. 10.19.
Заметим, что при выходе из обработчика мы не выполняем метод Tablel. Post, т.е. оставляем НД сотрудников кафедры в одном из режимов корректировки с тем, чтобы пользователь затем смог сам либо отменить внесение изменений в TDBGrid (клавишей Esc) или подтвердить внесение изменений (перейдя на другую запись в TDBGrid).
В вызываемой форме (Form2) можно добавлять, изменять и удалять записи, прежде чем осуществить выбор.
Заметим также, что в Form2 нужно предусмотреть ситуацию, когда нажата кнопка "Выбрать" или "Отменить", а НД, связанный с ТБД "UCHSTEP.DB", остался в одном из режимов редактирования. Например, в этом случае можно не производить выбора по нажатию кнопки "Выбрать" в обработчике события OnEditButtonClick формы Formi и принудительно переводить НД Form2.Table2 в режим dsBrowse с потерей последних неподтвержденных изменений (выполняя метод Cancel):
procedure TFormI.DBGridlEditButtonClick(Sender: TObject);
begin
Form2.ShowModal;
IF Form2.Tablel.State о dsBrowse THEN
begin
Form2.Tablel.Cancel ;
ShowMessage('Изменения в справочнике не запомнены');
Exit;
end;
IF Form2.ModalResult = mrOK THEN
begin
IF Tablel.State = dsBrowse THEN TableI.Edit;
Form1.Tablel.FieldByName('UchStepen').Value :=Form2.Tablel.FieldByName('UchStepen').Value;
end;
end;