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. #21
    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
    1ère étape,
    une fois mon formulaire ouvert, avec une date de fabrication et un composant remplis, une requête basée sur le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT TOP 1 T_Lots.IDLot, T_Lots.Lot
    FROM T_Lots
    WHERE (((T_Lots.Composant)=[Formulaires]![F_Fabrications]![Composant]) AND ((T_Lots.[Date début utilisation])<=[Formulaires]![F_Fabrications]![Date fabrication]))
    ORDER BY T_Lots.[Date début utilisation] DESC;
    me retourne bien le lot correct. (par exemple LC1-b pour une fabrication du 15/1/2015)

    Mais que faire maintenant de ce résultat? (qui se trouve dans une "table" ouverte en plus de mon formulaire). Je ne comprends pas comment programmer le formulaire pour qu'il mette à jour son champ Lot sur base du résultat de cette requête... d'où mon insistance à utiliser une fonction dlookup qui semble faite pour ça (et qui peut intégrer le where dans ses critères)

  2. #22
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    Bonsoir byacces2,


    Citation Envoyé par byacces2
    Le fait que vous utilisiez des noms de champ différents de ceux de ma base me perturbe un peu, ainsi que le fait que vous utilisiez des alias "as" dont je me demande quoi faire

    OK. J’ai aligné la structure de mes tables sur les vôtres. Quant aux alias « as » ils me permettent de manipuler des noms plus courts pour les tables.

    Ainsi, question d’habitude, je préfère pour ma part coder :

    
    SELECT Max(x.DateDebutUtilisation) AS theDateDebutUtil, Max(x.lot) AS theLot
    FROM   T_Lots AS x inner JOIN TLC_Composants AS y ON x.Composant = y.N°
    WHERE  y.Composant ='C1'
      AND  x.DateDebutUtilisation <= Cdate('25/01/2015')
    GROUP BY x.Composant;
    
    
    Plutôt que :

    
    SELECT Max(T_Lots.DateDebutUtilisation) AS theDateDebutUtil, Max(T_Lots.lot) AS theLot
    FROM   T_Lots INNER JOIN TLC_Composants ON T_Lots.Composant = TLC_Composants.N°
    WHERE  TLC_Composants.Composant ='C1'
      AND  T_Lots.DateDebutUtilisation <= Cdate('25/01/2015')
    GROUP BY T_Lots.Composant;
    
    
    Mais bien entendu, vous choisissez le style avec lequel vous vous sentez à l’aise.


    Je vais regarder la suite de votre message, et essayer de manipuler un formulaire, chose qui ne m’est pas arrivée depuis un bon moment, il faut donc que je me dérouille à ce sujet...
    (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.

  3. #23
    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
    Citation Envoyé par fsmrel Voir le message

    Je vais regarder la suite de votre message, et essayer de manipuler un formulaire, chose qui ne m’est pas arrivée depuis un bon moment, il faut donc que je me dérouille à ce sujet...
    D'avance merci, j'ai passé une partie de l'après-midi à exploiter le code de mon précédent post (avec le TOP 1). Il marche de manière "brute", mais dès que je veux l'intégrer à un champ du formulaire, j'obtiens une erreur de syntaxe. Le DLOOKUP permet justement d'extraire, sur base d'un enregistrement, les données relatives à cet enregistrement situées dans une autre table. J'ai vu quelques exemples sur google, mais bizarrement, peu de réponses aux questions. Pourtant ça marche, quand il y a un seul enregistrement correspondant (par exemple un article avec son prix). Mais la solution proposée plus haut (avec des critères between par exemple), devrait permettre d'intégrer le filtre de la requête.
    Je continue à chercher mais pas facile de jouer du piano sans avoir appris, ou alors de manière empirique...

  4. #24
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    Bonsoir byacces2,


    Je regarderai cette histoire de Dlookup, mais en attendant...

    J’ai refait du VBA, ça faisait un moment ! Je me suis livré à l’exercice suivant (dans le style que j'utilisais il y a 20 ans) :

    Création du formulaire F_Fabrications, dans lequel l’utilisateur fournit un nom de composant et une date de référence, à partir de laquelle on cherchera par requête SQL la date de fabrication inférieure ou égale, ainsi que le lot correspondant. Cette recherche est déclenchée quand on clique sur le bouton « GO ».






    Après avoir fait GO, il y a affichage des valeurs correspondantes dans les champs IDFabrication, DateFabrication, Lot et il y a insertion d’une ligne dans la table T_Fabrications.





    Les champs du formulaire sont ainsi nommés :

    Composant

    DateReference

    IDFabrication

    DateFabrication

    Lot

    Et le bouton : GO.


    Structure des tables que j’utilise :


    TLC_Composants {N° autonumber, Composant short text}

    T_Lots {IDLot autonumber, Composant number, Lot short text, DateDebutUtilisation date}

    T_Fabrications {IDFabrication autonumber, DateFabrication date, Composant number, Lot short text}



    Code VBA (évidemment améliorable, je n’ai pas fait dans la dentelle !) :

    
    Private Sub Composant_GotFocus()
    
    Me.IDFabrication = ""
    Me.DateFabrication = ""
    Me.Lot = ""
    
    End Sub
    
    Private Sub GO_Click()
    
    Dim r As String, theComposant As String
    Dim theDateReference As String, theDateFabrication As String, MaxIdFabrication As Integer
    Dim Sqlresult As DAO.Recordset
    Dim insert As String
    Dim theDataBase As DAO.Database
    Dim Style As Integer
    Dim Insulte As String
    Dim Titre As String, Reponse As String
    Dim theKount As Integer, theComposantNo As Integer
    
    On Error Resume Next
    
    Set theDataBase = CurrentDb
    
    '-------------------------------------------------------------------------
    ' Contrôle du composant
    '-------------------------------------------------------------------------
    
    theComposant = Composant.Value
    
    theKount = 0
    
    If Len(theComposant) > 0 Then
         r = "SELECT COUNT(*) AS Kount FROM TLC_Composants WHERE Composant = '" & theComposant & "' ;"
    
         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
    End If
    
    If theKount = 0 Then
        Style = vbExclamation
        Insulte = "Le champ Composant doit contenir un composant existant !  "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Composant.SetFocus
        Exit Sub
    End If
    
    
    r = "SELECT N° AS ComposantNo FROM TLC_Composants WHERE Composant = '" & theComposant & "' ;"
    
    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("ComposantNo").Value
    
    r = "SELECT COUNT(*) AS Kount FROM T_LOTS WHERE Composant = " & 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 n'est référencé dans la table des lots !  "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        Composant.SetFocus
        Exit Sub
    End If
    
    
    '-------------------------------------------------------------------------
    ' Contrôle de la date de référence
    '-------------------------------------------------------------------------
    
    theDateReference = DateReference.Value
    
    If Not IsDate(theDateReference) Then
        Style = vbExclamation
        Insulte = "Le champ date de référence doit contenir une date !  "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        DateReference.SetFocus
        Exit Sub
    End If
    
    '--------------------------------------------------------------------------------------------------------------------
    ' Insert d'une ligne dans la table T_Fabrications
    '--------------------------------------------------------------------------------------------------------------------
    
    insert = "insert into T_Fabrications (DateFabrication, Lot, Composant) " _
                  & "SELECT Max(x.DateDebutUtilisation), Max(x.lot), " & theComposantNo & " " _
                  & "FROM   T_Lots AS x INNER JOIN TLC_Composants AS y ON x.Composant = y.N° " _
                  & "WHERE  y.Composant = '" & theComposant & "'" _
                  & "  AND  x.DateDebutUtilisation <= CDate('" & theDateReference & "')" _
                  & " GROUP BY x.Composant ; "
    
    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
    
    '--------------------------------------------------------------------------------------------------------------------
    ' Détermination de la dernière ligne insérée dans la table T_Fabrications
    '--------------------------------------------------------------------------------------------------------------------
    
    r = "SELECT MAX(IdFabrication) AS Maxfab FROM T_Fabrications ; "
    
    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
    
    MaxIdFabrication = Sqlresult.Fields("Maxfab").Value
    
    Me.IDFabrication = MaxIdFabrication
    
    '--------------------------------------------------------------------------------------------------------------------
    ' Détermination de la date de fabrication pour la dernière ligne insérée dans la table T_Fabrications
    '--------------------------------------------------------------------------------------------------------------------
    
    r = "SELECT DateFabrication FROM T_Fabrications WHERE IDFabrication = " & Me.IDFabrication & " ; "
    
    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
    
    Me.DateFabrication = Sqlresult.Fields("DateFabrication").Value
    
    '--------------------------------------------------------------------------------------------------------------------
    ' Détermination du lot de la dernière ligne insérée dans la table T_Fabrications
    '--------------------------------------------------------------------------------------------------------------------
    
    r = "SELECT Lot FROM T_Fabrications WHERE IdFabrication = " & MaxIdFabrication & " ;"
    
    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
    
    Me.Lot = Sqlresult.Fields("Lot").Value
    
    End Sub
    
    
    J'espère me rapprocher de ce que vous cherchez...
    (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.

  5. #25
    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
    Blam, me voilà ko...
    Je pensais avoir à faire à une simple demande mais visiblement, c'est plus compliqué!
    Encore une fois grand merci pour votre temps passé sur mon problème, votre solution n'est pas ce que j'attendais mais il y a certainement des idées que je pourrais exploiter.

    Je pense avoir compris ceci quant au principe que vous proposez:
    Sur base d'une date de référence, le "ok" va chercher dans la table des fabrications la dernière date où le composant a été utilisé, et va chercher dans la table des lots le lot utilisé à cette date. Ensuite, le "ok" crée une nouvelle fabrication à cette date.

    Je voudrais resituer le contexte dans lequel je souhaite utiliser cette base de données:
    Je fabrique des produits composés de plusieurs composants; cette composition varie en fonction des fabrications. Je fabrique un lot par jour (c'est donc la date de fabrication qui me sert de lot pour mes produits finis; je simplifie grandement, ces tables seront intégrées dans une bdr plus complexe).
    On me demande une traçabilité de chaque lot de produit fini quant à ses composants. Cette traçabilité n'est à fournir qu'en cas de constatation de produit fini incorrect, pour lequel je vais devoir identifier tous les composants utilisés, et leurs lots afin de pouvoir le cas échéant identifier tous les produits finis fabriqués à base de ce lot, chez moi mais aussi chez tous les autres clients ayant reçu ce lot. Exercice occasionnel donc (heureusement...).
    J'ai donc plusieurs possibilités pour assurer cette traçabilité:

    1) soit je note pour chaque fabrication les composants utilisés, et je recopie chaque fois le n° de lot de chaque composant que je lis sur l"étiquette de ce composant (solution archaïque, pouvant être faite plus rapidement encore sur papier...). Inconvénient: prend du temps et redondant (certains composants sont utilisés pendant un an avant d'entamer un nouveau lot). Au niveau informatique, 3 colonnes, fichier Excel ou Access avec encodage manuel de la date de fabrication, du composant 1, 2,... , du n° de lot de ce composant.

    2) soit je note sur une feuille les lots de composants que j'achète, je place cette feuille sur l'étagère de chaque composant, et je mentionne la date à partir de laquelle j'entame un nouveau lot de ce composant (j'applique le principe du fifo - first in first out - et donc je n'entame jamais un nouveau lot de composant sans avoir épuisé tous les sacs du composant ayant une date de péremption inférieure). Solution permettant de faire l'économie de recopie de chaque lot comme en 1), et me permettant de ne mentionner dans mes fiches de fabrications que les divers composants utilisés. Si on me demande leurs lots, je n'ai qu'à aller noter manuellement ceux entamés à la date demandée. Solution simple, encore archaïque, dispense de recopier chaque fois les lots utilisés. Au niveau informatique, 2 colonnes, fichier Excel ou Access avec encodage manuel de la date de fabrication, du composant 1, 2,... . Inconvénient: en cas de produit fini incorrect, je devrais aller manuellement relever chaque fiche de composant papier pour vérifier le lot utilisé à la date x.

    C'est cette deuxième solution que je voudrais exploiter dans une bdr.
    J'encode dans une table mes fiches de lots de composants (à chque fois que j'entame un nouveau lot). C'est ma table T_Lots.
    J'encode à chaque fabrication les composants utilisés. C'est ma table T_Fabrications. Je l'ai dans ma version de test limitée au plus simple mais en réalité il y aura une table T_Fabrication-Composants qui me permettra de choisir plusieurs composants dans un sous-formulaire du formulaire F_Fabrications. Je reposte ici une v3 de la bdr adaptée.
    lot-date v3.zip
    J'encoderai donc toutes mes fabrications dans mon formulaire F_Fabrications, les tables n'étant jamais utilisées en tant que telles.
    C'est pourquoi je voudrais limiter mes encodages à une date de fabrication, et x composants. Rien de plus. Et obtenir une fiche de fabrication complète directement. Ce que je voudrais c'est que quand je choisis un composant, son lot vienne se copier directement dans le champ indépendant Lot de cette table T_Fabrication-Composants.

    Bon, je pourrais en effet créer des formulaires ou des requêtes pour réaliser la traçabilité dont je parle plus haut (par exemple tapez la date de fabrication, cliquez ici et cela ouvre un état). Mais ce que je souhaiterais, c'est pouvoir fournir aux clients, pour chaque fabrication, la liste de chaque composant utilisé avec leurs lots respectifs. Ainsi ils pourraient directement en cas de rappel de tous les produits fabriqués à partir de tel lot de composant, savoir si les produits finis qu'ils ont en stock contiennent ce lot de composant. (Ils pourraient attendre que je les informe moi-même après avoir fait mon exercice, mais quelques heures gagnées pourraient être importantes).

    Alors si cette option n'est pas réalisable, éventuellement une requête mise à jour qui remplirait à chaque fois qu'on l'exécute les champs Lots encore vides dans la table T_Fabrication-Composants, pourquoi pas.

    Donc je vais mettre mes lunettes et me plonger dans vos lignes de code, essayer de les comprendre, et recréer la base de données telle que vous l'avez modifiée, sauf si vous avez la possibilité de la mettre en ligne, par exemple en version v4, de manière à ce que je puisse voir directement le fruit de vos cogitations.

    D'avance merci pour vos heures passées.

  6. #26
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    Bonsoir byacces2,


    Citation Envoyé par byacces2
    Je vais mettre mes lunettes et me plonger dans vos lignes de code, essayer de les comprendre, et recréer la base de données telle que vous l'avez modifiée.
    Marquons une pause... Jusque-là on s’est entraîné avec des barres d’échauffement, ça m’a permis de revoir un peu VBA et les formulaires, mai il est temps de commencer par le commencement, à savoir modéliser, produire une assise correcte pour la base de données. Les structures des tables que j’ai utilisées sont ont les suivantes (cf. mon message précédent) :


    TLC_Composants { autonumber, Composant short text}

    T_Lots {IDLot autonumber, Composant number, Lot short text, DateDebutUtilisation date}

    T_Fabrications {IDFabrication autonumber, DateFabrication date, Composant number, Lot short text}


    Prenons maintenant votre dernier diagramme :





    Nos structures sont les mêmes, à ceci près qu’apparaît une table supplémentaire, T_Fabrication-Composants.

    Quoi qu’il en soit, selon ce diagramme, les premières règles de gestion des données sont les suivantes :

    (RG1) Un composant est composé d’au moins un lot et au plus plusieurs.

    (RG2) Un lot appartient à un au moins et au plus un composant.

    Ce à quoi j’ajoute la règle jusque-là implicite, selon laquelle {Lot} est clé alternative de T_Lots :

    (RG3) Deux lots ne peuvent pas avoir le même nom.


    Si ces règles sont correctes, l’attribut IDComposant doit disparaître de l’en-tête de la table T_Fabrication-Composants, car cause d’une redondance : pour connaître le composant d’un lot, il suffit en effet de faire référence à la table T_Lots, auquel cas le lien entre TLC_Composants et T_Fabrication-Composants est à remplacer par un lien entre T_Lots et T_Fabrication-Composants...


    Je vais essayer d’aller plus à fond dans votre description, mais j’aimerais d’abord avoir votre avis sur les énoncés des règles ci-dessus et leurs conséquences.
    (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.

  7. #27
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    reBonsoir byacces2,


    Si l’on rapproche les règles RG1, RG2, RG3 de la structure du sous-formulaire, ça coince, car selon ces règles, un lot fait référence à un composant et un seul, autrement dit c’est le champ Lot qui devrait faire l’objet d’une combo plutôt que le composant...


    Sous-formulaire actuel :





    Si les règles de gestion des données sont exactes, ça change :







    Qu’en est-il ?
    (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. #28
    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,
    Pour vous donner un exemple concret, imaginez la fabrication d'un gâteau. On va y mettre du sucre (le lot est par exemple une suite de chiffres: 123), du lait (le lot est par exemple la date de péremption 31/12/2015) et de la farine (le lot est par exemple la date de péremption 31/12/2015).
    Sur base de cet exemple fantaisiste (drôle de gâteau...), les règles sont les suivantes:

    (RG1) Un composant n'aura qu'un lot par gâteau (quoi qu'en théorie on pourrait utiliser deux lots de sucre, la fin d'un sac et le début d'un autre lot, mais faisons simple), mais au bout de l'année plusieurs lots différents de chaque composant aura été utilisé. Donc votre règle est correcte,
    Citation Envoyé par fsmrel Voir le message
    chaque composant est composé d’au moins un lot et au plus plusieurs.
    (RG2)
    Citation Envoyé par fsmrel Voir le message
    Un lot appartient à un au moins et au plus un composant
    . Faux car le lot 31/12/2015 est le même pour le lait et la farine.

    Citation Envoyé par fsmrel Voir le message
    Ce à quoi j’ajoute la règle jusque-là implicite, selon laquelle {Lot} est clé alternative de T_Lots :

    (RG3) Deux lots ne peuvent pas avoir le même nom.
    Par composant, non, je n'aurais en effet jamais dans la table des lots doublons Farine-31/12/2015. Je présume que c'est ce que vous considérez comme la deuxième clé primaire ("clé alternative") de la table T_Lots.


    Citation Envoyé par fsmrel Voir le message
    Si ces règles sont correctes, l’attribut IDComposant doit disparaître de l’en-tête de la table T_Fabrication-Composants, car cause d’une redondance : pour connaître le composant d’un lot, il suffit en effet de faire référence à la table T_Lots, auquel cas le lien entre TLC_Composants et T_Fabrication-Composants est à remplacer par un lien entre T_Lots et T_Fabrication-Composants...
    N'étant pas expert en bdr (j'y suis toujours allé par try&error), j'ai ajouté IDComposant dans la table T_Fabrication-Composants pour me permettre, via le formulaire, d'encoder plusieurs composants par fabrication. Je ne vois pas d'autre solution me permettant d'inclure le SF F_Fabrication-Composants sous-formulaire dans le formulaire principal.


    Comprenez-vous ma solution tordue de relations pour pouvoir utiliser ce fichu formulaire unique?

    Voilà, je précise que le champ "Lot" que j'ai ajouté à ma table T_Fabrication-Composants est indépendant de tout autre champ, et que c'est là que je souhaiterais que mon DLOOKUP (si un jour je parviens à trouver la syntaxe correcte) aille écrire la valeur du lot trouvée sur base de la date (sorry pour cette obsession pour cette procédure dlookup -recherche domaine en français-, mais j'ai eu le malheur de la découvrir lors de la conception d'une base de données de facturation, où le prix d'un article encodé devait être le dernier en date le jour de la facturation dans la table des articles, sans modifier les prix de ce même article facturé les années précédentes; je n'avais pas à l'époque jugé utile d'enregistrer l'historique des prix de chaque article, d'où cette solution élégante et simple maintes fois partagée avec des amis amateurs de rubik's cube).
    Mais à défaut de pouvoir automatiser ce copier/coller dans le champ Lot, une requête mise à jour pourrait peut-être convenir.

  9. #29
    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
    Citation Envoyé par fsmrel Voir le message
    reBonsoir byacces2,


    Si l’on rapproche les règles RG1, RG2, RG3 de la structure du sous-formulaire, ça coince, car selon ces règles, un lot fait référence à un composant et un seul, autrement dit c’est le champ Lot qui devrait faire l’objet d’une combo plutôt que le composant...


    Sous-formulaire actuel :





    Si les règles de gestion des données sont exactes, ça change :







    Qu’en est-il ?
    c'est bien la première structure qu'il me faut, j'ai expliqué dans mon post juste avant que nous nous croisions que le champ Lot est là pour recevoir la valeur qui viendrait du champ Lot de la table T_Lots

  10. #30
    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
    @ fsmrel: vu l'heure, ne passez pas votre soirée là-dessus, ni même votre w-e, je ne suis pas à un mois près pour proposer une solution
    Je vais aller arroser et je recogiterai ce w-e

  11. #31
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    Février 2010
    Messages
    8 409
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : Février 2010
    Messages : 8 409
    Points : 16 250
    Points
    16 250
    Par défaut
    Bonjour
    Citation Envoyé par byaccess2 Voir le message
    1ère étape,
    une fois mon formulaire ouvert, avec une date de fabrication et un composant remplis, une requête basée sur le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT TOP 1 T_Lots.IDLot, T_Lots.Lot
    FROM T_Lots
    WHERE (((T_Lots.Composant)=[Formulaires]![F_Fabrications]![Composant]) AND ((T_Lots.[Date début utilisation])<=[Formulaires]![F_Fabrications]![Date fabrication]))
    ORDER BY T_Lots.[Date début utilisation] DESC;
    me retourne bien le lot correct. (par exemple LC1-b pour une fabrication du 15/1/2015)

    Mais que faire maintenant de ce résultat? (qui se trouve dans une "table" ouverte en plus de mon formulaire). Je ne comprends pas comment programmer le formulaire pour qu'il mette à jour son champ Lot sur base du résultat de cette requête... d'où mon insistance à utiliser une fonction dlookup qui semble faite pour ça (et qui peut intégrer le where dans ses critères)
    La requête ne doit pas être créée comme une requête standard.
    Il faut mettre le champ lot du formulaire sous forme de liste déroulante et dans ses propriétés (en mode création), dans la zone contenu, cliquer sur les ... , dans la fenêtre de requête, passer en SQL et coller le code ci-dessus.
    En utilisation, la valeur apparaitra dans la liste déroulante et alimentera le champ lot de la table T_fabrications.

    Cependant de façon générale, une fabrication intégrant plusieurs composants, il faudrait un formulaire principal basé sur la fabrication (clé, date, produit fabriqué) et un sous formulaire sur les composants et leur lot.

    Un lot ne peut être commun à deux composants même si la date est la même : vous devez avoir un identifiant différent pour le lot de farine et pour le lot de lait car si le lait est contaminé, la farine peut ne pas l'être... En cas de contamination il faut cerner la source et intervenir soit chez le producteur de lait, soit chez le producteur de farine, soit chez transporteur.
    Chris
    PowerQuery existe depuis plus de 13 ans, est totalement intégré à Excel 2016 &+. Utilisez-le !

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  12. #32
    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 78chris,

    Citation Envoyé par 78chris Voir le message
    Cependant de façon générale, une fabrication intégrant plusieurs composants, il faudrait un formulaire principal basé sur la fabrication (clé, date, produit fabriqué) et un sous formulaire sur les composants et leur lot.
    C'est ce que j'ai fait dans la version 3 que j'ai postée un peu avant.

    Citation Envoyé par 78chris Voir le message
    La requête ne doit pas être créée comme une requête standard.
    Il faut mettre le champ lot du formulaire sous forme de liste déroulante et dans ses propriétés (en mode création), dans la zone contenu, cliquer sur les ... , dans la fenêtre de requête, passer en SQL et coller le code ci-dessus.
    En utilisation, la valeur apparaitra dans la liste déroulante et alimentera le champ lot de la table T_fabrications.
    Je viens de tester, pour faire facile sur base de la version 2 (pas de SF Fabrication-Composants). ça fonctionne +/-, j'ai bien un champ liste déroulante qui, lorsque je clique dessus, m'affiche dans la liste déroulante une seule valeur qui correspond bien au lot en fonction de la date de fabrication. Lorsque je la sélectionne, la valeur se recopie dans le champ Lot indépendant du même formulaire. Si je change de composant ou de date, je dois Actualiser le formulaire, recliquer sur la liste, sélectionner la valeur qui se recopie dans le champ Lot
    Donc le principe est bon, à adapter bien sûr avec la v3, mais comment automatiser ce "actualiser, clic sur menu déroulant, sélection de la valeur unique de la liste"?
    Je joins la version v2 bis avec mon adaptation provisoire:

    lot-date v2bis.zip

    Citation Envoyé par 78chris Voir le message
    Un lot ne peut être commun à deux composants même si la date est la même : vous devez avoir un identifiant différent pour le lot de farine et pour le lot de lait car si le lait est contaminé, la farine peut ne pas l'être... En cas de contamination il faut cerner la source et intervenir soit chez le producteur de lait, soit chez le producteur de farine, soit chez transporteur.
    Le lot pourrait être commun à plusieurs composants (par exemple si c'est une date de péremption) et cela doit rester possible. Les filtres se baseront toujours sur le couple Composant+Lot. Il serait même possible que sur les fiches papier, la personne note deux fois le même lot avec des dates d'utilisation successives. Il faudrait que dans ce cas l'encodage ne bloque pas sur base de ce doublon, d'où ma réticence à faire une clé primaire de ce couple. Je préfèrerais garder une clé primaire sur l'ID de la table T_Lots.

    Merci pour votre avis.

  13. #33
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut En amont des traitements : les données
    @byacces2


    Je reviens sur vos réponses d’hier :


    Citation Envoyé par byacces2
    C'est bien la première structure qu'il me faut, j'ai expliqué dans mon post juste avant que nous nous croisions que le champ Lot est là pour recevoir la valeur qui viendrait du champ Lot de la table T_Lots
    La colonne (ou attribut) Lot est présente à la fois dans les tables T_Lots et T_Fabrication-Composants, ce qui, comme je l’ai déjà fait observer, dénote une redondance, conséquence d’une erreur de conception (les « composants » d’un formulaire ne sont pas à reprendre à l’identique dans la structure d’une table !)

    Quoi qu’il en soit, si c’est la première structure qui est à retenir, votre modélisation est à revoir, puisqu’elle est actuellement inférée des règles :

    RG1 : Un composant est constitué d’au moins un lot ;

    RG2 : Un lot fait partie d’un composant et d’un seul.




    Tout en notant incidemment que :

    — L’attribut Composant de T_Lots fait référence à l’attribut IDComposant de TLC_Composants et non pas à l’attribut Composant de cette table (au cas où pour le lecteur un doute pourrait subsister, du fait de l’homonymie de noms).

    — Deux lots ne peuvent pas avoir le même nom avec la même date de début d’utilisation, d’où une clé alternative {Lot, DateDebutUtilisation}, règle RG3 révisée (mais encore révisable...)

    Maintenant, si la règle RG1 est valide et la règle RG2 fausse, la modélisation ne peut qu’évoluer ainsi :





    Mais La sémantique en prend un coup : le lot qui n’était jusque-là qu’une propriété multivaluée d’un composant devient entité-type de plein doit, entretenant des liens avec les composants sur un plan d’égalité :




    La modélisation n’est pas un art pifométrique, elle a ses règles et lois, et le diagramme résultant doit être validé par les parties prenantes, tout comme les architectes doivent être d’accord sur les fondations et ce qui s’ensuit, avant qu’on ne commence à élever les murs de la maison...


    J’agrée volontiers la métaphore du gâteau et des ingrédients qui entrent dans sa composition, mais en passant, dans votre système quel est l’homologue du gâteau, le produit (fini ou non) ? Quelle est la table correspondante dans votre diagramme ? Merci d’être rigoureux quant aux règles de gestion, sinon on n’en finira pas de supputer différents scénarios.
    (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.

  14. #34
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Reprenons l’exemple des gâteaux :

    Citation Envoyé par byacces2
    imaginez la fabrication d'un gâteau. On va y mettre du sucre (le lot est par exemple une suite de chiffres: 123), du lait (le lot est par exemple la date de péremption 31/12/2015) et de la farine (le lot est par exemple la date de péremption 31/12/2015).
    Sur base de cet exemple fantaisiste (drôle de gâteau...)

    Citation Envoyé par 78chris
    Un lot ne peut être commun à deux composants même si la date est la même : vous devez avoir un identifiant différent pour le lot de farine et pour le lot de lait car si le lait est contaminé, la farine peut ne pas l'être...
    Si on reprend l’exemple, le sujet n’est certes pas bien compliqué en soi, mais vous confirmez, Chris, que les règles de gestion des données ne sont pas ici rigoureusement définies. De mon côté, j’irai jusqu’à dire que les quiproquos, ambiguïtés, contradictions, doutes et paradoxes sont bien présents et guettent...

    Mais, vous serez d’accord avec moi, que lorsqu’on modélise une base de données, on ne peut pas se fonder sur des exemples où chaque concept n’a pas son homologue, cf. la question que j’ai posée dans mon message précédent : quelle table dans le diagramme correspond au gâteau ? On ne voit pas dans le modèle clairement défini le produit (fini ou non), tout au plus peut-on soupçonner qu’il se cache du côté de la table T_Fabrications, mais là encore le doute subsiste.

    Le concept de lot lui-même n’est pas clair : comme vous dites, Chris : « Un lot ne peut être commun à deux composants même si la date est la même », ce qui correspond à la règle RG2, mais byacces2 infirme cette règle...

    Dans ces conditions, si un lot donné n’est pas la propriété d’un composant donné, le modèle de données devient le suivant :





    En tout cas, il est de règle de ne pas échafauder des traitements tant que le modèle n’est pas stabilisé et complété et explicité, sinon c’est à ses risques et périls...
    (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.

  15. #35
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    Février 2010
    Messages
    8 409
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : Février 2010
    Messages : 8 409
    Points : 16 250
    Points
    16 250
    Par défaut
    Bonjour

    fsmrel : nous sommes bien d'accord sur la nécessité d'être rigoureux en ce qui concerne la structure de la BD avant de créer quoi que ce soit et sur l'absence de clarté ici sur le processus et les données liées.

    byacces2 : dans mon approche, il faut effectivement ajouter trois évènements au formulaire :
    l'un lié à chacun des champs qui influe sur la liste de lots (date et composant). Ces évènements doivent avoir un code (VBA ou macro) qui remet le champ lot à la "valeur" null, et réactualise le champ liste de lots.
    le dernier associé à l'activation du formulaire (ou sous-formulaire) lui-même et qui actualise seulement le champ liste de lots.
    Chris
    PowerQuery existe depuis plus de 13 ans, est totalement intégré à Excel 2016 &+. Utilisez-le !

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  16. #36
    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
    fsmrel et 78chris,
    j'ai lu attentivement vos remarques, et j'ai essayé dans un premier temps de modifier ma structure pour qu'elle corresponde au dernier post de fsmrel de 17h13.
    je poste ici la version v4 de la db modifiée. J'ai cependant conservé un champ Lot indépendant que j'ai renomme Lotdujour pour le différencier du Lot de la table T_Lots.

    lot-date v4.zip

    Confirmez-moi que c'est bien cette structure que vous proposez.
    Si c'est le cas, je me trouve avec une interface inexploitable pour celui qui va encoder. Je n'ai pas pu en effet faire apparaître dans le formulaire F_Fabrications le SF permettant de choisir les composants de la recette du jour.

    Je rappelle que l'encodage doit se limiter à deux endroits:
    - la table (ou un formulaire basé sur cette table pour faire joli) T_Lots où l'ouvrier qui va fabriquer va encoder chaque fois qu'il entame un nouveau lot d'un composant x (il encodera donc le composant, le lot qu'il lit sur l'emballage, et la date du jour où il entame ce lot)
    - le formulaire F_Fabrications où l'ouvrier va encoder la date du jour et les composants de sa recette du jour

    Je reprécise que cette structure est imaginaire et uniquement décrite pour mieux comprendre le contexte. En réalité, beaucoup d'autres facteurs seront présents dans la base de données, mais ces quelques tables simples sont là pour résoudre le problème de l'attribution du lot de chaque composant à la fabrication du jour.

    L'exemple en version 3 que j'ai posté plus en avant me convient parfaitement au niveau de la structure d'encodage, et ne pose aucun problème d'intégrité quant aux relations entre tables. Je concède que le champ Lot (électron libre) de la table T_Fabrication-Composants mériterait, afin d'éviter toute confusion avec le lot de produit fini (qui n'est pas présent dans l'exemple pour ne pas embrouiller encore plus l'affaire), de s'appeler Lotducomposantdujour par exemple. Cette source de confusion est corrigée dans la v3bis que je reposte ici:

    lot-date v3bis.zip

    Je suppose que vous comprenez chacun l'utilité de pouvoir figer la valeur d'un champ dans un autre champ, de manière à éviter qu'il soit mis à jour en cascade. L'exemple-type est celui que je décrivais plus haut:
    - table des articles avec leurs prix
    - table des détails d'une facture avec la liste des articles facturés
    Si on veut faire simple sans historiser l'évolution des prix, il ne faudrait pas que chaque fois qu'on modifie un prix dans cette liste, que les prix de chaque facture soient mis à jour en cascade. C'est pour cela que la procédure dlookup me fige le prix de chaque ligne d'article dans les factures. Je pourrais faire comme ça dans ma db des fabrications en faisant encoder en temps réel le n° de lot de chaque composant dans la table TLC_Composants, et ensuite avec la procédure dlookup, aller rechercher cette valeur qui serait figée dans le champ Lotducomposantdujour pour chaque fabrication. Mais pour des raisons pratiques, il se pourrait que l'encodage des lots entamés continue à se faire sur papier dans un premier temps, et ne soit encodé dans le fichier que quelques jours après, idem pour les fiches de fabrication. D'où la nécessité d'historiser les dates d'utilisation des différents lots.

    Maintenant que j'y pense, il serait même possible qu'en pratique l'encodage informatique des fabrications ait lieu alors que les fiches d'utilisation des n° de lots n'aient pas encore été encodées (personnes différentes). Ce ne serait peut-être pas idiot d'envisager une requête qui pourrait mettre à jour ce champ Lotducomposantdujour de manière régulière, et au moins avant chaque envoi de produit au client…

    @fsmrel: merci de vérifier si la v4 postée ci-dessus correspond à votre proposition de relations

    @78chris: je vais essayer d'adapter la v2 (version simpliste de la v3) selon vos suggestions. Dommage que la propriété "contenu" ne soit par définition pas disponibles pour les champs qui ne sont pas une liste modifiable. Je vais tenter une requête mise à jour, mais je n'en ai jamais eu besoin avant donc ce sera une découverte.

    Encore merci pour votre temps passé à solutionner ce que je pensais être une broutille.
    Pas d'urgence cependant, les fiches papier fonctionnent très bien, ce serait juste dommage de ne pas donner un petit coup de modernité en informatisant le système.

    Salutations

  17. #37
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Vous proposez une V4 allant dans le sens de ce que j’ai initialement proposé, conforme aux canons de la normalisation (respect de la troisième forme normale). Par contre, la présence de l’attribut Lotdujour dans l’en-tête de la table T_Fabrication_Composants mérite des explications, car elle engendre a priori la dépendance fonctionnelle {Idlot} -> {Lotdujour}, faisant que la deuxième forme normale est violée :





    D’autre part, vous proposez une V3bis pour laquelle mes remarques restent d’actualité :




    Cela dit, dans le cadre de la V4, on sait produire une table virtuelle (vue, ou requête ACCESS), permettant d’émuler la table T_Fabrication_Composants de la V3bis, par jointure des tables de la V4 : T_Fabrication_Composants, T_Lots, TLC_Composants :

    
    SELECT x.IDFabrication, y.IDComposant, y.NomLot, z.Nomcomposant
    FROM   T_Fabrication_Composants AS x, T_Lots AS y, TLC_Composants AS z
    WHERE  x.IDLot = y.IDLot
      AND  y.IDComposant = z.IDComposant ;
    
    
    =>



    Il y a aussi l’alternative qui consiste identifier les lots relativement aux composants (table T_Lots) :

    
    IDComposant    IDLot    NomLot         DateDebutUtilisation
    -----------    -----    ------         --------------------
              1        1    LA1-a          01/07/2015
              1        2    LA1-b          15/07/2015
              1        3    LA1-c          23/07/2015
              1        4    LA1-d          28/07/2015
              1        5    LA1-e          30/07/2015
              2        1    LA2-truc       09/07/2015
              2        2    LA2-muche      16/07/2015
              3        1    LA3-trois_a    07/07/2015
              3        2    LA3-xyz        21/07/2015
    
    
    Pour chaque composant, la numérotation des IDLot recommence à 1. Dans ces conditions, la clé primaire de la table T_Lots est la paire {IDComposant, IDLot}. Ainsi, tout en respectant les règles de la normalisation , on propage l’attribut IDComposant jusqu’à la table T_Fabrication_Composants :



    Mais ma question concernant l’attribut Lotdujour (que je n’ai pas fait figurer) demeure, comment fonctionne-t-il exactement ? Quelles sont les règles de gestion qui le concernent ? Ça serat bien d'illustrer par l’exemple.



    Citation Envoyé par byacces2
    les fiches papier fonctionnent très bien
    Si on les avait sous les yeux, ça serait épatant...
    (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.

  18. #38
    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,

    Citation Envoyé par fsmrel Voir le message
    Si on les avait sous les yeux, ça serait épatant...
    Difficile en pratique, mais en gros, nouvel exemple simpliste:
    imaginez une étagère de sacs de farine avec un sac entamé du lot A, utilisé depuis le 1/6/2015, et 5 sacs récemment achetés et disposés derrière, avec comme lot B.
    Aujourd'hui, la personne qui fabrique vide le sac du lot A. Demain, la personne qui fabrique entamera le 1er sac du lot B et notera ça sur une feuille papier qui ressemblera à ceci:

    Composant: Farine
    Lot Date début utilisation
    A 1/6/2015
    B 21/7/2015

    Le même genre de feuille est collée sur l'étagère du sucre, etc
    Ces données sont encodées dans la table T_Lots (quel composant, le lot et sa date de première utilisation)
    De cette manière, en combinant chaque feuille de chaque composant, il est possible de déterminer quel lot de chaque composant était entamé à la fabrication de telle date.

    En théorie, (je n'aurais pas la compétence pour faire un cours sur la traçabilité ici), il faudrait pour faire joli comme les moyens et gros industriels (mécanique, automobile, aéronautique, alimentaire, pharma, ...), faire à l'aide d'une douchette code-barres une fiche de fabrication complète avec le code-barres de chaque composant qui intègre le lot entre autres infos. Mais ne dérivons pas sur l'utilisation de codes-barres avec Access (quoi que ça marche ).

    Je veux donc obtenir un rapport (fiche de fabrication) avec les données présentées sous cette forme:

    Date fabrication: 20/7/2015
    Composant Lotdujour
    Farine Lot A
    Sucre Lot S

    Donc, sans donner trop d'importance à la structure des relations entre tables (d'un point de vue académique, votre structure est réglementaire, mais ma v3bis tient la route au niveau intégrité), il me faudrait juste une requête qui, sur base d'une fiche de fabrication telle que décrite ci-avant, va me chercher dans la table T_Lots le lot de Farine utilisé le 20/7/2015 (A dans l'exemple), et me le copie dans le champ Lotdujour, idem pour le sucre, etc

    Afin de ne pas être tenu à un encodage journalier dans Access de cette table T_Lots, une requête remplissant tous les champs Lotdujour vides chaque fois qu'on la fait tourner serait parfaite. (pour une question de lourdeur, l'idéal serait une requête qui ne travaille que sur les champs Lotdujour vides, sinon, ça risque vite de devenir lourd de vérifier et encoder chaque lot depuis la première date de fabrication). Mais c'est là qu'est l'os: je n'y connais pas grand chose en requêtes. D'où ma proposition de partir de la version v2bis toute simple que j'ai bricolée selon la proposition de 78chris, qui me donne au final le bon n° de lot pour chaque fabrication, mais au prix d'une gymnastique épuisante que j'ai décrite plus haut, et qui ne marche que quand la table T_Lots est à jour; en effet, si l'encodage de T_Lots n'est pas à jour, impossible de déterminer le n° de certains composants récemment entamés.
    Donc à partir de cette structure, comment écrire cette requête?
    Nom : v2bis.jpg
Affichages : 298
Taille : 40,3 Ko

  19. #39
    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 902
    Points
    30 902
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Partons de votre diagramme v2bis :







    Citation Envoyé par byacces2
    Ma v3bis tient la route au niveau intégrité.
    Non. Selon le diagramme que vous proposez, l’attribut Lotdujour de la table T_Fabrications ne fait pas référence à la table T_Lots, donc une mise à jour dans l’une ou l’autre table peut transformer Lotdujour en orphelin. Il y a là une redondance non contrôlée par le système.

    Cela dit, je n’ai pas encore fait l’adéquation avec les lots sur les étagères et ce que vous voulez faire avec ACCESS. Histoire de continuer à me dérouiller un peu, j’ai fait un peu de VBA avec l’idée suivante : pour chaque composant, farine, sucre etc., à partir d’une date de référence fournie par l’utilisateur, enrichir la table T_Fabrications.

    Par rapport à ce que j’avais fait au départ, J’ai réduit le formulaire au seul champ « Date de référence » et ajouté un sous-formulaire dans lequel la table T_Fabrications est rafraîchie au fil des inserts :




    Les tables que j'utilise ici sont celles de votre diagramme (j'ai harmonisé les noms des attributs)...


    Une fois que l’utilisateur à proposé une date (le 22/07/2015 dans l’exemple), il clique sur le bouton « Ajout ». Le programme agit ainsi :

    Pour chaque composant (table TLC_Composants) pour lequel on a au moins un lot (table T_Lots), on détermine le lot du jour ainsi que sa date de fabrication et on envoie tout ça dans la table T_Fabrications.

    Y a du ménage à faire dans le code ci-dessous, mais ça n’est pas bien important...

    Je ne sais pas si je me rapproche de ce que vous cherchez, vous me direz...


    Code VBA :

    
    Option Compare Database
    Option Explicit
    
    Private Sub Form_Load()
    
    DateReference.SetFocus
    
    End Sub
    
    '-------------------------------------------------------------------------
    'Ajouts dans la table T_Fabrications, pour l'ensemble des composants
    '-------------------------------------------------------------------------
    
    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, theComposant As String
    Dim theDateReference As String
    Dim theComposantNo As Integer, theDateDebutUtil As Date
    
    
    '-------------------------------------------------------------------------
    ' Contrôle de la date de référence
    '-------------------------------------------------------------------------
    
    theDateReference = Me.DateReference
    
        If Not IsDate(Me.DateReference) Then
    
        Style = vbExclamation
        Insulte = "Le champ date de référence doit contenir une date !  "
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
        DateReference.SetFocus
        Exit Sub
        
    End If
    
    '-------------------------------------------------------------------------
    ' Traitement composant par composant
    '-------------------------------------------------------------------------
    
    Set theDataBase = CurrentDb
    
    r = "SELECT IDComposant FROM TLC_Composants as x where exists (select '' from T_Lots as y where x.IDComposant = y.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
    
    Do While Not Sqlresult.EOF
    
        theComposantNo = Sqlresult.Fields("IDComposant").Value
        If Not TournerManege(theComposantNo, theDateReference) Then
            Exit Sub
        End If
        Sqlresult.MoveNext
    Loop
    
        Style = vbOK
        Insulte = "Terminus !"
        Titre = "Formulaire " & Me.Name
        Reponse = MsgBox(Insulte, Style, Titre)
    
    
    theDataBase.Close: Set theDataBase = Nothing
    
    End Sub
    
    
    '-------------------------------------------------------------------------
    'Ajouts dans la table T_Fabrications, pour l'ensemble des composants)
    '-------------------------------------------------------------------------
    
    Private Function TournerManege(ComposantNo, DateReference)
    
    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
    Dim theDateReference As String, theDateFabrication As String, MaxIdFabrication As Integer
    Dim insert As String
    Dim theKount As Integer, theComposantNo As Integer, theDateDebutUtil As Date, theNomLot As String
    
    
    On Error Resume Next
    
    TournerManege = False
    
    Set theDataBase = CurrentDb
    
    '------------------------------------------------------------------------------------------------------
    ' Insert d'une ligne dans la table T_Fabrications
    '------------------------------------------------------------------------------------------------------
    
    theComposantNo = ComposantNo
    theDateReference = DateReference
    
    'Pour le composant en cours theComposantNo, on détermine le lot correspondant à la date de référence theDateReference,
    '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('" & theDateReference & "') " _
        & " 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 Function
    End If
    
    theDateDebutUtil = Sqlresult.Fields("theDateDebutUtil").Value
    theNomLot = Sqlresult.Fields("theNomLot").Value
    
    'On vérifie si le triplet <composant, date de fabrication, lot> n'est pas déjà présent dans la table T_Fabrications
    
    r = "select count(*) as k from T_Fabrications where Datefabrication = Cdate('" & theDateDebutUtil & "') " _
        & " and Lotdujour = '" & 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 Function
    End If
    
    theKount = Sqlresult.Fields("k").Value
       
    'Si le triplet <composant, date de fabrication, lot> n'est pas déjà présent dans la table T_Fabrications, on le crée
    
    If theKount = 0 Then
     
        insert = "insert into T_Fabrications (DateFabrication, Lotdujour, IDComposant) " _
                  & " SELECT Max(x.DateDebutUtilisation), Max(x.Nomlot), " & theComposantNo _
                  & " FROM   T_Lots AS x, TLC_Composants AS y " _
                  & " WHERE  y.IDComposant = " & theComposantNo & " " _
                  & "   AND  x.IDComposant = y.IDComposant " _
                  & "   AND  x.DateDebutUtilisation <= CDate('" & theDateReference & "') " _
                  & " GROUP BY x.IDComposant ; "
                  
        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 Function
    
        End If
        
        'on rafraîchit le sous-formulaire
        
        Me.Recalc
    
    End If
    
    TournerManege = True
    
    End Function
    
    Private Sub Quitter_Click()
    
    DoCmd.Close
    
    End Sub
    
    
    (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.

  20. #40
    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,

    Une heure de libre donc je lis votre proposition avec attention.
    Difficile cependant d'objectiver tout ça sans votre base sous les yeux.
    J'y vois des idées intéressantes à utiliser, mais le concept de l'encodage s'éloigne de ce que je souhaiterais.
    Citation Envoyé par fsmrel Voir le message
    Selon le diagramme que vous proposez, l’attribut Lotdujour de la table T_Fabrications ne fait pas référence à la table T_Lots, donc une mise à jour dans l’une ou l’autre table peut transformer Lotdujour en orphelin. Il y a là une redondance non contrôlée par le système.
    Votre remarque est tout-à-fait exacte. Même si en pratique ça ne devrait pas exister, il se pourrait que quelqu'un rectifie à posteriori un encodage dans la table T_Lots (par exemple suite à une erreur de lecture du n° de lot du sac ou de la date de début d'utilisation). Dans ce cas, avec une requête basée comme je le souhaiterais sur la mise à jour des champs Lotdujour vides, les valeurs erronées de ce champ ne seraient jamais corrigées.
    Dans ce cas, le responsable qualité (terme pompeux désignant le mari, la femme ou la fille aînée encore célibataire d'une entreprise familiale ) peut avoir 6 attitudes:
    1) soit il vire le(s) responsable(s) de l'encodage incorrect, et il y a fort à parier que cette erreur n'arrivera plus souvent
    2) soit il considère que la solution Access est nulle et qu'il faut soit acheter un système SAP avec codes-barres et tout le bazar, et l'entreprise dépose le bilan le lendemain
    3) soit il revient à des fiches papier (qui comme je le répète sont fiables puisqu'elles ne concernent que les tables T_Lots et T_Fabrications), les organismes de contrôle sont satisfaits et ne trouveront probablement jamais aucune erreur pour peu qu'ils comprennent quelque chose dans l'amoncellement de papiers, les clients de l'entreprise restant par contre en attente d'un façadisme plus vendeur à leurs yeux
    4) soit vu le nombre de fabrications, de composants, etc., il considère que l'erreur n'a qu'un impact négligeable sur la traçabilité de ce composant, juge le risque négligeable et ne fait rien (si l'entreprise fabrique des smartphones bon marché le lot passera au SAV ssi le composant mal encodé est par malchance défecteux)
    5) soit il préfèrerait que l'erreur soit corrigée manuellement, en reprenant le composant dont les données sont incorrectes et en passant une heure s'il le faut à mettre à jour le champ Lotdujour incorrect
    6) soit il est perfectionniste et souhaiterait que l'Access prévoie une possibilité de requête màj sur base de l'enregistrement incorrect dans la table T_Lots. Sur base de l'IDLot, cela devrait être possible.

    La solution 5 me conviendrait dans un premier temps, la 6 étant the cherry on the cake qui pourrait venir ultérieurement.

    Citation Envoyé par fsmrel Voir le message
    Par rapport à ce que j’avais fait au départ, J’ai réduit le formulaire au seul champ « Date de référence » et ajouté un sous-formulaire dans lequel la table T_Fabrications est rafraîchie au fil des inserts
    Pour chaque composant (table TLC_Composants) pour lequel on a au moins un lot (table T_Lots), on détermine le lot du jour ainsi que sa date de fabrication et on envoie tout ça dans la table T_Fabrications.
    C'est cette « Date de référence » qui me pose problème. Je ne vois toujours pas à quoi elle correspond: à la date de fabrication? à la date à laquelle on fait tourner la requête? à la date à laquelle on veut avoir les lots de chaque composant? à la date où est on sûr d'avoir encodé tous les lots de la table T_Lots?
    Je suppose que la requête sous le bouton "Ajout" n'ajoute aucun enregistrement dans la table de fabrication… sinon ce n'est pas le but recherché. Je lis dans le code " Insert d'une ligne dans la table T_Fabrications" et c'est là où je me pose des questions.

    Pourrait-on imaginer une simple requête exécutée en cliquant dessus (les boutons viendraient après), qui effectue la mise à jour des champs Lotdujour vides de la table T_Fabrications, sur base des enregistrements déjà présents dans les tables T_Fabrications et T_Lots, sans aucune table ou formulaire ouvert.
    Comment l'écrire? J'aurais ainsi l'occasion de voir le résultat et d'avancer ensuite dans cette voie en complétant la base avec d'autres tables.

    Je ne voudrais pas à l'instar de votre signature faire plus simple que simple, c'est pourquoi en repartant de la version v2bis, je pourrais visualiser le début de l'histoire.
    Encore merci pour vos propositions.

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