Показать полную графическую версию : Вывод родствеников
student_po
23-04-2013, 09:01
Доброго времени суток. Есть база в access с именем члена семьи и данными о родителях.
Из этой базы как нужно вывести всех предков данного человека. Заранее спасибо всем.
student_po, это надо сделать средствами Access? Или средствами Delphi? Потому что средствами Access это проблематично. Средствами Delphi -- это задача на графы.
Потому что средствами Access это проблематично. »
Почему? Обычная рекурсия (концепт, без необходимых проверок):
Option Compare Database
Option Explicit
Sub Sample(strFIO As String)
Dim objRS As Recordset
Dim lngLevel As Long
lngLevel = 0
Set objRS = CurrentDb.OpenRecordset("SELECT * FROM Genealogy WHERE [ФИО] = '" & strFIO & "'")
GetParents objRS.Fields.Item("ID").Value, lngLevel
End Sub
Sub GetParents(lngID As Long, ByVal lngLevel)
With CurrentDb.OpenRecordset("SELECT [ФИО], [Отец], [Мать] FROM Genealogy WHERE [ID] = " & lngID & "")
With .Fields
Debug.Print String(lngLevel, vbTab) & .Item("ФИО").Value
lngLevel = lngLevel + 1
If Not IsNull(.Item("Отец").Value) Then
GetParents .Item("Отец").Value, lngLevel
End If
If Not IsNull(.Item("Мать").Value) Then
GetParents .Item("Мать").Value, lngLevel
End If
End With
End With
End Sub
Примерный результат работы по вызову «Sample("Я")»:
Я
Папа
Дед (отец отца)
Бабка (мать отца)
Мама
Дед (отец матери)
Бабка (мать матери)
student_po
23-04-2013, 12:18
Средствами Delphi
student_po, так переведите с VBA на Delphi. Алгоритм один и тот же.
Iska, я с Access ом не работал. Поэтому я затруднился дать ответ. Была мысль написания единого SQL запроса, и она потонула в сомнениях (AFAIK SQL не поддерживает рекурсию). Поэтому возникла мысль запросить всю таблицу в Delphi, сформировать массива и работать с ним как с матрицей, описывающий граф гинеалогического дерева.
lxa85, а мне сразу PROLOG вспомнился ;).
student_po
23-04-2013, 18:13
procedure TForm1.genealogy(iddb:integer);
var f,m:integer;
begin
Datam.ADOQuery3.Locate('id',iddb, []);
if Datam.ADOQuery3.FieldByName('Отец').AsInteger<>0 then
begin
f:=(datam.ADOQuery3.FieldByName('Отец').AsInteger);
Memo2.Lines.Add(inttostr(f));
Datam.ADOQuery3.Locate('id',f, []);
genealogy(Datam.ADOQuery3.FieldByName('id').AsInteger);
end;
if Datam.ADOQuery3.FieldByName('Мать').AsInteger<>0 then
begin
m:=(datam.ADOQuery3.FieldByName('Мать').AsInteger);
Memo2.Lines.Add(inttostr(m));
Datam.ADOQuery3.Locate('id',m, []);
genealogy(Datam.ADOQuery3.FieldByName('id').AsInteger);
end;
end;
До деда по отцу доходит и встали. Где я скриворукил.
student_po, обратите внимание на разницу — я сначала выбираю запись, делаю вывод «ФИО», затем проверяю в записи свойства «Отец»/«Мать» и, если они не пустые — рекурсивно вызываю процедуру. В Вашем коде логика иная: если у деда нет «Отца» — самого деда в «Memo2» Вы не увидите.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.