IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Access Discussion :

Optimiser un calcul avec parcours de recordset


Sujet :

Access

  1. #1
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut Optimiser un calcul avec parcours de recordset
    Bonjour j'ai une fonction qui me permet de calculer un PAMP (Prix d'achat moyen pondere) en VBA.

    Le problème est que dans certains états ayant plus de 10 lignes de calcul, access ne semble pas avoir le temps de calculer certaines valeurs et me met erreur.
    Si je passe en mode creation et reviens en mode etat, tout est ok.

    Y aurait t-il un moyen de demander un pre calcul avant le chargement ou quelque chose dans le style?
    Merci

    Pour info voici ma fonction:
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    Option Explicit
    Function stpmp(codeval As Long, Compte As Long, ref As String) As Double
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
    Set base = CurrentDb()
    sql = "SELECT DateFormatte,idTypetransaction, idProduit, idClient, Quantite, Prix FROM 2TRANSACTIONS "
    sql = sql & "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
    Set mesvaleurs = base.OpenRecordset(sql)
    mesvaleurs.MoveLast
    mesvaleurs.MoveFirst
    Do While Not mesvaleurs.EOF
    If mesvaleurs![IdTypeTransaction] = "1" Then
    pmp = pmp + (mesvaleurs![Quantite] * mesvaleurs![Prix])
    Stock = Stock + mesvaleurs!Quantite
    Else
    If Stock - mesvaleurs!Quantite = 0 Then
    pmp = pmp / mesvaleurs![Quantite]
    Else
    pmp = pmp - (mesvaleurs![Quantite] * (pmp / Stock))
    End If
    Stock = Stock - mesvaleurs!Quantite
    End If
    mesvaleurs.MoveNext
    Loop
    Set mesvaleurs = Nothing
    Set mesvaleurs = Nothing
    If Stock = 0 Then
    stpmp = pmp
    Else
     stpmp = pmp / Stock
    End If
    End Function

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2006
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 214
    Points : 169
    Points
    169
    Par défaut
    je pense que tu a déjà moyen d'alléger le code, voici ce que je te propose

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    Option Explicit
    
    Function stpmp(codeval As Long, Compte As Long, ref As String) As Double
    
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
    
    Set base = CurrentDb "()" 'pas nécessaire
    
    sql = "SELECT DateFormatte,idTypetransaction, idProduit, idClient, Quantite, Prix FROM 2TRANSACTIONS " & _ 
    ' petite amélioration car déclaration en 1 temps au lieu de 2
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
    
    Set mesvaleurs = base.OpenRecordset(sql)
    
    mesvaleurs.MoveLast
    
    mesvaleurs.MoveFirst
    
    Do While Not mesvaleurs.EOF
    If mesvaleurs![IdTypeTransaction] = "1" Then
         pmp = pmp + (mesvaleurs![Quantite] * mesvaleurs![Prix])
         Stock = Stock + mesvaleurs!Quantite
    Else
         If Stock - mesvaleurs!Quantite = 0 Then
              pmp = pmp / mesvaleurs![Quantite]
         Else
              pmp = pmp - (mesvaleurs![Quantite] * (pmp / Stock))
         End If
         Stock = Stock - mesvaleurs!Quantite
    End If
    
    mesvaleurs.MoveNext
    
    Loop 'pourquoi utiliser un do while not alors qu'un while not suffit :
    
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
         pmp = pmp + (mesvaleurs![Quantite] * mesvaleurs![Prix])
         Stock = Stock + mesvaleurs!Quantite
       Else
         If Stock - mesvaleurs!Quantite = 0 Then
              pmp = pmp / mesvaleurs![Quantite]
         Else
              pmp = pmp - (mesvaleurs![Quantite] * (pmp / Stock))
         End If
         Stock = Stock - mesvaleurs!Quantite
       End If
    
       mesvaleurs.MoveNext
    Wend
    
    (Set mesvaleurs = Nothing
    Set mesvaleurs = Nothing) cela n'est pas necessaire n'ont plus vue que tu atribut une valeur au début
    
    If Stock = 0 Then
         stpmp = pmp
    Else
         stpmp = pmp / Stock
    End If
    End Function
    *
    avec sa je pense que l'on a moins de temps precesseur mais pas sur, en tout cas je pense qu'il est optimiser

  3. #3
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Ceci ne sert à rien :
    mesvaleurs.MoveLast

    mesvaleurs.MoveFirst
    Quant à l'attribution de nothing ou non, ce n'est pas ça qui va faire gagner du temps et encore mois le () dans currentdb

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2006
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 214
    Points : 169
    Points
    169
    Par défaut
    oui mais ce sont des chose inutile et c'est ce que je voulais dire.

  5. #5
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    Merci pour votre attention, mais ca na pas lair de resoudre mon probleme.

    En fait, comme j'ai besoin du stock au fur et à mesure, j'ai dédoublé ma fonction pour pouvoir récupérer la valeur stock en changer juste la fin:
    La fonction porte un nom différent, y aurait til un moyen de recuperer la Variable stock sans refaire une fonction qui double le travail?

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    Function stockp(codeval As Long, Compte As Long, ref As String) As Double
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
    Set base = CurrentDb
    sql = "SELECT DateFormatte,idTypetransaction, idProduit, idClient, Quantite, Prix FROM 2TRANSACTIONS " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
     
    Set mesvaleurs = base.OpenRecordset(sql)
     
    Do While Not mesvaleurs.EOF
    If mesvaleurs![IdTypeTransaction] = "1" Then
         pmp = pmp + (mesvaleurs![Quantite] * mesvaleurs![Prix])
         Stock = Stock + mesvaleurs!Quantite
    Else
         If Stock - mesvaleurs!Quantite = 0 Then
              pmp = pmp / mesvaleurs![Quantite]
         Else
              pmp = pmp - (mesvaleurs![Quantite] * (pmp / Stock))
         End If
         Stock = Stock - mesvaleurs!Quantite
    End If
     
    mesvaleurs.MoveNext
     
    Loop
     
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
         pmp = pmp + (mesvaleurs![Quantite] * mesvaleurs![Prix])
         Stock = Stock + mesvaleurs!Quantite
       Else
         If Stock - mesvaleurs!Quantite = 0 Then
              pmp = pmp / mesvaleurs![Quantite]
         Else
              pmp = pmp - (mesvaleurs![Quantite] * (pmp / Stock))
         End If
         Stock = Stock - mesvaleurs!Quantite
       End If
     
       mesvaleurs.MoveNext
    Wend

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Points : 4 297
    Points
    4 297
    Par défaut
    je suis assez surpris de donner un pmp à un solde à 0
    d'autre part le pmp se calcule dynamiquement à l'intro des mouvements
    en cherchant le pmp précédent (dlookup ou sous requete) et modif si achat

  7. #7
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    y a til un moyen de recuprer Stock dans la premiere fonction, cela meviterai de relancer une dexuieme fonction...

    Merci

  8. #8
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    je suis pas au top cote vb, lorsque jai ma fonction ci dessus par exemple, je vais mettre stpmp(1erparametre,2emeparametre,3emeparametre) dans un champs dans une requete et ca va me donner le resultat de stpmp.

    Si je souhaite recupérer une variable utilisée dans mon code genre "Stock" pour ma requete. Comment dois je proceder?

    Est ce possible, ou dois refaire une nouvelle fonction, qui va entrainer du coup deux fois plus de longueur.

    Merci

  9. #9
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Là, il y a deux boucles, les temps sont forcément multipliés par 2

    De plus je pense que le calcul peut être effectué à partir du simple requête même mieux, en appliquant la solution de random

    d'autre part le pmp se calcule dynamiquement à l'intro des mouvements

  10. #10
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    Oui mais je n'y suis jamais arrivé à partir d'une simple requete, j'vais été aidé pour le code ci dessus.

    Il n'y a donc pas moyen de recuperer dans une requete ce "Stock" à l'intérieur de la fonction?

  11. #11
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    il faudrait pas faire un tableau pour pouvoir recueperer ce "Stock" ?

  12. #12
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    Voici en fait le code final pour ceux qui rechercheraient un code vb pour du calcul PMP

    La premiere fonction permet de calculer le PMP et la seconde de calculer le Stock au fur et a mesure pour pouvoir l'utiliser dans une requete.

    La fonction stpmp est concue pour afficher un pmp lorsqu'il ne reste plus de produit. l'avantage est que l'on peut ainsi l'utilisée de facon lineaire pour calculer la performance d'une vente. Mais lors du futur achat, on ne reexploitera plus cette valeur on partira directement sur le nouveau prix dachat, tout simplement.

    Le seul defaut de tout ca est que je calcul deux fois sur deux fonction differentes mon Stock, car je ne sais pas recuprer plus de une valeur sur une fonction.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    Function stpmp(codeval As Long, Compte As Long, ref As String) As Double
     
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
     
    Set base = CurrentDb
     
    sql = "SELECT DateFormatte,idTypetransaction, idProduit, idClient, Quantite, Prix FROM 2TRANSACTIONS " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
     
    Set mesvaleurs = base.OpenRecordset(sql)
     
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            If Stock = 0 Then
            pmp = mesvaleurs![Prix]
            Stock = mesvaleurs!Quantite
            Else
            pmp = ((pmp * Stock) + (mesvaleurs![Quantite] * mesvaleurs![Prix])) / (Stock + mesvaleurs!Quantite)
            Stock = Stock + mesvaleurs!Quantite
            End If
       Else
            pmp = pmp
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
     
    Wend
     
    stpmp = pmp
     
    End Function
     
    Function stockp(codeval As Long, Compte As Long, ref As String) As Double
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Set base = CurrentDb
    sql = "SELECT DateFormatte,idTypetransaction, idProduit, idClient, Quantite, Prix FROM 2TRANSACTIONS " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
     
    Set mesvaleurs = base.OpenRecordset(sql)
     
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            Stock = Stock + mesvaleurs!Quantite
       Else
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
     
    Wend
     
    stockp = Stock
    End Function

  13. #13
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par random
    je suis assez surpris de donner un pmp à un solde à 0
    Je met un pmp lorsque le solde est à 0 car cela me permets de calculer une perf

    Citation Envoyé par random
    d'autre part le pmp se calcule dynamiquement à l'intro des mouvements
    en cherchant le pmp précédent (dlookup ou sous requete) et modif si achat
    c'est en gros ce qu'il se passe, sauf que c'est fait d'une autre manière, je donne une valeur à pmp et Stock, puis je passe a l'enregistrement suivant et je me sert de ces valeurs
    Est ce que ca te choque dans la manière de faire, ca serait plus rapide avec un DlookUp (je connais pas) ou une sous requete (je vois pas tres bien comment la construire)

  14. #14
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Points : 4 297
    Points
    4 297
    Par défaut
    si on entre des transactions on commence par un achat nécessairement

    je peux écrire
    ref produit ,date heure achat ,quantite, prix unitaire, nbpmp=quantité*pu
    et stock=quantité
    ensuite si un mouvement est achat
    ref produit ,date heure achat ,quantite, prix unitaire ,nbpmp=ex nbpmp+(quantité*pu) et stock=quantité+ex stock

    le jeu consiste à trouver les valeurs de l'enregistrement précédent
    cela se fait avec une sous requete ou un dlookup

  15. #15
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    je comprends pas, ce que je fais est la meme chose mais avec une boucle.
    (Sauf que jai peux etre pas tout bien expliqué... IdTypeTransaction =1 c'est un achat et 2 c'est une vente)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            If Stock = 0 Then
            pmp = mesvaleurs![Prix]
            Stock = mesvaleurs!Quantite
            Else
            pmp = ((pmp * Stock) + (mesvaleurs![Quantite] * mesvaleurs![Prix])) / (Stock + mesvaleurs!Quantite)
            Stock = Stock + mesvaleurs!Quantite
            End If
       Else
            pmp = pmp
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
    Boucle ouverte:
    Si c'est un achat:
    Si ya pas de stock existant je prends le prix d'achat pour pmp et la quantite pour le stock
    Si ya du stock je rajoute au stock et au pmp le resultat de la formule identique à la tienne

    Sinon c'est une vente et la:
    le pmp reste identique (ca me permet de pouvoir faire une perf et comme jai fais une detection de stock existant avant, ca ne gene pas pour le calcul pmp du futur achat), et le stock sera diminiué
    Boucle fermé

    et la je passe à l'enregistrement suivant

    On fais la meme chose mais en utilisant une autre methode, peut etre que le dlookup serait plus rapide à executer, ce qui est mon premier probleme, mais je ne sais aps utilisee le dlook up

    Mon deuxieme probleme important, qui me sauverait la vie, serait de pouvoir recupérer "Stock" dans une requete sans recréer une deuxieme fonction. Et ca je sais pas faire monsieur, donc si tu me mets sur la piste, tu fais un homme heureux

  16. #16
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Points : 4 297
    Points
    4 297
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    NSERT INTO matable ( produit, quté, pu, stock, dateop, spmp )
    SELECT nprod, nq, npu, nstock,ndateop, nspmp
    FROM (SELECT [produit ?] AS nprod, [quté ?] AS nq, [pu ?] AS npu,
    [produit], First([dateop]) AS PremierDedateop,[stock],[spmp], [stock]+[quté ?] AS nstock, Now() AS ndateop, IIf([quté ?]>0,[spmp]+([quté ?]*[pu ?]),[spmp]-([spmp]/[stock]*[quté ?]*[pu ?])) AS nspmp
    FROM matable
    GROUP BY [produit ?], [quté ?], [pu ?], [matable].[produit], [matable].[stock], [matable].[spmp], [stock]+[quté ?], Now(), IIf([quté ?]>0,[spmp]+([quté ?]*[pu ?]),[spmp]-([spmp]/[stock]*[quté ?]*[pu ?]))
    HAVING (((produit)=[produit ?]) AND ((First(matable.dateop))<Now()))
    ORDER BY First([matable].[dateop]) DESC);
    crée une table matable avec les champs suivants produit, quté, pu, stock, dateop, spmp

    et lance cette requête

  17. #17
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    je lai fait mais je ne vois pas bien lutilité....

    Le but c'est qu'il calcul à chaque fois les données en dur, mais ca ne minteresse aps car en cas d'annulation de transaction, tu dois annuler toutes les transactions intermediaires puis toute les revalider...

    Mon systeme permet de tout changer en boucle.
    Le seul probleme est que comme je n'arrive pas à recuperer "Stock" dans ma premiere fonction, je relance une deuxieme fonction qui a mon avis ralenti grave le tout.

  18. #18
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    CE petit message est adressé à random.

    J'avais commencé en avril 2005 à cherché une solution à mon pb de pamp (en fait jy pensait depuis 2004).
    A l'époque j'avais une requete qui calculait les nouveaux pamp et stock à chaque validation de transaction et je les stockait dans une table. Ce qui obligait à annuler dans le meme sens et a revalider dans le meme sens en cas derreur sur les premiere transaction.

    Tu m'avais donné le code initial, (à l'epoque je ne savais pas manipuler du tout le vba http://www.developpez.net/forums/sho...t=61724&page=3

    Tu peux voir au dessus (jai legerement modifier 2 ou 3 choses et rajouter une fonction pour le calcul avec les frais, je posterai les 3 fonctions finales lundi pour ce que ca peut aider) comment jai transformer un peu ton code pour me permettre de faire ce dont javais besoin et ca foncitonne nickel.

    Il m'a fallu plus d'un an pour trouver la force de modifier ma base initiale, qui m'a demandé 2 mois de travail (c'etait une base de 3 ans de travail avec des evolutions au fur et a mesure et la je suis repartie de 0 en gardant seulement les setats et formulaires.)

    Javais gardé precieusement ton code pour le ressortir le jour X.

    La base est desormais sur sa fin et ca fonctionne nickel, jai un peu de lenteur sur le calcul, car je suis obligé de repeter la fonction 3 fois, une pour avoir le stock, une pour le pamp et une pour le pamp net, donc pour chaque ligne, il y a trois boucle, mais ca fonctionne.

    Donc je te remercie, ceci m'a apporté un grand plus, et aujourd'hui est l'aboutissement de 2 ans à rechercher ce code et à enfin avoir une base qui gere les stocks de produits et de cash avec perfs et pamp en direct et surtout en boucle. Si je modifie une valeur tout se change automatiquement et c'est nickel.

    Bon e et un grand merci à toi.

  19. #19
    Membre régulier Avatar de hugo69
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    512
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 512
    Points : 122
    Points
    122
    Par défaut
    Voici le code final: (idType Transaction correspond a si cest une vente ou un achat, 1 ou l'achat et 2 pour la vente et Date formatee corespond à la mise en forme de la date de transaction à l'inverse avec l'heure: 20060610110230)

    Le "FROM 2TransactionBis " est une requete qui se sert de la table de transaction avec une liaison vers une requete qui fait le total des frais liée à chaque transaction dont les valeurs sont stockées dans une table Frais liée à la table transaction

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    Option Explicit
     
    Function stpmp(codeval As Long, Compte As Long, ref As String) As Double
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
    Set base = CurrentDb
    sql = "SELECT DateFormatte, idClient, idProduit, IdTypeTransaction, Quantite, Prix FROM 2TransactionBis " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
    Set mesvaleurs = base.OpenRecordset(sql)
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            If Stock = 0 Then
            pmp = mesvaleurs![Prix]
            Stock = mesvaleurs!Quantite
            Else
            pmp = ((pmp * Stock) + (mesvaleurs![Quantite] * mesvaleurs![Prix])) / (Stock + mesvaleurs!Quantite)
            Stock = Stock + mesvaleurs!Quantite
            End If
       Else
            pmp = pmp
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
    Wend
    stpmp = Round(pmp, 5)
    End Function
     
     
    Function stpmpnet(codeval As Long, Compte As Long, ref As String) As Double
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
    Set base = CurrentDb
    sql = "SELECT DateFormatte, idClient, idProduit, IdTypeTransaction, Quantite, Prix, TotalFrais FROM 2TransactionBis " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
    Set mesvaleurs = base.OpenRecordset(sql)
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            If Stock = 0 Then
            pmp = mesvaleurs![Prix] + (mesvaleurs![TotalFrais] / mesvaleurs!Quantite)
            Stock = mesvaleurs!Quantite
            Else
            pmp = ((pmp * Stock) + ((mesvaleurs![Quantite] * mesvaleurs![Prix]) + mesvaleurs![TotalFrais])) / (Stock + mesvaleurs!Quantite)
            Stock = Stock + mesvaleurs!Quantite
            End If
       Else
            pmp = pmp
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
    Wend
    stpmpnet = Round(pmp, 5)
    End Function
     
     
    Function stockp(codeval As Long, Compte As Long, ref As String) As Double
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Set base = CurrentDb
    sql = "SELECT DateFormatte, idClient, idProduit, IdTypeTransaction, Quantite, Prix FROM 2TransactionBis " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
    Set mesvaleurs = base.OpenRecordset(sql)
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            Stock = Stock + mesvaleurs!Quantite
       Else
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
    Wend
    stockp = Stock
    End Function
    Ces fonctions donne le PAMP de la précedente transaction lorsque la derniere transaction est une vente du solde des parts, ainsi avec un nombre de part, apres vente, à 0 on a sur la ligne le pamp d'avant et on peut calculer la performance de la vente. Lors de l'achat suivant, on repartira avec un PAMP à 0.

    Ainsi ce code fonctionne au top, la seule chose est que l'on utilise 3 requetes lourdes pour le calculer de stockp,stpmpnet et stpmp. Avec bcp de transactions, ca alourdie pas mal et le processeur passe vite à 100%.

    N'y aurait t-il pas moyen, de recuperer plusieurs valeurs à partir d'une simple boulce ou fonction du style:

    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
    25
    26
    27
    28
    Function stpmp(codeval As Long, Compte As Long, ref As String) As Double And stockp(codeval As Long, Compte As Long, ref As String) As Double 'on fait une meme fonction de calcul et on recupere soit le stock soit le pmp
    Dim base As DAO.Database
    Dim mesvaleurs As DAO.Recordset
    Dim sql As String
    Dim Stock As Long
    Dim pmp As Double
    Set base = CurrentDb
    sql = "SELECT DateFormatte, idClient, idProduit, IdTypeTransaction, Quantite, Prix FROM 2TransactionBis " & _
    "WHERE (DateFormatte <= " & ref & ") And ( idProduit = " & codeval & " ) And ( idClient = " & Compte & " )ORDER BY DateFormatte;"
    Set mesvaleurs = base.OpenRecordset(sql)
    While Not mesvaleurs.EOF
       If mesvaleurs![IdTypeTransaction] = "1" Then
            If Stock = 0 Then
            pmp = mesvaleurs![Prix]
            Stock = mesvaleurs!Quantite
            Else
            pmp = ((pmp * Stock) + (mesvaleurs![Quantite] * mesvaleurs![Prix])) / (Stock + mesvaleurs!Quantite)
            Stock = Stock + mesvaleurs!Quantite
            End If
       Else
            pmp = pmp
            Stock = Stock - mesvaleurs!Quantite
       End If
    mesvaleurs.MoveNext
    Wend
    stpmp = Round(pmp, 5)
    stockp= Stock 'on recupere egalement le stock dans la meme fonction
    End Function

  20. #20
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    Bonjour,

    j'ai une question un peu simpliste mais bon :
    Les colonnes de la clause WHERE sont-elles indexées ?
    Corrections : C'est une requête !

    les 3 fonctions sont pratiquements identiques et je ne vois ce qui coince pour n'en faire qu'une ?
    Corrections : Sont-elles appelées directement d'une requête ?

    Si je suis à côté de la plaque il faut me le dire car je prends le fil de la discussion en cours !

    Philippe

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Optimisation du code avec recordset
    Par bakman dans le forum VBA Access
    Réponses: 2
    Dernier message: 01/08/2012, 18h01
  2. [Optimisation][Fonction]calcul du nombre de jours ...
    Par m-mas dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 26/10/2005, 14h39
  3. Optimisation de tournées avec contraintes
    Par DelphiManiac dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 25/10/2005, 11h35
  4. Optimisation de requête avec Tkprof
    Par stingrayjo dans le forum Oracle
    Réponses: 3
    Dernier message: 04/07/2005, 09h50
  5. Réponses: 2
    Dernier message: 22/03/2004, 10h50

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