Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка БД.doc
Скачиваний:
6
Добавлен:
16.11.2019
Размер:
842.75 Кб
Скачать

1.4.6. Пример выполнения лабораторной работы

Организация поиска

Допустим, у нас имеются четыре таблицы (см. прил. 1, вар. 3). На форме необходимо разместить 4 компонента Table, 4 DataSource и 4 DBGrid и связать их между собой (процедура связывания таблиц описана в лаб. работе № 2). Для выбора таблицы, в которой будет проводиться поиск, и поля поиска нам потребуется компонент ComboBox (способы работы с ним см. в [1]). Главное окно программы может выглядеть, например, так (рис. 14):

Рис. 14. Пример организации интерфейса приложения

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

  1. установить связи между таблицами так, чтобы главной стала выбранная таблица;

  2. задать в главной таблице условие фильтрации по тому значению поля, которое мы ищем.

Рассмотрим установление связей. Пусть, например, пользователь выбрал в ComboBox1 таблицу RECORDS, т.е. Table4. Чтобы для каждой записи можно было найти ее исполнителя, альбом, в который она входит, и стиль музыки, требуется сделать таблицу Table4 главной. Для этого вначале устраним существующие связи между таблицами (эту операцию удобно описать в отдельной процедуре):

Table1.MasterFields:='';

Table1.MasterSource:=nil;

Эти действия необходимо выполнить для каждой из четырех таблиц.

Далее, установим связи между таблицами так, чтобы для Table1 и Table2 главной стала таблица Table3, а для Table3 — таблица Table4.

Свойствам IndexName подчиненных таблиц, имеющих более одного индекса, присваиваются имена соответствующих индексов (их можно узнать в окне Object Inspector, просмотрев значения свойства IndexName требуемой таблицы). Например, если в таблице Table3 (ALBUMS) определены 3 индекса:

  • ID_ALBUM (индекс по коду альбома);

  • ID_ARTIST (по коду исполнителя);

  • ID_STYLE (по коду стиля),

то при связывании ее с таблицей Table1 (ARTISTS) нужно установить Table3.IndexName:=’ID_ARTIST’, а при связывании с Table2 (STYLES) устанавливается Table3.IndexName:=’ID_STYLE’, и т.д.

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

В последнюю очередь свойствам MasterFields присваиваются имена полей главных таблиц, по которым они связываются с подчиненными.

Итак:

Table1.MasterSource:=DataSource3;

Table1.MasterFields:='ID_ARTIST';

Table2.MasterSource:=DataSource3;

Table2.MasterFields:='ID_STYLE';

Table3.IndexName:='ID_ALBUM';

Table3.MasterSource:=DataSource4;

Table3.MasterFields:='ID_ALBUM';

Чтобы сформировать в ComboBox2 список полей таблицы Table4, очистим его и добавим в него все имеющиеся в Table4 имена полей:

ComboBox2.Clear;

for i:=0 to Table4.FieldDefs.Count-1 do

ComboBox2.Items.Add(Table4.FieldDefs.Items[i].Name);

В итоге, событие OnChange компонента ComboBox1 будет выглядеть так:

procedure TForm1.ComboBox1Change(Sender: TObject);

var

i: byte;

begin

// разрываем связи между таблицами

Table1.MasterFields:='';

Table1.MasterSource:=nil;

Table2.MasterFields:='';

Table2.MasterSource:=nil;

Table3.MasterFields:='';

Table3.MasterSource:=nil;

Table4.MasterFields:='';

Table4.MasterSource:=nil;

ComboBox2.Clear;

case ComboBox1.ItemIndex of

3: begin // выбрана таблица Table4

// делаем Table4 главной

Table1.IndexName:='ID_ARTIST';

Table1.MasterSource:=DataSource3;

Table1.MasterFields:='ID_ARTIST';

Table2.IndexName:='ID_STYLE';

Table2.MasterSource:=DataSource3;

Table2.MasterFields:='ID_STYLE';

Table3.IndexName:='ID_ALBUM';

Table3.MasterSource:=DataSource4;

Table3.MasterFields:='ID_ALBUM';

// заполняем ComboBox2 именами полей таблицы Table4

for i:=0 to Table4.FieldDefs.Count-1 do

СomboBox2.Items.Add(Table4.FieldDefs.Items[i].Name);

end;

0: begin // выбрана таблица Table1

// выполняем аналогичные действия для Table1

end;

1: begin // выбрана таблица Table2

// выполняем аналогичные действия для Table2

end;

2: begin // выбрана таблица Table3

// выполняем аналогичные действия для Table3

end;

end;

end;

