student_po |
23-04-2013 09:01 2138059 |
Вывод родствеников
Вложений: 2
Доброго времени суток. Есть база в access с именем члена семьи и данными о родителях.
Из этой базы как нужно вывести всех предков данного человека. Заранее спасибо всем.
|
student_po, это надо сделать средствами Access? Или средствами Delphi? Потому что средствами Access это проблематично. Средствами Delphi -- это задача на графы.
|
Цитата:
Цитата lxa85
Потому что средствами 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 2138182 |
Средствами Delphi
|
student_po, так переведите с VBA на Delphi. Алгоритм один и тот же.
|
Iska, я с Access ом не работал. Поэтому я затруднился дать ответ. Была мысль написания единого SQL запроса, и она потонула в сомнениях (AFAIK SQL не поддерживает рекурсию). Поэтому возникла мысль запросить всю таблицу в Delphi, сформировать массива и работать с ним как с матрицей, описывающий граф гинеалогического дерева.
|
lxa85, а мне сразу PROLOG вспомнился ;).
|
student_po |
23-04-2013 18:13 2138401 |
Код:
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» Вы не увидите.
|
Время: 03:11.
© OSzone.net 2001-