[ACCESS] Insert° d'1 moyen. pond. ds la table servant à la calculer

Insert° d'1 moyen. pond. ds la table servant à la calculer [ACCESS] - SQL/NoSQL - Programmation

Marsh Posté le 31-08-2004 à 21:20:42    

Bonjour tout le monde,
 
Je voudrais calculer une moyenne pondérée de la façon suivante (je vais utiliser un exemple pour mieux vous expliquer):
 
Je fais une petite appli pour un agriculteur et il a besoin de connaitre le prix moyen du carburant utilisé.
J'ai donc une table type_carburant, une table achat_carburant(nb_litres, prix_achat) et une table conso_carburant(nb_litres_conso, prix_moyen) (ces deux dernières tables sont liées à la première). Je fais une requête (facture_carburant) sur la table achat_carburant pour avoir le total en euros d'un achat (nb_litres x prix_achat), je fais une requête (charges_carburant) sur la table conso_carburant pour avoir le total en euros d'une consommation (nb_litres_conso x prix_moyen).
Puis je fais une dernière requête sur facture_carburant et charges_carburant pour calculer le prix moyen (pour un type de carburant donné).
Mon problème est que je n'arrive pas, lorsque je veux saisir une nouvelle consommation de carburant, à insérer de façon automatique le prix moyen actuel du type de carburant dans le champ prix_moyen de la table conso_carburant.
J'ai mis en bleue les tables, en rouge les requêtes et en vert ce qui me pose problème.
Le prix moyen se calcule d'une certaine façon en fonction de lui-même.
 
Voilà mon problème. Je vous remercie de vos réponses.


Message édité par Manu la Science le 01-09-2004 à 20:58:19

---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 31-08-2004 à 21:20:42   

Reply

Marsh Posté le 31-08-2004 à 22:09:51    

j'ai pas bien lu en détail ton post, mais il faut se rappeller de la formule de la moyenne :
moyenne = somme(prix) / somme(litres)
 
l'idée ici est donc de calculer
prix_moyen * nb_litres_conso = somme(prix)
à ce résultat tu ajoute le nouveau prix qu'ensuite tu divise par (nb_litres_conso + nouveaux_litres)
 
en résumé,  
 
nouveau_prix_moyen = (prix_moyen * nb_litres_conso + nouveau_prix) / (nb_litres_conso + nouveaux_litres)
 
:jap:
 

Reply

Marsh Posté le 31-08-2004 à 22:20:13    

Je te remercie d'avoir détailler le calcul du nouveau prix moyen. C'est en effet comme cela que je fais mais le problème que j'ai est d'insérer de façon automatique la valeur du nouveau prix moyen lorsque je met un nouvelle consommation de carburant. Dans mon formulaire de saisie de consommation, comment je fais pour que le champ de remplissage de prix_moyen ait la valeur du nouveau prix moyen et que ce prix "rentre" dans la table conso_carburant. C'est le remplissage de cette table et plus précisément du champ prix_moyen qui me pose problème


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 31-08-2004 à 22:44:11    

Désolé, mais access ça fait longtemps que je n'y touche plus ;)

Reply

Marsh Posté le 01-09-2004 à 21:06:45    

J'ai modifier le titre de mon premier post pour que vous compreniez mieux. Je veux insérer une valeur dans le champ d'une table alors que cette valeur utilise ce champ pour son calcul.
Merci de votre aide.


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 02-09-2004 à 20:49:59    

Est-il possible de créer une macro qui remplisse le champ prix_moyen du formulaire de saisie à l'aide de la requête de calcul de ce prix moyen ?
Comment puis-je la faire si c'est le cas ?
Merci de vos réponses.


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 00:30:44    

Au lieu de faire ça avec une "macro" (ou un tigger, ça serait mieu), utilise une vue.
 
Access ne gère pas à proprement les vues, mais c'est tout comme.
 
Ecrit la requête qui permet de faire ton calcul. Enregistre là en temps que "requête".
 
Tu peux alors l'utiliser en tant que "table" :
 
Select * from nom_de_la_requête
 
Tu pourras alors faire des jointures si nécessaires, afin de retrouver en plus des colonnes de ta table "conso_carburant" ta colonne contenant ce nombre calculé.

Reply

Marsh Posté le 03-09-2004 à 13:56:22    

Saut,
 
Bon, je t'explique un peu plus ce que j'ai fait.
 