Теперь опишем событие, которое произойдет, когда пользователь нажмет на кнопку «Поиск». В этом случае для выбранной пользователем таблицы нужно установить критерий фильтрации по выбранному полю. Событие будет выглядеть так (Edit1 — поле ввода значения, которое ищет пользователь):

procedure TForm1.Button1Click(Sender: TObject);

var

FilterString: String;

begin

FilterString:=ComboBox2.Text + '=''' + Edit1.Text + '''';

case ComboBox1.ItemIndex of

0: begin

Table1.Filter:=FilterString;

Table1.Filtered:=True;

end;

1: // аналогичные действия для Table2

2: // аналогичные действия для Table3

3: // аналогичные действия для Table4

end;

end;

В результате, как только пользователь нажмет на кнопку «Поиск», во всех таблицах должны появиться записи, соответствующие найденной записи в главной таблице.

Работа с формами

Часто на главной форме не хватает места для новых компонентов, или число их слишком велико для восприятия. В таких случаях используются дополнительные формы, которые невидимы до тех пор, пока не потребуется их отобразить.

Для создания нового окна в программе выберите в меню File->New->Form. Появится новая форма. При запуске программы она не будет видна, но во время разработки вы ее видите и можете размещать на ней компоненты. Для переключения между формами используйте клавиши Shift-F12.

Чтобы вызвать вторую форму (т.е. сделать ее видимой и активной), надо использовать метод ShowModal. Например, при нажатии кнопки «Добавить запись» на первой форме нужно, чтобы появилась вторая (рис. 15).

Это делается так:

procedure TForm1.Button1Click(Sender: TObject);

begin

Form2.Showmodal;

end;

Можно использовать и метод Show вместо ShowModal, но особенность последнего в том, что нельзя переключиться на другие окна программы, пока не будет закрыта форма, метод которой вызвали.

Если нужно из второй формы (Form2) обратиться к объектам первой формы (Form1), то надо это явно указать. Например, при нажатии кнопки на второй форме требуется изменить надпись на кнопке первой формы:

procedure TForm2.Button1Click(Sender: TObject);

begin

Form1.Button1.Caption:=’Новое имя’;

end;

Добавляя «Form1» перед интересующим нас объектом, мы и указываем, что действия надо проводить с объектом на первой форме.

Когда работа со второй формой завершена, ее надо закрыть. Это делает метод Close:

procedure TForm2.Button1Click(Sender: TObject);

begin

//Здесь выполняется все, что требуется

Close; // а здесь мы закрываем форму и возвращаемся

// на форму, откуда вызывали…

end;

Рис. 15. Использование дополнительной формы

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

В приведенном выше примере на второй форме находятся компоненты для изменения данных во всех четырех таблицах, причем таблицы, в которых необходимо вставить или изменить данные, пользователь отмечает «галочками» — компонент CheckBox. В этом компоненте есть свойство Checked, которое равно True, если «галочка» установлена, и False в противном случае. Компонент находится на закладке Standard.

Кроме того, рекомендуется использовать компонент DBLookupComboBox для установки значений тех полей, которые ссылаются на данные в справочных таблицах (рис. 16). Особенности работы с этим компонентом описаны ниже.

Рис. 16. Использование компонента DBLookupComboBox

Использование компонента DBLookupComboBox

Компонент DBLookupComboBox находится на закладке Data Controls (рис. 17). Он предназначен для формирования выпадающего списка значений на основе полей одной из таблиц БД.

Рис. 17. Компонент DBLookupComboBox

Для того чтобы получить полный набор этих значений, можно добавить дополнительный компонент Table, не связанный с другими таблицами, и DataSource для него. Свойства компонента DBLookupComboBox настраиваются так:

  • ListSource — это объект DataSource, связанный со справочной таблицей, по данным которой формируется выпадающий список;

  • ListField — поле таблицы, значения которого отображаются в списке. Эти значения будет видеть пользователь;

  • KeyField — поле таблицы, значение которого компонент возвращает при выборе пользователем одного из элементов списка.

Чтобы получить значение ключа выбранного элемента программно, нужно обратиться к свойству KeyValue. Оно имеет тип Variant; это означает, что вам может потребоваться преобразование типа перед использованием значения этого свойства:

var id: string;

...

id:=DBLookupComboBox1.KeyValue; // здесь тип Variant преобра-

// зуется к типу String

Table1.InsertRecord([Edit1.Text, id, Edit2.Text])

Необходимо отметить, что компонент DBLookupComboBox можно напрямую связать с таблицей, данные которой требуется изменить. Для этого в свойстве DataSource устанавливается источник данных редактируемой таблицы, а в DataField — ее поле. Тогда при выборе одного из элементов списка в это поле будет записано значение ключевого поля, указанного в KeyField.