Форма для работы с рейсами – заполнение выпадающего списка данными

Для демонстрации методики заполнения выпадающего списка создадим новую форму FormFlight. В верхней части формы находиться список, который должен показывать все рейсы. Чтобы ограничить список будем показывать только рейсы, вылетающие из указанного нами аэропорта. Выбор аэропорта вылета будем осуществлять при помощи выпадающего списка ComboBoxFrom.

Разместим на форме компоненты для работы с данными

Назначение запроса Компонент доступа к данным (IBQuery) Компонент модификации данных (IBUpdateSQL) Компонент источник данных DataSource
Находит аэропорты, из которых совершаются рейсы IBQueryAP    
Извлекает данные по рейсам (название авиакомпании, номер авиалиний, дата вылета, тип самолета, название аэропортов откуда и куда) IBQueryFl DataSourceFl  
Извлекает ФИО и роль членов экипажа для выбранного рейса IBQueryEQ IBQueryEQ IBUpdateSQLEQ
Данные по личности (для Lookup полей) IBQueryPr    

 

Для начала обеспечим первоначальное заполнение списка, для этого у формы создадим событие на создание - OnCreate (можно было также сделать событие на показ формы - OnShow). В этом событии нужно выполнить запрос, получающий все возможные аэропорты вылета. Нам нужно сохранить в нашем списке не только название аэропорта, но и его код. Для этого применим хитрый прием. Сначала напомним, что список строк (Items) может также использоваться для хранения для каждой строки ссылки на объект; осуществить это можно с помощью AddObject и свойства Objects. Обманем компонент и будем хранить не ссылки на какой – либо объект, а целые значения первичного ключа. Этого можно добиться путем преобразования целого типа в тип TObject. При использовании сохраненного значения для него нужно будет совершить обратное преобразование.

Итак, событие будет иметь следующий вид.

procedure TFormFlight.FormCreate(Sender: TObject);

Begin

ComboBoxFrom.Items.Add(' '); //вначале списка будет пустая строка

 

IBQueryAP.SQL.Text := 'select distinct AP.AP_CODE, AP.AP_NAME '

+ ‘from AIRPORT AP '

+ 'inner join AIRLINE AL on AP.AP_CODE =

+ 'AL.AL_AP_FROM order by AP.AP_NAME';

 

IBQueryAP.Open;

while not IBQueryAP.Eof do begin //вставляем в список аэропорты

ComboBoxFrom.Items.AddObject(IBQueryAP.FieldByName('AP_NAME').AsString,
TObject(IBQueryAP.FieldByName('AP_CODE').AsInteger));

IBQueryAP.Next;

end;

end;

Вначале списка будет вставлена пустая строка, при выборе которой мы должны будем получить все рейсы.

Сохраненные значения первичного ключа будут использоваться при выборе аэропорта из выпадающего списка, т.е. нам нужно создать обработчик OnClick для списка ComboBoxFrom.

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

SELECT A.AL_NUM, F.FL_DATE, A.AL_AP_FROM, A.AL_AP_TO, A.AL_PL_CODE, F.FL_BRD_NUM, AL_AC_CODE

FROM AIRLINE A

INNER JOIN FLIGHT F ON A.AL_NUM = F.FL_NUM

WHERE :from IN (A.AL_AP_FROM, 0)

 

Как работает такая конструкция? Если параметру передать ненулевое значение, будут отобраны только те записи, у которых значение поля равно указанному значению. Если передать 0, условие будет проигнорировано, и запрос вернет все записи.

При выборе строки в ниспадающем списке подставим значение кода аэропорта в параметр запроса и переоткроем этот запрос.

 

procedure TFormFlight.ComboBoxFromClick(Sender: TObject);

Begin

IBQueryFl.Close;

IBQueryFl.ParamByName('from').AsInteger := Integer(ComboBoxFrom.Items.Objects[ComboBoxFrom.ItemIndex]);

IBQueryFl.Open;

end;

Как видно, мы используем преобразование типа TObject к целому типу.

В нижней части формы будет располагаться список экипажа для указанного рейса. Соответствующий запрос (IBQueryEQ) будет иметь вид

SELECT PR.PR_NAME, PR.PR_NAME2, PR.PR_NAME3, RNK.RNK_NAME,

EQ.EQ_CODE, EQ.EQ_FL_DATE, EQ.EQ_RNK_CODE, EQ.EQ_PR_CODE, EQ.EQ_FL_NUM

FROM EQUIPAGE EQ

INNER JOIN RANK RNK ON EQ.EQ_RNK_CODE = RNK.RNK_CODE

INNER JOIN PERSON PR ON EQ.EQ_PR_CODE = PR.PR_CODE

WHERE EQ.EQ_FL_NUM = :NUM AND EQ.EQ_FL_DATE = :DT

Подстановка параметров и переоткрытие запроса производится при изменение текущих значения рейса (отработке события DataChange для компонента DataSourceFl)

 

procedure TFormFlight.DataSourceFlDataChange(Sender: TObject;

Field: TField);

Begin

IBQueryEQ.Close;

//члены экипажа зависят от номера авиалинии и даты рейса

IBQueryEQ.ParamByName('NUM').AsString := IBQueryFlAL_NUM.Value;

IBQueryEQ.ParamByName('DT').AsDate := IBQueryFlFL_DATE.Value;

IBQueryEQ.Open;

end;

Сделаем запрос IBQueryEQ редактируемым при помощи компоненты UpdateSQL.