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 :

Test existence d'une valeur saisie dans une zone de texte aux données d'un champ d'une table [AC-2003]


Sujet :

VBA Access

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut Test existence d'une valeur saisie dans une zone de texte aux données d'un champ d'une table
    Bonjour à tous,

    Je suis en train de concevoir une base access me permettant d'extraire des données de flux et de stocks. Le volume des données étant très important je suis obligé d'extraire Mois par Mois ces données.
    J'ai donc créé un formulaire basique avec 2 zones de texte : ANNEE et MOIS et mon bouton d'exécution de toutes les requêtes.
    Ce bouton va lancer des "requêtes ajout" qui vont alimenter une table historique.

    Je souhaite intégrer un test d'existence des valeurs saisies dans mes 2 zones de texte à celui de la base historique de sorte à éviter que l’utilisateur charge 2 fois le même mois de la même année.

    Sur le papier, la procédure me semble assez évidente mais en code c'est nettement moins évident.

    J'imagine qu'il faut créer un Recordset avec un code sql extrayant les couples année et mois de ma table Historique.
    Puis balayez celui-ci avec les valeurs saisies dans mon formulaire.

    Pouvez-vous m'aidez à démarrer? Je suis persuadé que ce n'est pas si compliqué mais je n'y connais pas grand chose.

    Merci d'avance pour votre aide.

    Bonne journée

  2. #2
    Membre éclairé Avatar de dumas.blr
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2010
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2010
    Messages : 598
    Points : 879
    Points
    879
    Par défaut
    bonjour Antisthene

    Même si je ne comprend pas exactement la finalité de cette demande, voici un algorithme base de SQL que je te proposerais. Ce SQL pourrait être le recordsource d'une liste déroulante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT mois, année FROM <choix>
    WHERE mois BETWEEN 1 and 12
    AND année BETWEEN <borne inférieure> AND <borne supérieure>
    AND (mois, année) NOT IN
    (SELECT mois, année FROM <ma table historique>
    group by mois, année)
    Cet algo doit bien sur être adapté pour être exécuté en SQL

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonjour Dumas merci pour ta contribution,

    Toutefois ma vision est quelque peu différente

    Je souhaite vraiment récupérer ce que va saisir l'utilisateur dans la zone de texte ANNEE et MOIS de mon formulaire EXTRACTION.

    Ensuite, je pense qu'il faut prendre ma base HISTORIQUE et faire une boucle dessus en testant la présence des valeurs (du couple) ANNEE et MOIS. C'est d'ailleurs ce que tu fais plus ou moins dans ton code.

    J'ai essayé aujourd'hui avec ma vision mais rien n'a fonctionné. En gros j'avais fais ça:

    Private Sub


    Je créé une requête sql de tous mes couples MOIS ANNEE présent dans la table HISTORIQUE (je regarde donc tous ce qui a déjà été chargé)

    sql= select HISTORIQUE.MOIS ,HISTORIQUE.ANNEE, HISTORIQUE.MOIS&""&HISTORIQUE.ANNEE as COUPLE FROM HISTORIQUE GROUP BY COUPLE

    Set rec=CurrentDb.OpenRecordset (sql,dbOpenSnapshot)


    Je test si mon couple saisie dans le formulaire est présent dans le champ COUPLE de mon recordset rec

    If Forms!Extraction!MOIS&""&Forms!Extraction!ANNEE In rec![COUPLE]
    then msgbox " ce mois est déjà chargé choisir un autre mois"
    Exit Sub

    else .... je lance toutes mes requêtes de mise à jour

    End Sub


    Quelqu'un peux-il m'aider encore un peu

    Merci d'avance en tous cas

  4. #4
    Membre éclairé Avatar de dumas.blr
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2010
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2010
    Messages : 598
    Points : 879
    Points
    879
    Par défaut
    Je maintiens ma proposition qui permettrait de ne sélectionner que ce qui n'a pas encore été archivé :
    Créer dans un formulaire une liste déroulante dont le rowsource sera égal à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT mois &  année as couple FROM <ma table>
    WHERE couple NOT IN
    (select  HISTORIQUE.MOIS & HISTORIQUE.ANNEE as COUPLE FROM HISTORIQUE GROUP BY HISTORIQUE.MOIS ,HISTORIQUE.ANNEE)
    (Attention la clause GROUP BY doit reprendre l'ensemble des champs, dans l'ordre où ils ont été choisis dans la clause SELECT)
    Le résultat affichera la liste des période qui n'ont pas encore été archivées

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonjour Dumas,

    La solution que tu me proposes est plein de bon sens mais j'ai un petit soucis je vais essayer de t'expliquer.

    Admettons que j'utilise ton idée

    Mon formulaire a nécessairement 2 zones de textes ou 2 listes déroulantes. En effet, j'utilise les résultats des 2 zones de textes comme critère d'une requête sélection ACCESS
    critère sur mon champ ANNNE : LIKE Forms!EXTRACTION!T1
    critère sur mon champ MOIS : LIKE Forms!EXTRACTION!T2

    Ton code à intégrer dans le row source ne fonctionne que sur la base d'un couple ANNEE MOIS. Moi si je veux 2 zones de textes (ou liste déroulante), je devrais créer 2 row source je teste si l'année a déjà été extraite et par ailleurs si le mois a déjà extrait. Ceci ne marchera pas. Car si j'ai déjà extrait le mois de JANVIER pour l'année 2013 je ne pourrais plus extraire les autres mois de l'année 2013.

    SOLUTION : 1) créer dans ma requête sélection un champ COUPLE qui sera égal à ANNEE&" "&MOIS
    comme ça je ne demanderais à l'utilisateur de sélectionner qu'une valeur dans mon formulaire. Faire la même chose dans ma base HISTORIQUE créer ce champ COUPLE.

    Je ne sais pas comment contourner le problème autrement.

    Par contre, ce code SQL s'insère comment dans ma liste déroulante? Il y a t-il une propriété RowSource a édité ou dois-je directement passé par VBA?


    Je vais essayer de tester ça cet après midi.

    Merci pour ton aide je te tiens au courant Dumas

  6. #6
    Membre éclairé Avatar de dumas.blr
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2010
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2010
    Messages : 598
    Points : 879
    Points
    879
    Par défaut
    Bonjour Antisthene

    L'idée dans ce cas là est de faire 2 listes déroulantes liées
    • La 1ère ne sélectionnera que les années à archiver,
    • La seconde ne sélectionnera que les mois à archiver de l'année sélectionnée dans la première liste.

    Les requêtes seront par contre légèrement plus compliquées à gérer, notamment pour la première, car il faudra gérer les années incomplètes.
    A mon avis, il serait plus simple de partir sur une table de pilotage qui va te décrire l'ensemble des périodes à archiver.
    la structure serait la suivante
    • année
    • mois
    • indicateur d'archivage (oui/non)

    Lorsque'une période a été archivée, il suffit de mettre à jour l'indicateur d'archivage
    Cette méthode offre le triple avantage :
    - de simplifier les requêtes des listes
    - de réduire énormément les temps de réponse pour afficher les liste, car tu ne parcours que la table de pilotage, et non la table d'historique.
    - de n'autoriser que des valeurs disponibles (exemple l'utilisateur saisit 2014, alors que 2014 n'est pas historisé ... car il n'existe pas)

    Concernant les listes liées, regarde ce tutoriel et celui-ci, qui t'aideront

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonjour Monsieur DUMAS,

    J'ai parcouru les deux tutos, cela fut fort intéressant.

    J'ai cependant opté pour votre 1er solution à savoir une liste déroulante qui exclue l'annee-mois déjà chargé cela me conviens pleinement et ça fonctionne bien.

    J'aimerais toutefois au regard des derniers éléments que vous m'avez donné, que vous m'aidiez à imaginer comment mettre à jour cette variable indicateur (OUI/NON) au fur et à mesure des historisations? VBA ou requête mise à jour?

    Il s'agit d'une partie du code présent dans le 1er tuto afin de prendre en compte ma variable indicateur historisé je pensais rajouter à la clause where " AND variable indicateur historisé ="NON". Ainsi seul les éléments non historisés apparaitraient dans ma seconde zone déroulante. J'imagine que c'est ça qu'il faut faire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Private Sub cmbCategories_AfterUpdate()
    Dim lngIDCat   As Long
    Dim SQL        As String
     
      '' Vérifie que l'on a cliqué sur une catégorie pour éviter le NULL
      If Not IsNumeric(Me!cmbCategories) Then Exit Sub
      '' Affecte la valeur de IDCategorie à la variable lngIDCat
      lngIDCat = Me!cmbCategories
      '' Construit la chaîne SQL avec la catégorie concernée
      SQL = "SELECT IDMetier, Metier, IDCategorie FROM TBLMetiers WHERE IDCategorie =" & lngIDCat & " ORDER BY Metier"
     
    ......
    En tout cas merci pour votre disponibilités et votre aide

  8. #8
    Membre éclairé Avatar de dumas.blr
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2010
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2010
    Messages : 598
    Points : 879
    Points
    879
    Par défaut
    Bonjour Antishtène,

    L'option liste qui exclue le couple mois/année déjà chargé, ne prend donc en compte que 2 tables :
    - La table à historiser
    - la table historisée

    Dans le cas, l'indicateur ne sert à rien, car par principe :
    - dans La table à historiser, l'indicateur est à NON
    - dans La table à historisée, l'indicateur est à OUI

    Ce que je pensais, par l'utilisation d'une table de pilotage, c'était d'offir 2 avantages :
    - Le 1er avantage est d'éviter de parcourir la table historique, qui, d'après ce que tu dis, est extêmement important. Ce qui implique que lorsque tu voudra consulter ta liste détroulante, parcourera à chaque fois l'intégralité de ta table; ce qui, si la table fais plusisurs centaines de milliers d'enregistrements, risque de prendre plusieurs minutes. Access est adapté sur des volumétries relativement imortants, mais pas sur des gros volumes. Dans ce cas, il faut passer à des solutions plus performantes et plus robustes (type SQLserver, Oracle ou autre)
    - Le 2ème avantage est de n'offir que des choix possibles. En effet, si tu ne consulte la table historique, comment veux-tu savoir ce que tu veux historiser ... car ils ne sont pas présents dans cette table.
    Il faudra donc partir, non de la table historique, mais de la table des données à historiser (en utilisant le mécanisme inverse : sélectionner l'ensemble des couples année/mois présents). mais on retrouve la problématique de volumétrie, et donc de temps de réponse.

    L'utilisation de la table de pilotage de permettrait d'afficher ta liste immédiatement (car la volumétrie est très petite), en 1 ou 2 liste (sache que les règles d'ergonomie précisent que si une liste dépasse 20 item, elle est difficilement utilisable). Par contre, elle t'obligereait à une mise à jour régulière (ajout des nouvelles périodes qui ont été ajoutées par les données de stock)

    Enfin, noublie pas que, à la requête ajout, doit s'ajouter la requête suppression; car, une fois qu'elles ont été ajouté à la base historiques, les données doivent être supprimées de la base "vivante"... ce qui résoudrait en même temps ta problématique de départ : éviter que l’utilisateur charge 2 fois le même mois de la même année.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonsoir Monsieur Dumas,

    J'avais bien pris note de l'inutilité d'utiliser un indicateur (OUI/NON) dans le cas retenu.
    Merci pour vos explications et pour le temps que vous avez su consacrer à mon problème et surtout me proposer des solutions.

    Je me permets de vous embêtez une dernière fois même si je vais allez regarder sur le forum dans la foulée. Je voulais savoir comment mettre à jour mes mois chargés dans mon formulaire, je m'explique.

    Dans mon formulaire, j'ai une partie qui affiche une table qui référence les mois déjà historisés et à droite ma liste déroulante des mois non encore chargés. Un bouton va lancer l'extraction pour la période choisie. Cependant à la fin de mon extraction , le mois nouvellement chargé n'apparaît pas dans la partie de gauche et est toujours disponible dans ma liste déroulante. Je dois fermer mon formulaire et le ré-ouvrir pour que tout soit actualisé.

    N'y a t-il pas un bout de code que je placerais a la fin de mon code d'extraction et qui actualiserait les données présentes dans mon formulaire ( partie de gauche et liste déroulante) ?

    J'imagine que oui...

    Merci et bonne soirée à vous

  10. #10
    Expert éminent

    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    3 846
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 846
    Points : 7 983
    Points
    7 983
    Par défaut
    Bonsoir,

    La méthode Requery pour mettre à jour un formulaire ou contrôle dont les données sources ont été modifiées
    Il y a aussi Refresh pour mettre à jour l'affichage uniquement.

    Bonne continuation

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonsoir,

    Merci pour les liens j'ai réussi à mettre en place cette procédure pour mon formulaire principale (EXTRACTION).
    Cependant j'ai un sous-formulaire (SUPPRESSION) qui permet de supprimer des Mois présents dans une zone de liste de mon formulaire principale. Or je n'arrive pas actualiser ces valeurs depuis mon sous-formulaire.

    La syntaxe utilisé dans mon sous formulaire (SUPPRESSION) :

    EXTRACTION.refresh
    EXTRACTION.L1.refresh (L1 est ma zone de liste à mettre à jour)

    j'ai essayé avec des points d'exclamation mais rien y fait n'y fait j'ai le droit à un message : objet non définis. On dirait qu'il n'arrive pas à trouver le bon chemin avec le code que je lui donne.

    Pouvez-vous me venir en aide?

    Merci d'avance

    Bonne nuit.

  12. #12
    Membre éclairé Avatar de dumas.blr
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2010
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2010
    Messages : 598
    Points : 879
    Points
    879
    Par défaut
    il vaux mieux utiliser l'instruction requery
    si l'on veut tout rafraichir, il suffit d'écrire

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonjour Monsieur Dumas,

    Effectivement le fonctionne très bien quand on l’exécute dans le formulaire ou l'on veut mettre à jour sa zone de liste.

    Cependant, je souhaiterais mettre à jour à partir de mon sous-formulaire ( SUPPRESSION), une zone de liste qui se situe dans un autre formulaire (EXTRACTION). Dans ce cas le ne fonctionne pas.

    C'est pourquoi, j'avais essayé de lui donner le chemin de mon autre formulaire EXTRACTION
    mais visiblement il n'aime pas en tout cas il ne comprend pas ce que ca vient faire là. Certainement un problème de syntaxe.

    Une idée ?

  14. #14
    Expert éminent

    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    3 846
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 846
    Points : 7 983
    Points
    7 983
    Par défaut
    Bonjour,

    Si tu fais référence à un autre formulaire ou son contrôle il faut utiliser la syntaxe complète avec la collection :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Forms!EXTRACTION.L1.requery

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 50
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    Merci pour la syntaxe j'aurais du m'en douter.

    Bonne journée

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 12/06/2014, 16h18
  2. récupérer une valeur saisie dans alertdialog
    Par lupus83 dans le forum Android
    Réponses: 2
    Dernier message: 20/03/2011, 13h51
  3. [Oracle] inserer les données saisies dans les zones de textes dans une table sous oracle
    Par sara-souad-wf dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 25/09/2009, 12h16
  4. Réponses: 10
    Dernier message: 07/05/2008, 23h19
  5. Réponses: 2
    Dernier message: 11/12/2004, 22h20

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