Newsgroup: it.comp.appl.access
Titolo: [Rapporti famigliari] come implementarli???

Innanzitutto un ciao a tutti,
visto che l'ultima volta che ho scritto, ho solo scroccato consigli, questa
volta voglio anche dare  un piccolissimo contributo con una funzioncina che
ho utilizzato per ricercare dei dati, al posto di utilizzare il classico
'trova' di Access (menoso perchè bisogna settare se parte del campo, se
cercare in su , in giù ecc. ecc.).
Sicuramente i più in gamba avranno modo di sorridere e migliorarla (sarà
meglio per tutti noi) ...ma le mie capacità non sono elevate.
Ora veniamo al mio problema...
sono alle prese con uno di quei problemi che mi fanno arrovellare il
cervello senza cavare un ragno dal buco.
Come da oggetto devo implementare i rapporti famigliari (padre, madre, ecc.
fino al 3° grado di parentela!!!!) di una serie di personaggi inseriti in
una
tabella.
Io pensavo di relazionare in modo ricorsivo, cioè duplicare nella finestra
delle relazioni, la tblPersone con una tabella tblRappFam composta dai
campi:
tblPersone.ID   tblRappFam.Tipo   tblPersone(1).ID
Poi tramite una function (mi viene male al solo pensiero) completare i
rapporti
famigliari della persona specificata con tutte le altre correlate ad essa.
Forse un esempietto spiega meglio eh?
Allora...
se in una maschera dichiaro che Pippo è figlio di Ciccio, cioè aggiungo un
record es:
tblPersone.ID   tblRappFam.Tipo   tblPersone(1).ID
     Pippo                figlio                        Ciccio
e nella tabella tblRappFam Ciccio è gia stato inserito come marito di Minni,
la funzione dovrebbe aggiungermi un record:
tblPersone.ID   tblRappFam.Tipo   tblPersone(1).ID
     Pippo                figlio                        Minni
NB: * ID in effetti è numerico
Sono sulla strada giusta o fuori completamente?
Voi come risolvereste?
Eventualmente un aiutino o una dritta sulla *funzioncina*?
Un grazie di cuore a chi perderà un po' di tempo su questo quesito.
Come promesso ecco la funzioncina 'cerca':
**********************
Public Function Cerca()
On Error GoTo ERRORE
Dim dbs As Database              '
Dim tdf As TableDef              '
Dim fld As Field                 '
Dim intTipodati As Integer       '
Dim strDaTrovare As String       '
Dim strDaTrovMod1 As String      '
Dim StringaCambiata As Boolean   ' dichiaro le variabili
Dim strMex As String             '
Dim strPerSQL As String          '
Dim rst As Recordset             '
Dim varSLib As Variant           '
Set dbs = CurrentDb
' imposto la variabile tabella *tdf* con l'origine record della maschera
corrente
Set tdf = dbs.TableDefs(Screen.ActiveForm.RecordSource)
' rendo lo stato attivo al controllo precedente alla pressione del pulsante
Screen.PreviousControl.SetFocus
' imposto la variabile campo *fld* con l'origine dati del controllo corrente
Set fld = tdf.Fields(Screen.ActiveControl.ControlSource)
StringaCambiata = False ' imposto a falso il flag
strMex = "Cosa devo cercare?" ' imposto il testo della InputBox
' imposto la variabile stringa con il testo immesso nell'Inputbox
strDaTrovare = InputBox(strMex, "Trova nel campo " & UCase(fld.Name), _
                         Nz(strDaTrovare, ""), 5000, 6000)
' se non è stato immesso testo o si è premuto il tasto Annulla esco dalla
funzione
If strDaTrovare = "" Then Exit Function
' imposto il recorset sull'origine dati della maschera
Set rst = Screen.ActiveForm.RecordsetClone
With rst
   Do Until strDaTrovare = "" ' ciclo fino a quando il testo immesso è nullo
   ' imposto la striga di filtro per il metodo Find in base al campo
selezionato
   ' e controllo che si effettui la ricerca in un campo in cui è consentito
      Select Case fld.Type
         Case 2 To 4   ' numerico
            strPerSQL = " = " & Trim(strDaTrovare)
         Case 8   ' data/ora
            strPerSQL = " = #" & Format(Trim(strDaTrovare), "yyyy" & "/" &
"mm" & "/" & "dd") & "#"
         Case 10   ' testo (in questo caso permetto la ricerca in parte del
campo)
            strPerSQL = " Like " & Chr(34) & "*" & Trim(strDaTrovare) & "*"
& Chr(34)
         Case Else ' altrimenti messaggio e esco dal 1° ciclo
            MsgBox "Impossibile effettuare una ricerca in questo campo!" _
                  , vbInformation, "Esecuzione terminata"
            Exit Do
      End Select
      .MoveLast ' muovo il puntatore all'ultimo record per riempire il
buffer della memoria
      .MoveFirst ' torno al primo record
      .FindFirst fld.Name & strPerSQL   ' cerco il primo record che soddisfa
le condizioni
      If .NoMatch Then ' se non ho trovato nulla mex e via dal 1° ciclo
         MsgBox "Nessuna corrispondenza trovata in questo campo!", _
                 vbInformation, "Testo non trovato"
         Exit Do
      End If
      varSLib = .Bookmark ' altrimenti marco la posizione
      Screen.PreviousControl.SetFocus ' rendo disponibile il controllo per
