Execution de deux requêtes SELECT à la suite
j'utilise ACCESS 2010 et voudrais automatiser l'exécution de deux requêtes l'une à la suite de l'autre ou alors en imbriquant la seconde dans la première.
Ma première requête est:
SELECT [Architectures-besoins].Architecture, [Materiel pour architecture].ID_materiel, [Materiel pour architecture].Pondération, Materiel.Materiel FROM Materiel INNER JOIN ([Architectures-besoins] INNER JOIN [Materiel pour architecture] ON [Architectures-besoins].Architecture = [Materiel pour architecture].Architecture) ON Materiel.ID = [Materiel pour architecture].ID_materiel WHERE ((([Architectures-besoins].Besoin)="Automatic filling of the application"));
Ma seconde requête est une requête de tri sur le champ "pondération":
SELECT [Pour un besoin donné quel matériel est nécessaire].Pondération, [Pour un besoin donné quel matériel est nécessaire].Architecture, [Pour un besoin donné quel matériel est nécessaire].ID_materiel, [Pour un besoin donné quel matériel est nécessaire].Materiel
FROM [Pour un besoin donné quel matériel est nécessaire]
WHERE ((([Pour un besoin donné quel matériel est nécessaire].Pondération)=DMax("Pondération","Pour un besoin donné quel matériel est nécessaire")));
J'ai essayé de faire une macro:
Public Sub DoSQL()
Dim qry1 As String
Dim qry2 As String
qry1 = "SELECT [Architectures-besoins].Architecture, [Materiel pour architecture].ID_materiel, [Materiel pour architecture].Pondération, Materiel.Materiel"
FROM Materiel INNER JOIN ([Architectures-besoins] INNER JOIN [Materiel pour architecture] ON [Architectures-besoins].Architecture = [Materiel pour architecture].Architecture) ON Materiel.ID = [Materiel pour architecture].ID_materiel
WHERE ((([Architectures-besoins].Besoin)="Automatic filling of the application"))"
qry2 = "SELECT [Pour un besoin donné quel matériel est nécessaire].Pondération, [Pour un besoin donné quel matériel est nécessaire].Architecture, [Pour un besoin donné quel matériel est nécessaire].ID_materiel, [Pour un besoin donné quel matériel est nécessaire].Materiel"
FROM [Pour un besoin donné quel matériel est nécessaire]
WHERE ((([Pour un besoin donné quel matériel est nécessaire].Pondération)=DMax("Pondération","Pour un besoin donné quel matériel est nécessaire")))"
DoComd.RunSQL qry1
DoComd.RunSQL qry2
End Sub
Malheureusement cela ne fonctionne pas car à priori on ne peut pas exécuter une requête de sélection avec cette commande.
Si quelqu'un avait une solution simple à mettre en place ou des pistes de réflexion à me donner, je suis preneur.
merci d'avance :)
26 réponses
Le problème porte sur l'automatisation de l'exécution de deux requêtes SELECT dans Access 2010, soit en les enchaînant, soit en les imbriquant, afin d'obtenir l'association entre architecture et matériel pondéré. Des propositions suggèrent d'utiliser une approche en deux requêtes successives, d'intégrer des paramètres dans une requête unique ou d'exploiter des fonctions comme Last ou MaxDom selon le contexte. En pratique, certaines propositions préconisent une requête paramétrée avec des sous-requêtes ou des agrégations, tandis que d'autres recommandent le mode graphique et des liaisons pour éviter le SQL complexe. Une avancée utile consiste à passer des paramètres comme Besoin1 et Besoin2 dans une requête unique, puis à récupérer Last ou Pondération selon le contexte.
-
Salut,
j'ai fais pas mal d'essais, voilà ce que ça donne si jamais ça peut servir à d'autres:
SELECT Max(Materiel_Architecture.Pondération) AS MaxPondération FROM ([Architectures-besoins] AS ab1 LEFT JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) LEFT JOIN ([Architectures-besoins] AS ab3 LEFT JOIN Materiel_Architecture ON ab3.Architecture = Materiel_Architecture.Architecture) ON ab2.Architecture = ab3.Architecture GROUP BY ab1.Besoin, ab2.Besoin, ab3.Besoin HAVING (((ab1.Besoin) Like "*" & [Besoin1] & "*") AND ((ab2.Besoin) Like "*" & [Besoin2] & "*") AND ((ab3.Besoin) Like "*" & [Besoin3] & "*"));
Encore merci pour ton aide ;) -
Re...
Regarde comment procéder avec 2 et tu rajoutes un 3ème. Après tu testes et tu corriges jusqu'à ce que ça passe.
Bonne suite -
Nickel, ta réponse sur l'autre poste a été très utile :)
J'ai éssayé de modifier cette requête:SELECT Max(Materiel_Architecture.Pondération) AS MaxPondération FROM ([Architectures-besoins] AS ab1 LEFT JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) LEFT JOIN Materiel_Architecture ON ab2.Architecture = Materiel_Architecture.Architecture GROUP BY ab1.Besoin, ab2.Besoin HAVING (((ab1.Besoin) Like "*" & [Besoin1] & "*") AND ((ab2.Besoin) Like "*" & [Besoin2] & "*"))
afin d'avoir 3 "besoins" mais sans succès. Sais-tu comment faire cela facilement? -
Re...
Tu ne peux pas mettre une jointure un-à-un derrière une jointure un-à-plusieurs; il faut donc que tu mettes ta jointure en un à plusieurs. Voir ma réponse précédente à SnowManXDXD : http://www.commentcamarche.net/forum/affich-31955809-fusionner-des-tableaux (tout en bas de la page)
Bonne suite -
-
-
Bonjour,
Je ne sais pass comment tu t'y es pris. Mon Access me répond que la requête ne supporte pas la liaison "Join".
Il ne sert à rien d'essayer coute que coute à écrire les requêtes directement en SQL, sans prétendre être un modèle je ne le fait jamais, il faut utiliser le mode graphique, c'est bien assez difficile comme ça.
Pour ta requête, il suffit de l'ouvrir en mode graphique, d'ajouter la table que tu veux et d'établir la liaison, et la sélection du champ voulu évidemment.
Pour le reste je ne comprends pas.
Bonne suite. -
Salut,
merci pour ton aide, cela fonctionne parfaitement!
J'ai juste voulu amélioré la requête afin qu'au lieu d'afficher ID_materiel, elle affiche directement le nom du materiel, ce matériel se trouve dans un autre table (table nommée "matériel", champ "matériel").
J'ai pour cela ajouté la table en question avec le mode graphique de création de requête et ai sélectionné le champ matériel. Malheureusement ACCESS me dit que la table externe n'est pas supporté, le message d'erreur exact est:
"Instruction SQL non executée en raison de jointure externe ambigüe. Pour forcer l'ordre d'exécution d'une des jointures en premier,créez une requête distincte qui exécute la première jointure , puis insérez cette requête dans votre requête SQL."
Voilà ce que ça donne en SQL:
SELECT DISTINCT MaxDoubleBesoin.MaxPondération, Materiel_Architecture.Architecture, Materiel_Architecture.ID_materiel, Materiel.Materiel FROM Materiel INNER JOIN (MaxDoubleBesoin LEFT JOIN Materiel_Architecture ON MaxDoubleBesoin.MaxPondération = Materiel_Architecture.Pondération) ON Materiel.ID = Materiel_Architecture.ID_materiel;
Une idée de comment intégrer cela facilement?
Encire merci ;) -
J'ai pu faire un truc qui marche, en espérant que ça corresponde à ce que tu veux faire. Cela dit, tu pourras apporter des corrections éventuellement.
Il suffit de copier/coller les expressions telles quelles, sans rien corriger dans un 1er temps. En principe il ne devrait pas y avoir de problème.
Pour les faire fonctionner, il suffit de lancer directement la 2ème, les boites de dialogue successives vont apparaître, là aussi il suffira d'entrer une seule partie de l'appellation demandée, par exemple "Acars" ou "Tablette", j'ai fait en sorte qu'il ne soit nécessaire de rentrer l'appellation en entier. Ce n'est pas du tout judicieux d'avoir fait une liaison et une sélection sur des noms aussi longs, il faut savoir faire simple, les N° sont le plus pratique dans ce cas.
Les 2 requêtes sont :
1) - SELECT Max(Materiel_Architecture.Pondération) AS MaxPondération
FROM ([Architectures-besoins] AS ab1 LEFT JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) LEFT JOIN Materiel_Architecture ON ab2.Architecture = Materiel_Architecture.Architecture
GROUP BY ab1.Besoin, ab2.Besoin
HAVING (((ab1.Besoin) Like "*" & [Besoin1] & "*") AND ((ab2.Besoin) Like "*" & [Besoin2] & "*"))
2) - SELECT DISTINCT MaxDoubleBesoin.MaxPondération, Materiel_Architecture.Architecture
FROM MaxDoubleBesoin LEFT JOIN Materiel_Architecture ON MaxDoubleBesoin.MaxPondération = Materiel_Architecture.Pondération
En les ouvrant en mode graphique, tu peux voir comment je m'y suis pris. La 1ère sélectionne la pondération, la 2ème enchaîne sur l'architecture.
Bon courage -
J'ai bien reçu la base, mais du coup je ne comprends pas ce que tu essaies de faire.
Je ne comprends pas le lien entre AB1 et AB2. A quoi ça correspond? Dans quel but?
J'attends réponse.-
La requête DoubleBesoin permet d'afficher les architectures qui satisfont les deux besoins (à partir de la table Architectures-besoins). AB1 et AB2 ne sont que des alias de la table Architectures-besoins. j'ai réussis à faire fonctionner la requête comme cela, mais fondamentalement si il est possible de faire autrement ça me convient parfaitement.
La requête TriPondération permet de ne sélectionner que les architectures ayant la valeur de pondération maximale parmi celles qui sont retournées par la première requête.
Et donc l'idéal serait de n'avoir que le résultat de la requête TriPondération qui s'affiche après avoir rentré les deux besoins (Besoin 1 et Besoin 2 )
j'espère avoir été assez explicite.
-
-
Je n'ai pas les tables !!!!
Envoie ta base (un extrait) via Cjoint.com, ça ira beaucoup plus vite.-
Voici le lien pour obtenir le fichier ACCESS:
https://www.dropbox.com/sh/dc5q0v5iw024jwr/AACaqlF0w1SC4DvjpBr1WC37a?dl=0
Je n'ai laissé que les tables utiles à l'exécution des deux requêtes afin de faciliter la compréhension. -
-
Bonjour,
Cjoint.com n'acceptant pas les fichier trop volumineux, je l'ai uploadé chez free. Normalement aucune connexion n'est requise: http://dl.free.fr/getfile.pl?file=/ySmFtvVG
merci pour ton aide :) -
Désolé, je n'arrive à l'ouvrir.
Peux-tu faire une sélection avec juste les 2 tables et les 2 requêtes.
Il suffit de :
1) ouvrir une base vierge
2) Données Externes / Importer
3) sélectionner la base originelle / sélectionner les éléments à importer
4) Emballer
Une autre solution serait de faire un double de la base par Copier/Coller, supprimer ce qui est inutile, compacter et envoyer. -
Merci pour l'astuce, voici la BDD: https://www.cjoint.com/?3Ehmf5kCX93
-
-
Je te confirme que ma requête initiale fonctionne correctement lorsque je l'exécute:
PARAMETERS Besoin1 Text ( 255 ), Besoin2 Text ( 255 ); SELECT Materiel.Materiel, ab1.Architecture, Materiel_Architecture.Pondération FROM ([Architectures-besoins] AS ab1 INNER JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) INNER JOIN (Materiel_Architecture INNER JOIN Materiel ON Materiel_Architecture.ID_materiel = Materiel.ID) ON ab1.Architecture = Materiel_Architecture.Architecture WHERE (((ab1.Besoin)=[Besoin1]) AND ((ab2.Besoin)=[Besoin2]));
Lorsque j'éssai ta solution avec des guillemets, elle ne fonctionne plus (elle ne renvoie aucune valeur):
PARAMETERS Besoin1 Text ( 255 ), Besoin2 Text ( 255 ); SELECT Materiel.Materiel, ab1.Architecture, Materiel_Architecture.Pondération FROM ([Architectures-besoins] AS ab1 INNER JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) INNER JOIN (Materiel_Architecture INNER JOIN Materiel ON Materiel_Architecture.ID_materiel = Materiel.ID) ON ab1.Architecture = Materiel_Architecture.Architecture WHERE (((ab1.Besoin)= " [Besoin1] " ) AND ((ab2.Besoin)= " [Besoin2] " ));
Je ne suis pas persuadé que l'erreur se trouve dans cette requête puisqu'elle s'exécute correctement. Le problème dois provenir de la seconde requête qui effectue le tri sur le champ "Pondération" :/ -
Re-...
Il manque des guillemets ( "ACARS Communication")
mais comme il y a très longtemps que je fais autrement, avec une boite de dialogue personnalisée, je ne sais plus éxaactement où il faut les mettre.
Essaye :
WHERE (((ab1.Besoin)= " [Besoin1] " ) AND ((ab2.Besoin)= " [Besoin2] " )) -
Bonjour,
et bien je rentre les variables sous forme de texte dans les boites de dialogues utilisés par les requêtes paramétrés.

