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 :

[Access 2007 ou 2010] Rechercher une valeur dans une table sur base d'une date


Sujet :

Access

  1. #41
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par byaccess2
    Difficile cependant d'objectiver tout ça sans votre base sous les yeux.
    Comme je l’ai précisé dans mon dernier message, les tables que j'utilise ici sont celles de votre diagramme, dans lequel j'ai harmonisé les noms des attributs. Voici donc le diagramme sur lequel je me suis basé :





    Le contenu des tables TLC_Composants et T_Lots :










    Supposons que la table T_Fabrications soit vide :





    Sur la base d’une date hypothétique (qui peut être la date du jour ou autre), que j’ai nommée date de référence, le programme réalise la tâche suivante :

    Pour chaque composant (table TLC_Composants) pour lequel on a au moins un lot (table T_Lots), on détermine le lot du jour, c'est-à-dire celui pour lequel la date de début d’utilisation est immédiatement ≤ à la date de référence. Le triplet ainsi obtenu <IDComposant, NomLot, DateDebutUtilisation> dans la table T_Lots est recopié dans la table T_Fabrications.

    Dans l’exemple, on commence avec le 22/07/2015 comme date de référence.

    Pour le composant C1, la date de début d’utilisation immédiatement ≤ à la date de référence est le 15/07/2015 et le lot correspondant : LA1-b.

    Pour le composant C2, la date de début d’utilisation immédiatement ≤ à la date de référence est le 31/07/2015 et le lot correspondant : LA2-b.

    Contenu de la table T_Fabrications suite à l’exécution du code :





    Il y aurait 1000 composants « lotis », la table contiendrait 1000 lignes.


    Par la suite, je réexécute le code avec le 31/07/2015 comme date de référence.

    Pour le composant C1, la date de début d’utilisation immédiatement ≤ à la date de référence est le 30/07/2015 et le lot correspondant : LA1-e.

    Pour le composant C2, la date de début d’utilisation immédiatement ≤ à la date de référence est le 07/07/2015 et le lot correspondant : LA2-a.

    Contenu de la table T_Fabrications suite à l’exécution du code :





    Maintenant, la table ainsi constituée ne correspond peut-être pas à ce que vous attendez : vous me direz. Quant au mode opératoire, à votre tour de décrire comment les choses doivent se passer dans le temps (avec les images...)
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  2. #42
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bonsoir,

    Je commence maintenant à voir où sont les points où nous ne nous comprenons pas.

    La table T_Lots est remplie conformément à ce que je prévois.

    Mais:
    1) L'exemple simplifié de la version 2 supposait qu'il y avait un seul composant par fabrication. Votre structure suppose qu'à chaque fabrication, TOUS les composants entamés à cette date seront incorporés dans la recette. Hors c'est justement ce que je ne souhaite pas. J'ai adapté cette version simple pour prévoir le choix des composants de chaque fabrication dans la version V3bis. La structure relationnelle biscornue à vos yeux me permet d'obtenir un formulaire pratique pour l'encodage, à savoir
    Nom : v3bis.jpg
Affichages : 187
Taille : 123,2 Ko
    Il suffit avec ce formulaire d'encoder la date de fabrication, et de choisir alors dans le SF le ou les composant(s) de cette fabrication. Laissez tomber le champ Lotdujour 'ici appelé Lotcomposantdujour) pour le moment et testez l'encodage de quelques fabrications avec cette version v3bis.

    2) Au niveau de la structure de votre formulaire d'encodage, la date de fabrication qui apparaît dans T_Fabrications_subform n'est pas correcte. Là devrait se trouver le 22/7/2015 pour les deux premiers enregistrements, et le 31/7 pour les deux suivants. La date qui y est présentement mentionnée est la date de première utilisation du composant, qui n'a à figurer nulle part sauf dans la table T_Lots.
    D'où mon interrogation quant au rôle et à l'utilité de cette "date de référence"… D'autant que si on modifie la date de fabrication de votre table, rien ne sera modifié dans le champ Lotdujour.

    Sinon, in fine, hormis cette date erronée, la table T_Fabrications mentionne l'info que je souhaite dans le champ Lotdujour. Donc une partie du code fonctionne comme je le souhaiterais.

    Partant de cette version v3bis, j'ai encodé deux fabrications, une le 15/1 avec un composant, et une le 16/1 avec 2 composants. Voici les écrans des deux enregistrements.
    Nom : fabrication1.jpg
Affichages : 182
Taille : 132,5 Ko
    Nom : fabrication2.jpg
Affichages : 234
Taille : 138,9 Ko

    Ce que souhaiterais, c'est pouvoir, sur base d'une requête telle que la requête1 qui me retourne les valeurs suivantes
    Nom : requête1.jpg
Affichages : 370
Taille : 97,7 Ko

    filtrer les valeurs "Lotcomposantdujour" vides et les remplir avec les lots que votre code permet de retourner. Je reposte pour que vous la testiez la v3bis avec les deux enregistrements:
    lot-date v3bis.zip
    Comprenez-vous mieux maintenant les relations entre les différents tables?

  3. #43
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bonjour,
    après avoir tâtonné pendant des heures, j'arrive tout doucement à un résultat (mais est-ce le bon?)
    J'ai créé toute une série de requêtes en cascade, dont la dernière (R3) me sort une liste des ID Fabrication-composants avec le bon n° de lot pour chaque composant en fonction de la date de fabrication.
    Mais je bute sur la dernière étape. Je voudrais copier pour chaque enregistrement la valeur se trouvant dans le champ [Lot] vers le champ [Lotducomposantdujour].
    J'ai créé une requête Mise à jour mais elle ne fonctionne pas.
    Voici le message d'erreur.
    Nom : màj.jpg
