PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2025 → La vitesset d'affichage et la fonction Thread()
La vitesset d'affichage et la fonction Thread()
Iniciado por Devnet2001, 26,dic. 2015 10:08 - 13 respuestas
Publicado el 26,diciembre 2015 - 10:08
Bonjour,

J'aurai besoin de votre expèrience en developpement.

Je voudrais bien afficher un etat d'évaluation du stock à partir d'un fichier "ARTICLES" qui contient 87000 articles en calculant le stock de chaque article (je mémorise pas le stock après chaque opération de vente/Retour ou Achat/Retour)
Pour calculer le stock je doit parcourir par reference article les lignes du fichier vente et achat (Stock_article=Vente-Achat)
Automatiquement l'affichage se sera lent, donc j'utilise la fonction ThRead() afin d'optimiser la viteese d'affichage, mais je vois qui il n'y a pas une bonne amilioration au niveau de la vitesse. mon code est comme suit:

// Parcour le fichier ARTICLES
HLitPremier(ARTICLES)
TANTQUE PAS HEnDehors(ARTICLES)
TableauAjouteLigne(table,ARTICLES.Reference,ARTICLES.CodeArticle,...
ARTICLES.ARTICLE,ARTICLES.PrixAch,ARTICLES.RemiseAchat,ARTICLES.TAUXTVA,0) // 0 colonne du stock à calculer
HLitSuivant(ARTICLES)
FenRepeint()
FIN

ThreadMode(threadSectionCritique)

MonStock est une numerique
// Parcour la table des articles pour calculer le stock
POUR TOUT LIGNE K DE Table
SectionCritiqueDébut(ThSt)
ThreadExécute(ThSt,threadNormal,"Stock",nid)
TANTQUE ThreadEtat(ThSt)<>threadInexistant
ThreadPause(10)
FIN
SectionCritiqueFin(ThSt)

col_stock=MonStock // ci dessous
FenRepeint()
FIN

// Procedure Stock

HExécuteRequête(REQ_StkDep_V,hRequêteDéfaut,pnArticle)
HLitPremier(REQ_StkDep_V,hSansRafraîchir)
SI PAS HEnDehors(REQ_StkDep_V)
QV=REQ_StkDep_V.la_somme_Quantite_Livr
FIN
HLibèreRequête(REQ_StkDep_V)

HExécuteRequête(REQ_StkDep_A,hRequêteDéfaut,pnArticle)
HLitPremier(REQ_StkDep_A,hSansRafraîchir)
SI PAS HEnDehors(REQ_StkDep_A)
QA=REQ_StkDep_A.la_somme_Quantite_Livr
FIN

HLibèreRequête(REQ_StkDep_A)

MonStock=QV-QA

Donnez moi s'il vous plait une piste
Merci d'avance
Miembro registrado
148 mensajes
Publicado el 27,diciembre 2015 - 00:25
Bonjour

Je vois que votre code ne contient pas des erreurs de code.
je propose de tester ça peut-être la vitesse de l'affichage s'améliore

HLitPremier(ARTICLES)
TANTQUE PAS HEnDehors(ARTICLES)

SectionCritiqueDébut(ThSt)
ThreadExécute(ThSt,threadNormal,"Stock",nid)
TANTQUE ThreadEtat(ThSt)<>threadInexistant
ThreadPause(10)
SectionCritiqueFin(ThSt)

TableauAjouteLigne(table,ARTICLES.Reference,ARTICLES.CodeArticle,...
ARTICLES.ARTICLE,ARTICLES.PrixAch,ARTICLES.RemiseAchat,ARTICLES.TAUXTVA,MonStock )

HLitSuivant(ARTICLES)
FenRepeint()
FIN

bondev

--
FETOUI MOHAMED
Développeur, Consultant et Formateur WinDev, WebDev et WinDev Mobile
fib.fetouimed@gmail.com
https://www.linkedin.com/pub/mohamed-el-fetoui/a0/680/109
MAROC+212(0)661249774
Miembro registrado
2.682 mensajes
Publicado el 27,diciembre 2015 - 06:55
Bonjour,

Est-il possible d'avoir le code la requête que vous exécutez ? Parce que faire 2 requêtes par article c'est extrêmement pénalisant en terme de ressources.

