Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Вывод родствеников (http://forum.oszone.net/showthread.php?t=259218)

student_po 23-04-2013 09:01 2138059

Вывод родствеников
 
Вложений: 2
Доброго времени суток. Есть база в access с именем члена семьи и данными о родителях.
Из этой базы как нужно вывести всех предков данного человека. Заранее спасибо всем.

lxa85 23-04-2013 10:26 2138103

student_po, это надо сделать средствами Access? Или средствами Delphi? Потому что средствами Access это проблематично. Средствами Delphi -- это задача на графы.

Iska 23-04-2013 11:41 2138148

Цитата:

Цитата 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

Iska 23-04-2013 13:10 2138208

student_po, так переведите с VBA на Delphi. Алгоритм один и тот же.

lxa85 23-04-2013 14:41 2138264

Iska, я с Access ом не работал. Поэтому я затруднился дать ответ. Была мысль написания единого SQL запроса, и она потонула в сомнениях (AFAIK SQL не поддерживает рекурсию). Поэтому возникла мысль запросить всю таблицу в Delphi, сформировать массива и работать с ним как с матрицей, описывающий граф гинеалогического дерева.

Iska 23-04-2013 15:11 2138278

lxa85, а мне сразу PROLOG вспомнился ;).

lxa85 23-04-2013 17:21 2138377

Iska, :yes:

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;

До деда по отцу доходит и встали. Где я скриворукил.

Iska 23-04-2013 18:46 2138428

student_po, обратите внимание на разницу — я сначала выбираю запись, делаю вывод «ФИО», затем проверяю в записи свойства «Отец»/«Мать» и, если они не пустые — рекурсивно вызываю процедуру. В Вашем коде логика иная: если у деда нет «Отца» — самого деда в «Memo2» Вы не увидите.


Время: 03:11.

Время: 03:11.
© OSzone.net 2001-