1- J'ai une table d'achat des carburants où je mets la date d'achat, le prix par litre, le nombre de litres achetés, le tout pour un type de carburant (autre table liée à celle-ci). J'appelle donc cette table achat_carburant.
 
2- A côté de cela, j'ai une table conso_carburant où je mets le nombre de litres consommés, le type de carburant (autre table liée à celle-ci) et le prix moyen du carburant "dans les cuves actuelles" et qui doit être calculé et inséré automatiquement.
 
3- Je fais une requête sur la table achat_carburant que j'appelle facture_carburant où je reprends les champs de la table achat_carburant et auxquels j'ajoute un champ calculé (prix x nb_litres_achetés) pour avoir le montant de la facture.
 
4- Ensuite, je fais une seconde requête sur la requête facture_carburant appelée total_facture_carbu où je retrouve le montant total de litres achetés par type de carburant ainsi que le montant en euros des factures.
 
5- Je fais la même chose pour la consommation de carburant. J'ai donc une requête que j'appelle charge_carburant sur la table conso_carburant qui reprend ses champs et qui calcule un autre champ (prix_moyen x nb_litres_consommés) pour avoir le montant des charges de la consommation.
 
6- Ensuite, je fais une seconde requête sur la requête charge_carburant appelée total_charge_carbu où je retrouve le montant total de litres consommés par type de carburant ainsi que le montant en euros des charges.
 
7- Enfin, je fais une dernière requête sur les requêtes total_facture_carbu et total_charge_carbu et calcule le prix moyen par type de carburant (avec la formule: (total_facture - total_charge)/(total_nb_litres_achetés - total_nb_litres_consommés)).
Donc, je pense bien utiliser les vues ou requête Sélection pour Access pour calculer le prix moyen.
 
Ce qui me pose problème est de rentrer de façon automatique la valeur du prix moyen de la requête dans la table conso_carburant (qui est la base du système de requête).
 
C'est au niveau du formulaire que j'ai un problème. Je voudrais que l'exploitant n'ai pas à se soucier du calcul du prix moyen du carburant à l'heure où il saisit sa consommation et que ce prix moyen s'insère lorsqu'il met un enregistrement de consommation.
 
Comment faire ?
 
Résoudre ce problème me permettrait également de l'appliquer à d'autres choses comme les produits phytosanitaires (appelés vulgairement pesticides) et pour lesquels le prix moyen peut varier fortement.
 
Merci de vos réponses.


Message édité par Manu la Science le 03-09-2004 à 18:40:08

---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 20:28:24    

Je réitère ma première réponse : Il faut que ce prix_moyen soit issu d'une vue et non pas de la table.
 
Sinon, tu peux toujours faire une fonction "recalcule_prix_moyen" que tu appelles à chaque achat / consommation de carburant, et qui met à jour ce champ.
 
Ceci dit, je pense sincèrement que tu atteinds les limites de ton modèle si tu conserves ce système.
 
En effet, imagine.
 
Aujourd'hui, le carburant coûte 1.
Tu en achète 500 litres. Tu en consommes 400.
Le prix change à 2.
Tu en rachètes 400. Tu en re-consommes à nouveau 400.
 