Personnellement, je ne ferai qu'une requête qui renverrait la totalité des valeurs vendues et achetées par article, et je parcourrai cette source de donnée. Je pense même que dans ce cas le thread n'a plus aucune utilité.

Je ferai quelque chose comme ça
SELECT ARTICLES.Reference,ARTICLES.CodeArticle,ARTICLES.ARTICLE,ARTICLES.PrixAch,ARTICLES.RemiseAchat,ARTICLES.TAUXTVA,
(SELECT SUM(qte) FROM table_vente WHEREtable_vente.CodeArticle = ARTICLES.CodeArticle) AS QteVendue,
(SELECT SUM(qte) FROM table_achat WHERE table_achat.CodeArticle = ARTICLES.CodeArticle) AS QteAchetée
FROM ARTICLES


Tu dois pouvoir exécuter cette requête comme ceci, sans assurance que cela fonctionne. Windev est capricieux au niveau des requêtes.
HExécuteRequêteSQL(ReqClient,hRequêteSansCorrection,connexion,texte_requete)


Si ça ne fonctionne pas, une autre solution est faire ta requête de cette manière (le code est surement à retoucher, je le fais à main levée):
SELECT CodeArticle,'V',SUM(qte) AS Qte FROM table_vente GROUP BY CodeArticle,'V'
UNION
SELECT CodeArticle,'A',SUM(qte) AS Qte FROM table_achat GROUP BY CodeArticle,'A'
ORDER BY 1,2


Tu charges tes données dans une table mémoire ou un tableau d'une structure définie à l'avance.
Tu exécutes ta requête, tu la parcours et tu recherches tes données dans la table ou le tableau et tu ajoutes ou retires les valeurs en fonction de ce dont tu as besoin.

Cordialement,

Philippe SAINT-BERTIN
Publicado el 28,diciembre 2015 - 08:30
Bonjour

Merci M Fetoui et M Philippe pour vos réponses.

Pour le code de 2 requêtes (REQ_Vente,REQ_Achat sont des requêtes stockée) est comme suit :

// Je demande la somme des quantités vendue à partir du fichier "LigneVente"
SELECT
SUM(LigneVente.QuantiteVendue) AS la_somme_QuantiteVendue
FROM
LigneVente
WHERE
LigneVente.Reference = {P_refArt}
AND LigneVente.Annee = {P_année}

//Dans une procédure stockée, j'affecte la somme de quantités dans une variable QV
HExécuteRequête(REQ_Vente,hRequêteDéfaut,pnArticle,pAnnée)
HLitPremier(REQ_Vente,hSansRafraîchir)
SI PAS HEnDehors(REQ_Vente)
QV=REQ_Vente.la_somme_Quantite
FIN
HLibèreRequête(REQ_Vente) // je libère ma requête

// Je demande la somme des quantités achetée à partir du fichier "LigneAchat"
SELECT
SUM(LigneAchat.QuantiteAchete) AS la_somme_QuantiteAchete
FROM
LigneAchat
WHERE
LigneAchat.Reference = {P_refArt}
AND LigneAchat.Annee = {P_année}

//Dans une procédure stockée, j'affecte la somme de quantités dans une variable QA
HExécuteRequête(REQ_Achat,hRequêteDéfaut,pnArticle,pAnnée)
HLitPremier(REQ_Achat,hSansRafraîchir)
SI PAS HEnDehors(REQ_Achat)
QA=REQ_Achat.la_somme_Quantite
FIN
HLibèreRequête(REQ_Achat) // je libère ma requête

// Calcul
StkDispo =QA-QV
RENVOYER StkDispo

Voilà comment j'exécute mes 2 requêtes stockée

Merci de m'adier
Publicado el 28,diciembre 2015 - 09:14
Le 28/12/2015 07:30, Devlo a écrit :
Bonjour
Merci M Fetoui et M Philippe pour vos réponses.

Pour le code de 2 requêtes (REQ_Vente,REQ_Achat sont des requêtes
stockée) est comme suit :
// Je demande la somme des quantités vendue à partir du fichier
"LigneVente"
SELECT SUM(LigneVente.QuantiteVendue) AS la_somme_QuantiteVendue
FROM LigneVente
WHERE LigneVente.Reference = {P_refArt}
AND LigneVente.Annee = {P_année}

