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

Bases de données Delphi Discussion :

Récupération résultat requête SELECT


Sujet :

Bases de données Delphi

  1. #1
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut Récupération résultat requête SELECT
    Bonsoir à tous.

    Avant toute chose, je tiens à dire que j'ai farfouillé sur google, que j'ai fais plusieurs forums, que j'ai fais plusieurs recherches...bref, que je ne viens pas ici sans m'être renseignée avant.

    Voilà,

    Ma question est peut-être stupide...mais je ne trouves pas de résultat.

    Pour un travail scolaire, je dois faire un projet delphi-sql.
    Ce projet est un cahier de recettes virtuel.

    On peut y ajouter/modifier/supprimer des recettes de cuisine.

    J'ai bien commencé le projet..et j'arrive à une toute petite impasse.
    Petite, mais qui me bloque à plusieurs endroits.

    Je m'explique.
    L'ajout de la recette en lui-même fonctionne très bien.
    C'est ensuite, l'ajout des ingrédients qui pose un problème.

    En effet, tant que la recette n'est pas créée, je ne peux pas y ajouter les ingrédients.

    Cependant, j'ai trouvé la parade à ce soucis-là, et je récupère l'id de la dernière recette entrée pour ajouter les ingrédients.

    (à coups d'onglets

    étape 1 : ajout détail
    étape 2 : ajout ingrédients
    ....)

    J'ai un query ajout recette (qui fonctionne) :

    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
    procedure TFmCompte.AjoutRecette(Titre, Texte, Temps_prep, Difficulte_prep: string;  Prix_Prep, NbrePersonne, id_Personne, id_Origine:integer);
    begin
     Query_Ajouter_Recette.SQL.Clear;
     Query_Ajouter_Recette.SQL.Add('INSERT INTO trecettes (NomRecette, Recette, Prix,  Temps, Difficulte, NbrePersonne, idPersonne, idOrigine)');
     Query_Ajouter_Recette.SQL.Add('VALUES (:Titre, :Texte, :Prix_Prep, :Temps_prep, :Difficulte_prep, :NbrePersonne, :id_Personne, :id_Origine)');
     Query_Ajouter_Recette.ParambyName('Titre').asString:=Titre;
     Query_Ajouter_Recette.ParambyName('Texte').asString:=Texte;
     Query_Ajouter_Recette.ParambyName('Prix_Prep').asInteger:=Prix_Prep;
     Query_Ajouter_Recette.ParambyName('Temps_prep').asString:=Temps_prep;
     Query_Ajouter_Recette.ParambyName('Difficulte_prep').asString:=Difficulte_prep;
     Query_Ajouter_Recette.ParambyName('NbrePersonne').asInteger:=NbrePersonne;
     Query_Ajouter_Recette.ParambyName('id_Personne').asInteger:=id_Personne;
     Query_Ajouter_Recette.ParambyName('id_Origine').asInteger:=id_Origine;
     Query_Ajouter_Recette.ExecSQL;
    end;
    Le code récupération de l'ID (qui devrait me retourne le bon)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TFmCompte.RecupIdApresAjout();
    var
     id_Recette:integer;
    begin
     Query_Ajouter_Recette.SQL.Clear;
     Query_Ajouter_Recette.SQL.Add('SELECT max(idRecette) FROM trecettes');
     Query_Ajouter_Recette.open;
     id_Recette:=Query_Ajouter_Recette.fields[0].asInteger;
    end;
    Le code ajout des ingrédients avec l'id récupéré (qui devrait fonctionner) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TFmCompte.AjoutIngredientRecette(genreProduit: string;  idRecette, idIngredient, Nombre:integer);
    begin
     Query_Ajouter_Recette.SQL.Clear;
     Query_Ajouter_Recette.SQL.Add('INSERT INTO tcontenir (idRecette, idIngredient, Nombre, genreProduit)');
     Query_Ajouter_Recette.SQL.Add('VALUES (:idRecette, idIngredient, :Nombre, :GenreProduit)');
     Query_Ajouter_Recette.ParambyName('idRecette').asInteger:=idRecette;
     Query_Ajouter_Recette.ParambyName('idIngredient').asInteger:=idIngredient;
     Query_Ajouter_Recette.ParambyName('Nombre').asInteger:=Nombre;
     Query_Ajouter_Recette.ParambyName('genreProduit').asString:=genreProduit;
     Query_Ajouter_Recette.ExecSQL;
    end;
    Mais...dans mon code bouton...

    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
    procedure TFmCompte.BtAjouterUnIngredientClick(Sender: TObject);
    var
     GenreIngredient, Ingredient : string;
     idIngredient, NbreIngredient : integer;
    begin
      NbreIngredient :=StrToInt(EdNombreIngredient.text);
      GenreIngredient :=CbExtension.items[CbExtension.itemindex];
      Ingredient := DBLC_Ajout_Ingredient_Recette.Text;
      idIngredient:= DBLC_Ajout_Ingredient_Recette.KeyValue;
      LbListeIngredient.items.add(IntToStr(NbreIngredient) + GenreIngredient + Ingredient);
    
    
      RecupIdApresAjout();
      AjoutIngredientRecette(GenreIngredient, idRecette, idIngredient, NbreIngredient);
    end;
    Comment préciser que je veux l'id récupéré dans la seconde procédure pour la mettre dans la troisième ?

    Comme solution, pour le moment, j'écris le code de la récupération de l'ID directement dans l'ajout de l'ingrédient..
    Mais j'ai besoin de ce même code dans l'ajout de l'image de la recette et dans l'ajout du type de recette..
    Et réécrire chaque fois le même code n'est pas l'idéal pour ce genre de code..

    C'est très bête, mais je bloque !

    Merci d'avance...

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour ,

    Il suffit de changer de procédure en fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function TFmCompte.RecupIdApresAjout : Integer;
    begin
     Query_Ajouter_Recette.SQL.Clear;
     Query_Ajouter_Recette.SQL.Add('SELECT max(idRecette) FROM trecettes');
     Query_Ajouter_Recette.open;
     result:=Query_Ajouter_Recette.fields[0].asInteger;
    end;
    je ne m'attarde pas sur le reste , mais Quid lorsque c'est une modification de recette
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    La méthode de SergioMaster fonctionnera si tu n'as pas d'accès concurrentiel

    Tout dépend de la DB !
    en MySQL : LAST_INSERT_ID() dans une même transaction

    en Sybase, tu peux écrire "INSERT ... ; SELECT @@Identity;" dans un TSQLQuery, cela récupérera l'identifiant inséré !

    Chaque DB à sa propre sémantique, idem, chaque Provider fournira des informations différentes ! MyDAC par Exemple fourni une propriété InsertId sur son TMyQuery

    Avec BDE + Paradox, un simple Append\Post sans SQL, sera plus simple !

    Avec une procédure stockée, tu peux avoir une valeur de retour !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    Oh mais oui.

    Bien sûr.

    J'ai pensé au last_insert_id, mais...
    Le fait de l'utiliser en php habituellement m'a convaincue qu'il n'était pas possible de le faire en delphi.

    Mais pour l'utiliser, il faut bien déclarer de cette manière ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT last_insert_id( )
    FROM trecettes
    Car, j'essaye cela et ça me renvoie une liste de "0"

    Et merci pour la solution de la Fonction.
    J'avais totalement oublié que l'utilisation des fonctions renvoyaient des valeurs.

    MERCI MERCI MERCI ^^

    L'ajout fonctionne de cette manière

  5. #5
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    J'ai une autre question..

    (Je penses pas que recréer un sujet pour elle soit très utile. Mais s'il le faut, j'en referai un.)


    Voilà.

    A l'arrivée sur l'application, il est possible, en tant que "visiteur" de pouvoir voir toutes les recettes triées

    1. par occasion (petit-déjeuner, viandes, soupes, ...)
    2. par ingrédient (sel, farine, chocolat, ...)
    3. par origine (france, suisse, ...)

    Ces trois propositions mènent à une seule et même page (TFmRecetteTriee) qui est modifiée selon le premier choix.

    Si, par exemple, je décide de trier mes recettes par occasion, sur la page du tri, j'ai un DBLookupComboBox dans lequel, il y a tous les types de recettes (libellé de chaque occasion).

    Ensuite, dés que la valeur de ce DBLC (j'abrège) change, un DBLookupListBox juste en dessous est censé m'afficher toutes les recettes (id et nom) appartenant à ce type.

    J'ai fais une requête qui trie les recettes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function TFmRecetteTriee.Tripartype : string;
    begin
     Query_Tri_Type.SQL.Clear;
     Query_Tri_Type.SQL.Add('SELECT trecettes.idRecette, trecettes.NomRecette');
     Query_Tri_Type.SQL.Add('FROM trecettes, tappartenir, ttypes');
     Query_Tri_Type.SQL.Add('WHERE trecettes.idRecette=tappartenir.idRecette');
     Query_Tri_Type.SQL.Add('AND tappartenir.idType=ttypes.idType');
     Query_Tri_Type.SQL.Add('AND ttypes.idType=:idType');
     Query_Tri_Type.open;
    end;

    J'ai ma procédure qui sélectionne l' id du type dans le ComboBox

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    procedure TFmRecetteTrier.DBLC_Tri_TypeClick(Sender: TObject);
    var
     idType: integer;
    begin
      idType:=DBLC_Tri_Type.keyValue;
    end;

    Cependant, je ne sais pas comment dire au listbox que les valeurs qu'il doit m'afficher correspondent à la valeur du combobox.

    J'ai vu sur internet qu'il était possible d'affecter un query au DBLL mais..j'ai pas compris..

    J'ai fouillé dans la fac sans vraiment trouver de réponses précises à ma question..

    Si vous savez éclairer ma lanterne..
    Merci d'avance !

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    2 Solutions :
    Soit mettre un paramètre a la fonction Tripartype qui ne retourne rien dans ton code , donc pourrait être une procédure

    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
    procedure TFmRecetteTriee.Tripartype(id : Integer);
     Query_Tri_Type.SQL.Clear;
     Query_Tri_Type.SQL.Add('SELECT trecettes.idRecette, trecettes.NomRecette');
     Query_Tri_Type.SQL.Add('FROM trecettes, tappartenir, ttypes');
     Query_Tri_Type.SQL.Add('WHERE trecettes.idRecette=tappartenir.idRecette');
     Query_Tri_Type.SQL.Add('AND tappartenir.idType=ttypes.idType');
     Query_Tri_Type.SQL.Add('AND ttypes.idType=:idType');
    Query_Tri_Type.paramByName('idType').asInteger:=id;  // en plus il manquait l'affectation du paramètre
     Query_Tri_Type.open;
    end;
     
    procedure TFmRecetteTrier.DBLC_Tri_TypeClick(Sender: TObject);
    //var  idType: integer;  inutile
    begin
      Tripartype(DBLC_Tri_Type.keyValue);
    end;
    Soit mettre la query directement dans DBLC_Tri_TypeClick

    nota : j'aurais plutôt dit sélection (ou filtre) que tri , une sélection c'est avec une clause WHERE un tri avec une clause ORDER BY
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  7. #7
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    Merci d'avoir corrigé mes erreurs.. (à cette heure-ci, j'ai un peu de mal ^^)

    J'ai donc..

    1. Ma procédure query qui sélectionne les recettes d'après l'occasion choisie (je préfère séparer les requêtes du reste du code, plus propre pour le reste)
    2. Ma procédure qui s'active quand on clique sur le ComboBox
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //--------------------------1--------------------------
    
    procedure TFmRecetteTriee.Tripartype(id : Integer);
    begin
     Query_Tri_Type.SQL.Clear;
     Query_Tri_Type.SQL.Add('SELECT trecettes.idRecette, trecettes.NomRecette');
     Query_Tri_Type.SQL.Add('FROM trecettes, tappartenir, ttypes');
     Query_Tri_Type.SQL.Add('WHERE trecettes.idRecette=tappartenir.idRecette');
     Query_Tri_Type.SQL.Add('AND tappartenir.idType=ttypes.idType');
     Query_Tri_Type.SQL.Add('AND ttypes.idType=:idType');
     Query_Tri_Type.paramByName('idType').asInteger:=id;
     Query_Tri_Type.open;
    end;
    
    
    //--------------------------2-------------------------- 
    
    procedure TFmRecetteTrier.DBLC_Tri_TypeClick(Sender: TObject);
    begin
       Tripartype(DBLC_Tri_Type.keyValue);
       DBLbxTriOccasions ....
    end;
    Mais ma question reste là..

    Comment lier le ListBox à ça ?

    Sur Internet, il y a pas énormément d'explication détaillée de chaque propriété.
    J'ai tenté de les utiliser au hasard (d'après mes connaissances)...sans grand succès.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Je n'ai pas lu la discussion dans le détail mais on parle d'un problème similaire ici. Chercher "master detail" sur le net...

  9. #9
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    Merci beaucoup GoustiFruit,

    je n'avais pas vu cette discussion en cours..

    Mais..

    Entre les disputes...
    J'ai réussi à comprendre que...

    Citation Envoyé par MickSou Voir le message
    Essaye un peu d'utiliser les composants DBLookupCombobox et DBlookUplistBox.
    Reliés sur des composants d'accès aux bases de données correctement configurés en Maitre6détail tu ne devrais pas avoir à gérer toutes ces listes. Le lien entre les deux devrait se faire automatiquement.
    Et..

    Citation Envoyé par ShaiLeTroll Voir le message

    Remplace ton TListBox par un TDBListBox connecté sur un TTable contenant l'ensemble de listeproduit

    le SELECT dans Query2 doit fournir id et categuorie de la table categuories

    Pour en revenir au Maître-Détail, en utilisant deux TDBListBox, c'est une solution totalement différente, celle à laquelle pensait MickSou qui est impossible avec un TCombobox.
    la première TDBListBox est connectée sur la table Categories, la seconde sur Produits
    Ensuite, en mettant Categories comme MasterSource de Produits, ID comme MasterField, enfin dans IndexFieldNames, tu mets idcateguorie

    A lire impérativement : Comment faire de la table la partie détail d'un autre ensemble de données
    J'ai pas tout compris, là, parce qu'il y a beaucoup de choses qui se chevauchent..

    Mais je vais étudier les propriétés Maître-Détail.

  10. #10
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    J'ai trouvé ça...

    Qui illustre totalement ce que j'aurais voulu faire..

    Mais je ne parviens pas à comprendre totalement la solution.

    J'ai

    Un DBLookupComboBox DBLC_Tri_Type qui affiche les noms de chaque occasions

    Les valeurs du DBLC sont :

    DataField -> idRecette
    DataSource -> DS_Appartenir
    ListSource -> DS_Type
    ListField -> NomType
    KeyField -> idType


    ***************************


    Un query Query_Tri_Type qui sélectionne les recettes selon le choix du DBLC

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT trecettes.idRecette, trecettes.NomRecette
    FROM trecettes, tappartenir, ttypes
    WHERE trecettes.idRecette=tappartenir.idRecette
    AND tappartenir.idType=ttypes.idType
    AND ttypes.idType=:idType

    ***************************

    Un DBLookupListBox DBLbxTriOccasion qui m'affiche absolument toutes les recettes
    (mais qui n'est censé m'afficher que celles dont l'occasion est celle choisie par ComboBox)

    Les valeurs du DBLX sont :

    DataField -> idRecette
    DataSource -> DS_Appartenir
    ListSource -> DS_Recette
    ListField -> NomRecette
    KeyField -> idRecette



    Pour tout ce petit blabla, j'ai :

    Trois DataSource DS_Appartenir, DS_Recette et DS_Type
    Trois TTable TAppartenir, TRecettes et TTypes



    Je vois vraiment pas comment faire.
    J'essaye de comprendre les propriétés Maitre-Detail, mais....

    Dans le lien que j'ai trouvé, la solution est que je ne dois pas renseigner datasource ni le datafield du ComboBox


    Mais en fait, mon soucis, là, c'est juste que je ne comprend pas du tout comment lier le Query au ListBox..

    Je vois qu'il y a eu plusieurs fois cette question posée sur des forums (je le vois en ayant de meilleurs critères de recherches), mais désolée, je n'arrive pas à les comprendre...

  11. #11
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    AH !

    J'ai trouvé comment poser un Query dans le DataSource, je progresse.

  12. #12
    Membre chevronné Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 552
    Points : 1 780
    Points
    1 780
    Par défaut
    Un lien vers un bon exemple sur les relation Maître/Détail

  13. #13
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    hum...

    CA MARCHE


    Et j'ai trouvé toute seule comme une grande
    Mais non, j'aurais pas réussi sans vos conseils

    J'ai cependant, pas utilisé les propriétés "Maitre-détail" telles qu'elles.

    Bon, j'explique ce que j'ai fais.
    Si vous avez de meilleures idées, je suis preneuse.


    Voilà, donc...

    1. Mon DBLookupComboBox qui affiche les occasions
    2. Mon Query qui sélectionne les recettes d'après l'id de l'occasion du DBLC
    3. Mon DataSource lié au Query
    4. Mon DBLookupListBox lié au DataSource
    5. Ma procédure qui modifie les valeurs du DBLookupListBox

    En code, ça donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    procedure TFmRecetteTriee.Tripartype(id : Integer);
    begin
     Query_Tri_Type.SQL.Clear;
     Query_Tri_Type.SQL.Add('SELECT trecettes.idRecette, trecettes.NomRecette');
     Query_Tri_Type.SQL.Add('FROM trecettes, tappartenir, ttypes');
     Query_Tri_Type.SQL.Add('WHERE trecettes.idRecette=tappartenir.idRecette');
     Query_Tri_Type.SQL.Add('AND tappartenir.idType=ttypes.idType');
     Query_Tri_Type.SQL.Add('AND ttypes.idType=:idType');
     Query_Tri_Type.paramByName('idType').asInteger:=id;
     Query_Tri_Type.open;
    end;
     
    procedure TFmRecetteTriee.DBLC_Tri_TypeClick(Sender: TObject);
    begin
       DS_Tri_Type.DataSet:=Query_Tri_Type;
       Tripartype(DBLC_Tri_Type.keyValue);
       DBLbxTrieeOccasions.ListSource:=DS_Tri_Type;
       DBLbxTrieeOccasions.ListField:='idRecette; NomRecette';
       DBLbxTrieeOccasions.KeyField:='idRecette';
    end;
    En image, voici le résultat : Affichage de l'id et du nom de la recette.


  14. #14
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    J'ai encore une petite question (J'arrive gentiment au bout du programme, là..)

    Excusez, je sais que j'abuse..

    Il y a une petite chose qui me bloque encore, et qui me bloque depuis que j'ai commencé cette application.

    Je m'explique..

    Maintenant que TOUS mes tris fonctionnent, que je peux ajouter une recette, un ingrédient, une image, etc.., je souhaiterais que, quand je clique sur une recette (dans le listBox, par exemple), je sois redirigée sur une nouvelle page qui m'affiche le détail de la recette.

    Dans le détail, j'entend : Titre de la recette, Nom de la recette, image, etc...

    En fait, je voudrais conserver la valeur d'une variable d'une page à l'autre.

    Et, ça, je sais le faire en PHP mais pas en delphi..(ou alors, je sais plus --')



    Ici, ça dit de jouer sur les variables globales..

    Mais est-ce que je peux jouer sur la valeur de cette variable dans ma procédure qui part sur l'autre page ?

    (Je pose la question ici, si jamais quelqu'un sait me répondre, mais je continue à chercher de mon côté..)

  15. #15
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    Bon, là, je vais franchement m'excuser ^^

    J'ai la mauvaise habitude de crier au secours avant d'avoir entièrement cherché une solution.

    Solution que j'ai trouvé. (oui, bon, c'est un peu de la triche, mais bon !)

    1. J'ai récupéré l'id de la recette dans le ListBox.
    2. J'ai envoyé cet id dans un lb invisible sur la page détail
    3. J'affiche le détail de la recette d'après la valeur dans le lb

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Oulà j'ai l'impression que tu aimes les trucs tarabiscotés !
    Tu pourrais faire quelque chose comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TFmRecetteTriee.btnDetailsRecetteClick(Sender: TObject);
    var
      ficheDetailsRecette: TfmDetailsRecettes;
    begin
      ficheDetailsRecette := TfmDetailsRecettes.Create(Self);
      with ficheDetailsRecette do begin
        // A adapter à la façon dont tu stockes l'ID dans les éléments de ta listbox:
        IDRecette := Integer(Listbox1.Items.Objects[Listbox1.ItemIndex]);
        ShowModal;
        Release;
      end;
    end;
    Dans la fiche détails, tu déclares une variable IDRecette (Integer), et dans le OnShow tu utilises cette variable...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TfmDetailsRecettes.FormShow(Sender: TObject);
    begin
      // AfficherDetails(IDRecette);
    end;
    En passant, pourrais-tu détailler un peu la structure de ta base de données, parce que tes requêtes me semblent bien touffues aussi...

  17. #17
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    Je me complique tout le temps la vie en croyant la simplifier..

    Mais, dans ta procédure, tu utilises "with...do begin" et release.
    Ce que moi, je n'utilises pas et ne sais pas utiliser.

    Et pour ma base de données, je l'explique.

    J'ai (je met pas toutes les tables, uniquement les principales)...

    recettes ==> idRecette, titre, recette, l'idPersonne, l'idorigine
    personnes ==> toutes les données de la personne
    origine ==> idorigine, nomOrigine
    ingredients ==> idIngredient, nomIngredient
    contenir ==> idRecette, idIngredient, Nombre (quantité de l'ingrédient), GenreProduit (litres, grammes..)
    types (occasions) ==> idType, NomType
    appartenir ==> idType, idRecette
    J'ai fais les tables contenir et appartenir car une recette peut appartenir à plusieurs types d'occasions (Fêtes, viandes, etc.) et peut contenir, logiquement, plusieurs ingrédients.


    Hier soir, ou plutôt, trèèès tôt, ce matin, je me suis rendue compte que j'avais un soucis.

    Quand je trie mes recettes, elles s'affichent parfaitement bien dans mon DBLookupListBox.
    Au double clic sur une occurrence de ce DBLX, je suis censée arriver sur la page détail.

    Je parviens à récupérer l'id en l'envoyant depuis la page tri à la page détail, j'ai mon query qui me sélectionne tout ce que je veux afficher, c'est à dire, le titre, la recette, les commentaires et le détail des ingrédients

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TFmDetailRecette.selection_detail_Recette(id:integer);
    begin
     Query_Affichage_Recette.SQL.Clear;
     Query_Affichage_Recette.SQL.Add('SELECT trecettes.NomRecette, trecettes.Recette, tcommentaires.Commentaire, tcontenir.Nombre, tcontenir.genreproduit, tingredients.NomIngredient');
     Query_Affichage_Recette.SQL.Add('FROM trecettes, tcontenir, tingredients, tcommentaires');
     Query_Affichage_Recette.SQL.Add('WHERE tcontenir.idRecette=trecettes.idRecette');
     Query_Affichage_Recette.SQL.Add('AND trecettes.idRecette=tcommentaires.idRecette');
     Query_Affichage_Recette.SQL.Add('AND tingredient.idIngredient=tcontenir.idIngredient');
     Query_Affichage_Recette.SQL.Add('AND trecettes.idRecette=:idRecette');
     Query_Affichage_Recette.paramByName('idRecette').asInteger:=id;
     Query_Affichage_Recette.open;
    end;
    Aussi, vu que c'est lorsqu'on arrive sur la form que le détail est sensé changer, j'ai voulu écrire mon code sur le create.
    Mais mon problème est que, vu que l'id de la recette nécessaire à l'affichage du détail n'a pas encore été récupéré lors de la création de la page détail, il y a un couac..

    Et en attendant de trouver mieux, j'ai fais les modification des données d'après un DBcomboBox simple où j'ai stocké les idRecette, comme j'ai fais pour les tris.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TFmDetailRecette.Db_Id_RecetteChange(Sender: TObject);
    begin
       selection_detail_Recette(StrToInt(Db_Id_Recette.DataField));
       DS_Affichage_Detail.DataSet:=Query_Affichage_Recette;
     
       DBMemDetailRecette.DataSource:=DS_Affichage_Detail; //Affiche le texte de la recette
       DBMemDetailRecette.DataField:='Recette';
     
       DBlbIngredients.DataSource:=DS_Affichage_Detail; //Affiche le détail des ingrédients
       DBlbIngredients.DataField:='Nombre;genreproduit;NomIngredient';
    end;

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Citation Envoyé par MélanieS Voir le message
    Aussi, vu que c'est lorsqu'on arrive sur la form que le détail est sensé changer, j'ai voulu écrire mon code sur le create.
    Mais mon problème est que, vu que l'id de la recette nécessaire à l'affichage du détail n'a pas encore été récupéré lors de la création de la page détail, il y a un couac..
    C'est pour ça que je t'ai proposé le code que je t'ai proposé ;-)
    Le with...do begin évite de saisir "ficheDetailsRecette" à chaque fois, c'est équivalent à:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TFmRecetteTriee.btnDetailsRecetteClick(Sender: TObject);
    var
      ficheDetailsRecette: TfmDetailsRecettes;
    begin
      ficheDetailsRecette := TfmDetailsRecettes.Create(Self);
      // A adapter à la façon dont tu stockes l'ID dans les éléments de ta listbox:
      ficheDetailsRecette.IDRecette := Integer(Listbox1.Items.Objects[Listbox1.ItemIndex]);
      ficheDetailsRecette.ShowModal;
      ficheDetailsRecette.Release;
    end;
    Dans ce code la fiche est d'abord créée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficheDetailsRecette := TfmDetailsRecettes.Create(Self);
    Puis tu lui passes l'ID de la recette:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficheDetailsRecette.IDRecette := Integer(Listbox1.Items.Objects[Listbox1.ItemIndex]);
    Et tu peux coder le chargement de la recette dans le OnShow qui sera "déclenché" par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficheDetailsRecette.ShowModal;
    Une fois la fiche fermée, la dernière ligne "libère" les ressources utilisées:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficheDetailsRecette.Release;
    Quant à tes requêtes, elles me semblent bizarres... Je ne suis pas expert mais est-ce que tu ne devrais pas faire plusieurs requêtes au lieu de tout combiner en une seule, étant donné que chaque recette peut avoir plusieurs commentaires et plusieurs ingrédients ?
    -> Une première requête pour récupérer les infos générales sur la recette (nom, auteur)
    -> Une deuxième requête pour récupérer la liste des ingrédients
    -> Une autre requête pour récupérer la liste des commentaires
    -> ...
    ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    procedure TFmDetailRecette.selection_detail_Recette(id:integer);
    var
     sNomRecette: string;
    begin
      with Query_Affichage_Recette do begin
        SQL.Text := 'SELECT NomRecette FROM trecettes WHERE idRecette = :p0';
        Params[0].AsInteger := IDRecette;
        Open;
        sNomRecette := Fields[0].AsString;
        // Faire quelque chose avec sNomRecette
     
        SQL.Clear;
        SQL.Add('SELECT c.Nombre, c.genreproduit, i.NomIngredient');
        SQL.Add('FROM tcontenir AS c, tingredients AS i');
        SQL.Add('WHERE c.idRecette = :p0 AND c.idIngredient = i.idIngredient');
        Params[0].AsInteger := IDRecette;
        Open;
        while not Eof do begin
          // Récupérer chaque ingrédient/genre/nombre et en faire quelque chose
        end;
     
        // Etc.
      end;
    end;
    Et puis ça doit être encore mieux à coups de "LEFT JOIN" il me semble... !?

  19. #19
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    ah, je vois.

    Mais juste une question.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ficheDetailsRecette.IDRecette := Integer(Listbox1.Items.Objects[Listbox1.ItemIndex]);
    IDRecette correspond bien à une variable globale de la Fiche détail ?
    Parce que, même déclaré, "Identificateur non déclaré : 'IDRecette'"

    Quant aux recettes, tu as raisons.

    Il y a, en effet plusieurs ingrédients et plusieurs commentaires par recettes.

  20. #20
    Membre à l'essai
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 59
    Points : 19
    Points
    19
    Par défaut
    Ah, pour l'histoire de la variable, c'et réglé.
    J'avais simplement oublié que c'est en public, qu'il fallait la déclarer

    Je suis en train de voir si je parviens à afficher toutes les données en plusieurs query

Discussions similaires

  1. [Toutes versions] Affichage résultat requête Select depuis code VB
    Par gronimo21000 dans le forum VBA Access
    Réponses: 2
    Dernier message: 07/09/2011, 15h26
  2. [AC-2003] Récupération résultats requête SQL dans VBA
    Par rberniga dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 19/08/2009, 11h28
  3. Afficher résultat requête Select
    Par rasta girl dans le forum VBA Access
    Réponses: 1
    Dernier message: 16/06/2008, 14h01
  4. récupération des requêtes select dans un log
    Par aemag dans le forum Oracle
    Réponses: 1
    Dernier message: 01/12/2006, 16h16
  5. récupération résultat requête
    Par philippe281281 dans le forum Requêtes
    Réponses: 10
    Dernier message: 05/07/2006, 10h46

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