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

Requêtes et SQL. Discussion :

appel d'une fonction dans une requête [AC-2000]


Sujet :

Requêtes et SQL.

  1. #1
    Membre du Club
    Profil pro
    autre
    Inscrit en
    Octobre 2005
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Octobre 2005
    Messages : 135
    Points : 62
    Points
    62
    Par défaut appel d'une fonction dans une requête
    Bonjour,

    Il y a quelques semaines j'ai réussi avec l'aide du forum a créer une fonction qui calcule la Médiane (http://www.developpez.net/forums/d81...alcul-mediane/)

    Aujourd'hui je m'aperçois que ma fonction ne renvoi pas le résultats que j'attends:

    Ma requête regroupe des résultats d'analyses par catégories de produit Je cherche pour chaque catégorie, le mimi, le maxi, la moyenne et la médiane. Or pour le mimi, le maxi et la moyenne j'ai bien un résultat différent pour chaque catégorie, alors que pour la médiane j'ai un seul résultat qui correspond à la médiane de l'ensemble de la table et qui est répété à chaque catégorie.

    Avez-vous une idée de mon erreur ?

    Merci

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    710
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 710
    Points : 847
    Points
    847
    Par défaut
    L'erreur est que ta fonction calcul la médiane d'une table.
    Que tu l'utilise dans une requete, un état ... elle te renvoi toujours la médiane de la table.

    Peut être dois tu ajouter un paramètre dans ta fonction (élement sur lequel pourte le regroupement) et ajouter un critère utilisant cet argumentde séléction dans la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " ORDER BY " & strField)
    Cela peut donner qqchose du genre de ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Public Function fMediane(strTable As String, strField As String, Optional Arg_Champ_Regroupement As String, Optional Arg_Valeur_Regroupement) As Variant
     
    Dim oDBS As DAO.Database
    Dim oRST As DAO.Recordset
    Dim blnEven As Boolean
    Dim vntMedian As Variant
     
      Set oDBS = CurrentDb()
      If IsMissing(Arg_Regroupement) Then
        Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " ORDER BY " & strField)
      Else
        Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " WHERE " & Arg_Champ_Regroupement & " = """ & Arg_Valeur_Regroupement & """ ORDER BY " & strField)
      End If
    ...............
    Ainsi avec ta fonction existante tu mettais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fMediane("T_ISB", "MO")
    Il te faudra l'utiliser dans ta requete :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     fMediane("T_ISB", "MO";"nomduchampcategorie";[nomduchampcategorie])

  3. #3
    Membre du Club
    Profil pro
    autre
    Inscrit en
    Octobre 2005
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Octobre 2005
    Messages : 135
    Points : 62
    Points
    62
    Par défaut
    Bonjour Muhad'hib, et merci de te pencher sur mon problème.

    je viens de faire une modification de mon code selon ta proposition. Mais j'ai une erreur.

    Voilà le code tel qu'il est modifié:
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    Public Function fMediane(strTable As String, strField As String, Optional Arg_Champ_Regroupement As String, Optional Arg_Valeur_Regroupement) As Variant
     
    Dim oDBS As DAO.Database
    Dim oRST As DAO.Recordset
    Dim blnEven As Boolean
    Dim vntMedian As Variant
     
      Set oDBS = CurrentDb()
      If IsMissing(Arg_Regroupement) Then
        Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " ORDER BY " & strField)
      Else
        Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " WHERE " & Arg_Champ_Regroupement & " = """ & Arg_Valeur_Regroupement & """ ORDER BY " & strField)
      End If
     
     
      If oRST.EOF = False Then
         oRST.MoveLast
         'Y a-t'il un nombre pair d'enreistrements ?
         blnEven = (oRST.RecordCount Mod 2 = 0)
         'Classer en décroissant si on a un nombre pair
         oRST.PercentPosition = 50
         vntMedian = oRST.Fields(strField)
         If blnEven Then
             oRST.MoveNext
             'faire la moyenne entre cet enregistrement et le précédent
             vntMedian = (vntMedian + oRST.Fields(strField)) / 2
         End If
      End If
     
      fMediane = vntMedian
      oRST.Close
      Set oRST = Nothing
      Set oDBS = Nothing
     
    End Function
    J'ai modifié ma requête pour notifier les nouveaux paramètres mais lorsque je l'exécute j'ai le message :

    "Erreur d'exécution 3061

    Trop peu de paramètres. 1 attendu."

    Au débogage c'est la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set oRST = oDBS.OpenRecordset("SELECT * FROM " & strTable & " WHERE " & Arg_Champ_Regroupement & " = """ & Arg_Valeur_Regroupement & """ ORDER BY " & strField)
    Qui est surlignée en jaune.

    Où est ma bêtise ?

    PS:
    Dans ma requête j'appelle la fonction comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MedianeISB: Round(fMediane("T_ISB";"ISB";"Cd_Type_Prod_Org";[T_Type_Prod_Org].[Cd_Type_Prod_Org]);2)

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    710
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 710
    Points : 847
    Points
    847
    Par défaut
    Bon aprés avoir regardé ta base, le problème est que tu veux faire un regroupement pour le calcul de ta médiane sur un champ qui ne fait pas parti de la table sur laquel tu fais le calcul.

    La fonction doit renvoyer la médiane du champ "ISB" de ta table "T_ISB".
    Si tu veux calculer la médiane d'une partie de la table, il faut que "Arg_Champ_Regroupement" soit un des champs de cette même table et que "Arg_Valeur_Regroupement" soit une des valeur du champ "Arg_Champ_Regroupement"

    J'ai aussi modifié un peu la fonction, pour que le SQl soit plus propre :

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    Public Function fMediane(strTable As String, strField As String, Optional Arg_Champ_Regroupement As String, Optional Arg_Valeur_Regroupement) As Variant
     
    Dim oDBS As DAO.Database
    Dim oRST As DAO.Recordset
    Dim blnEven As Boolean
    Dim vntMedian As Variant
    Dim Sql As String
      Set oDBS = CurrentDb()
      If IsMissing(Arg_Regroupement) Then
        Sql = "SELECT " & strTable & ".* FROM " & strTable & " ORDER BY " & strTable & "." & strField & ";"
      Else
        Sql = "SELECT " & strTable & ".* FROM " & strTable & " WHERE " & strTable & ".[" & Arg_Champ_Regroupement & "]=" & Arg_Valeur_Regroupement & " ORDER BY " & strTable & "." & strField & ";"
     
      End If
      Set oRST = oDBS.OpenRecordset(Sql, dbOpenDynaset)
     
      If oRST.EOF = False Then
         oRST.MoveLast
         'Y a-t'il un nombre pair d'enreistrements ?
         blnEven = (oRST.RecordCount Mod 2 = 0)
         'Classer en décroissant si on a un nombre pair
         oRST.PercentPosition = 50
         vntMedian = oRST.Fields(strField)
         If blnEven Then
             oRST.MoveNext
             'faire la moyenne entre cet enregistrement et le précédent
             vntMedian = (vntMedian + oRST.Fields(strField)) / 2
         End If
      End If
     
      fMediane = vntMedian
      oRST.Close
      Set oRST = Nothing
      Set oDBS = Nothing
     
    End Function

    Muhad'hib, un autre Cantalou

  5. #5
    Membre du Club
    Profil pro
    autre
    Inscrit en
    Octobre 2005
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Octobre 2005
    Messages : 135
    Points : 62
    Points
    62
    Par défaut
    Si j'ai bien compris, il faudrait peut-être que je fasse le calcul de la médiane dans une deuxième requête. La première servant à réunir les données et le champ de regroupement?

    Peux-tu me donner quelques explications sur l'emploi de "Arg_Champ_Regroupement" et de "Arg_Valeur_Regroupement" quelle est la différence ?

    Merci de ton aide

  6. #6
    Membre du Club
    Profil pro
    autre
    Inscrit en
    Octobre 2005
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Octobre 2005
    Messages : 135
    Points : 62
    Points
    62
    Par défaut
    Cette fois c'est bon !

    En faisant appel à la fonction dans une requête basée sur une requête intermédiaire qui rapproche le champ de regroupement et les valeurs à prendre en compte, ça fonctionne.

    La meilleure fonction de calcul de la médiane après les modifs proposées par Muad'hib est donc:
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     Public Function fMediane(strTable As String, strField As String, Optional Arg_Champ_Regroupement As String, Optional Arg_Valeur_Regroupement) As Variant
     
    Dim oDBS As DAO.Database
    Dim oRST As DAO.Recordset
    Dim blnEven As Boolean
    Dim vntMedian As Variant
     
      Set oDBS = CurrentDb()
        If IsMissing(Arg_Regroupement) Then
        Sql = "SELECT " & strTable & ".* FROM " & strTable & " ORDER BY " & strTable & "." & strField & ";"
      Else
        Sql = "SELECT " & strTable & ".* FROM " & strTable & " WHERE " & strTable & ".[" & Arg_Champ_Regroupement & "]=" & Arg_Valeur_Regroupement & " ORDER BY " & strTable & "." & strField & ";"
     
      End If
     
      Set oRST = oDBS.OpenRecordset(Sql, dbOpenDynaset)
     
     
      If oRST.EOF = False Then
         oRST.MoveLast
         'Y a-t'il un nombre pair d'enreistrements ?
         blnEven = (oRST.RecordCount Mod 2 = 0)
         'Classer en décroissant si on a un nombre pair
         oRST.PercentPosition = 50
         vntMedian = oRST.Fields(strField)
         If blnEven Then
             oRST.MoveNext
             'faire la moyenne entre cet enregistrement et le précédent
             vntMedian = (vntMedian + oRST.Fields(strField)) / 2
         End If
      End If
     
      fMediane = vntMedian
      oRST.Close
      Set oRST = Nothing
      Set oDBS = Nothing
     
    End Function
    Merci pour ton aide !

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    710
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 710
    Points : 847
    Points
    847
    Par défaut
    Un petit alors ?

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

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. Réponses: 4
    Dernier message: 04/06/2010, 14h48
  3. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  4. Appel d'une fonction dans une fonction (sql server 2005)
    Par catchouse dans le forum Développement
    Réponses: 10
    Dernier message: 06/05/2009, 12h03
  5. Appeler une fonction dans une fonction
    Par bryanstaubin dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 18/06/2007, 09h39

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