Программирование формы для расписания – использование параметров запроса
Как это видно из модели расписание зависит, прежде всего, от выбранной авиалинии, таким образом, целесообразно спроектировать форму для работы с расписанием разместив на ней две таблицы и два навигатора. Верхняя пара этих визуальных компонентов будет служить для работы с таблицей AIRLINE (Авиалиния), а нижняя для TIMETABLE (Расписание). Разместим компоненты доступа к данным, настроим их, связав с базой данных, и затем свяжем наборы данных с визуальными компонентами, размещенными на форме. Результат показан на рисунке 22.
Рисунок 22 Форма FormTimeTable – Расписание
Приведем названия компонент размешенных на форме. Если колонка «Компонент модификации данных» не заполнена, это значит, что данный запрос не редактируется.
Назначение запроса | Компонент доступа к данным (IBQuery) | Компонент модификации данных (IBUpdateSQL) | Компонент источник данных DataSource |
Извлекает номера авиалиний, тип самолета, название авиакомпании, название аэропортов откуда и куда | IBQueryAL | IBUpdateSQLAL | DataSourceAL |
Извлекает все данные из расписания для выбранной авиалинии. | IBQueryTBL | IBUpdateSQLTBL | DataSourceTBL |
Находит максимальный существующий порядковый номер аэропорта в расписании для выбранной авиалинии | IBQueryNumb |
Для запроса расположенного в верхней части (IBQueryAL) зададим SQL запрос, который извлечет все номера авиалиний, тип самолета, название авиакомпании, название аэропортов откуда и куда. Результат упорядочим по номерам авиалиний.
SQL = ‘SELECT AL_NUM, AL_PL_CODE, AL_AC_CODE, AL_AP_FROM, AL_AP_TO
FROM AIRLINE ORDER BY AL_NUM '
Добавим все поля (Add all fields) в этом запросе и зададим их свойства, для полей AL_AC_CODE, AL_AP_FROM, AL_AP_TO зададим свойство Visible (видимость) – False, это сделано т.к. нам не нужно видеть коды авиакомпаний и аэропортов, а нужно получить их названия. Добавим Lookup поля для просмотра названия авиакомпании (используем для извлечения названия запрос IBQueryAC из формы справочники FormRef), названий аэропорта откуда и куда (используем для извлечения названия запрос IBQueryAP из формы справочники FormRef). Для всех полей введем русские наименования и установим ширину, при которой все поля помещаются в решетку без прокрутки.
Помещаем на форму компонент IBUpdateSQL, чтобы обеспечить редактирование этого запроса.
В нижней части запрос должен вывести все строки расписания для выбранной авиалинии. Для этого используем запрос с параметрами.. Параметр, которому мы дадим имя «al», будем использовать в условии where:
SELECT TBL_AL_NUM, TBL_AP_CODE, TBL_START_TIME, TBL_DOWN_TIME, TBL_NUMBER FROM TIMETABLE
WHERE TBL_AL_NUM = :al
Как мы это уже делали для верхнего запроса, добавим все поля для нижнего запроса и зададим их свойства.
Теперь необходимо обеспечить подстановку в запрос значения параметра соответствующего коду авиакомпании являющейся текущей в верхней таблице. Иными словами при каждом изменении в верхнем источнике данных нужно закрыть нижний запрос, подставить в него новое значение параметра и вновь его открыть.
Воспользуемся событием onDataChange для компонента DataSourceAL.
procedure TFormTimeTable.DataSourceALDataChange(Sender: TObject; Field: TField);
Begin
IBQueryTBL.Close;
IBQueryTBL.ParamByName('al').AsInteger := IBQueryACAL_NUM.AsInteger;
IBQueryTBL.Open;
end;
Мы видим, что при выборе новой Авиалинии в верхней таблице произойдет переоткрытие запроса IBQueryTBL с новым параметром соответствующим текущему значению номера авиалинии (IBQueryACAL_NUM.AsInteger). На рисунке 23 Показано как это будет выглядеть.
Теперь нужно сделать запросы редактируемыми, настроив компоненты UpdateSQL.
Рисунок 23 Вид формы «Расписание»
Осталось добавить механизм, который сделает две вещи. Во-первых при создании новой записи для таблицы «Расписание» подставит в качестве значения поля TBL_AL_NUM номер авиалинии. Во-вторых автоматически пронумерует последовательность аэропортов на маршруте TBL_NUMBER. Для того чтобы это реализовать, нужно воспользоваться событием onAfterInsert (после вставки) для компонента IBQueryTBL.
procedure TFormTimeTable.IBQueryTBLAfterInsert(DataSet: TDataSet);
Begin
//номер авиалинии
IBQueryTBLTBL_AL_NUM.AsInteger := IBQueryTBL.ParamByName('al').AsInteger;
//новый порядковый номер
IBQueryNumb.ParamByName('al').AsInteger := IBQueryTBLTBL_AL_NUM.AsInteger;
IBQueryNumb.Open;
IBQueryTBLTBL_NUMBER.AsInteger := IBQueryNumb.Fields[0].AsInteger + 1;
IBQueryNumb.Close;
end;
Теперь каждый раз при добавлении новой записи в таблицу «Расписание» номер авиалинии будет в этой строке устанавливаться автоматически. Порядковый номер аэропорта вычисляется при помощи запроса IBQueryNumb, который вычисляет максимальный существующий порядковый номер для заданной авиалинии.
SELECT MAX (TBL_NUMBER)
FROM TIMETABLE WHERE TBL_AL_NUM = :al
Понятно, что компонент IBQueryNumb должен быть предварительно размещен на форме и настроен. Как видно этот запрос также использует параметр, при помощи которого задается номер авиалинии.