Calcul :
Lors du premier achat, le carburant a un prix moyen de 1 (puisque tu n'avais pas de stock).
Lors du second achat, le carbutant à comme prix :
 
500 * 1 + 400 * 2 / 500 + 400 = 1300 / 900 = 1.44
 
Cependant, la valorisation de ton stock (véritable prix moyen est totalement différente !)
 
(500 - 400) * 1 + 400 * 2 / 500 - 400 + 400 = 900 / 500 = 1.8
 
C'est très différent !
 
Encore mieu, alors qu'avec ton calcul le prix moyen du carburant ne change pas lors de ta deuxième consommation, la valorisation du stock est quand à elle impactée.
En effet, il ne te reste plus que 100 litres à 2, puisque tu as consomme les 500 litres à 1, puis 300 litres des 400 à 2 :
 
(500 - 400 - 100) * 1 + (400 - 300) * 2 / 500 - 400 + 400 - 400 = 200 / 100 = 2
 
Vérifie bien, mais à mon avis la valorisation du sock est bien plus intéressante que ta moyenne. En effet, avec ta moyenne, dans 10 ans, les achats qui ont été fait aujourd'hui impacteront encore la moyenne. Hors, si tu limites la date, imagine que tu as un type de carburant que tu réaprovisionnes rarement, tu n'auras plus de moyenne !
 
Et pour gérer le système de calcul dont je te parle, tu dois créer une autre table "stock", dans laquelle tu met à jours la valorisation de ton stock à chaque mouvement.
 
Dans consommation, tu ne t'occupes que de faire le calcul et le stocker à partir de cette valorisation (avant écriture de la consimation).
 
PS: faire ça avec Access, je pense que c'est un doux suicide, ça commence à faire des traîtements "complexes" et qui nécessitent une grande sécurité lors de leur mise à jour, et un trigger avec gestion de transactions ne me semble pas du luxe : être sûr que la valorisation est bien recalculée à chaque mouvement, sinon toutes les données sont foirées.


Message édité par Arjuna le 03-09-2004 à 20:30:28
Reply

Marsh Posté le 03-09-2004 à 20:37:41    

Arjuna a raison tu sais, mais c'est quand même réalisable. Il suffit de coder tes calculs dans une requête, c'est un peut comme une "Store Procedure" dans SQL Server. Si tu utilises VB et ADO comme méthose d'acces aux données, tout devrais bien aller.

Reply

Marsh Posté le 03-09-2004 à 20:37:41   

Reply

Marsh Posté le 03-09-2004 à 20:59:32    

Arjuna --> Merci pour ton post
 
Je l'ai lu attentivement et je ne suis pas tout à fait d'accord avec tes calculs. En suivant ton exemple de consommation, avec ma formule, cela donne:
[(500*1+400*2(coût d'achat des 2 livraisons))-(400*1(coût de consommation)]/[900(nb total de litres achetés)- 400 (nb total de litres consommés)]= 1,8.
 
Bon, pour le calcul c'est pas super important. Je l'obtient à l'aide de requêtes sélection dans Access. Mon plus gros problème étant d'insérer cette valeur.
 
Quand je lance le formulaire d'enregistrement des consommation, comment pourrais-je faire pour insérer la valeur du prix moyen (provenant de la requête) dans la zone de texte du formulaire qui remplit le champ prix moyen ?
 
Si je change le source de cette zone de texte en mettant ma requête comme source, je ne pourrai plus remplir le champ prix_moyen. C'est à ce niveau que je pense avoir un problème...
 
CrashSerge --> je te remercie de ta réponse, je n'ai hélas pas tout compris. Mon proverbe perso s'applique hélas à la programmation sur Access.  
 
snif...


Message édité par Manu la Science le 03-09-2004 à 21:00:12

---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 21:21:32    

Manu la science a écrit :

Arjuna --> Merci pour ton post
 
Je l'ai lu attentivement et je ne suis pas tout à fait d'accord avec tes calculs. En suivant ton exemple de consommation, avec ma formule, cela donne:
[(500*1+400*2(coût d'achat des 2 livraisons))-(400*1(coût de consommation)]/[900(nb total de litres achetés)- 400 (nb total de litres consommés)]= 1,8.


C'est la partie en gras qui me pose problème en fait. Ce "*1", tu le trouves d'où ?
Quelque soit la méthode que j'imagine, sans suivi de stock, tu ne pourras pas conserver une valeur correcte.
 
Essaie tes calculs avec :
 
A: 100 * 1
A: 200 * 2
C: 150
A: 20 * 1
A: 20 * 1
A: 10 * 3
C: 50
C: 50
C: 50
 
Avec mes calculs et les tiens, je doute qu'on trouve le même résultat, hors, je doute que tu puisses gérer la valeur que j'ai mis en gras dans ta requête sans perdre des infos lors des différentes mises à jour que j'ai cité ci-dessus si tu n'as pas un suivi de stock.

Reply

Marsh Posté le 03-09-2004 à 21:23:31    

Manu la science a écrit :


Quand je lance le formulaire d'enregistrement des consommation, comment pourrais-je faire pour insérer la valeur du prix moyen (provenant de la requête) dans la zone de texte du formulaire qui remplit le champ prix moyen ?
 
Si je change le source de cette zone de texte en mettant ma requête comme source, je ne pourrai plus remplir le champ prix_moyen. C'est à ce niveau que je pense avoir un problème...


Abandonne le code généré par Access et code toi-même tes formulaires.
Là tu as besoin d'un formulaire complexe qui va nécessiter des actions lors de la procédure d'enregistrement, et plusieurs sources de données pour l'affichage. Tu ne peux pas faire autrement que de mettre les pattes dans le cambouis.

Reply

Marsh Posté le 03-09-2004 à 21:26:30    

Le 1 en gras est le prix moyen du carburant car il n'y avait que 500 litres achetés à 1.
 
Je te cite: "Aujourd'hui, le carburant coûte 1.  
Tu en achète 500 litres. Tu en consommes 400."
 
Je fais les calculs et je poste la réponse.
 
Merci de ton intérêt pour ma question (saugrenue, je le reconnais...)


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 21:44:12    

Voici mes résultats:
A la fin du 2eme achat, le prix moyen est de 1,66....7
Je consomme 150 litre à 1,66...7. Après les trois autres achats, le prix moyen est de 1,6 et ne varie plus pour les trois consommations qui suivent.
 
Arjuna --> Je sais que je dois mettre les mains dans le cambouis, mais où intervenir et comment ? J'imagine un bouton de "mise à jour" du prix moyen, mais comment insérer la valeur du prix moyen dans la zone de texte.
 
Et j'ai un autre problème, je dois faire attention au type de carburant à sélectionner dans le formulaire car il influe sur le prix moyen. Le fioul n'est pas au même prix que le super...
 
Je pense que sur la MAJ de la liste de choix du type de carbu dans le formulaire de conso, je devrai déclencher l'action (mais quoi comme action? une macro, du code...). Certaines personnes pourraient dire que je suis vicieux ou tordu...


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 22:03:45    

J'ai une erreur de calcul en effet dans ma déduction du 2 à la fin... Il est toujours à 1.8 €/litre le stock... C'est quand on réapprovisionne qu'il change, et non pas quand on le consomme...
 
Par contre c'est bien le 1.8 le prix moyen, puisqu'on équilibre les comptes avec mon système :
 
Détail des achats :
1) 500 * 1
2) 400 * 2
-----------
1300 €
 
Détail des consmations :
1) 400 * 1
2) 400 * 1.8
3) 100 * 1.8
------------
400 + 720 + 180 = 1300
 
:)
 
Pour le détail des mouvement que j'ai indiqué dans mon post au dessus ça donne :
 
Achats :
A: 100 * 1  
A: 200 * 2  
A: 20 * 1  
A: 20 * 1  
A: 10 * 3  
------------
100 + 400 + 20 + 20 + 30 = 570 €
 
Consommations :
-- Lors du second achat la valorisation passe à 1.67 : (100 * 1 + 200 * 2) / 100 + 200
C: 150 * 1.67 = 250
-- Revalorisation à 150 * 1.67 + 20 * 1 / 150 + 20 = 1.59
-- Revalorisation à 170 * 1.59 + 20 * 1 / 170 + 20 = 1.53
-- Revalorisation à 190 * 1.53 + 10 * 3 / 190 + 10 = 1.6
C: 50 * 1.6 = 80
C: 50 * 1.6 = 80  
C: 50 * 1.6 = 80
-----------------------
250 + 240 = 490 €
 
Plus le reste du stock valorisé à 1.6 :
(100 + 200 + 20 + 20 + 10 = 350) - (150 + 50 + 50 + 50 = 300) = 50 * 1.6 = 80
 
=> Consommation totale (avec prévision sur le stock restant) = 490  + 80 = 570 €
 
On retombe sur nos pattes, donc mon calcul est bon :)
 