il segnalibro
      Screen.ActiveForm.Bookmark = varSLib ' visualizzo nella maschera il
recor trovato
      Do Until .EOF ' ciclo fino alla fine del recordset
' imposto questa variabile per verificare se nell'InputBox è cambiata la
stringa  di ricerca
         strDaTrovMod1 = InputBox(strMex, "Continua la ricerca nel campo " _
                        & UCase(fld.Name), strDaTrovare, 2000, 2000)
         If strDaTrovare = strDaTrovMod1 Then ' se è uguale
            .FindNext fld.Name & strPerSQL ' cerco il successivo record
            If .NoMatch Then ' se non ne trovo mex e via dal 2° ciclo
               StringaCambiata = False
               MsgBox "Nessun altra corrispondenza trovata in questo
campo!", _
                                    vbInformation, "Testo non trovato"
               Exit Do
            End If
            varSLib = .Bookmark ' se trovo... come prima
            Screen.PreviousControl.SetFocus
            Screen.ActiveForm.Bookmark = varSLib
         Else ' se la stringa di ricerca (strDaTrovMod1) è diversa
            StringaCambiata = True ' flag a vero
            strDaTrovare = strDaTrovMod1 ' e imposto la stringa da trovare
con quella nuova
            Exit Do ' esco dal 2° ciclo per rifare tutto il 1°
         End If
      Loop
' se ho raggiunto l'ultimo record oppure è stata impostata a zero la
lunghezza della stringa
      If StringaCambiata = False Or strDaTrovare = "" Then
         Exit Do ' esco anche dal 1° ciclo
      End If
   Loop ' altrimenti faccio un'altro giro
   .Close ' chiudo il recordset
End With
ESCI:
   Set rst = Nothing    '
   Set fld = Nothing    ' imposto i vari oggetti a nulla
   Set tdf = Nothing    '
   Set dbs = Nothing    '
   Screen.PreviousControl.SetFocus ' rendo attivo il controllo precedente al
clic del pusante
   Exit Function
ERRORE:
   If Err.Number = 0 Then
      Resume Next
   ElseIf Err.Number = 438 Then
      MsgBox "Prima di trovare dei dati bisogna che almeno" & vbCrLf & _
            "un campo sia selezionato.", vbCritical, "Errore: campo non
selezionato"
      Resume ESCI
   ElseIf Err.Number = 3070 Then
      MsgBox "Stringa di ricerca non valida per il campo selezionato!" _
            , vbCritical, "Errore: tipo di dati non corrispondenti"
      Resume ESCI
   ElseIf Err.Number = 3077 Then
      MsgBox "Stringa di ricerca non valida per il campo selezionato!" _
            , vbCritical, "Errore: tipo di dati non corrispondenti"
      Resume ESCI
   Else
      MsgBox Err.Number & vbCrLf & Err.Description, vbCritical, "Errore non
gestito"
      Resume ESCI
   End If
End Function
*******************************************
Ciao, Simone

Io ho fatto cosí (premetto che quanto segue non gestisce i nuclei storici se
hai questa esigenza allora bisogna fare un'altro discorso):
Sono andato all'anagrafe e mi sono fatto dare tutti i codici che loro
utilizzano tipo
CF = capo famiglia
FGO Figlio/Figlia
FGA Fifglia (vediamo di leggerla bene questa sigla ... )
MG moglie
CV Convivente
MD Madre (nel senso di madre del CF)
PD padre (come sopra solo che é il nonno)
CU cugino
ecc ecc (tutti i rapporti di parentela dei componenti del nucleo familiare
con il CF)
Ora se strutturi la ricorsione in questo modo
Codice_persona PK
Nome
Cognome
Parentela
Ecc.
Ecc.
Codice_CF (che é la FK)
é imponi che:
   il CF nel campo codice_CF ha il codice_persona di se stesso
   quando insersci una qualsiasi persona devi assegnargli anche il codice
del suo CF
Risultato: tutti i componenti il nucleo familiare hanno il proprio
codice_persona e nel campo Codice_CF il codice del proprio CF (il CF di se
stesso).
ESEMPIO
Se inserisci i record
1000
Paolino
Paolone
FGO
ecc.
ecc.
123
1001
Bella
Bionda
MG
ecc.
ecc.
123
(deve esistere giá il record con codice_persona =123 ed essere un CF questo
lo controlli con un trigger - o una procedura se il tuo database non
supporta i trigger- e con un controllo referenziale) allora non devi
inserire un record per dire che Paolino Paolone é figlio anche di Bella
Bionda in quanto appartengono allo stesso nucleo familiare e sono
rispettivamente moglie e figlio del CF 123. Il rapporto di parentela tra i
due (nel caso semplice) lo deduci (lo  espliciti con una tabella a parte nel
caso che Bella Bionda sia la seconda moglie di 123 e che Paolino Paolone sia
figlio della prima moglie e figliastro di Bella Bionda).
Ovviamente a richiesta posso fornire svariati rompicapi per gli
azzeccagarbugli delle situazione dove ad esempio la moglie del cognato sposa
il cugino del nonno il quale a sua volta convive con la sorella del padre di
suo nipote e tutti vivono a casa del figlio di tua zia  ma la struttura nel
suo complesso regge bene (per i nuclei familiari non storicizzati).
Prooova!!!

Proverò grazie (anche se sarà dura...)
cosa intendi per nuclei familiari non storicizzati ?