Newsgroup: it.comp.lang.visual-basic
Titolo: Qualcuno mi puo aiutare? Recordset ricursivi

Ciao a tutti ,
mi chiamo FLavio ed ho un problema con i recordset ricursivi:
Nella mia tabella ci sono (tra i vari campi)Padri e figli.
Devo trovare dato un padre tutti i flgli,a sua volta tutti i figli dei figli
e cosě via.
Questo lo devo fare con VB ma non trovo il codice appropiato.
Grazie a tutti coloro che mi risponderanno
FLAVIO

e cosě via.
Come ti dimostrero', e' necessario il solo campo [Padre] per definire e
trovare tutto un ramo (o l'intero albero) di una genealogia. Se il campo
e' Null o e' settato ad un apposito valore-sentinella, il record
rappresenta un capostipite della genealogia.
Alla struttura del record aggiungerei pero' un campo booleano da
resettare prima del ciclo in modo da evitare (o segnalare) riferimenti
circolari dovuti ad un'errata costruzione dei dati.
Ipotizziamo di avere una tabella in un database Access e che la nostra
tabella si chiami [Genealogia] e che abbia tre campi:
[CognomeENome] che rappresenta l'ID univoco del record (p.e. testo[50])
[Padre] che fa riferimento ad un [CognomeENome] di un record diverso
(testo[50])
[Flag] per evitare riferimenti circolari (Bool).
Prima di partire, resetto [Flag] a False usando questa query SQL:
UPDATE [Genealogia] SET [Flag] = False;
Definisco ora la QueryDef qdfTrovaFigli con il seguente codice SQL:
PARAMETERS [Papa] TEXT;
SELECT * FROM [Genealogia] WHERE [Padre] = [Papa];
ed anche la QueryDef di comando qdfSettaFlag per settare il flag:
PARAMETERS [Codice] TEXT;
UPDATE [Genealogia] SET [Flag] = True WHERE [CognomeENome] = [Codice];
Il codice che effettua la scansione dell'albero potrebbe dunque essere:
Function ScansioneAlbero(ByVal sPadre$) As Boolean
    Dim rstFigli As Recordset
    ' Inizializzo a False il valore di ritorno della funzione
    ScansioneAlbero = False
    ' Setto il flag per questo record
    qdfSettaFlag!Codice = sPadre
    qdfSettaFlag.Execute
    ' Passo il parametro alla query e creo lo snapshot con i figli del
padre
    qdfTrovaFigli!Papa = sPadre
    Set rstFigli = qdfTrovaFigli.OpenRecordset(dbOpenSnapshot)
    ' Scansione per i figli
    Do While Not rstFigli.EOF
        ' Controllo di non essere gia' passato da questo record
        If rstFigli("Flag") Then
            MsgBox "Riferimento circolare", vbCritical, "Errore!"
            Exit Do
        End If
        ' Chiamo ricorsivamente la funzione per trovare i figli dei
figli e cosi' via
        ' Se si verifica un errore, questo si propaga per tutte le
chiamate
        If Not ScansioneAlbero(rstFigli("CognomeENome")) Then Exit
Function
        ' Prossimo figlio
        rstFigli.MoveNext
    Loop
    ' Libero l'oggetto ed setto a True il valore della funzione
    Set rstFigli = Nothing
    ScansioneAlbero = True
    ' qui potrebbe andare il codice per processare questo record
End Function
Questo codice dovrebbe fare al caso tuo. Non c'e' il controllo degli
errori, ma non si puo' avere tutto dalla vita... :-)
Ciao
Gian Michele Bertoni
--
Home Page: 
http://space.tin.it/computer/gbertoni/


ANCORA!!!
BASTA!!!
E' le centesima volta che posti questa risposta, ed e' la duecentesima che
la gente ti da soluzioni senza che tu ti degnassi di rispondere e
commentarle!!!
MA LEGGI QUESTO NG O NO?
Mo ti invio un mail in privato per dirti di leggerti il NG!!!   E che
ca...o!
Ti riposto ancora una volta la mia soluzione, ma questa e' l'ultma volta!
=======================================================
Un modo potrebbe essere quello di memorizzare in un campo testo il Path.
in pratica ogni record ha il campo [Path] del tipo:
Nome        Path
-----------------------------
Mario       "00"
Claudio     "01"
Sara        "02"
Gigi        "00/00"
Luca      "00/01"
Rosa        "00/02"
Paola       "01/00"
Nicola      "01/01"
Fabio       "01/01/00"
Cristina    "01/01/01"
Luciana     "00/02/00"
Elisabetta  "00/02/01"
Paperino    "00/02/00/00"
Pluto       "00/02/01/00"
A questo punto se vuoi sapere tutti i figli di Rosa basta fare:
"SELECT * FROM [Tabella] WHERE (Left$([Path],4)="00/02") ORDER BY
len([Path])"
Ovviamente si puo fare anche:
Nome        Path
-----------------------------
Mario       "Mario"
Claudio     "Claudio"
Sara        "Sara"
Gigi        "Mario/Gigi"
Luca      "Mario/Luca"
Rosa        "Mario/Rosa"
Paola       "Claudio/Paola"
Nicola      "Claudio/Nicola"
Fabio       "Claudio/Nicola/Fabio "
Cristina    "Claudio/Nicola/Cristina"
Luciana     "Mario/Rosa/Luciana"
Elisabetta  "Mario/Rosa/Elisabetta"
Paperino    "Mario/Rosa/Luciana/Paperino"
Pluto       "Mario/Rosa/Elisabetta/Pluto"
L'unica limitazione e' che il Path non puo' essere piu' lungo di 255 Bytes,
ma forse puoi usare un campo memo.
By -MES-   Maronese Ettore
http://ilmes.freeweb.org
(con OCX per stampare i recordset)
Sito Comune di programmatori Visual Basic
http://www.murialdo.it/it_lang_vb

...
Grazie,
ma il mio intento non era certo quello di scroccare in eterno
Ciao!!

...


...


Grazie,
ma questa soluzione va bene se devo creare una tabella per poi inserire il
tutto ,mentre io devo lavorare su una tabella esistente
CIAO

???