Je ne comprends pas comment tu retrouve 1,6 sans passer par ces étapes (:??:)


Message édité par Arjuna le 03-09-2004 à 22:05:22
Reply

Marsh Posté le 03-09-2004 à 22:10:45    

PS: avec ton système tel que je le comprends, je trouve 1,6285714285714285714285714285714 pour le prix moyen à la fin. Moi c'est 1,6 pile.
Si après une dernière consommation qui vide le stock on rachète des l'essence à 1, alors la valorisation sera de 1. Toi, elle sera un peu en dessouss de 1.62... mais plus grande que 1, ce qui n'est pas vrai d'un point de vue financier : aujourd'hui, si tu tapes dans ton fioul, il te coûte 1 € et non pas 1,xxx €

Reply

Marsh Posté le 03-09-2004 à 22:18:14    

Tu as trouvé comme moi... Je le trouve grâce au système de requêtes que j'ai décris plus haut. Tu as écrit un peu plus sur la valorisation du stock, méthode que tu as utilisée pour ce calcul, et tu disais que c'est un doux suicide pour l'utiliser.
 
Alors, je pense que je vais garder ma méthode de calcul, qui se sert en effet de toutes les transactions (achats et conso, sur dix ans...). Seulement, c'est au niveau de la création du formulaire de saisie des conso. Comment récupérer la valeur du prix moyen?
 