//Dans une procédure stockée, j'affecte la somme de quantités dans une
variable QV
HExécuteRequête(REQ_Vente,hRequêteDéfaut,pnArticle,pAnnée)
HLitPremier(REQ_Vente,hSansRafraîchir)
SI PAS HEnDehors(REQ_Vente) QV=REQ_Vente.la_somme_Quantite
FIN
HLibèreRequête(REQ_Vente) // je libère ma requête

// Je demande la somme des quantités achetée à partir du fichier
"LigneAchat"
SELECT SUM(LigneAchat.QuantiteAchete) AS la_somme_QuantiteAchete
FROM LigneAchat
WHERE LigneAchat.Reference = {P_refArt}
AND LigneAchat.Annee = {P_année}

//Dans une procédure stockée, j'affecte la somme de quantités dans une
variable QA
HExécuteRequête(REQ_Achat,hRequêteDéfaut,pnArticle,pAnnée)
HLitPremier(REQ_Achat,hSansRafraîchir)
SI PAS HEnDehors(REQ_Achat) QA=REQ_Achat.la_somme_Quantite
FIN
HLibèreRequête(REQ_Achat) // je libère ma requête

// Calcul
StkDispo =QA-QV
RENVOYER StkDispo
Voilà comment j'exécute mes 2 requêtes stockée

Merci de m'adier



Bonjour à tous.

Pour accélérer le process, il faut déjà diminuer le nombre de
rafraichissement de l'écran (c'est ça le plus lent)

Dans mes boucles, s'il y beaucoup de traitement, je place un compteur et
je ne mets à jour l'affichage qu'une fois sur 100 ou 1000 lectures.

si modulo(lcpt,1000) = 0 alors fenrepeint()

Toute instruction de raffraichissement de l'écran (ou threadpause) ne va
faire que ralentir le traitement.

