IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Access Discussion :

Somme des descendants


Sujet :

Access

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut Somme des descendants
    Bonjour,
    j'essaye de compter le nombre de descendants d'une personne.
    J'ai une table "personne" reliée à elle même via les relations: "A pour père"et "A pour mère".
    Je peux facilement compter le nombre d'enfants qu'a une personne en faisant un regroupement sur son identifiant dans le champ "num_père" ou "num_mère", mais ce que je voudrais faire, c'est compter le nombre de descendants total, c'est à dire la somme de chaque génération.
    Quelqu'un pourrait m'aider pour faire la requête car je ne vois pas comment faire?
    Merci

  2. #2
    seb92400
    Invité(e)
    Par défaut
    J'ai une table "personne" reliée à elle même
    euh...

    As-tu un extrait de tes tables ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Je ne vois pas ce que tu veux dire par extrait, mais donc ce que je voulais dire, c'est que j'ai dans ma base de donnée, la table "Personne" reliée à elle même par les associations "A pour père"et "A pour mère". C'est à dire, une personne a un et un seul père, et une et une seule mère.

  4. #4
    Membre chevronné
    Inscrit en
    Août 2006
    Messages
    1 588
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 1 588
    Points : 2 178
    Points
    2 178
    Par défaut
    Un exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     Nb = NbDescendants(17)
    Si 17 est le numero de l'enfant (champ NumeroAuto Num par exemple), on extrait le num_pere avec la fonction DLookUp
    n = num_pere le père devient l'enfant et on recommence jusqu'à ce qu'il n'y ait plus de père num_pere = 0
    Le nombre de descendants est compté à chaque boucle
    A adapter pour rechercher du coté de la mère aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Function NbDescendants(n As Long) As Long
     Dim num_pere As Long
     NbDescendants = 0
     Do
      num_pere = DLookup("[num_pere]", "tbNoms", "[num]=" & n)
      If num_pere = 0 Then Exit Do
      n = num_pere
      NbDescendants = NbDescendants + 1
     Loop
    End Function

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Merci, je vais regarder ça.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Comme tu l'as dit:
    le père devient l'enfant
    ce qui veut dire que cette fonction compte le nombre d'ascendants et non de descendants.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    j'ai essayé d'adapter la fonction précédente à mon cas, mais le problème c'est que la fonction Dlookup ne peut renvoyer qu'un seule valeur alors qu'un père peut avoir plusieurs enfants.
    Quelqu'un aurait une idée?

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2004
    Messages : 52
    Points : 50
    Points
    50
    Par défaut
    A ce moment moment là, tu fais un recordest, il contiendra toutes les données que tu souhaite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Set rst=currentdb.openrecordet("Select * from parents where num=" & numenfant &";")
     
    rst.movefirst
    while not rst.eof
    '--Traitements
    wend
    dis moi si ça te conviens
    @+

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Function NbDescendants(n As Long) As Long
        Dim num_pere As Long
        NbDescendants = 0
     
        Set rst = CurrentDb.OpenRecordset("Select * from Personne where num_pere=" & n & ";")
     
        rst.MoveFirst
        While Not rst.EOF
            '--Traitements
        Wend
    End Function
    J'obtiens l'erreur trop peu d'arguments, 1 attendu sur la ligne du openrecordset.
    Et pour compter l'ensemble des descendants, est-ce que c'est possible de passer par une fonction récursive?

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2004
    Messages : 52
    Points : 50
    Points
    50
    Par défaut
    Citation Envoyé par Gebudi.
    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Function NbDescendants(n As Long) As Long
        Dim num_pere As Long
        NbDescendants = 0
     
        Set rst = CurrentDb.OpenRecordset("Select * from Personne where num_pere=" & n & ";")
     
        rst.MoveFirst
         While Not rst.EOF
            '--Traitements
        Wend
    End Function
    J'obtiens l'erreur trop peu d'arguments, 1 attendu sur la ligne du openrecordset.
    Et pour compter l'ensemble des descendants, est-ce que c'est possible de passer par une fonction récursive?
    Fais un msgbox de : "Select * from Personne where num_pere=" & n & ";" juste avant le openrecordset pour voir s'il y a pas une erreur de syntaxe.

    Moi je vois bien une fonction qui fait un select de tous les enfants du parent, puis pour chaque enfant, on test s'il y a un enfant avec un autre recordset.
    en gros :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Punlic nbenf as integer
    Sub nbenf(n as long)
     
    Set rstEnf = CurrentDb.OpenRecordset("Select * from Personne where num_pere=" & n & ";")
    nbenf=0
    While not rstEnf.eof
       nbenf=nbenf+1
    	if rstEnf![NumPere]<>”” then
       		nbenf(rstEnf![NumPere])
    	end if
    rstEnf.movenext
    wend
     
    end sub
    Hum bon c'est taper à l'arrache, à tester
    Dis moi si ça marche, je suis suceptible de m'en servir un jour
    @+

  11. #11
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Bonjour,

    Pour ma part, je verrais plus une fonction récursive

    Prenons cette table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    NumPersonne	Prenom	NumPere
    1	Pauk	
    2	Jacques	1
    3	Lucien	
    4	Marc	1
    5	Edouard	2
    6	Setfan	5
    7	Hector	6
    8	Sofia	6
    9	Lucie	6
    10	Martin	5
    11	Edmon	3
    On va utiliser cette requête paramétrée nommée r1 qui retourne les enfants d'une personne donnée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PARAMETERS pPers Long;
    SELECT NumPersonne
    FROM tblPersonne
    WHERE NumPere=pPers;
    Exemple pour la personne 1

    Ensuite cette fonction de comptage en VBA (nécessite la référence DAO)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Function getNbDescendant(intNumPersonne As Integer, Optional odb As DAO.Database) As Integer
     
        Dim oQdf As DAO.QueryDef
        Dim oRst As DAO.Recordset
     
        If Not IsMissing(odb) Then Set odb = CurrentDb
        Set oQdf = odb.QueryDefs("r1")
        With oQdf
            .Parameters("pPers").Value = intNumPersonne
            Set oRst = .OpenRecordset
        End With
        With oRst
            While Not .EOF
                getNbDescendant = getNbDescendant + 1 + getNbDescendant(.Fields(0).Value, odb)
                .MoveNext
            Wend
            .Close
        End With
     
        Set oQdf = Nothing
        Set oRst = Nothing
     
    End Function
    Que l'on utilise ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Sub test()
        MsgBox getNbDescendant(1)
    End Sub
    Et qui retourne bien 8

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Voilà ce que j'ai fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Function NbDescendants(n As Long)
     
    Set rstenf = CurrentDb.OpenRecordset("Select * from Personne where num_pere=" & n & ";")
     
    While Not rstenf.EOF
        nbenf = nbenf + 1
        NbDescendants (rstenf![NUM_Personne])
        rstenf.MoveNext
    Wend
    End Function
    Mais la récursivité ne marche pas, il ne me compte que la première génération.

    [Edit] Tofalu, je vais essayer ta solution et je te tiens au courant.
    Merci en tout cas pour votre aide, ça fait plaisir!!!

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Ca marche...presque.
    En fait, avec ta solution tofalu, il compte bien le nombre d'enfants d'un père, mais si un homme a une fille, que cette fille a un enfant, ce dernier ne sera pas compté car c'est via la relation num_mere qu'ils sont reliés.

    Je continue de regarder quand même de mon côté voir si je trouve, mais n'étant pas très habitué à DAO et ces objets, j'ai un peu de mal à tout comprendre.

  14. #14
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Il suffit de faire un OR NumMere=pPers dans la requete SQL

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 40
    Points : 24
    Points
    24
    Par défaut
    Citation Envoyé par Tofalu
    Il suffit de faire un OR NumMere=pPers dans la requete SQL
    En effet, c'est tout bête.
    En tout cas, ça a l'air de marcher.
    Merci vraiment!!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Access] Combinatoire : Liste article dont la somme des prix
    Par enibris dans le forum Langage SQL
    Réponses: 14
    Dernier message: 17/03/2006, 10h03
  2. Somme des valeurs de certaines lignes
    Par Tartenpion dans le forum Langage SQL
    Réponses: 6
    Dernier message: 16/02/2006, 16h46
  3. somme des champs null
    Par s.rais dans le forum Access
    Réponses: 4
    Dernier message: 09/02/2006, 09h05
  4. Réponses: 2
    Dernier message: 09/01/2006, 16h10
  5. Somme des champs ? existe t il une fonction ...
    Par dark_vidor dans le forum Langage SQL
    Réponses: 6
    Dernier message: 02/01/2006, 11h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo