Обработчик OnDoubleClick
procedure TForm2.DBGrid2DblClick(Sender : TObject);
var NewRangeID, SelectedEmployeeID : String; begin { Выводим информацию о текущей записи } if Table1.FieldByName('Boss_ID').AsString = '' then Label1.Caption := Table2.FieldByName ('Boss_ID').AsString else Label1.Caption := Label1.Caption + ':' + Table2.FieldByName ('Boss_ID').AsString; { Предполагается, что свойство Table1.IndexFieldNames все еще равно 'Boss_ID;Emp_ID' } SelectedEmployeeID := Table2.FieldByName ('Emp_ID').AsString; NewRangeID := Table2.FieldByName ('Boss_ID').AsString; Table1.SetRange([NewRangeID],[NewRangeID]);
Table1.FindKey([NewRangeID, SelectedEmployeeID]);
end; procedure TForm2.UpOneLevelButtonClick(Sender : TObject);
var PrevPos : Integer; NewRangeID : String; begin { Записи фильтруются по Boss_ID выбранного работника. } NewRangeID := Table1.FieldByName ('Boss_ID').AsString; Table1.CancelRange; Table1.IndexFieldNames := 'Emp_ID'; Table1.FindKey([NewRangeID]);
NewRangeID := Table1.FieldByName ('Boss_ID').AsString; Table1.IndexFieldNames := 'Boss_ID'; { Восстанавливаем синхронизацию Table2. } Table1.SetRange([NewRangeID],[NewRangeID]);
if Table1.FieldByName('Boss_ID').AsString = '' then Label1.Caption := '<Top level>
'; else begin PrevPos := 0; while Pos(':', Copy(Label1.Caption, PrevPos + 1, 999))<>
0 do PrevPos := Pos(':',Copy(Label1.Caption, PrevPos +1, 999)) + PrevPos; Label1.Caption := Copy(Label1.Caption, 1, (PrevPos - 1));
end; end;
Когда пользователь нажимает кнопку Up One Level, записи левой таблицы фильтруются по значению Boss_ID текущего фильтра. Хотя этот способ и допускает бесконечную рекурсию, вы все равно не сможете легко получить список всех подчиненных текущего начальника вместе с их подчиненными и так далее, вниз по иерархии. Кроме того, вам также не удастся получить всю цепочку вышестоящих начальников. Для этого придется перемещаться по ссылкам в нужном направлении, причем заранее неизвестно, через сколько уровней иерархии потребуется пройти.
Но и такие иерархии приносят пользу — они позволяют выбрать объект любого уровня и при этом снабжают приложение адекватными данными. Например, вы можете последовательно разделять географический регион на более мелкие области, но приложение всегда сможет узнать, к какому региону относятся эти области (кто является родителем самого верхнего уровня).
Кроме того, общие категории можно разделить на отдельные специали зации, но так, чтобы выбор общей категории приводил к включению всех специализаций. Например, при выборе категории «художники» в нее будут автоматически включены художники-портретисты, художники-баталисты, художники-маринисты и т. д. В этом случае для получения списка объектов общей категории вам не придется составлять отдельные списки для членов каждой специализации.