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

IHM Discussion :

[Formulaire] Comment créer des champs correspondant à un critère d'un autre champ? [AC-2003]


Sujet :

IHM

  1. #1
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut [Formulaire] Comment créer des champs correspondant à un critère d'un autre champ?
    [Debutant] [Access 2003]

    Bonjour,

    J'ai 3 tables : T_Article, T_Prevision et T_Enseigne.


    T_Article contient :
    • ID_Article
    • prix


    T_Enseigne contient :
    • ID_Enseigne
    • nomEnseigne


    T_prevision contient :
    • ID_Enseigne
    • ID_Article
    • Mois (octet entre 1 et 12)
    • Quantite (entier long)

    J'essaie de créer un formulaire m'affichant tous les articles de T_Article et pour chacun avoir 12 cases correspondant aux quantités de chacun des mois.
    Le but est de pouvoir entrer les quantités de chacun des mois. Possibilité de n'avoir aucune quantité renseignée sur des articles.

    De plus quelle est le type de relation à mettre entre T_Article et T_Prevision? J'avais pensé à T_Article 1->infini T_Prevision mais je commence à me demander si ce ne serait pas mieux avec une relation du type "Tous les éléments de T_Article et uniquement ceux de T_Prevision correspondant"...

    Pourriez-vous m'éclairer ou m'orienter?
    Merci

  2. #2
    Rédacteur/Modérateur
    Avatar de Jeannot45
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2004
    Messages
    3 871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 871
    Points : 8 489
    Points
    8 489
    Par défaut


    Il te faudrait un formulaire principal présentznt les caractéristiques de l'article et un sous formulaire pour saisir les quantités
    Jeannot

    Liens Office indispensables à visiter: Cours (Tutos), F.A.Q., Sources VBA

    Ne posez pas de questions par MP, je n'ai pas le temps d'y répondre

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    Merci Jeannot45.

    J'aimerais tout avoir sur la même ligne pour chaque enregistrement et avoir aussi le formulaire en mode continu. Or il semble impossible de garder un formulaire en mode continu si on veut y inclure un sous-formulaire.

    En fait, j'ai 2 problèmes je crois :
    Le premier :
    je n'arrive pas à croiser le champs Mois et le champ Qte dans mon formulaire.
    J'aimerais voir s'afficher une fenetre me permettant d'entrer les quantités de chacun des mois pour tous les articles (mode continu) :

    Article1 Qte(mois=1) Qte(Mois=2) Qte(Mois=3)... Qte(Mois=12)
    Article2 Qte(mois=1) Qte(Mois=2) Qte(Mois=3)... Qte(Mois=12)
    ...

    Comment fait-on pour dire, par exemple, au formulaire que la quantité entrée dans Qte(Mois=1) est une quantité à mettre dans le champ Qte qu'il faut entrer pour l'article 1 et mettre dans le champ Mois :"1" pour préciser que c'est bien le mois numéro 1 et ainsi de suite?

    Je m'en sort si je crée dans la table les champs QteJanv QteFev... QteDec parce que j'enlève une dimension mais c'est dommage de faire ça dans une base de donnée...

    Je pense que c'est une base que je dois comprendre pour faire les choses bien.

    Donc pour le moment je continue avec une table ayant des champs de la forme : QteJanv, QteFev... QteDec (quand je saurais faire avec un champs Mois et un champs Qte, je changerai!)

    Le second problème :
    j'ai des cases activées et non protégées et pourtant je ne peux pas entrer les quantités.

    J'ai créé une requête faisant un produit cartésien entre les articles et les enseignes (donc j'ai aussi toutes les caractéristiques des articles etc.)
    Dans la source de mon formulaire, j'ai pris cette requête et j'ai ajouté la table des prévisions. La relation entre les 2 tables est : "tous les éléments de la requête du produit cartésien (donc toutes les combinaisons article-enseigne) avec les prévisions correspondantes (c'est la relation 2 dans Access).
    J'ai donc bien tous mes champs et un formulaire continu.
    Mais je ne peux pas les remplir... (le formulaire est bien ouvert en modification)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 103
    Points : 91
    Points
    91
    Par défaut
    Bonjour,
    Sur la question des douze mois à afficher sur une seule ligne.
    Sans être un ultra spécialiste des BD, il ne semble pas possible de le faire avec un seul champs.
    1 champs = 1 ligne
    12 champs = 1 ligne
    Access se fiche pas mal de savoir si un champs est 1/12 du tout. Access voit 1 champs comme 1 champs
    Acces ne gères pas les base de données multidimentionnelles comme les tableaux excel avec deux echelles. (cette comparaison est-elle acceptable ?)

    Vous voulez suivre JANVIER FEVRIER MAI JUIN etc.. ce sont des données spécifiques qui appartiennent certainement à ANNEE
    c'est comme une table PERSONNE avec des champs ADRESSE TELEPHONE FAX etc...
    De la même façon vous ne pouvez pas créer une table PERSONNE avec un champs RENSEIGNEMENT pour entrer les données ci-dessus énoncées ...

    Ou bien, vous vous amusez à créer 1 formulaire principal et 11 sous formulaires à afficher cote-cote, avec une requête spécifique pour chaque sous formulaire en isolant le mois, mais là je ne garantie pas le résultat ni même qu'il sera possible d'ajouter des données.

    J'espère avoir cerné le problème... et pas avoir répondu à coté de la plaque...

    Cordialement.

  5. #5
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 688
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 688
    Points : 57 223
    Points
    57 223
    Billets dans le blog
    40
    Par défaut
    bonsoir,

    J'essaie de créer un formulaire m'affichant tous les articles de T_Article et pour chacun avoir 12 cases correspondant aux quantités de chacun des mois.
    Le but est de pouvoir entrer les quantités de chacun des mois. Possibilité de n'avoir aucune quantité renseignée sur des articles.
    Et l’enseigne là-dedans ? Vous la voyez où dans le formulaire ?
    Doit-on comprendre que vous souhaitez remplir sur un même écran de saisie les quantités de chacun des mois pour un article ET pour une enseigne ?

    Sinon, une solution formulaire/Sous-formulaire vous donne deux possibilités :
    - Formulaire « père » de source Article puis un sous-formulaire « fils » de source Prévision.
    Pour un article, on saisit chaque ligne (enseigne,mois,qtté)

    - Formulaire « père » de source Enseigne puis Sous-formulaire « fils » de source Prévision.
    Pour une enseigne, on saisit chaque ligne (article,mois,qtté)

    Avec une nouvelle table « Mois », on pourrait éventuellement envisager :
    - Formulaire « père » de source Mois puis Sous-formulaire « fils » de source Prévision.
    Pour un mois, on saisit chaque ligne (enseigne,article,qtté). Elle ne vous conviendrait pas cette dernière solution ?

    Sinon je ne vois donc pas autre chose (sauf erreur de ma part) que partir d'un formulaire indépendant avec des contrôles indépendants, du style:

    - 12 champs de saisie indépendants (qttéJanvier, qttéFévrier,...)
    - un bouton "Valider" avec du code VBA sur l'évènement « sur clic ».

    Dans le code VBA, on récupère les informations saisies pour générer les requêtes « ajouts » dans la table Prevision pour chaque mois (ou « mises à jour » si c’est une modification d’une ligne existante).

    Bon c'est qu'une ébauche de brouillon de proposition d'idée hein!

    Tiens,
    J'espère avoir cerné le problème... et pas avoir répondu à coté de la plaque...
    tout pareil.

  6. #6
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 124
    Points : 55 903
    Points
    55 903
    Billets dans le blog
    131
    Par défaut
    Bonjour

    Formulaire en continu => pas de sous-formulaire, donc on oublie...

    Je rejoins la conclusion de f-leb. La seule possibilité me semble être de passer par VBA pour résoudre ce cas.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  7. #7
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    Merci à tous!

    Je pensais qu'Access pouvait (par je ne sais trop quel moyen) gérer une table multidimensionnelle...

    Donc pour pouvoir faire ce que je veux, je dois passer par du VBA?
    En passant, doit-on éviter de mettre du code VBA dans une BD?

    Je pars sur la solution des champs indépendants avec du VBA.
    Comment dois-je m'y prendre pour distinguer chaque enregistrement dans mon formulaire continu pour récupérer les données et les mettre dans la table?

  8. #8
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 688
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 688
    Points : 57 223
    Points
    57 223
    Billets dans le blog
    40
    Par défaut
    Donc pour pouvoir faire ce que je veux, je dois passer par du VBA?
    oui, il semblerait.

    Je pars sur la solution des champs indépendants avec du VBA.
    Comment dois-je m'y prendre pour distinguer chaque enregistrement dans mon formulaire continu ...
    dans un formulaire continu en plus ? Allez faire un tour par
    ici par exemple.

    En VBA on peut tout faire mais vous êtes sûr de vouloir vous lancer là dedans ?

  9. #9
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour/Bonsoir,

    Je fais aussi une suggestion...
    Citation Envoyé par f-leb Voir le message
    Et l’enseigne là-dedans ? Vous la voyez où dans le formulaire ?
    ...mais qui ne tiendra pas compte de l'enseigne (donc il faudra compléter).

    Il est possible de "construire" une requête qui effectue 12 jointures entre T_Article et 12 sous-requêtes basées sur T_Prevision filtrée par n° de mois.

    Comme c'est assez "lourd" à décrire dans une requête Access en mode création, je te la fais en VBA.
    N.B. En plus, dans mon Access 2000, ce type de sous-requête est bogué lorsqu'on travaille dessus en mode création.

    Voici une procédure VBA qui crée une requête nommée R_Prev, en utilisant la bibliothèque DAO qu'il faut penser à référencer si besoin.
    La requête R_Prev liste les prévisions pour les 4 premiers mois (la procédure est à compléter pour traiter les 12 mois, je donne juste le principe)

    Code VBA : 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
    Public Sub CréerReqPrévisions()
        Dim oDB As DAO.Database
        Dim oQD As DAO.QueryDef
        Dim SQL As String
     
        Set oDB = CurrentDb
     
        On Error Resume Next
        oDB.QueryDefs.Delete "R_Prev"
     
        On Error GoTo 0
        SQL = "SELECT T_Article.ID_Article, T_Article.Prix, " & _
            "T_Prevision_Janv.Quantite AS QteJanv, " & _
            "T_Prevision_Fevr.Quantite AS QteFevr, " & _
            "T_Prevision_Mars.Quantite AS QteMars, " & _
            "T_Prevision_Avr.Quantite AS QteAvr " & _
            "FROM (((T_Article " & _
            "INNER JOIN (SELECT * FROM T_Prevision WHERE Mois=1) AS T_Prevision_Janv " & _
            "ON T_Article.ID_Article = T_Prevision_Janv.ID_Article) " & _
            "INNER JOIN (SELECT * FROM T_Prevision WHERE Mois=2) AS T_Prevision_Fevr " & _
            "ON T_Article.ID_Article = T_Prevision_Fevr.ID_Article) " & _
            "INNER JOIN (SELECT * FROM T_Prevision WHERE Mois=3) AS T_Prevision_Mars " & _
            "ON T_Article.ID_Article = T_Prevision_Mars.ID_Article) " & _
            "INNER JOIN (SELECT * FROM T_Prevision WHERE Mois=4) AS T_Prevision_Avr " & _
            "ON T_Article.ID_Article = T_Prevision_Avr.ID_Article "
     
        Set oQD = oDB.CreateQueryDef("R_Prev", SQL)
     
        Application.RefreshDatabaseWindow
    End Sub
    Donc il faut d'abord exécuter cette procédure, une fois pour toute.
    Ensuite, on peut créer un formulaire "tabulaire" (avec l'assistant, par exemple) basé sur la requête R_Prev.

    Dans ce formulaire, les données ne seront modifiables qu'à la condition que le type de recordset soit fixé à "Feuille rép.dyn.(MAJ globale)".
    Aussi, il faut ouvrir le formulaire en mode création et rectifier cette propriété qui se trouve dans l'onglet Données.
    On peut en profiter pour interdire les ajouts via ce formulaire, en fixant à "Non" la propriété Ajout autorisé.

    Bref, sur mon PC cela fonctionne parfaitement:
    • affichage en colonne des prévisions mensuelles,
    • possibilité de modifier les prévisions directement dans le formulaire.

    Une copie d'écran en prime:




    _

  10. #10
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    ça y est, j'ai enfin réussi (oui c'était bien expliqué mais j'ai eu des loupés lors de mes modifications sur mes tables )
    Par contre, j'ai créé un article supplémentaire et il n'apparaît pas, j'ai donc fait une tentative pour modifier les liaisons des tables dans la requête en les mettant en "1 vers l'infini" de T_Article vers les autres.
    Et lorsque j'essaie de voir le résultat dans la requête, Access me met une erreur :"Le Moteur de base de données MS Jet ne peut pas trouver la table ou la requete source 'SELECT * FROM T_Prevision WHERE Mois=1;"

    Comment puis-je faire pour voir apparaître mon nouvel article avec la possibilité de rentrer les quantités pour chacun des mois? (et donc comme il est nouveau, que des enregistrements soient ajoutés dans ma table T_Quantite sans que je devoir taper l'identifiant de l'article)

  11. #11
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour buzz73 !

    Citation Envoyé par buzz73 Voir le message
    ça y est, j'ai enfin réussi (oui c'était bien expliqué mais j'ai eu des loupés lors de mes modifications sur mes tables )
    De quoi parles-tu ? De la solution que je t'ai donnée ?
    Je pense que c'est ça... Donc je vais te répondre.

    Citation Envoyé par buzz73 Voir le message
    j'ai donc fait une tentative pour modifier les liaisons des tables dans la requête en les mettant en "1 vers l'infini" de T_Article vers les autres.
    Et lorsque j'essaie de voir le résultat dans la requête, Access me met une erreur :"Le Moteur de base de données MS Jet ne peut pas trouver la table ou la requete source 'SELECT * FROM T_Prevision WHERE Mois=1;"
    Je crois que tu connais le même bogue d'Access que j'évoquais précédemment.
    C'est à cause de ce bogue que je crée cette requête par programmation... OK ?

    Si tu veux (quand j'aurai le temps ) je te donnerai un rectificatif de la procédure pour l'adapter aux 12 mois avec 12 jointures externes (cf. plus bas dans ce message). Tu peux aussi la corriger par toi-même.

    Citation Envoyé par buzz73 Voir le message
    Par contre, j'ai créé un article supplémentaire et il n'apparaît pas, j'ai donc fait une tentative pour modifier les liaisons des tables dans la requête en les mettant en "1 vers l'infini" de T_Article vers les autres.
    [...]
    Comment puis-je faire pour voir apparaître mon nouvel article avec la possibilité de rentrer les quantités pour chacun des mois? (et donc comme il est nouveau, que des enregistrements soient ajoutés dans ma table T_Quantite sans que je devoir taper l'identifiant de l'article)
    Pour joindre 2 tables qui ont une relation 1-N, et pour lesquelles il pourrait ne pas y avoir d'enregistrement associé du côté N, tu dois utiliser une jointure externe (à gauche ou à droite, cf. ce message dans ton autre discussion).

    Cependant, dans la situation où tu crées un article, je te conseille d'utiliser une procédure événementielle Après insertion qui se chargera de créer les 12 enregistrements dans la table T_Prevision pour l'article et l'enseigne ciblés.

    Ici, je fais l'hypothèse que pour un article et une enseigne donnés, il y a toujours exactement 12 enregistrements (ni plus, ni moins) dans la table T_Prevision. Est-ce le cas ?

    Si ce principe est accepté (exactement 12), après on pourra réfléchir à la situation où tu afficherais le prévisionnel vide d'un article/enseigne (c'est à dire sans aucun enregistrement côté T_Previsionnel) et que l'on veut renseigner.
    Donc à suivre...

    En attendant, voici la procédure événementielle pour créer les enregistrements dans la table T_Previsionnel, suite à l'ajout d'un nouvel article via le formulaire.
    Les quantités saisies dans les contrôles sont correctement ajoutées.
    D'ailleurs, pour simplifier le traitement, j'ai nommé ces contrôles Mois1, Mois2, Mois3... ainsi on peut y accéder par leur "nom indexé".

    N.B. Ça fonctionne même si la requête sous-jacente utilise des jointures internes.
    Code VBA : 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
    Private Sub Form_AfterInsert()
        Dim i As Integer, vQté As Variant
        Dim oRS As DAO.Recordset
     
        Set oRS = CurrentDb.OpenRecordset("T_Prevision")
     
        For i = 1 To 12
            vQté = Me.Controls("Mois" & i).Value
     
            oRS.AddNew
     
            oRS!ID_Article = Me.ID_Article
            oRS!Mois = i
            oRS!Quantite = vQté
     
            ' /!\  à compléter  /!\
            '
            'oRS!ID_enseigne = ???
     
            oRS.Update
        Next i
     
        oRS.Close
     
        Me.Refresh
    End Sub
    _

  12. #12
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    Merci beaucoup pour la piste et les codes!
    Je commence à comprendre le fonctionnement.

    Effectivement, pour un article, il y a exactement 12 enregistrement dans la table T_Prevision.

    J'ai changé les jointures "INNER" en "LEFT" (en vérifiant le côté ) (après lecture du tuto)
    Pour passer aux 12 mois avec ce que tu m'as passé ce sera très facile.

    Maintenant, avec la jointure externe, j'ai bien à l'affichage tous mes articles avec la possibilité d'entrer mes quantités.
    En revanche lorsque je met des quantités sur un nouvel article et que je change d'enregistrement, Access me met une erreur :
    "Un index ou une clé primaire ne peut pas contenir une valeur null."
    Je n'ai pas cette erreur lorsque je modifie les quantités d'un autre article existant déjà dans T_Prevision.
    Cela dit, si je crée un article directement dfans le formulaire, tout se passe bien avec la procédure événementielle Form_AfterInsert

    Comment peut-on dire à Access que le nouvel enregistrement à créer doit prendre la valeur de l'ID_Article résultant de la jointure externe? En effet, les articles ne doivent pas être créés là...

    ps : merci du temps passé c'est vraiment sympa et je suis bien placé pour savoir qu'aider les autres en prend beaucoup!

  13. #13
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par buzz73 Voir le message
    Effectivement, pour un article, il y a exactement 12 enregistrement dans la table T_Prevision.
    Précision: pour un article ET une enseigne, il y aura soit 0 enregistrement, soit 12 enregistrements dans la table T_Prevision. OK ?

    Citation Envoyé par buzz73 Voir le message
    En revanche lorsque je met des quantités sur un nouvel article et que je change d'enregistrement, Access me met une erreur :
    "Un index ou une clé primaire ne peut pas contenir une valeur null."
    Je n'ai pas cette erreur lorsque je modifie les quantités d'un autre article existant déjà dans T_Prevision.
    Tout cela est "normal" si tu as mis en place l'intégrité référentielle.

    Citation Envoyé par buzz73 Voir le message
    Cela dit, si je crée un article directement dfans le formulaire, tout se passe bien avec la procédure événementielle Form_AfterInsert
    Dans mon premier message, je t'avais proposé de ne pas permettre les ajouts dans ce formulaire...

    Citation Envoyé par buzz73 Voir le message
    Comment peut-on dire à Access que le nouvel enregistrement à créer doit prendre la valeur de l'ID_Article résultant de la jointure externe? En effet, les articles ne doivent pas être créés là...
    Ici, il faut créer une procédure événementielle pour l'événement Après MAJ.
    Voici un code possible mais qu'il faudra compléter pour gérer l'enseigne.

    Au passage, j'ai besoin de connaître le type de ID_Article: numérique ou texte.
    C'est important de le connaître car, parfois, on peut avoir besoin de délimiter un texte avec des guillemets doubles ou simples (guillemet simple = apostrophe).

    Dans mon exemple je l'ai considéré comme un texte.

    J'utilise la fonction de domaine DCount() pour savoir s'il existe déjà des enregistrements dans la table T_Prevision pour un ID_Article donné (bien sûr, à compléter avec l'ID_Enseigne).

    S'il n'y a pas d'enregistrement, alors on les crée:
    Code VBA : 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
    Private Sub Form_AfterUpdate()
        Dim i As Integer, vQté As Variant
        Dim oRS As DAO.Recordset
     
        If DCount("*", "T_Prevision", "ID_Article='" & Me.ID_Article & "'") = 0 Then
     
            Set oRS = CurrentDb.OpenRecordset("T_Prevision")
     
            For i = 1 To 12
                vQté = Me.Controls("Mois" & i).Value
     
                oRS.AddNew
     
                oRS!ID_Article = Me.ID_Article
                oRS!Mois = i
                oRS!Quantite = vQté
     
                ' /!\  à compléter  /!\
                '
                'oRS!ID_enseigne = Me.ID_Enseigne  ???
     
                oRS.Update
            Next i
     
            oRS.Close
            Me.Refresh
     
        End If
    End Sub

    Pour prendre en compte l'enseigne, il faudra modifier DCount() de cette manière:
    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    DCount("*", "T_Prevision", "ID_Article='" & Me.ID_Article & "' AND ID_Enseigne=" & Me.ID_Enseigne)

  14. #14
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    Précision: pour un article ET une enseigne, il y aura soit 0 enregistrement, soit 12 enregistrements dans la table T_Prevision.
    Ok!

    Au passage, j'ai besoin de connaître le type de ID_Article: numérique ou texte.
    C'est effectivement du texte.

    Dans mon premier message, je t'avais proposé de ne pas permettre les ajouts dans ce formulaire...
    C'était juste pour comprendre ce qu'allait faire Access, je l'ai enlevé maintenant (ajout=création d'un nouvel article et non mise de quantité sur un article que j'aurais ajouté au préalable dans T_Article, c'est bien ça?)

    Citation:
    Envoyé par buzz73
    En revanche lorsque je met des quantités sur un nouvel article et que je change d'enregistrement, Access me met une erreur :
    "Un index ou une clé primaire ne peut pas contenir une valeur null."
    Je n'ai pas cette erreur lorsque je modifie les quantités d'un autre article existant déjà dans T_Prevision.
    Tout cela est "normal" si tu as mis en place l'intégrité référentielle.
    Elle est effectivement en place. Mais comment faire pour ajouter l'enregistrement comme on est coincé avant de pouvoir atteindre le code VBA?

  15. #15
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    J'ai testé en mettant le code dans la procédure événementielle Form_BeforeUpdate
    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
     
    Private Sub Form_BeforeUpdate(Cancel As Integer)
        Dim i As Integer
        Dim vQte As Variant
        Dim oRS As DAO.Recordset
     
        If DCount("*", "T_Prevision", "ID_Article='" & Me.ID_Article & "'") = 0 Then
     
            Set oRS = CurrentDb.OpenRecordset("T_Prevision")
     
            For i = 1 To 4
                vQte = Me.Controls("Mois" & i).Value
     
                oRS.AddNew
     
                oRS!ID_Article = Me.ID_Article
                oRS!Mois = i
                oRS!Quantite = vQte
     
                oRS.Update
            Next i
     
            oRS.Close
            'Me.Refresh
        End If
    End Sub
    l'article est maintenant ajouté mais juste au moment de sortir de la procédure (après avoir fait son boulot) j'ai encore cette erreur de clé primaire ou d'index null...

    Par contre, le Me.refresh n'est plus accepté :
    "Erreur d'exécution '2115'
    La macro ou fonction attribuée à la propriété Avant MAJ ou Valide si pour ce champ empêche Access d'enregistrer les données dans le champs."
    Alors que tout semble fonctionner et avoir été enregistré correctement.

    J'ai donc aussi testé avec ce code que j'ai fait et j'ai les mêmes résultats.
    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 Form_BeforeUpdate(Cancel As Integer)
        Dim strReq As String
        strReq = "INSERT"
        strReq = strReq & " INTO T_Prevision"
        strReq = strReq & " (ID_Article, Mois,Quantite)"
        strReq = strReq & " values("
        strReq = strReq & "'" & Me.ID_Article & "',"
        strReq = strReq & "'" & 2 & "',"
        strReq = strReq & "'" & Me.Mois2 & "'"
        strReq = strReq & ");"
     
        DoCmd.RunSQL strReq 
    End Sub
    (C'est bien un test pour le mois numéro 2.)

    Je n'arrive toujours pas à mettre des quantités dasn T_Prevision pour un article qui vient d'être créé dans T_Article sans avoir d'erreur alors que tout semble fonctionner... Toujours cette erreur de clé null...

  16. #16
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour,
    Citation Envoyé par buzz73 Voir le message
    J'ai testé en mettant le code dans la procédure événementielle Form_BeforeUpdate
    Pourquoi avoir déplacé le code de Form_AfterUpdate vers Form_BeforeUpdate ?
    Sur mon PC cela fonctionne parfaitement... Alors quel est le problème ?

    Citation Envoyé par buzz73 Voir le message
    l'article est maintenant ajouté mais juste au moment de sortir de la procédure (après avoir fait son boulot) j'ai encore cette erreur de clé primaire ou d'index null...
    Je pense que tu as oublié de renseigner le champ T_Prevision.ID_Enseigne, c'est ce qui provoque l'erreur puisqu'il est normalement lié à T_Enseigne.ID_Enseigne.

    (je t'avais pourtant prévenu avec le commentaire /!\ à compléter /!\)

    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
            For i = 1 To 12
                vQté = Me.Controls("Mois" & i).Value
                
                oRS.AddNew
                
                oRS!ID_Article = Me.ID_Article
                oRS!Mois = i
                oRS!Quantite = vQté
                
                ' /!\  à compléter  /!\
                '
                'oRS!ID_enseigne = Me.ID_Enseigne  ???
                
                oRS.Update
            Next i

  17. #17
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    Je pense que tu as oublié de renseigner le champ T_Prevision.ID_Enseigne, c'est ce qui provoque l'erreur puisqu'il est normalement lié à T_Enseigne.ID_Enseigne.
    Pour le moment j'ai enlevé les enseignes pour simplifier (pour moi ) puis je les ajouterai.

    Pourquoi avoir déplacé le code de Form_AfterUpdate vers Form_BeforeUpdate ?
    Sur mon PC cela fonctionne parfaitement... Alors quel est le problème ?
    Lorsque je mets le code dans Form_AfterUpdate (Code VBA pour faire la jointure externe pour avoir tous les articles!), si je mets une quantité pour un article n'ayant jamais été entré dans T_Prevision et que je change d'enregistrement, j'ai instantanément l'erreur d'une soit disant clé avec valeur null et je suis coincé. De plus l'enregistrement n'est pas ajouté dans T_Prevision car la procédure Form_AfterUpdate n'est pas lancée.
    Par contre, si je modifie une quantité d'un article étant déjà entré dans T_Prevision, tout marche (sauf que là, on n'entre pas dans condition "IF").

    En revanche, si je mets le code dans Form_BeforeUpdate, lorsque j'entre une quantité pour un article n'ayant jamais été entré dans T_Prevision et que je change d'enregistrement, la procédure est lancée, les enregistrements sont fait dans T_Prevision mais :
    1. Me.Refresh me retourne l'erreur évoquée plus haut => pas possible
    2. Juste avant de sortir de la procédure (sur le End Sub) l'erreur de la clé null apparait seulement à ce moment

  18. #18
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Sur mon PC avec Access 2000, tout fonctionne.
    Je te passe ma base de test en pièce jointe.
    _
    Fichiers attachés Fichiers attachés

  19. #19
    Membre habitué
    Inscrit en
    Juillet 2008
    Messages
    268
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 268
    Points : 130
    Points
    130
    Par défaut
    Merci.
    Je viens de tester ta base et effectivement elle marche.
    Par contre T_Prevision a une clé primaire dans mon cas prenant #ID_Article et #Mois (pour la tienne il y aurait donc aussi #Enseigne)
    Et si je les ajoute j'ai la même erreur de clé null.
    Et justement :
    J'ai remarqué que pour un ID_Article n'apparaissant pas dans T_Prevision, si depuis le formulaire tu entres 3 quantités par exemple, alors le senregistrement dans T_Prevision seront : tous les mois ok
    mais aussi 3 enregistrements supplémentaires sans ID_Article et sans Mois.

    En fait le souci semble bien être la création de doublons dans la table.
    J'ai aussi enlevé les macros et j'ai lancé le formulaire pour renseigner des quantités.
    Il se passe exactement la même chose : Le bon nombre d'enregistrements avec #ID_Article, #Mois et #Quantite renseignés mais aussi un supplément d'enregistrement sans #ID_Article et sans #Mois mais avec la quantité (et ça pour chaque quantité renseignée) d'où l'erreur qui s'affichait chez moi : il y avait bien des enregistrements avec clé null.
    Je suis séché là.

  20. #20
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Ok, je comprends !

    Alors je te propose une solution "simpliste" mais qui a l'avantage de fonctionner à tout les coups, sans créer des enregistrements fantômes.

    Il s'agirait de créer les 12 enregistrements de T_Prevision quand on se positionne sur une ligne d'un article sans prévisionnel.
    Et c'est tout.

    L'événement est Sur activation et voici le code de la procédure événementielle.
    Code VBA : 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
    Private Sub Form_Current()
        Dim i As Integer
        Dim oRS As DAO.Recordset
     
        ' Traiter le cas où le forumulaire n'affiche aucun enregistrement
        If Me.CurrentRecord = 0 Then Exit Sub
     
        If DCount("*", "T_Prevision", "ID_Article='" & Me.ID_Article & "'") = 0 Then
     
            Set oRS = CurrentDb.OpenRecordset("T_Prevision")
     
            For i = 1 To 4
                oRS.AddNew
                oRS!ID_Article = Me.ID_Article
                oRS!Mois = i
                oRS!Quantite = Null
     
                ' /!\  à compléter  /!\
                '
                'oRS!ID_enseigne = ???
     
                oRS.Update
            Next i
     
            oRS.Close
            Me.Refresh
     
        End If
    End Sub

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AC-2007] Comment créer des champs et sous-champs déroulants?
    Par Fibule dans le forum Access
    Réponses: 5
    Dernier message: 15/07/2014, 06h29
  2. Réponses: 2
    Dernier message: 08/06/2014, 21h48
  3. [AC-2010] Comment créer des formulaires et boutons dans un programme Access ?
    Par psycho59179 dans le forum IHM
    Réponses: 5
    Dernier message: 22/05/2013, 16h13
  4. [AC-2003] Comment créer des champs nommés dynamiquement
    Par franz.moraine dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 03/07/2012, 14h35
  5. Réponses: 1
    Dernier message: 04/10/2006, 14h21

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