Ensuite, je ferais une seule requête pour le vente (avec tous les
articles dedans et une seule pour les achats (avec tous les articles dedans)

et ensuite je ferais une lecture ligne à ligne dans chaque requête
pour alimenter mon tableau de résultat.

L'idéal néanmoins serait de rajouter un fichier dans la base de donnée
contenant pour chaque article, le stock, le cumul des entrées et des
sorties et les dates de dernières entrées / sortie, inventaire, ...


Bon dev,

Fred
Miembro registrado
148 mensajes
Publicado el 28,diciembre 2015 - 09:51
Bonjour

Votre méthode peut être se sera rapide si on mémorise dans un fichier par exemple "Stock" le stock final
Mais Devlo dit : (je mémorise pas le stock après chaque opération de vente/Retour ou Achat/Retour)

Pour Les fonctions de rafraichissement oui je suis pour , elles ralentit un tout petit peu le traitement.

Bon dev

--
FETOUI MOHAMED
Développeur, Consultant et Formateur WinDev, WebDev et WinDev Mobile
fib.fetouimed@gmail.com
https://www.linkedin.com/pub/mohamed-el-fetoui/a0/680/109
MAROC+212(0)661249774
Miembro registrado
2.682 mensajes
Publicado el 28,diciembre 2015 - 11:28
Bonjour DEVLO,

Voici ce que je ferai (Attention ce code n'a pas été testé, juste tapé à la volée) :

Une fois le tableau rempli tu peux en faire ce que tu en veux, notamment l'afficher dans une table

nIndiceTableau est un entier

STStock est une structure
Reference est une chaîne
CodeArticle est une chaîne
ARTICLE est une chaîne
PrixAch est un monétaire
RemiseAchat est un monétaire
TAUXTVA est numérique
Stock est un numérique
FIN
tabMonStock est un tableau de STStock

sdSource est une Source de Données
sMaRequete est une chaîne = [
SELECT LigneVente.Reference AS Reference,'V' AS TypeSomme,SUM(LigneVente.QuantiteVendue) AS Qte
FROM LigneVente
WHERE LigneVente.Annee = %1
GROUP BY LigneVente.Reference,'V'

UNION

SELECT LigneAchat.Reference AS Reference,'A' AS TypeSomme,SUM(LigneAchat.QuantiteAchete) AS Qte
FROM LigneAchat
WHERE LigneAchat.Annee = %1
GROUP BY LigneAchat.Reference,'A'

ORDER BY Reference, TypeSomme
]

SI PAS HExécuteRequêteSQL(sdSource,hRequêteDéfaut,ChaîneConstruit(sMaRequete,2015)) ALORS
// Traitement erreur
SINON
FichierVersTableau(tabMonStock,"ARTICLE")
POUR TOUT sdSource
nIndiceTableau = TableauCherche(tabMonStock,tcLinéaire,sdSource.Reference)
SI nIndiceTableau = -1 ALORS
// article non trouvé
// traiter l'erreur
SINON
SI sdSource.TypeSomme = "A" ALORS
tabMonStock[nIndiceTableau].Stock += sdSource.Qte
SINON
tabMonStock[nIndiceTableau].Stock -= sdSource.Qte
FIN
FIN
FIN
FIN


--
Cordialement,

Philippe SAINT-BERTIN
Géode Informatique
Publicado el 28,diciembre 2015 - 13:23
Bonjour

Utiliser un thread ne fera pas gagner de temps... Ca rendra juste
l'interface utilisable pendant la suite des calculs.

Dans tous les cas, l'accès aux données doit se faire et ira à la même
vitesse, que les données soient lu dans le thread principal ou un
secondaire.

Si tu veux améliorer la vitesse, une solution est de stocker le résultat
que tu obtiens ici dans un autre fichier, avec la date/heure de calcul.

De cette manière, lors du calcul suivant, seuls les mouvements plus
récents que cette date heure seront nécessaires pour ajouter/soustraire
au stock à la date...

Et comme tu ne devrais jamais modifier des mouvements anciens ou en
ajouter à une autre date heure que maintenant, ca sera toujours juste...

Un précalcul sans affichage peut même être lancé automatiquement (toutes
les nuits, par exemple, pour traiter les mouvements de la journée).

Cordialement


--
Fabrice Harari
Consultant WinDev, WebDev et WinDev Mobile International

A votre disposition : WXShowroom.com, WXReplication (open source) et
maintenant WXEDM (open source)

Plus d'information sur http://fabriceharari.com



On 12/26/2015 4:08 AM, Devlo wrote:
Bonjour,

J'aurai besoin de votre expèrience en developpement.

Je voudrais bien afficher un etat d'évaluation du stock à partir d'un
fichier "ARTICLES" qui contient 87000 articles en calculant le stock de
chaque article (je mémorise pas le stock après chaque opération de
vente/Retour ou Achat/Retour)
Pour calculer le stock je doit parcourir par reference article les
lignes du fichier vente et achat (Stock_article=Vente-Achat)
Automatiquement l'affichage se sera lent, donc j'utilise la fonction
ThRead() afin d'optimiser la viteese d'affichage, mais je vois qui il
n'y a pas une bonne amilioration au niveau de la vitesse. mon code est
comme suit:

// Parcour le fichier ARTICLES
HLitPremier(ARTICLES)
TANTQUE PAS HEnDehors(ARTICLES)
TableauAjouteLigne(table,ARTICLES.Reference,ARTICLES.CodeArticle,...
ARTICLES.ARTICLE,ARTICLES.PrixAch,ARTICLES.RemiseAchat,ARTICLES.TAUXTVA,0) // 0 colonne du stock à calculer
HLitSuivant(ARTICLES)
FenRepeint()
FIN

ThreadMode(threadSectionCritique)

MonStock est une numerique
// Parcour la table des articles pour calculer le stock
POUR TOUT LIGNE K DE Table
SectionCritiqueDébut(ThSt)
ThreadExécute(ThSt,threadNormal,"Stock",nid)
TANTQUE ThreadEtat(ThSt)<>threadInexistant
ThreadPause(10) FIN
SectionCritiqueFin(ThSt)

col_stock=MonStock // ci dessous
FenRepeint()
FIN

// Procedure Stock

HExécuteRequête(REQ_StkDep_V,hRequêteDéfaut,pnArticle)
HLitPremier(REQ_StkDep_V,hSansRafraîchir)
SI PAS HEnDehors(REQ_StkDep_V) QV=REQ_StkDep_V.la_somme_Quantite_Livr
FIN
HLibèreRequête(REQ_StkDep_V)

HExécuteRequête(REQ_StkDep_A,hRequêteDéfaut,pnArticle)
HLitPremier(REQ_StkDep_A,hSansRafraîchir)
SI PAS HEnDehors(REQ_StkDep_A) QA=REQ_StkDep_A.la_somme_Quantite_Livr
FIN

HLibèreRequête(REQ_StkDep_A)

MonStock=QV-QA

Donnez moi s'il vous plait une piste Merci d'avance
Miembro registrado
1.640 mensajes
Publicado el 28,diciembre 2015 - 14:10
Effectivement une seule requête sera bien plus rapide en exécution.
Une petite précision au passage (que j'ai déjà eu donc autant en faire profiter), pensez à intégrer une date de dernier inventaire avec une quantité inventoriée ;) (cette date deviendra le seuil de recherche dans les factures Vte / Achat)
Ce qui donnera un calcul plus proche de : Qté inventaire - vente + achat !
Publicado el 28,diciembre 2015 - 18:20
Bonsoir

Merci Pour vos réponses, je vais essayez vos méthodes ainsi je vais tester
Publicado el 29,diciembre 2015 - 10:20
Bonjour

J'executer ma requête UNION et j'ai le message :

Erreur à la ligne 47 du traitement Clic sur BTN_Execute.
Vous avez appelé la fonction TableauCherche.
Les valeurs de recherche ne correspondent pas aux paramètres de recherche précisés.

/// le code requete UNION
nIndiceTableau est un entier

STStock est une Structure
Reference est une chaîne
CodeArticle est une chaîne
ARTICLE est une chaîne
PrixAch est un monétaire
RemiseAchat est un monétaire
TAUXTVA est numérique
Stock est un numérique
FIN
tabMonStock est un tableau de STStock

sdSource est une Source de Données
sMaRequete est une chaîne = [
SELECT
FLigneCde.Reference AS Reference,
Sum(FLigneCde.Quantite_Livr) AS Qté
FROM
FLigneCde
WHERE
FLigneCde.Annee = %1
GROUP by
FLigneCde.Reference

UNION

SELECT
FLigneCde_A.Reference AS Reference,
Sum(FLigneCde_A.Quantite_Livr) AS Qté
FROM
FLigneCde_A
WHERE
FLigneCde_A.Annee = %1
GROUP by
FLigneCde_A.Reference
]

SI PAS HExécuteRequêteSQL(sdSource,hRequêteDéfaut,ChaîneConstruit(sMaRequete,2015)) ALORS
// Traitement erreur
SINON

FichierVersTableau(tabMonStock,"FARTICLES")
POUR TOUT sdSource
nIndiceTableau = TableauCherche(tabMonStock,tcLinéairePremier,sdSource.Reference)
SI nIndiceTableau = -1 ALORS
Trace( "article non trouvé" )
// traiter l'erreur
SINON
SI sdSource.TypeSomme = "A" ALORS
tabMonStock[nIndiceTableau].Stock += sdSource.Qte
SINON
tabMonStock[nIndiceTableau].Stock -= sdSource.Qte
FIN
FIN
FIN
FIN

Merci d'avance de m'aider
Miembro registrado
148 mensajes
Publicado el 29,diciembre 2015 - 11:48
bONJOUR

au lieu de nIndiceTableau = TableauCherche(tabMonStock,tcLinéairePremier,sdSource.Reference)
met ça nIndiceTableau = TableauCherche(tabMonStock,tcLinéairePremier, "Reference",sdSource.Reference)

Comme elle dans votre structure
Bon dev

--
FETOUI MOHAMED
Développeur, Consultant et Formateur WinDev, WebDev et WinDev Mobile
fib.fetouimed@gmail.com
https://www.linkedin.com/pub/mohamed-el-fetoui/a0/680/109
MAROC+212(0)661249774
Publicado el 29,diciembre 2015 - 11:53
Bonjour


Merci Me FETOUI , ça marche trés bien

Oups, je n'ai pas fait attention


Merci
Publicado el 05,septiembre 2020 - 08:05
j'ai aussi tout fonctionne parfaitement depuis la première fois l'installation et la mise à jour