Le paramètre est sous forme de texte et c'est la première requête (DoubleBesoin) qui est paramétrée. Malheuresement lorsque j'execute la seconde requête (TriPondération) j'ai un message d'erreur:

Je pense que cela répond à tes questions? -
Bonjour,
"je devrais pouvoir entrer les deux paramètre dans une boite de dialogue"
Oui !
Et laquelle de boite de dialogue?
Et comment sont écrites tes variables quand tu les saisis?
Sous quelles formes les rentres-tu?
C'est ça les questions qu'il faut te poser. -
Re-...
Je ne crois vraiment pas que ne pas arriver à faire une manip de manière simple soit amélioré en tentant de la faire de manière complexe.
MaxDom() ne se fait pas en mode graphique parce que c'est une expression et non pas une requête.
La syntaxe (de toute la série du même type) est très particulière : MaxDom("VariableArechercher";"Domaine Table ou Requête","VariableDeSélection = ValeurARechercher") -
Attention en écriture française on met des " ; ",
alors que en anglais (SQL) on met des " , " simples
Voir le didacticiel Icône "?" Références du développeur.-
Hello, j'ai l'impression d'être tout proche de la solution mais j'ai encore un message d'erreur qui m'embête :/
Si je récapitule, je veux pouvoir faire une sélection sur deux critères (entrés par l'utilisateur) puis un tri sur le champ "pondération". Je n'ai malheureusement pas réussi à le faire une seule et unique requête donc je procède comme cela:
Une première requête qui permet de faire la sélection sur deux critères:SELECT Materiel.Materiel, ab1.Architecture, Materiel_Architecture.Pondération FROM ([Architectures-besoins] AS ab1 INNER JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) INNER JOIN (Materiel_Architecture INNER JOIN Materiel ON Materiel_Architecture.ID_materiel = Materiel.ID) ON ab1.Architecture = Materiel_Architecture.Architecture WHERE (((ab1.Besoin)="ACARS communication") AND ((ab2.Besoin)="In-Flight connectivity"));
puis j'exécute la seconde requête qui me permet de faire le tri sur le champ "pondération":
SELECT DoubleBesoin.Pondération, DoubleBesoin.Architecture, DoubleBesoin.Materiel FROM DoubleBesoin WHERE (((DoubleBesoin.Pondération)=DMax("Pondération","DoubleBesoin")));
Cela fonctionne parfaitement (c'est un bon point :D ) mais je voudrais automatiser la chose afin que:
-L'utilisateur rentre les deux critères initiaux dans une boite de dialogue et non pas dans l'éditeur de requête.
-Il ne faille executer qu'une seule requête et non pas deux.
Pour cela j'ajoute des paramètres à la première requête, elle devient alors:
PARAMETERS Besoin1 Text ( 255 ), Besoin2 Text ( 255 ); SELECT Materiel.Materiel, ab1.Architecture, Materiel_Architecture.Pondération FROM ([Architectures-besoins] AS ab1 INNER JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) INNER JOIN (Materiel_Architecture INNER JOIN Materiel ON Materiel_Architecture.ID_materiel = Materiel.ID) ON ab1.Architecture = Materiel_Architecture.Architecture WHERE (((ab1.Besoin)=[Besoin1]) AND ((ab2.Besoin)=[Besoin2]));
Elle fonctionne parfaitement. Normalement en exécutant la seconde requête je devrais pouvoir entrer les deux paramètre dans une boite de dialogue et ACCESS devrait ne renvoyer que le résultat final de cette seconde requête.
Mais lorsque j'exécute la seconde requête, après avoir rentré les deux critères (Besoin1 et Besoin2) dans la boite de dialogue j'ai le message d'erreur suivant:
"L'expression entrée comme paramètre de requête est à l'origine de l'erreur suivante "Microsoft ACCESS ne parvient pas à trouver le nom "Besoin1" entré dans l'expression" ".
Sais tu à quoi cela pourrait être du? :/
-
-
J'ai réalisé l'ensemble de mes requêtes en mode graphique.
Malheureusement pour celle-ci je n'ai pas réussi à faire fonctionner la fonction Max Dom correctement en mode graphique.
J'ai alors voulu la faire en une seule requête directement en SQL, sans succès. J'ai finalement réussi à faire ce que je voulais mais en deux requêtes distinctes.
Malheureusement je n'arrive pas à automatiser l'exécution de mes deux requêtes.
Il y a deux solutions pour résoudre mon soucis: soit réussir à automatiser l'exécution des deux requêtes l'une à la suite de l'autre. Soit réussir à intégrer la requête de tri sur le champ "pondération" directement dans la première requête. C'est cette deuxième possibilité qui me semble la meilleure. Malheureusement que ce soit en mode graphique ou en mode SQL je n'arrive pas à le faire. Ta dernière proposition semble cohérente mais ACCESS détecte une erreur dans la clause WHERE :/ -
Bonjour,
Il faut absolument que tu passes en mode "graphique" pour créer tes requêtes, c'est bien plus facile et en même temps tu apprends à utiliser le système; une fois que tu as réussi à obtenir ce que tu voulais il est grandement temps de passer en mode SQL.
Tu galères inutilement; c'est comme si tu essayais d'apprendre à skier en te lançant sur une piste noire. Après 15 ans de pratique, je n'écris jamais en SQL mais toujours en graphique. Pour le reste, je n'ai pas tes tables sous les yeux, alors je ne peux pas faire grand-chose. -
Salut,
alors en effet, si j'arrive à effectuer le tri qui se fait actuellement grâce à la seconde requête directement dans la première requête cela serait idéal!
Malheureusement je n'ai pas été en mesure de le faire jusqu'à maintenant.
Lorsque je teste ta proposition de requête:
PARAMETERS [Besoin 1] Text ( 255 ), [Besoin 2] Text ( 255 ); SELECT Materiel.Materiel, ab1.Architecture, Last(Materiel_Architecture.Pondération) as Pondération FROM ([Architectures-besoins] AS ab1 INNER JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) INNER JOIN (Materiel_Architecture INNER JOIN Materiel ON Materiel_Architecture.ID_materiel = Materiel.ID) ON ab1.Architecture = Materiel_Architecture.Architecture GROUP BY Materiel.Materiel, ab1.Architecture WHERE (((ab1.Besoin)=[Besoin 1]) AND ((ab2.Besoin)=[Besoin 2]))
J'ai le message d'erreur suivant:
"Erreur de syntaxe (opérateur absent) dans l'expression (((ab1.Besoin)=[Besoin 1]) AND ((ab2.Besoin)=[Besoin 2]))"
A priori la clause WHERE pose problème. As-tu une idée d'où cela pourrait venir?
A+ -
Re-Bonjour,
J'ai relu attentivement tes 2 requêtes successives.
Je n'arrive pas à comprendre pourquoi tu éprouves le besoin de lancer 2 requêtes successives alors que tu peux tout aussi bien sélectionner les valeurs recherchées directement sur la 1ère sans t'embêter avec une autre.
Il suffirait d'écrire un truc du genre:
"PARAMETERS [Besoin 1] Text ( 255 ), [Besoin 2] Text ( 255 );
SELECT Materiel.Materiel, ab1.Architecture, Last(Materiel_Architecture.Pondération) as Pondération FROM ([Architectures-besoins] AS ab1 INNER JOIN [Architectures-besoins] AS ab2 ON ab1.Architecture = ab2.Architecture) INNER JOIN (Materiel_Architecture INNER JOIN Materiel ON Materiel_Architecture.ID_materiel = Materiel.ID) ON ab1.Architecture = Materiel_Architecture.Architecture GROUP BY Materiel.Materiel, ab1.Architecture WHERE (((ab1.Besoin)=[Besoin 1]) AND ((ab2.Besoin)=[Besoin 2])) "
Bonne suite
- 1
- 2