Affichages : 180
Taille : 178,1 Ko
    Comment faire pour que cette requête fonctionne?
    je poste la version 3ter adaptée ci-dessous.
    lot-date v3ter.zip
    J'ai créé quelques enregistrements de fabrications, mais il faut que j'en crée de multiples combinaisons de composants et de dates afin de vérifier si mes 3 requêtes retournent bien les bonnes dates.
    Merci de m'éclairer sur la syntaxe correcte de cette requête mise à jour.

  4. #44
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bon finalement, en cumulant mon incompétence et mon obstination, j'arrive au résultat que je souhaite, mais à quel prix...
    je joins la version v3quater de la base:

    lot-date v3quater.zip

    la table T_Fabrication-Composants a bien les champs Lotducomposantdujour vides
    cliquez sur la macro1 en répondant oui à tous les messages (comment les accepter automatiquement???)
    réouvrez T_Fabrication-Composants et tous les champs Lotducomposantdujour sont complétés (sauf l'ID6 qui a été fabriqué avant l'encodage des lots, comme prévu)

    bon maintenant j'ai une table T_Tampon qui s'est créée (impossible de partir d'une mise à jour de la requête3, le champ Lotducomposantdujour ne peut être édité)
    on peut réexécuter autant de fois qu'on veut la macro1, la table T_Tampon s'auto-écrase

    Donc le résultat est là mais bof bof pour la manière, et en plus la table T_Tampon risque vite de grossir... (quoi que à tester puisqu'elle est sensée se créer - entre autres sur base de la requête R_Lots vides - avec les enregistrements pour lesquels Lotducomposantdujour est vide)

    Alors si vous avez une solution pro pour rendre ça plus simple.
    Merci d'avance

  5. #45
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir byaccess2,


    J’ai été bien chargé et ça n’est pas fini, aussi n’ai-je pas eu beaucoup de temps à vous consacrer. Avant que vous ne fassiez parvenir vos deux derniers messages, j’ai lu celui du 22/07/2015 à 20h58 et je réponds en fonction de celui-ci.

    Pour résumer, sur le plan de votre diagramme, pas de problème, depuis le début je l’ai interprété, vu les anomalies de modélisation (j’ai quand même pratiqué l’expertise, l’audit, le sauvetage des bases de données pendant près de 40 ans, on me surnommait même « Le docteur des bases », c’est tout dire...).

    Dans votre cas, le plus difficile est de comprendre non pas le « QUOI », mais ce que vous voulez en faire et comment. Quand j’ai mon interlocuteur en face de moi, les choses vont vite, mais la maïeutique à distance est beaucoup plus aléatoire, ça dure beaucoup plus longtemps. J’ai été obligé de proposer plusieurs diagrammes alternatifs, dans lesquels la redondance est évacuée (le coup de l’attribut Lotducomposantdujour), mais vous êtes manifestement partisan de l’approche Nouf-Nouf et Nif-Nif :





    plus que de l’approche Naf-Naf...





    Citation Envoyé par byaccess2
    Votre structure suppose qu'à chaque fabrication, TOUS les composants entamés à cette date seront incorporés dans la recette.
    La « recette », voilà un concept nouveau ! Il s’agit de décrire une recette ! De mon côté, ignorant la finalité du schmilblick, je me suis contenté d’énumérer comme je l’ai dit le lot en cours d’utilisation pour chaque composant. Le contenu que j’ai figurer dans le sous-formulaire n’est que le reflet de la situation générale du stock, indépendamment des recettes, à la date du tant (que j’ai nommée date de référence, n’ayant rien d’autre sous la dent, mais je vais la renommer date de fabrication).

    J’étais parti sur la base de votre énoncé initial :

    Citation Envoyé par byaccess2 Voir le message
    partant d'un exemple fictif de fabrication de plats préparés

    Tout en pensant que la base de données était en réalité celle d’une entreprise du secteur bancaire, industriel de l’assurance, etc., alors qu’il s’agit bien de la fabrication de plats préparés, comme quoi...


    Cela dit, pour voir si nous commençons à nous comprendre, j’a fabriqué un petit prototype sans prétention, du genre de ceux qu’on produisait en ACCESS v1 ou v2, il y a une vingtaine d’années.

    Les tables et leur contenu sont les vôtres :

    TLC_Composants






    T_Lots






    T_Fabrications






    T_Fabrication_Composants (vide au départ)





    Chez vous, cette table est nommée Fabrication-Composants : j’ai remplacé le trait d’union par un souligné, car SQL interprète « - » comme le symbole de la soustraction, et mes requêtes plantent. D’une manière générale, que ce soit pour les noms de tables ou le nom de leurs attributs, j’évite, ainsi que les espaces, lettres accentuées, etc.


    Le diagramme logique :








    Passons au « comment », au formulaire, pierre d’achoppement... Celui que je propose n’est pas bien ergonomique, mais les rubans on verra plus tard, on fait ici dans la faisabilité.







    Dans ce petit prototype, l’utilisateur fournit une valeur pour le champ IDFabrication, valeur devant exister dans la table T_Fabrications. Il choisit aussi un nom de composant dans la combo ad-hoc :






    Quand l’utilisateur a cliqué sur le bouton « Ajout » :






    Le programme a valorisé le champ « Date Fabrication » du formulaire, et mis à jour la table T_Fabrication_Composants. ACCESS ajouté une ligne dans le sous-formulaire.

    La source du sous-formulaire est requête suivante : .

    
    SELECT ID_F_C, x.IDFabrication, DateFabrication, NomComposant, Lotducomposantdujour
    FROM   T_Fabrication_Composants AS x, TLC_Composants AS y, T_Fabrications AS z
    WHERE  x.IDComposant = y.IDComposant
      AND  x.IDFabrication = z.IDFabrication ;
    
    
    Pour la fabrication 2, on procède de la même façon, ajout du composant C1 puis du composant C2, d’où le résultat :





    On peut aussi supprimer une ligne de la table T_Fabrication_Composants (bouton « Suppression ») et remplacer dans une ligne un composant par un autre (bouton « Modification »).


    Vous noterez que la colonne Lotcomposantdujour est toujours renseignée puisqu’on sait déterminer le lot pour un composant et une date de fabrication donnés : pourquoi s’en priver ?

    Code VBA (brut, donc à mettre en forme, il y a des éléments à factoriser et autres opérations de nettoyage) :

    
    '----------------------------------------------------------
    'Les recettes du jour
    '----------------------------------------------------------
    
    Option Compare Database
    Option Explicit
    
    
    Private Sub Form_Load()
    
    IDFabrication.SetFocus
    
    End Sub
    
    '----------------------------------------------------------
    'Les recettes du jour - Ajout
    '----------------------------------------------------------
    
    Private Sub FabricationAjouter_Click()
    
    Dim theDataBase As DAO.Database, Sqlresult As DAO.Recordset
    
    Dim Style As Integer, Insulte As String, Titre As String, Reponse As String
    Dim r As String, theNomComposant As String, theIDFabrication As Integer
    Dim theDateFabrication As String, MaxIdFabrication As Integer
    Dim insert As String
    Dim theKount As Integer, theComposantNo As Integer, theDateDebutUtil As Date, theNomLot As String
    
    '-------------------------------------------------------------------
    ' Table T_Fabrications : on vérifie que IDFabrication est renseigné
    '-------------------------------------------------------------------
    
    Set theDataBase = CurrentDb
    
    On Error Resume Next
    
    If Not DeterminerFabrication Then
       Exit Sub
    End If
    
    theIDFabrication = Me.IDFabrication
    theDateFabrication = Me.DateFabrication
    
    '-------------------------------------------------------------------------
    ' Contrôle d'existence du composant
    '-------------------------------------------------------------------------
    
    If IsNull(Me.ComposantCombo.Column(1)) Or Len(Me.ComposantCombo.Column(1)) = 0 Then
    
        Style = vbExclamation
        Insulte = "Le champ Composant doit contenir un composant existant !  "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        ComposantCombo.SetFocus
        Exit Sub
        
    End If
    
    '-----------------------------------------------------------------------------------
    ' On vérifie que le composant comporte au moins un lot
    '-----------------------------------------------------------------------------------
    
    theComposantNo = Me.ComposantCombo.Column(0)
    
    r = "SELECT count(*) as Kount FROM T_Lots where IDComposant = " & theComposantNo & " ;"
                
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("Kount").Value
    
    If theKount = 0 Then
    
        Style = vbExclamation
        Insulte = "Le composant " & theComposantNo & " n’a pas de lot. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        ComposantCombo.SetFocus
        Exit Sub
        
    End If
    
    '-------------------------------------------------------------------------------------
    'Pour le composant en cours theComposantNo, on détermine le lot correspondant
    'à la date de fabrication theDateFabrication,
    'ainsi que la date de début d'utilisation de ce lot.
    '-------------------------------------------------------------------------------------
    
    r = "SELECT Max(x.DateDebutUtilisation) AS theDateDebutUtil, Max(x.NomLot) AS theNomLot " _
        & " FROM T_Lots AS x, TLC_Composants AS y " _
        & " WHERE  y.IDComposant = " & theComposantNo & " " _
        & "   AND  x.IDComposant = y.IDComposant " _
        & "   AND  x.DateDebutUtilisation <= CDate('" & theDateFabrication & "') " _
        & " GROUP BY x.IDComposant ; "
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theDateDebutUtil = Sqlresult.Fields("theDateDebutUtil").Value
    theNomLot = Sqlresult.Fields("theNomLot").Value
    
    '---------------------------------------------------------------------------------------
    'On vérifie que le triplet <composant, date de fabrication, lot> n'est pas déjà présent
    'dans la jointure T_Fabrications, T_Fabrication_Composants
    '---------------------------------------------------------------------------------------
    
    r = "select count(*) as k from T_Fabrications as x, T_Fabrication_Composants as y " _
        & "where x.IDFabrication = y.IDFabrication " _
        & "  and Datefabrication = Cdate('" & theDateFabrication & "') " _
        & " and Lotducomposantdujour = '" & theNomLot & "' AND IDComposant = " & theComposantNo & " ;"
       
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("k").Value
       
    'Si le triplet <composant, date de fabrication, lot> n'existe pas déjà, on crée un tuple fabrication
    
    If theKount = 0 Then
    
         insert = "insert into T_Fabrication_Composants (IDFabrication, Lotducomposantdujour, IDComposant) VALUES (" _
             & "'" & theIDFabrication & "', '" & theNomLot & "', " & theComposantNo & ") ;"
                 
        theDataBase.Execute insert
    
        If Err.Number <> 0 Then
    
            Style = vbCritical
            Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit.."
            Titre = "Formulaire " & Me.Name
            Reponse = MsgBox(Insulte, Style, Titre)
            
            theDataBase.Close: Set theDataBase = Nothing
            Exit Sub
    
        End If
        
        'on rafraîchit le sous-formulaire
        
        Me.Recalc
    Else
        r = "select NomComposant from TLC_Composants " _
            & "where IDComposant = " & theComposantNo & " ;"
       
        Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
        If Err.Number <> 0 Then
    
            Style = vbCritical
            Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
            Titre = "Formulaire " & Me.Name
            Reponse = MsgBox(Insulte, Style, Titre)
            
            theDataBase.Close: Set theDataBase = Nothing
            Exit Sub
        End If
    
        theNomComposant = Sqlresult.Fields("NomComposant").Value
    
        Style = vbExclamation
        Insulte = "Il existe déjà un triplet : " & Chr(13) & Chr(13) & "DateFabrication = '" & theDateFabrication & "', " & Chr(13) _
                & "Composant = '" & theNomComposant & "'," & Chr(13) & "Lot = ' " & theNomLot & "'."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
       
    End If
    
    theDataBase.Close: Set theDataBase = Nothing
    
    End Sub
    
    
    Private Sub IDFabrication_LostFocus()
    
    '-----------------------------------------------------------------
    ' détermination de la date de fabrication
    '-----------------------------------------------------------------
    
    Dim theDataBase As DAO.Database, Sqlresult As DAO.Recordset
    
    Dim Style As Integer, Insulte As String, Titre As String, Reponse As String
    Dim r As String, theComposant As String, theIDFabrication As Integer
    Dim theDateFabrication As String, MaxIdFabrication As Integer
    Dim insert As String
    Dim theKount As Integer, theComposantNo As Integer, theDateDebutUtil As Date, theNomLot As String
    
    If IsNull(Me.IDFabrication) Then
        Style = vbCritical
        Insulte = "Veuillez renseigner IDFabrication."
        Titre = "Formulaire " & Me.Name
            
        Exit Sub
    End If
    
    theIDFabrication = Me.IDFabrication
    
    '-------------------------------------------------------------------------------
    ' On vérifie que IDFabrication est présent dans la table T_Fabrications
    '-------------------------------------------------------------------------------
    
    Set theDataBase = CurrentDb
    
    On Error Resume Next
    
    r = "SELECT COUNT(*) AS Kount FROM T_Fabrications where IDFabrication = " & theIDFabrication & " ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("Kount").Value
    
    If theKount = 0 Then
        Style = vbCritical
        Insulte = "L’identifiant IDFabrication = " & theIDFabrication & " n’existe pas dans la table T_Fabrications..."
        Titre = "Formulaire " & Me.Name
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    r = "SELECT DateFabrication FROM T_Fabrications where IDFabrication = " & theIDFabrication & " ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theDateFabrication = Sqlresult.Fields("DateFabrication").Value
    Me.DateFabrication = theDateFabrication
    
    
    End Sub
    
    '-------------------------------------------------------------
    ' suppression d'une ligne de la table TLC_Composant
    '-------------------------------------------------------------
    
    Private Sub FabricationSupprimer_Click()
    
    Dim theDataBase As DAO.Database, Sqlresult As DAO.Recordset
    
    Dim Style As Integer, Insulte As String, Titre As String, Reponse As String
    Dim r As String, theNomComposant As String, theIDFabrication As Integer
    Dim theDateFabrication As String, MaxIdFabrication As Integer, theTableId As Integer
    Dim theKount As Integer, theComposantNo As Integer, theDateDebutUtil As Date, theNomLot As String
    Dim Delete As String
    
    Set theDataBase = CurrentDb
    
    On Error Resume Next
    
    '-------------------------------------------------------------------------
    ' On demande à Cézigue la valeur de l'identifiant de la ligne à supprimer
    '-------------------------------------------------------------------------
    
    theTableId = InputBox("Veuillez fournir la valeur de l'identifiant de la ligne à supprimer :")
    
    '-------------------------------------
    ' Contrôle de structure l'identifiant
    '-------------------------------------
    If theTableId = 0 Then
        Style = vbCritical
        Insulte = "Identifiant de la ligne à supprimer : Valeur non conforme. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
    End If
    
    '-------------------------------------------------
    ' Vérification de l'existence de l'identifiant
    '-------------------------------------------------
    
    r = "select count(*) as kount from T_Fabrication_Composants where ID_F_C = " & theTableId & " ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("kount").Value
    
    If theKount = 0 Then
        Style = vbCritical
        Insulte = "Ligne à supprimer : l'identifiant '" & theTableId & "', n'existe pas. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
    End If
                
    '----------------------------------------
    ' Suppression de la ligne dans la table
    '----------------------------------------
    
    Delete = "delete from T_Fabrication_Composants where ID_F_C = " & theTableId & " ;"
    
    theDataBase.Execute Delete
    
        If Err.Number <> 0 Then
    
            Style = vbCritical
            Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit.."
            Titre = "Formulaire " & Me.Name
            Reponse = MsgBox(Insulte, Style, Titre)
            
            theDataBase.Close: Set theDataBase = Nothing
            Exit Sub
    
        End If
        
        'on rafraîchit le sous-formulaire
        
        Me.Recalc
    
    theDataBase.Close: Set theDataBase = Nothing
    
    End Sub
    
    '=============================================
    '
    ' Changement de composant
    '
    '=============================================
    
    Private Sub FabricationModifier_Click()
    
    
    Dim theDataBase As DAO.Database, Sqlresult As DAO.Recordset
    
    Dim Style As Integer, Insulte As String, Titre As String, Reponse As String
    Dim r As String, theNomComposant As String, theIDFabrication As Integer
    Dim theDateFabrication As String, MaxIdFabrication As Integer, theTableId As Integer
    Dim theKount As Integer, theComposantNo As Integer, theDateDebutUtil As Date, theNomLot As String
    Dim theUpdate As String
    
    Me.Recalc
    
    If Not DeterminerFabrication Then
        Exit Sub
    End If
    
    theIDFabrication = Me.IDFabrication
    theDateFabrication = Me.DateFabrication
    
    Set theDataBase = CurrentDb
    On Error Resume Next
    
    '-------------------------------------------------------------------------
    ' On demande à Cézigue la valeur de l'identifiant de la ligne à modifier
    '-------------------------------------------------------------------------
    
    theTableId = InputBox("Veuillez fournir la valeur de l'identifiant de la ligne à modifier :")
    
    '-------------------------------------
    ' Contrôle de structure l'identifiant
    '-------------------------------------
    
    If theTableId = 0 Then
        Style = vbCritical
        Insulte = "Identifiant de la ligne à modifier : valeur non conforme. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    '-------------------------------------------------
    ' Vérification de l'existence de l'identifiant
    '-------------------------------------------------
    
    r = "select count(*) as kount from T_Fabrication_Composants where ID_F_C = " & theTableId & " ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("kount").Value
    
    If theKount = 0 Then
        Style = vbCritical
        Insulte = "Ligne à modifier : l'identifiant '" & theTableId & "', n'existe pas. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
    End If
    
    '-------------------------------------------------------------------------
    ' On demande à Cézigue la valeur du nouveau composant
    '-------------------------------------------------------------------------
    
    theNomComposant = InputBox("Veuillez fournir la valeur du nouveau composant :")
    
    '-------------------------------------
    ' Contrôle de structure du composant
    '-------------------------------------
    
    If IsNull(theNomComposant) Or Len(theNomComposant) = 0 Then
        Style = vbCritical
        Insulte = "Nouveau composant : valeur non conforme. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
    End If
    
    '-------------------------------------------------
    ' Vérification de l'existence du composant
    '-------------------------------------------------
    
    r = "select count(*) as kount from TLC_Composants where NomComposant = '" & theNomComposant & "' ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("kount").Value
    
    If theKount = 0 Then
        Style = vbCritical
        Insulte = "Ligne à modifier : le composant '" & theNomComposant & "' est inconnu. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
    End If
        
    '-------------------------------------------------------------------
    ' Récupération de l'identifiant du composant à partir de son nom
    '-------------------------------------------------------------------
    
    r = "select IDComposant from TLC_Composants where NomComposant = '" & theNomComposant & "' ;"
          
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theComposantNo = Sqlresult.Fields("IDComposant").Value
    
    '-----------------------------------------------------
    ' Le composant doit comporter au moins un lot
    '-----------------------------------------------------
    
    r = "select count(*) as kount from TLC_Composants as x, T_Lots as y " _
        & "where x.IDComposant = y.IDComposant and NomComposant = '" & theNomComposant & "' ;"
    
    r = "select count(*) as kount from TLC_Composants as x, T_Lots as y " _
        & "where x.IDComposant = y.IDComposant and x.IDComposant = " & theComposantNo & " ;"
           
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theKount = Sqlresult.Fields("kount").Value
    
    If theKount = 0 Then
        Style = vbCritical
        Insulte = "Ligne à modifier : le composant '" & theNomComposant & "' ne comporte aucun lot. "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Exit Sub
    End If
    
    '-------------------------------------------------------------------------------------
    'Pour le composant de remplacement theComposantNo, on détermine le lot correspondant
    'à la date de fabrication theDateFabrication,
    'ainsi que la date de début d'utilisation de ce lot.
    '-------------------------------------------------------------------------------------
    
    On Error Resume Next
    
    r = "SELECT Max(x.DateDebutUtilisation) AS theDateDebutUtil, Max(x.NomLot) AS theNomLot " _
        & " FROM T_Lots AS x, TLC_Composants AS y " _
        & " WHERE  y.IDComposant = " & theComposantNo & " " _
        & "   AND  x.IDComposant = y.IDComposant " _
        & "   AND  x.DateDebutUtilisation <= CDate('" & theDateFabrication & "') " _
        & " GROUP BY x.IDComposant ; "
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    End If
    
    theDateDebutUtil = Sqlresult.Fields("theDateDebutUtil").Value
    theNomLot = Sqlresult.Fields("theNomLot").Value
    
    '-----------------------------------------------------------------------------
    ' On met à jour la ligne concernée dans la table T_Fabrication_Composants
    '-----------------------------------------------------------------------------
             
    On Error Resume Next
    
    theUpdate = "update T_Fabrication_Composants SET " _
        & "IDComposant = " & theComposantNo _
        & ", LotduComposantdujour = '" & theNomLot & "' " _
        & "where ID_F_C = " & theTableId & " ;"
                 
    theDataBase.Execute theUpdate
    
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit.."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Sub
    
    End If
        
    'on rafraîchit le sous-formulaire
        
    Me.Recalc
    
    
    theDataBase.Close: Set theDataBase = Nothing
    
    End Sub
    
    
    '-----------------------------------------------------------------
    ' Cézigue en a terminé. On ferme la boutique.
    '-----------------------------------------------------------------
    
    
    Private Sub Quitter_Click()
    
    DoCmd.Close
    
    End Sub
    
    '-----------------------------------------------------------------------
    '
    ' traitements et contrôles portant sur la table T_Fabrications
    '
    '-----------------------------------------------------------------------
    
    Function DeterminerFabrication()
    
    Dim theDataBase As DAO.Database, Sqlresult As DAO.Recordset
    
    Dim Style As Integer, Insulte As String, Titre As String, Reponse As String
    Dim r As String, theNomComposant As String, theIDFabrication As Integer
    Dim theDateFabrication As String, MaxIdFabrication As Integer, theTableId As Integer
    Dim theKount As Integer, theComposantNo As Integer, theDateDebutUtil As Date, theNomLot As String
    Dim Delete As String
    
    '-------------------------------------------------------------------
    ' Table T_Fabrications : on vérifie que IDFabrication est renseigné
    '-------------------------------------------------------------------
    
    DeterminerFabrication = False
    
    Set theDataBase = CurrentDb
    
    On Error Resume Next
    
    If IsNull(Me.IDFabrication) Then
        Style = vbCritical
        Insulte = "Veuillez renseigner le champ IDFabrication."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Function
    End If
    
    theIDFabrication = Me.IDFabrication
    
    '-------------------------------------------------------------------------------
    ' On vérifie que IDFabrication est présent dans la table T_Fabrications
    '-------------------------------------------------------------------------------
    
    r = "SELECT COUNT(*) AS Kount FROM T_Fabrications where IDFabrication = " & theIDFabrication & " ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Function
    End If
    
    theKount = Sqlresult.Fields("Kount").Value
    
    If theKount = 0 Then
        Style = vbCritical
        Insulte = "L’identifiant IDFabrication = " & theIDFabrication & " n’existe pas dans la table T_Fabrications..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Function
    End If
    
    '-----------------------------------------------------------------
    ' détermination de la date de fabrication
    '-----------------------------------------------------------------
    
    r = "SELECT DateFabrication FROM T_Fabrications where IDFabrication = " & theIDFabrication & " ;"
        
    Set Sqlresult = theDataBase.OpenRecordset(r, dbOpenDynaset)
     
    If Err.Number <> 0 Then
    
        Style = vbCritical
        Insulte = r & Chr(13) & Chr(13) & "Erreur " & Err.Number & ". " & Err.Description & Chr(13) & Chr(13) & " Prévenir qui de droit..."
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
            
        theDataBase.Close: Set theDataBase = Nothing
        Exit Function
    End If
    
    theDateFabrication = Sqlresult.Fields("DateFabrication").Value
    Me.DateFabrication = theDateFabrication
    
    DeterminerFabrication = True
    
    End Function
    
    

    Citation Envoyé par byaccess2
    Ce que souhaiterais, c'est pouvoir, sur base d'une requête telle que la requête1 qui me retourne les valeurs suivantes :





    filtrer les valeurs "Lotcomposantdujour" vides et les remplir avec les lots que votre code permet de retourner. Je reposte pour que vous la testiez la v3bis avec les deux enregistrements.
    De mon côté, je valorise tout de suite Lotducomposantdujour, puisque j’ai tous éléments pour faire, comme je l’ai écrit plus haut ; pourquoi vous acharner à ce que cet attribut soit vide dans le sous-formulaire ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  6. #46
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bonjour fsmrel,

    Vu la météo abominable ce matin, votre humour m'a redonné le moral.
    Comme je l'ai expliqué, l'exemple simple que j'ai proposé sur la fabrication de plats préparés pourrait correspondre à la structure des tables telle qu'elle s'applique à l'activité pour laquelle je souhaiterais trouver une solution informatique. Les secteurs d'activité dans lesquels vous me voyiez travailler ont bien d'autres moyens pour financer des informaticiens professionnels.
    Donc plutôt Nom : serveimage.jpg
Affichages : 168
Taille : 10,9 Ko que Nom : serveimage2.jpg
Affichages : 167
Taille : 10,9 Ko
    Artisan contraint de s'aligner sur les standards des "gros", autodidacte pour l'informatique, et soucieux de faire correctement moi-même ce que des commerciaux m'imposeraient avec leurs contraintes, mais espèce en voie de disparition (c'est pourquoi je ne souhaite pas donner trop de détails), mais soit, je me verrais bien en pizzaïolo, mais Mario est un pseudo déjà utilisé…

    Pour en revenir à votre solution, elle répond sur le fond à ma première intention, à savoir en "live" aller chercher chaque lot des composants qu'on ajoute. Je vois trois obstacles dans votre proposition:

    1) Elle est valable, comme je le pensais initialement, si chaque document papier est encodé immédiatement, voire remplacé (dans une autre vie) par un poste d'encodage dans la réserve. Hors il se pourrait que quelques jours se passent avant cet encodage dans la table T_Fabrication_Composants. D'où ma solution Nouf-Nouf et Nif-Nif de requêtes en cascade et de table tampon, qui met à jour la table T_Fabrications au rythme souhaité (l'important est qu'il n'y ait plus de champs vides dans les fiches de fabrication lorsqu'on les édite… vérifiable par une petite requête hebdomadaire par exemple). Bon, j'ai adapté une des requêtes pour ne plus extraire que les enregistrements vides Lotducomposantdujour, et converti la macro en VBA pour y ajouter les lignes permettant de supprimer les messages d’avertissement. La table tampon est automatiquement supprimée à chaque exécution, et se recrée uniquement avec les nouvelles valeurs de la table T_Lots. Donc c'est léger et ça marche comme on disait à l'armée.
    A condition bien sûr de ne mettre à jour qu'après avoir encodé toutes fiches papier T_Lots (sinon, les valeurs de Lotducomposantdujour se rempliront avec les données connues du dernier lot encodé), donc une petite organisation interne à prévoir.
    J'en ai profité pour corriger la requête3 où il manquait une jointure entre IDComposant et Composant.
    Voici le code de la macro:
    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
    Function Macro1()
    DoCmd.SetWarnings False
    On Error GoTo Macro1_Err
     
        DoCmd.OpenQuery "R_création_T_tampon", acViewNormal, acEdit
        DoCmd.OpenQuery "R_Mise à jour", acViewNormal, acEdit
     
     
    Macro1_Exit:
        Exit Function
     
    Macro1_Err:
        MsgBox Error$
        Resume Macro1_Exit
    DoCmd.SetWarnings True
     
    End Function
    Si on part du principe que les documents T_Lots papier sont néanmoins encodés dans leur table avant toute fabrication utilisant le nouveau lot, le code qui permet d'extraire et de copier le Lotducomposantdujour que vous avez écrit est parfait pour peu que je puisse l'identifier dans votre page complète de code. Mais:

    2) Si j'ai bien compris le fonctionnement des encodages, l'utilisateur doit donner un IDFabrication avant d'encoder les autres données et de créer l'enregistrement correspondant. Bizarre car j'ai plutôt prévu un NumAuto sur ce champ. Vous dites: "Dans ce petit prototype, l’utilisateur fournit une valeur pour le champ IDFabrication, valeur devant exister dans la table T_Fabrications". Je ne comprends pas cette logique.
    3) J'ai volontairement construit la structure du formulaire d'encodage pour éviter d'avoir à cliquer sur des boutons. Dans le formulaire, je dois juste encoder la date, dans le SF juste encoder le composant de la liste de choix. Pour les suppressions ou modifications, je les fais directement dans le SF. Mais ne voyant pas votre SF, impossible de savoir si le champ NomComposant est une liste déroulante (je ne pense pas).

    Ce qui serait parfait, c'est que sur l'évènement AfterUpdate du champ NomComposant de mon SF soit associée la partie du code qui permet d'extraire et de copier le Lotducomposantdujour dans le champ ad hoc.
    Cela raccourcirait le code global.
    Est-ce envisageable?

  7. #47
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir byaccess2,


    Je vais être bref et ne vais pas répondre précisément à vos interrogations et remarques, car j’ai peu de temps...


    Citation Envoyé par byaccess2
    L'important est qu'il n'y ait plus de champs vides dans les fiches de fabrication lorsqu'on les édite.
    Prenons le cas du composant C2 :





    Si la colonne Lotducomposantdujour n’est pas valorisée, c’est qu’on n’a pas encore le lot qui va bien pour C2 (ou bien qu’on n’a pas encore décidé du lot à retenir), sinon quelque chose m’échappe...

    C’est quelque chose comme ça ?



    Citation Envoyé par byaccess2
    Si j'ai bien compris le fonctionnement des encodages, l'utilisateur doit donner un IDFabrication avant d'encoder les autres données et de créer l'enregistrement correspondant. Bizarre car j'ai plutôt prévu un NumAuto sur ce champ. Vous dites: "Dans ce petit prototype, l’utilisateur fournit une valeur pour le champ IDFabrication, valeur devant exister dans la table T_Fabrications". Je ne comprends pas cette logique.
    Je suis parti du principe que la table T_Fabrications pouvait contenir d’autres attributs que IDFabrication et DateFabrication, donc qu’il existe un formulaire pour créer les lignes de cette table. A défaut, si cette table ne contient que les deux attributs IDFabrication et DateFabrication cela veut dire que lorsque l’utilisateur saisit directement dans le sous-formulaire les valeurs qui lui conviennent, il doit exister du code appartenant au formulaire ou au sous-formulaire, automatiquement déclenché pour effectuer les inserts dans la table T_Fabrications (sinon les contrôles d’intégrité référentielle rouspètent). Est-ce que vous attendez ?


    Citation Envoyé par byaccess2
    Ce qui serait parfait, c'est que sur l'événement AfterUpdate du champ NomComposant de mon SF soit associée la partie du code qui permet d'extraire et de copier le Lotducomposantdujour dans le champ ad hoc.
    Cela raccourcirait le code global.
    Est-ce envisageable?
    J’essaierai de trouver un moment pour voir ça, en tout cas ce lundi et ce mardi, je serai très peu disponible.


    Une question :

    Dans vos tables T_Lots et T_Fabrication-Composants, l’attribut IDComposant est de type numérique, OK, mais quand on les ouvre directement, c’est le nom du composant qui apparaît : quelle fonction ACCESS permet cela ? (je n’utilise ACCESS que bien épisodiquement et n'en connais que peu de choses...)


    Bon courage...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  8. #48
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bonjour fsmrel,

    J'ai profité du w-e pour implémenter mes petites tables de test dans ma "vraie" base de données. Un peu de bidouillage nécessaire, mais dans les grandes lignes, ma solution amateur de cascade de requêtes fonctionne, avec quelques restrictions (pas de lots différents entamés le même jour, etc mais marginal donc peut être résolu manuellement).

    Comme je l'ai expliqué précédemment, je me suis rendu compte qu'en pratique, votre solution d'automatiser l'actualisation du Lotducomposantdujour sur base des enregistrements présents dans la table T_Lots présente le même inconvénient que faire tourner mes petites requêtes trop régulièrement. Je m'explique:

    Si on n'encode les fiches papier T_Lots que tous les x jours, le Lotducomposantdujour qui va se créer dans la table T_Fabrication_Composants sera toujours le dernier connu, avec votre solution ou avec la mienne (que ce soit via votre code associé au bouton Ajouter, ou bien à la suite de mes requêtes en cascade). Ensuite tout dépend si les valeurs de ce champ sont "figées" ou mises à jour à chaque refresh des requêtes (dans votre solution j'avais accepté que si on met à jour la table T_Lots avec des lots plus récents par exemple, les valeurs recherchées par votre code pour le champ Lotducomposantdujour ne soient pas mises à jours pour les fabrications créées depuis la dernière mise à jour).

    Donc je n'ai trouvé que 2 solutions pour éviter ce problème, du moins avec mes petites requêtes en cascade:
    1) mettre à jour régulièrement TOUS les enregistrements depuis le 1er. Inconvénient: lourd à terme + risque d'imprimer des fiches de fabrication pas à jour si T_Lots pas à jour. En effet, une valeur se créera toujours dans le champ Lotducomposantdujour (la dernière connue), et on ne distinguera plus les "faux à jour".
    2) ne mettre à jour le champ Lotducomposantdujour qu'après avoir mis à jour la table T_Lots. Dans ce cas, les fiches de fabrication avec Lotducomposantdujour vides seront distinguables, et ne pourront être imprimées qu'après mise à jour de tout le reste.

    C'est cette seconde solution que j'ai retenue, filtrant ainsi au passage mes requêtes sur base du champ Lotducomposantdujour vide. Le résultat créé (table tampon qui s'auto-écrase) est ainsi léger à chaque fois. Bref de l'amateurisme fiable pour peu qu'on soit procédurier.

    Citation Envoyé par fsmrel Voir le message
    Si la colonne Lotducomposantdujour n’est pas valorisée, c’est qu’on n’a pas encore le lot qui va bien pour C2 (ou bien qu’on n’a pas encore décidé du lot à retenir), sinon quelque chose m’échappe...
    C’est quelque chose comme ça ?
    Exact, ça veut dire qu'on ne sait pas si un nouveau lot n'a pas été entamé depuis la dernière mise à jour, peut-être que oui peut-être que non.

    Citation Envoyé par fsmrel Voir le message
    Je suis parti du principe que la table T_Fabrications pouvait contenir d’autres attributs que IDFabrication et DateFabrication, donc qu’il existe un formulaire pour créer les lignes de cette table. A défaut, si cette table ne contient que les deux attributs IDFabrication et DateFabrication cela veut dire que lorsque l’utilisateur saisit directement dans le sous-formulaire les valeurs qui lui conviennent, il doit exister du code appartenant au formulaire ou au sous-formulaire, automatiquement déclenché pour effectuer les inserts dans la table T_Fabrications (sinon les contrôles d’intégrité référentielle rouspètent). Est-ce que vous attendez ?
    Citation Envoyé par fsmrel Voir le message
    (je n’utilise ACCESS que bien épisodiquement et n'en connais que peu de choses...)
    Aucune idée, je pensais que vos exemples et copies d'écran étaient créés dans une version anglaise d'Access, ou alors ça y ressemble très fort. Les sous-formulaires en mode Feuille de données permettent d'encoder les enregistrements de ce SF comme dans une table. Avec quel logiciel avez-vous créé votre base de données?

    Citation Envoyé par fsmrel Voir le message
    Dans vos tables T_Lots et T_Fabrication-Composants, l’attribut IDComposant est de type numérique, OK, mais quand on les ouvre directement, c’est le nom du composant qui apparaît : quelle fonction ACCESS permet cela ? (je n’utilise ACCESS que bien épisodiquement et n'en connais que peu de choses...)
    C'est un champ de type liste de choix. "Derrière" se trouve une requête dont voici l'illustration:
    Nom : table.jpg
Affichages : 162
Taille : 279,5 Ko

    Des logiciels de BDR tels que OpenOffice contiennent tous les outils nécessaires, hormis les macros. C'est justement ce dernier outil qui permet à des profanes comme moi de faire "comme si" et d'écrire du code sans le savoir. Néanmoins, il y a certaines limitations, comme dans l'exemple de ma Macro1 la gestion des actions telles que DoCmd.SetWarnings False qu'il faut rajouter à la main pour pallier aux limites des macros (du moins dans les anciennes versions d'Access). Je pense que le générateur de requêtes d'Access me retourne globalement un code qui doit ressembler au vôtre.
    D'où l'intérêt de forums tels que celui-ci qui est une vraie mine d'or où on peut s'échanger autre chose que des raiflecssiont sûr le dairnié aïfône…

    Ce que je dois absolument tester, c'est, après l'avoir identifiée, la partie de votre code qui permet de retourner les valeurs de Lotducomposantdujour "en direct". Cela ne doit pas être loin de la fonction dlookup qui semble propre à Access. En l'associant à l'évènement AfterUpdate du champ Composant du sous-formulaire, je vais essayer, à mon rythme, de faire fonctionner le SF et posterai mon résultat.

    Encore un grand merci pour le temps que vous passez sur ce projet.

  9. #49
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour byaccess2,


    Citation Envoyé par byaccess2
    Ce que je dois absolument tester, c'est, après l'avoir identifiée, la partie de votre code qui permet de retourner les valeurs de Lotducomposantdujour "en direct".
    J'ai une journée bien chargée, j'essaierai de traiter cette partie dans la soirée, si j’ai encore des forces, sinon ça sera demain, sauf imprévu...

    On y arrivera, mais Paris ne s’est pas fait en un jour...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  10. #50
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    J'ai oublié :

    Merci pour l’astuce, ça fonctionne aussi dans la version anglo-saxonne.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  11. #51
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bonjour,
    Citation Envoyé par fsmrel Voir le message
    J'ai oublié :

    Merci pour l’astuce, ça fonctionne aussi dans la version anglo-saxonne.
    Quelle astuce? C'est Access que vous utilisez ou pas?

  12. #52
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir byaccess2,


    Une nouvelle suggestion...


    Reprenons vos tables :


















    J’ai défini une requête LotsNonRenseignes, avec laquelle on sait pour quels composants de la table T_Fabrication-Composants la colonne Lotducomposantid n’est pas renseignée :


    
    SELECT t.IDFabrication AS IDFabrication, t.[Date Fabrication] AS DateFabrication, x.IDComposant AS IDComposant, x.Composant AS NomComposant
    FROM   TLC_Composants AS x, T_Lots AS y, T_Fabrications AS t, [T_Fabrication-Composants] AS z
    WHERE  x.IDComposant = y.Composant
      and  x.IDComposant = z.IDComposant
      and  z.IDFabrication = t.IDFabrication
      and  (z.Lotducomposantdujour is null or len(z.Lotducomposantdujour) = 0)
    GROUP BY t.IDFabrication, t.[Date Fabrication], x.IDComposant, x.Composant ;
    
    
    En l’occurrence, tout le monde répond présent...






    J’en fais un sous-formulaire nommé Fabrications_sans_lots :





    De cette façon, on voit en même temps le travail de saisie en cours, ainsi que toutes les fabrications (avec leur date de fabrication) pouvant être complétées avec le lot à la date la plus proche :






    Pour réaliser automatiquement la tâche consistant à compléter avec la date de lot la plus proche, on utilise le bouton « Lotir », suite à quoi :





    Si c’est trop radical comme traitement, on pourra voir comment affiner (s’arrêter sur chaque ligne sous-formulaire Fabrications_sans_lots et poser la question : « On le fait pour cette ligne ?) ou autre méthode.

    J’ai mis à jour votre v3bis, vous trouverez donc mes modifications ici.

    J’espère qu’avec la version française d’ACCESS vous n’aurez pas de problème pour ouvrir le fichier.


    Au cas où : Pour accéder au code VBA du bouton « Lotir », avec la version anglo-saxonne d’ACCESS 2013 :

    Barre de menus > Form Design Tools > Design > View Code.



    Citation Envoyé par byaccess2
    Quelle astuce? C'est Access que vous utilisez ou pas ?
    Certes, c’est ACCESS, mais je n’avais pas pensé dans la liste de choix à ramener la taille de la zone de texte à 0 cm pour IDComposant (cf. votre dernière image)...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  13. #53
    Membre à l'essai
    Homme Profil pro
    amateur
    Inscrit en
    Janvier 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Janvier 2015
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Bonsoir fsmrel,
    j'ai pu ouvrir votre version sans problème.
    Le bouton "ouvrir" fonctionne à merveille. Avec les précautions d'usage, à savoir que si on encode a posteriori un nouveau lot entamé avant d'avoir cliqué la dernière fois sur ouvrir, il n'y aura pas de màj de la valeur du champ (normal car il sera non vide). Mais c'est une des conditions préalables.
    Sinon j'ai adapté les liens père-fils du F_Fabrications (sur IDFabrication pour visualiser les composants par fenêtre de fabrication) et le bouton ouvrir fonctionne encore aussi bien.
    Je vais essayer de copier le code sur l'évènement AfterUpdate du champ Composant du SF, et voir ce que ça donne.
    Je posterai les résultats de mes essais ce w-e.
    Encore merci pour l'adaptation.

    PS: à 3h49 du matin, vous êtes insomniaque ou dans un autre fuseau horaire que Paris?

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/06/2010, 02h39
  2. Réponses: 1
    Dernier message: 17/04/2009, 15h44
  3. Réponses: 2
    Dernier message: 05/03/2008, 22h01
  4. problem avec la recherche d'une valeur dans les table
    Par anilane dans le forum Bases de données
    Réponses: 6
    Dernier message: 25/05/2007, 19h35
  5. [JSTL] Récupérer une valeur dans ma map à l'aide d'une clé
    Par Sim dans le forum Taglibs
    Réponses: 1
    Dernier message: 29/08/2006, 10h03

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