Newsgroup: it.comp.appl.access
Titolo: Query in routine ?

Ho cercato di rendere più semplice possibile l'esposizione seguente,
perdonatemi se non ci sono riuscito.
Ho una tabella che contiene i dati di un albero genealogico. Un esempio del
formato è il seguente:
            <nome>                   <età>                  <figlio di>
            MARIA                        19                      MARIO
            MARIANNA                20                      MARIO
            MARYMARY               01                      MARIA
            MARIOLINO               02                       MARIANNA
            PIERINO                     35                       PIERO
            PIERINA                     27                       PIERO
            PIERPIERO               05                       PIERINO
Vorrei creare mediante query una tabella che raccoglie tutte le generazioni
che discendono a partire da un certo nominativo (fra quelli elencati nel
campo <figlio di>).
Intuitivamente a me sembra di dover impostare una query che inizialmente mi
chiede un nominativo come parametro di ricerca per il campo <figlio di> ad
es:
[Immetti nome del capostipite:]  MARIO
i record restituiti saranno:
            <nome>                   <età>                  <figlio di>
            MARIA                        19                      MARIO
            MARIANNA                20                      MARIO
poi la query automaticamente dovrebbe effettuare una ulteriore ricerca con
il parametro di ricerca MARIA accodando ai record precedenti i seguenti:
            <nome>                   <età>                  <figlio di>
            MARYMARY               01                      MARIA
poi la query automaticamente dovrebbe effettuare una ulteriore ricerca con
il parametro di ricerca MARIANNA accodando ai record precedenti i seguenti:
            <nome>                   <età>                        <figlio
di>
            MARIOLINO               02                            MARIANNA
......... e così a seguire con gli eventuali figli di MARIA e MARIANNA ecc..
Il bello è che non ho proprio idea di come praticamente posso impostarla. E'
probabile anche che io sia fuoristrada, c'è qualcuno così gentile da darmi
una dritta ? C'è un metodo più banale che magari mi sfugge ?
Ringrazio già da ora chi mi potrà aiutare.
Ciao
Massimo

Massimo ha scritto nel messaggio ...

Non so se sia risolvibile via query ma per me questo si tratta del tipico
problema ricorsivo.
Ho buttato giu' una sub, vedi un po se ti puo' servire...
Sub TROVAFIGLI(NOMEGENITORE, livello)
Dim rst As Recordset, strsql As String
strsql = "SELECT * FROM TABELLA1 WHERE NOMEGENITORE = '" & NOMEGENITORE &
"'"
Set rst = DBEngine(0)(0).OpenRecordset(strsql)
Do While Not rst.EOF
    Debug.Print rst("NOMEFIGLIO"), rst("NOMEGENITORE"), livello
    TROVAFIGLI rst("NOMEFIGLIO"), livello + 1
    rst.MoveNext
Loop
Set rst = Nothing
End Sub
La sub la invochi la prima volta passandogli il nome del capostipite che
vuoi analizzare.
Ho messo debug.print ma se vuoi puoi inserire i dati in un'altra tabella di
appoggio mediante INSERT
Ciao Nicola
PS Attenzione che le procedure ricorsive 'mangiano' memoria.

campo <figlio di>).
non credo che si possa fare con una query, almeno non agevolmente.
quello che ti consiglierei sarebbe una bella funzione ricorsiva.
ti faccio un esempio da una funzione che ho realizzato per scrivere
l'elenco di messaggi in un forum, rispettando la struttura del thread.
in fondo un thread e un albero genealogico si assomigliano parecchio.
considera che e' stata scritta in vbscript per essere eseguita in un
file asp, quindi puoi trovare alcune cose strane.
sub ScriviSotto(idMessaggio, Livello)
	dim ssql 
	dim rst
	dim i
 
	ssql = "SELECT * FROM tMessaggi WHERE Parent = " & idMessaggio
& " AND FlagPubblicazione = True ORDER BY id"
	set rst=cn.execute(ssql)
	do until rst.eof
		for i = 1 to Livello
			if i > 10 then 
				exit for
			end if
			rw "&nbsp;&nbsp;&nbsp;&nbsp; "
		next
		rw "<a href=Forum.asp?idMessaggio=" & rst("id") &
"&idForum=" & session("idForum") & " target=_top>" & rst("Sender") &
"</a>" 
		if not (rst.bof and rst.eof) then
			ScriviSotto rst("id"), Livello + 1
		else
			exit sub
		end if
		rst.movenext
	loop
end sub
--
make it idiot proof and someone will make a better idiot.
--
il sito comune di it.comp.appl.access:
http://members.xoom.it/it_db_access/

Grazie a Nicola e Ibo per le indicazioni. Non ne mastico affatto di ciň di
cui avete parlato, ma mi sembrano indicazioni precise e consultando magari
anche l'help in linea vedo cosa riesco a combinare. D'altronde č cosě che si
impara ed č cosě che mi piace. Eventualmente chiedo ulteriori chiarimenti.
Di nuovo grazie e a presto.
Massimo.

PS Attenzione che le procedure ricorsive 'mangiano' memoria.
Nello specifico che cosa intendi ???
Carlo Ve

 ha scritto nel messaggio
news:7rTd5.11999$sE5.1...@news.infostrada.it...

Ho perso un po' la mano con problemi di dimensionalità e amenità del genere
ma credo di poter affermare  che una procedura ricorsiva abbia una
dimensionalità non lineare (spero di non aver detto troppe sciocchezze).
In sostanza le variabili restano in memoria fino a quando la procedura non
viene conclusa per cui se ho una procedura ricorsiva molto profonda (quanto
non saprei) potrei andare ad occupare tutta la memoria disponibile senza
troppa difficoltà.
In attesa di essere smentito da qualcuno con conoscenze maggiori...
Ciao  Nicola




 Massimo
Potresti costruire una maschera dove inserirai :
1 combobox che elenca i capostipiti
1 pulsante con codice associato
nel codice scrivi
SUB pulsante_click()
 trovafigli nomecombobox
END SUB
Ora il problema resta quello di visualizzare i discendenti. Ti avevo
suggerito di scaricare i dati in una tabella di appoggio utilizzando ad
esempio INSERT.
La cosa si potrebbe fare in questo modo.Supponiamo che la tabella si chiami
APPOGGIO composta da tre campi (NOMEFIGLIO,NOMEGENITORE,Livello).
Prima di tutto va svuotata e questo lo potresti fare sempre nel codice del
pulsante prima di chiamare la procedura TROVAFIGLI
DOCMD.RUNSql "DELETE FROM APPOGGIO"
Poi la sub trovafigli puň essere riscritta in questo modo
Sub TROVAFIGLI(NOMEGENITORE, livello)
Dim rst As Recordset, strsql As String
strsql = "SELECT * FROM TABELLA1 WHERE NOMEGENITORE = '" & NOMEGENITORE &
"'"
Set rst = DBEngine(0)(0).OpenRecordset(strsql)
Do While Not rst.EOF
DoCmd.SetWarnings False
    DoCmd.RunSQL "INSERT INTO APPOGGIO VALUES (rst(""NOMEFIGLIO""),
rst(""NOMEGENITORE""), livello) "
DoCmd.SetWarnings true
    TROVAFIGLI rst("NOMEFIGLIO"), livello + 1
    rst.MoveNext
Loop
Set rst = Nothing
End Sub
La tabella APPOGGIO puň essere visualizzata in una sottomaschera della
maschera iniziale.
Ciao Nicola