J'ai vu un truc comme ça:

Code :
  1. Dim qdfTmp As QueryDef
  2. Dim strText as String
  3.     Set qdfTmp = CurrentDb.QueryDefs("Nom_requete" )
  4.     strText = qdfTmp.SQL


pour récupérer la requête, je pense qu'il faut mettre la condition WHERE pour le type de carburant sélectionné.
 
Mais une fois que j'arrive à avoir la valeur, comment la mettre dans la zone de texte alimentant le champ prix moyen de la table conso_carburant ?


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 22:22:39    

Aucune idée, j'ai bossé avec Access pendant une semaine il y a 6 ans, avant de passer à une version PHP de l'outils parceque ça me gavait :D

Reply

Marsh Posté le 03-09-2004 à 22:24:58    

Je te remercie de l'intérêt que tu as porté à mon problème. Access est quand même plus pratique pour un agriculteur en rase campagne qu'un site Internet...


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 03-09-2004 à 23:17:44    

A ce moment, pense à faire une appli VB. C'est pas plus difficile à coder, et ça t'éviteras plein de problèmes. ;)


Message édité par Arjuna le 03-09-2004 à 23:17:53
Reply

Marsh Posté le 04-09-2004 à 10:37:44    

Arjuna a écrit :

A ce moment, pense à faire une appli VB. C'est pas plus difficile à coder, et ça t'éviteras plein de problèmes. ;)


Le problème, c'est que pour développer en vb, il faut acheter la licence du logiciel de microsoft, a moins qu'il existe un logiciel gratuit pour développer en vb. Je n'en connais pas.
 
Je croyais mon problème plus simple à démêler... Je pensais qu'il faille seulement programmer la mise à jour du choix du type de carburant lors de la consommation pour qu'elle insère la valeur du prix dans la zone de texte remplissant le champ prix_moyen.
 
Je pense que c'est ce qu'il y a de moins dur à mettre en place mais je ne sais pas trop comment faire...
 
Je vais essayer de mon côté.
 
Merci quand même. :jap:


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 04-09-2004 à 11:51:56    

Ben si j'avais Access installé, je te filerais bien un coup de main, mais je l'ai pas...

Reply

Marsh Posté le 05-09-2004 à 12:32:49    

