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

VBA Access Discussion :

Programme VBA trouvant une valeur répondant à plusieurs conditions ET/OU (non résolu par requête SQL) [Toutes versions]


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Par défaut Programme VBA trouvant une valeur répondant à plusieurs conditions ET/OU (non résolu par requête SQL)
    Bonsoir à tous les contributeurs de ce forum,
    Cette discussion fait suite à une problématique qui a été partiellement résolue à l'aide d'une requete SQL et de la persévérance de 'F-Leb'.
    Cependant, une nouvelle "couche" de condition a rendu le traitement du problème impossible via une simple requete SQL.
    Pour résumé, je dispose de 2 fichiers : une table CLIENTS et une table ELIGIBILITE.
    La table CLIENTS contient le nom de plusieurs clients (national) et un ensemble de conditions (x3) qui les caractérise.
    La table ELIGIBILITE contient les différents points d'éligibilité par région et les conditions auxquelles il faut répondre pour y appartenir. Cependant, une dernière condition, appelée RELATION ET/OU, précise si les 3 conditions doivent s'accumulées ou pas.
    Le but est de faire une jointure entre ces 2 tables sur les 3 conditions puis de voir à quelles conditions les clients peuvent légitimement prétendre.
    Un exemple (fichier Excel) est joint à cette discussion et permet de mieux comprendre la solution recherchée (onglet 'résultats attendus') et la difficulté posée par la relation ET/OU (champ 'commentaire').

    J'avoue que la fonction HAVING COUNT (*) avait permis de faire avancer les choses en requete SQL, mais la relation ET/OU a tout chamboulé (désolé F-leb).

    Merci pour votre aide et vos lumières car là je bloque ..

    Cdlt,
    David
    Fichiers attachés Fichiers attachés

  2. #2
    Membre Expert
    Homme Profil pro
    Indépendant développeur et formateur
    Inscrit en
    Octobre 2007
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant développeur et formateur
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 036
    Par défaut
    Hello
    comme ton problème est compliqué, il me faut plus d'explications:
    - pourquoi as tu plusieurs lignes pour décrire les conditions d'un client?
    - idem pour les critères d'éligibilité
    - comment interpréter les ET et les OU
    En fait, il faut de temps en temps revenir au tout début de la problématique, indépendamment de ce qu'on a déjà réalisé.
    Pistes:
    - tables intermédiaires et requêtes, voire requêtes UNION
    - programmation pure et dure de comparaison entre recordset

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Par défaut
    Citation Envoyé par Simplifi Voir le message
    - pourquoi as tu plusieurs lignes pour décrire les conditions d'un client?
    - idem pour les critères d'éligibilité
    ...
    En fait, il faut de temps en temps revenir au tout début de la problématique, indépendamment de ce qu'on a déjà réalisé.
    Effectivement, je pense à un problème de conception...Il y a sûrement un meilleur moyen pour modéliser les données et simplifier le traitement de l'information.

    Citation Envoyé par Simplifi Voir le message
    - comment interpréter les ET et les OU
    ça par contre c'est expliqué dans le fichier Excel

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Par défaut
    2 réponses !!!!! Ouuuuufff je voyais un zéro réponse depuis dimanche soir et je me disais que c'était pas bon signe
    Bon effectivement cela ne change rien à la problématique mais je suis heureux d'apprendre que certaines âmes généreuses se penche sur "mon cas"
    En fait, pour répondre à vos questions, il s'agit d'une "situation héritée" d'une logiciel existant (SAP pour ne pas le nommer). Mon exemple était bien entendu une simplification de la problématique.
    Je suis en train d'analyser les problématiques de séparation des taches dans l'ERP SAP. Grace à l'extraction des bonnes tables et aux conseils des membres de ce foum je suis capable:
    - de connaitre les autorisations par utilisateur,
    - d'intégrer le référentiel des autorisations incompatibles SAP dans ma base ACCESS.
    ... ll me "manque" juste à faire le rapprochement entre ces 2 fichiers pour savoir si les utilisateurs ont, ou non, des autorisations incompatibles.

    Pour essayer de faire simple (ca va etre DUR pour du SAP), et faire le rapprochement avec mon exemple simplifié des clients :
    - ma table 'utilisateur' (équivalent à ma table client dans l'exemple précédent) dispose de 3 niveaux d'autorisations fidèles à la logique SAP (les 3 conditions) :OBJET, CHAMP, VALEUR DU CHAMP

    - mon référentiel (ma table éligibilité) dicte les couples des 3 niveaux d'autorisation nécessaire pour avoir un accès effectif à cette transaction.

    Et là, j'apprends qu'il existe une colonne supplémentaire dans ce référentiel qui indique si ces couples d'objets d'autorisation doivent s'accumulées ou non .. et là c'est le drame sur mes précédentes requêtes.

    Je joins à cet message l'explication de la relation ET/OU et un exemple qui colle à mon problème.
    MAIS pour répondre à ta question : c'est CONCEPTUEL et propre à SAP ... je ne pourrai malheureusement pas changé cette logique et cette approche.

    David
    Fichiers attachés Fichiers attachés

  5. #5
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Par défaut
    Salut,
    J'ai réussi à écrire une fonction qui renvoie les zones éligibiles pour un client sous la forme : "SUD:01;NORD:02;NORD:03"
    Copie ce code dans un nouveau module que tu nommeras comme tu en as envie :
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    Option Compare Database
    Option Explicit
     
    Public Function zonesEligibles(pClient As String) As Variant
        ' Ceci est la fonction qui renvoit la liste des zones éligibles pour un client
        ' La valeur retournée est de cette forme : "SUD:01;NORD:03"
        Dim strSQL As String, strZone As String
        Dim rstZonesProbables As DAO.Recordset
     
        ' On récupère les zones susceptibles d'être éligibles
        strSQL = "SELECT DISTINCT Secteur, Eligibilité " & _
                 "FROM Clients INNER JOIN Eligibilité " & _
                 "ON (Clients.Condition3 = Eligibilité.Condition3) " & _
                    "AND (Clients.Condition2 = Eligibilité.Condition2) " & _
                    "AND (Clients.Condition1 = Eligibilité.Condition1) " & _
                 "WHERE Client='" & pClient & "';"
        Set rstZonesProbables = CurrentDb.OpenRecordset(strSQL)
     
        ' Pour chacune de ces zones,
        While Not rstZonesProbables.EOF
            ' On réunit les champs Secteur et éligibilité séparés par ":"
            strZone = rstZonesProbables(0) & ":" & rstZonesProbables(1)
            ' On vérifie si le client est éligible. Si c'est le cas, on concatène les zones séparées par des point-virgules
            If eligibiliteZone(pClient, strZone) Then
                zonesEligibles = zonesEligibles & ";" & strZone
            End If
            rstZonesProbables.MoveNext
        Wend
     
        ' On retire le premier point-virgule
        If Len(zonesEligibles) <> 0 Then zonesEligibles = Right(zonesEligibles, Len(zonesEligibles) - 1)
    End Function
     
    Private Function eligibiliteZone(pClient As String, pZone As String) As Boolean
        Dim strSQL As String, strSecteur As String, strEligibilite As String
        Dim rstConditionsClient As DAO.Recordset, rstRegroupementConditions As DAO.Recordset
        Dim verif As Boolean
     
        ' Initialisation
        verif = False
        ' On sépare les champs "Secteur" et "éligibilité"
        strSecteur = Left(pZone, InStr(pZone, ":") - 1)
        strEligibilite = Right(pZone, Len(pZone) - InStr(pZone, ":"))
     
        ' On récupère les conditions du client
        strSQL = "SELECT Condition1, Condition2, Condition3, Client FROM Clients WHERE Client = '" & pClient & "';"
        Set rstConditionsClient = CurrentDb.OpenRecordset(strSQL)
     
        ' On récupère les conditions de la zone regroupées sur les 2 premières conditions(les "ET" d'abord, les "OU" à la fin)
        strSQL = "SELECT DISTINCT Secteur, Eligibilité, Condition1, Condition2, Relation " & _
                 "FROM Eligibilité " & _
                 "WHERE Secteur='" & strSecteur & "' AND Eligibilité='" & strEligibilite & "' " & _
                 "ORDER BY Relation, Condition1, Condition2;"
        Set rstRegroupementConditions = CurrentDb.OpenRecordset(strSQL)
     
        Do Until rstRegroupementConditions.EOF
            verif = correspondCondition(rstConditionsClient, rstRegroupementConditions.Fields)
            If Not verif Then Exit Do
            rstRegroupementConditions.MoveNext
        Loop
     
        eligibiliteZone = verif
    End Function
     
    Private Function correspondCondition(rstClient As DAO.Recordset, fldsConditions As DAO.Fields) As Boolean
        Dim fld As DAO.Field
        Dim strSQL As String
        Dim rstConditionsCompletes As DAO.Recordset
        Dim test As Boolean
     
        strSQL = "SELECT DISTINCT Condition1, Condition2, Condition3, Relation " & _
                 "FROM Eligibilité " & _
                 "WHERE Secteur='" & fldsConditions(0).Value & "' " & _
                        "AND Eligibilité='" & fldsConditions(1).Value & "' " & _
                        "AND Condition1='" & fldsConditions(2).Value & "' " & _
                        "AND Condition2='" & fldsConditions(3).Value & "' " & _
                        "AND Relation='" & fldsConditions(4).Value & "' " & _
                 "ORDER BY Relation, Condition1, Condition2,Condition3;"
        Set rstConditionsCompletes = CurrentDb.OpenRecordset(strSQL)
     
        Do Until rstConditionsCompletes.EOF
            test = False
            rstClient.MoveFirst
            Do Until rstClient.EOF
                If rstClient(0) = rstConditionsCompletes(0) And rstClient(1) = rstConditionsCompletes(1) And rstClient(2) = rstConditionsCompletes(2) Then
                    test = True
                    Exit Do
                End If
                rstClient.MoveNext
            Loop
            If (test And rstConditionsCompletes(3) = "OU") Or (Not test And rstConditionsCompletes(3) = "ET") Then Exit Do
            rstConditionsCompletes.MoveNext
        Loop
        rstClient.MoveFirst
        If rstClient(3) = "C3" And fldsConditions(0).Value = "SUD" And fldsConditions(1).Value = "02" Then Debug.Print test
        correspondCondition = test
    End Function
    Ensuite, tu peux tester avec cette requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Client, zonesEligibles([Client]) AS Eligibilite FROM ClientsDistincts;
    Avec ClientsDistincts :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT Client FROM Clients;

    Pour tester et développer cette petite fonction, j'ai utilisé les données de ton premier post.

  6. #6
    Membre émérite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Par défaut
    Je te joins la base de test qui m'a servie à faire ça

    EDIT : Mise à jour du code et de la pièce jointe le 28/03/2013 à 15h22
    Fichiers attachés Fichiers attachés

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Par défaut
    Je suis impressionné ... Mille mercis.
    Hummm (du coup j'ai honte) ... j'ai copié et adapté ton code dans un module spécifique de ma base.
    Et maintenant ... je l'éxécute comment ?

    Désolé pour mon ignorance.

    David

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/08/2014, 12h42
  2. [XL-2002] Recherche d'une valeur sur plusieurs feuilles avec conditions
    Par Rat-Thon dans le forum Excel
    Réponses: 4
    Dernier message: 06/12/2013, 12h26
  3. Réponses: 2
    Dernier message: 28/05/2009, 15h44
  4. [XSL]récupérer une valeur de plusieurs fichiers XML
    Par snoop dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 05/02/2006, 00h32
  5. VBA : ajouter une valeur dans une liste déroulante
    Par remi59 dans le forum Access
    Réponses: 4
    Dernier message: 22/12/2005, 10h01

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