Bonjour,
La nouvelle valeur est-elle rajoutée lors d'un saisie à l'aide d'un formulaire ?
Si c'est le cas, c'est alors simple :
Imaginons que ce soit la zone 'nouveau prix' qui doit être renseigné pour prendre en compte la revalorisation de ta moyenne.
Avec l'événement 'txt_Nouveau_Prix_LostFocus()' tu peux créer une requête UPDATE tel que :
txtSQL = "UPDATE <nom-de-ta-table> SET <tu renseigne tes clés>, Moyenne = " & Nouvelle_Valeur;
1- Nouvelle_Valeur désigne la formule de ta moyenne en tenant compte de la valeur saisie dans la zone 'nouveau prix' : comme [#0000ff]par exemple : Nouvelle_Valeur = (n.ancienne_moyenne + txt_Nouveau_Prix)/(n+1)
   
2-Dim txtSQL as String  
Dim Req As Recordset  
 
    Set Req = CurrentDb.OpenRecordset("Nom_Table" )  
    DoCmd.RunSQL (txtSQL)[/#00718d]
Bien sûr tout ce qui est en VERT est à déclarer avant de construire la requête.
 
J'espère avoir été clair  :D  

Reply

Marsh Posté le 05-09-2004 à 15:10:49    

Bonjour,
 
Tu m'as apporté un élément de réponse. En fait, je voudrais que l'agriculteur saisisse sa consommation de carburant sans renseigner le champ prix_moyen. Celui-ci se renseigne "tout seul". J'aurai voulu avoir la possibilité d'afficher le prix moyen avant la fermeture du formulaire mais je me contenterai pour l'instant de la mise à jour de la table.
Je vais essayer...
Encore merci.


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 05-09-2004 à 16:22:39    

Tu peux afficher ton prix moyen dans ton formulaire.
Tu peux par exemple (Et toujours dans la procédure d'évènement _LostFocus() ), de faire la chose suivante :
If Not Req.EOF then
  txt_Prix_Moyen = Req(<Rang dans la requête> - 1)
Endif  
 
 : txt_Prix_Moyen est la zone dans laquelle tu voudrais afficher le prix moyen, Rang dans la requête c'est le rang de la colonne de ta requête txtSQL, ici dans l'exemple suivant (txtSQL = "UPDATE ... SET CLE = 5, Prix_Moyen = " & Prix_Moyen & ";" le rang est 2, donc txt_Prix_Moyen = req(1) (req(2-1));

Reply

Marsh Posté le 05-09-2004 à 16:33:37    

J'ai un problème, je n'arrive pas à exécuter ma requête...
Voici mon code

Code :
  1. Private Sub type_carbu_LostFocus()
  2. Dim txtSQL As String
  3. Dim Req As Recordset
  4.     txtSOL = "SELECT prix_moyen_carburant.prix_moyen FROM prix_moyen_carburant WHERE prix_moyen_carburant.id_type_carbu=" & type_carbu
  5.     Set Req = CurrentDb.OpenRecordset("prix_moyen_carburant" )
  6.     DoCmd.RunSQL (txtSQL)
  7. End Sub


En sachant que "prix_moyen_carburant" est une requête et qu'il me renvoie Req vide alors que "prix_moyen_carburant.id_type_carbu" est bien égal à 1 (valeur prise sur le formulaire après sélection du type de carburant).
Je ne suis pas un expert du VBA, plutôt un super novice... :( .
Une fois que j'aurai récupérer la valeur du champ prix_moyen de la requête, je la mettrai dans le controle_text... mais il faut que je la récupère.


Message édité par Manu la Science le 05-09-2004 à 16:35:54

---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 05-09-2004 à 19:10:35    

Primo, tu dois tester que ta requête ramène queleque chose :
If Not Req.EOF then
  prix_moyen = Req(n-1)  
END if
 
Secundo, vérifie que ta clause : WHERE prix_moyen_carburant.id_type_carbu=" & type_carbu  
ramène quelque chose.
 
Bon courage.

Reply

Marsh Posté le 05-09-2004 à 20:51:44    

Voici le code que j'ai testé:
 

Code :
  1. Private Sub type_carbu_LostFocus()
  2. Dim txtSQL As String
  3. Dim Req As Recordset
  4.     txtSOL = "SELECT prix_moyen_carburant.prix_moyen FROM prix_moyen_carburant WHERE prix_moyen_carburant.id_type_carbu=" & type_carbu
  5.     Set Req = CurrentDb.OpenRecordset("prix_moyen_carburant" )
  6.     DoCmd.RunSQL (txtSQL)
  7.     If Not Req.EOF Then
  8.         prix_moyen = Req(n - 1)
  9.     End If
  10. End Sub


Dans Microsoft Visual Basic, la ligne "Set Req = CurrentDb.OpenRecordset("prix_moyen_carburant" )" ne lui plaît pas. Lorsque je mets mon curseur sur type_carbu, il met bien type_carbu=1 (c'est la bonne valeur) mais je pense que c'est au niveau de l'appel de "prix_moyen_carburant" qui est une requête Sélection d'Access.
Il met "Req = Nothing".
Peut on appeler comme cela une requête Sélection ? Car normalement, je n'ai qu'un enregistrement pour ce recordset...
Merci pour l'aide  :jap:  
 
Une autre question, à quoi sert "prix_moyen = Req(n-1)" ?


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 06-09-2004 à 20:56:38    

La bonne syntaxe est la suivante :
Set Req = CurrentDB.OpenRecordset(TxTSQL)
    If Not Req.EOF Then
        Numcde = Req(20) 'Le 21 ème élément de cette requête correspond au N° de la commande recherchée.
    End If
    Req.Close
 
Dans ma réponse précédente (prix_moyen = Req(n-1)) : prix moyen est la zone dans laquelle tu veux récupérer l'argument (prix_moyen) de ta requête. d'où vient (n ou n-1).
Admettons que mon txtSQL = "SELECT NOM, PRENOM, RUE, VILLE, CODE_POSTAL FROM CLIENT WHERE NOM like 'QUE%';"
 
Set Req = CurrentDB.OpenRecordset(TxTSQL)
    If Not Req.EOF Then
        Var_NOM = Req(0) ou Req(1-1) 'Le 1er élément de cette requête     correspond au Nom du client.
        Var_CODE_POSTAL = Req(4)
    End If
    Req.Close
Voilà de cette façon tu récupères ce le dernier client ramené par cette requête.
 
Bon travail.

Reply

Marsh Posté le 06-09-2004 à 21:07:07    

Je te remercie pour ta réponse. Je vais l'essayer.
 
N'y a t'il pas moyen d'utiliser une requête enregistrée comme requête Sélection dans Access ou faut-il que je me "farcisse" la création en SQL de mon système de requêtes décrit plus haut ?
 
Si je ne peux pas utiliser une requête Sélection, je le ferai via SQL mais cela va être plutôt corsé...
 
 :jap:  :jap:  :jap:


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 06-09-2004 à 21:14:14    

C'est une question d'habitude :D  ! Ce n'est pas sorcier tu verras ?

Reply

Marsh Posté le 06-09-2004 à 21:29:50    

motra a écrit :

C'est une question d'habitude :D  ! Ce n'est pas sorcier tu verras ?


Très certainement, mais mon système de requête est plutôt très complexe.
Une première requete sur une table fait un produit de 2 champs d'une table, puis une deuxième requête fait une somme de champs de la première requête par regroupement d'un autre champ. Ce système de 2 requêtes est également réalisé sur une autre table.
Enfin, une requête de calcul est effectuée sur les deux requêtes effectuant la somme.
C'est plutôt très complexe...


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 06-09-2004 à 23:29:26    

D'un oeil objectif : ne faudrait-il pas "réorganiser" ta base de données. Essai de faire un test, sur une copie de ta base (je répète sur une copie de ta base), d'analyse de performance et de table. Tu auras au moins une idée sur ce qui est redondant ou ce qui est mal fait.
 
Sur un autre front, tu peux créer des requêtes de mise à jour à l'aide de l'assistant création de requête à laquelle tu pourras faire appel en VBA le moment venu par DoCmd.Query "<nom de ta requête">.

Reply

Marsh Posté le 07-09-2004 à 20:32:11    

Salut,
 
J'ai fait ce que tu m'as proposé pour une éventuelle réorganisation de ma base de données mais l'analyse de performance et de table n'a émis aucune suggestion. J'en conclu que ma base de données et que mes requêtes ne sont pas trop mal fait...
 
Je pense peut être faire autrement mais je ne sais pas si c'est possible. Puisque je n'arrive pas à exécuter une requête basée sur d'autres requête, je vais faire mon système de requête en vba.
 
Mais peut-on appliquer une requête SQL sur un Recordset émanant d'une première requête basée sur une table ? Y a-t'il une fonction appliquant à une recordset une requête SQL ?
 
Du genre nouveau_recordset = recordset.query(ma_requete) avec ma_requete définie avant en langage SQL...


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 07-09-2004 à 22:32:51    

Si tu as des requêtes répétitives (quatidienne ou mensuelle) dont les critère ne change pas mais seulement le résultat obtenu en fonction d'une date donnée, d'un utilisateur donné par exemple. Tu peux garder ces requêtes.
Au lieu de constituer une requête qui se base sur une autre requête je te conseille de la fabriquer entièrement en VBA en utilisant les tables plutôt que les requêtes. C'est simple, voici un exemple. Je considère 3 tables : CLIENTS, COMMANDES et DETAILS_COMMANDES, je veux afficher les détails suivants suite à la saisie du nom d'un client donné [Z_Nom_Cli].
txtSQL = "SELECT a.Numéro_Client, a. Prénom_Client, a.Nom_Client,"
txtSQL = txtSQL & " b.Numéro_Commande, c.Etat_Commande"
txtSQL = txtSQL & " WHERE a.Numéro_Client = b.Numéro_Client AND"
txtSQL = txtSQL & " b.Numéro_Commande = c.Numéro_Commande AND"
txtSQL = txtSQL & " a.Nom_Client LIKE '" & Z_Nom_Cli & "'";
 
TABLE CLIENTS                 COMMANDE                                 ------------               -------------
Numéro_Client (clé unique)    Numéro_Commande (Clé unique)  
Nom_Client                    Numéro_Client (Clé étrangère)
Prénom_Client                 .......
...
 
 
DETAILS_COMMANDES
-----------------
Numéro_Commande (Clé étrangère)
Etat_Commande
.......
 
Cette requête peut être exécutée par la suite par Set Req = CurrentDB....
 
Bon courage.

Reply

Marsh Posté le 07-09-2004 à 22:40:53    

Dans ce que tu as écrit, tu ne fait pas de Group By et de Sum. C'est ces opérations qui me gênent. Je pense que je ne peux pas faire une seule requête SQL mais deux (c'est sur) voire trois.
 
De plus, en ce moment, je galère pour exécuter la moindre requête. J'ai du mal à écrire le code vba qu'il faut, j'ai Access 2000 et je galère dur pour vraiment pas grand chose.


---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le 08-09-2004 à 07:29:32    

Peux-tu m'envoyer une de tes requête "désobeissante"  :fou:  sous access en m'expliquant s'il te plaît brièvement à quoi elle sert ??!!

Reply

Marsh Posté le 08-09-2004 à 21:01:54    

Voici les trois tables en questions:
 
table type_carburant
      id_type_carburant (clé primaire)
      type_carburant (label)
 
 
table conso_carburant
      id_conso_carburant (clé primaire)
      litres_conso (nombre de litres consommés)
      id_intervention (clé de la table intervention)
      type_carbu (clé de la table type_carburant)
      prix_moyen (valeur que je veux insérer automatiquement)
 
table achat_carburant
      id_achat_carburant (clé primaire
      id_type_carburant (clé de la table type_carburant)
      date
      prix_litre (prix du litre)
      litres_achetes (nombre de litres achetés)
 
Ensuite, je fais un premier type de transformation des données de ces tables sous forme de requêtes sélection. Un champ est ajouté pour calculé le montant (prix x nb de litres) de la transaction (c'est à dire l'achat ou la consommation)
 
Requête charges_carburant

Code :
  1. SELECT types_carburant.id_type_carbu AS ch_type_carbu, conso_carburant.litres_conso AS ch_litres_conso, conso_carburant.prix_moyen AS ch_prix_moyen, [litres_conso]*[prix_moyen] AS charge
  2. FROM types_carburant INNER JOIN conso_carburant ON types_carburant.id_type_carbu=conso_carburant.type_carbu;


 
Requête facture_carburant

Code :
  1. SELECT types_carburant.id_type_carbu AS fac_type_carbu, achats_carburant.litres_achetes AS fac_litres_achetes, achats_carburant.prix_litre AS fac_prix_achat, [litres_achetes]*[prix_litre] AS fac_cout
  2. FROM types_carburant INNER JOIN achats_carburant ON types_carburant.id_type_carbu=achats_carburant.type_carbu;


 
J'effectue ensuite un second traitement des requêtes citées au dessus pour faire la somme des montants calculés et la somme des litres. Ces sommes sont faites par regroupement du type de carburant.
 
Requête total_charge_carburant (basée sur la req. charges_carburant)

Code :
  1. SELECT DISTINCTROW charges_carburant.ch_type_carbu AS tot_ch_type_carbu, Sum(charges_carburant.ch_litres_conso) AS total_litres_consommes, Sum(charges_carburant.charge) AS total_charge
  2. FROM charges_carburant
  3. GROUP BY charges_carburant.ch_type_carbu;


 
Requête total_facture_carburant (basée sur la req. facture_carburant)

Code :
  1. SELECT DISTINCTROW facture_carburant.fac_type_carbu AS tot_fac_type_carbu, Sum(facture_carburant.fac_litres_achetes) AS total_litres_achetes, Sum(facture_carburant.fac_cout) AS total_facture
  2. FROM facture_carburant
  3. GROUP BY facture_carburant.fac_type_carbu;


 
Enfin, à l'aide des deux dernières requêtes (ci-dessus), je calcule le prix moyen (pour chaque type de carburant) avec la requête suivante:
 
Requête prix_moyen_carburant

Code :
  1. SELECT total_charges_carburant.tot_ch_type_carbu AS type_carburant, ([total_facture]-[total_charge])/([total_litres_achetes]-[total_litres_consommes]) AS prix_moyen
  2. FROM total_charges_carburant, total_facture_carburant
  3. WHERE (((total_charges_carburant.tot_ch_type_carbu)=total_facture_carburant.type_carbu));


 
L'esprit de ce que je veux faire est de permettre à l'exploitant de saisir ses achats de carburant et d'affecter automatique le prix moyen actuel du carburant utilisé lors de ses interventions dans les champs.


Message édité par Manu la Science le 08-09-2004 à 21:03:47

---------------
Proverbe chinois: il vaut mieux apprendre à pêcher à un mendiant que de lui donner du poisson...
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed