|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Bonjour à tous!
J'essaie actuellement d'encapsuler un traitement (calcul de balance comptable) assez long dans mon appli. La création d'un thread me paraît indiquée dans ce cas et j'ai donc mis en place les déclarations et la fonction AddrOf(fonction) dans mon code. A la compil, pas de problème. L'appel de la fonction se fait correctement, mais il me semble avoir un problème avec la fonction "GetCurrentVbaProject(hProject)" (appelée depuis la fonction AddrOf): à sa sortie la variable hProject a toujours la valeur 0 et le traitement ne se poursuit pas, bien sûr. J'avoue que j'utilise ce code "copié-collé" depuis la FAQ sans le comprendre entièrement, mais pour ce que j'en sais, il pourrait résoudre mon problème. Je soupçonne que le problème se trouve dans l'appel de la fonction reproduit ci-après: Code :
.En l'attente de vos conseils éclairés, merci d'avance. |
||
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() Inscription : avril 2006 Messages : 1 050 ![]() |
Bonjour,
si je comprends ton code, tu crées un thread pour ta procédure de création de thread ?? Il est peut-être heureux que ton code n'a pas fonctionné. La fonction AddrOf n'est-elle pas censée être l'équivalent Access97 de l'instruction VBA AddressOf des versions suivantes renvoyant l'adresse d'une fonction (pour les procédures je ne suis pas sûr) publique. |
|
|
00
|
|
|
#3 | ||||
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
En fait je crée un thread qui appelle un "sub" qui lui même calcule enregistrement par enregistrement, le solde (débit-crédit) d'une table 401-fournisseurs.
J'ai effectivement trouvé le post suivant: http://www.developpez.net/forums/d56...sation-thread/ et modifié mon code en conséquence sans plus de succès. (viré les références à vba332.dll) et remplacé l'appel de AdrOf par AddressOf). Pour répondre à ta question: j'avais une procédure appelée "CalculBalance411Solid" dont j'ai coupé-collé le code dans "CalculBalance411SolidThread": j'appelle cette dernière comme suit: Code :
Code :
)
|
||||
|
|
00
|
|
|
#4 |
|
Membre éprouvé
![]() Anthony SchrickeDéveloppeur informatique Inscription : juin 2008 Messages : 342 ![]() |
Bonsoir,
Si je me rappelle de ce que j'avais fait fait sur les thread, il y a fort longtemps, une fois le thread créé il est nécessaire de le lancer. Attention aussi à ce que le code appellant reste chargé en mémoire durant l'éxection du thread sinon on obtiens un thread orphelin et là ... bonjour l'état de la mémoire. Il faut savoir que les deux principaux systèmes d'exploitations ne possèdent pas de "garbage collector" pour nettoyer ces threads orphelins. Il faut aussi s'assurer à la désallocation du code parent de la bonne désallocation du thread en mémoire. Ce qui est très probablement fait avec Un autre aspect très important en ce qui concerne les threads est le mécanisme de ressources. Un thread peu consommer / produire une / plusieurs ressources. La difficulté de la programmation par thread est de ne pas se trouver en conditions d'interblocage ce qui paralyserai l'ordinateur (et non pas simplement access) surtout à cause (de mémoire) de l'attente active sur la ressource. Il faut aussi penser au mécanisme des interruptions pour pas que le thread s'arrête à l'instant t ou il ne devrait jamais s'arrêter. C'est surtout critique pour les systèmes embarqués. Pour adressOf ce n'est qu'une instruction qui permet d'avoir l'adresse en mémoire du début d'un objet / d'une fonction. Attention aussi au rôle des CallBack qui sont un mécanisme important des threads. Toujours de mémoire, ces méthodes sont les méthodes principale / de démarrage du thread. Elles sont analogues au main en C / C++ / Java et elle doivent très probablement respecter une signature particulière. J'espère avoir été utile et avoir permis diriger la reflexion vers la solution pour votre problème. Cordialement,
__________________
loi de LeBlanc : Plus tard signifie jamais. extrait de Coder proprement Auteur:Robert C. Martin |
|
|
00
|
|
|
#5 | ||
|
Membre Expert
![]() Inscription : avril 2006 Messages : 1 050 ![]() |
Ok, tu fais trop régulièrement appel au DoEvents dans ton code ce qui ralentit l'exécution du code.
Pour faire simple, ton formulaire n'a en fait besoin d'être rafraichi qu'après chaque 1% de tâche accomplie. Soit un test du genre : Code :
Je ne crois pas qu'il soit suffisant de créer un thread pour qu'il s'exécute pour autant, à voir ? Sinon, il y a ici une première ébauche de simulation de multithreads sans threads. |
||
|
|
00
|
|
|
#6 |
|
Membre éprouvé
![]() Anthony SchrickeDéveloppeur informatique Inscription : juin 2008 Messages : 342 ![]() |
J'ai trouvé en première partie d'un article la définition d'un thread
http://alwin.developpez.com/tutorial/JavaThread/ Un thread doit être démarrer pour qu'il puisse fonctionner. A la création d'un thread, des arguments obligatoires et le plus important est celui de la routine. La routine d'éxecution est une méthode qui serra executée tant que le thread serra en vie et actif. C'est à dire qu'il n'y a pas besoin d'écrire de boucle à l'intérieur du code de la routine. Dans l'exemple du premier article cité il s'agit des CallBacks. Donc par exemple, une routine qui aurait ce code : Passe toute sa vie à incrémenter la variable i qui soit dit en passant doit être accessible donc déclarée au minimum static. Pour la programmation de threads, la difficulté est de gérer les problèmes d'accès concurentiels aux ressources (par exemple la variable i). Ce qui dans le cas présent concerne tous les objets manipulés à l'intérieur de la routine. Les objets manipulés sont des objets Access et la routine va s'éxecuter de manière totalement indépendante du contexte d'execution. Donc l'accès à des objets d'Access risquent fortement d'être compromis. Le paramètre pour la routine est un pointeur sur fonction (j'ai donc de sérieux doutes concernant une Sub qui est une procedure). D'où la méthode AddrOf de l'article, à éventuellement remplacer par AddressOf dans les versions d'Access plus récentes. La méthode AddrOf calcule l'adresse mémoire de la première instruction à éxecuter d'une méthode passée en paramètre. La mise en place d'un traitement lourd dans un thread n'est pas chose facile. L'utilisation du thread ici serrai de prendre en charge uniquement le calcul mathématique des données à traiter. Cordialement,
__________________
loi de LeBlanc : Plus tard signifie jamais. extrait de Coder proprement Auteur:Robert C. Martin |
|
|
00
|
|
|
#7 |
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Merci Ilank et Tonioyo de vos réponses,
Je vais essayer d'utiliser vos réponses dans mon appli. Même si le thread s'avère difficile à mettre en place dans ce contexte, j'ai réussi à diminuer le temps de traitement du calcul des balances de moitié .Cela dit je m'enferre peut-être sur cette voie ??? Il existe peut-être une méthode simple pour effectuer ce genre de calculs. En gros une colonne débit, une colonne crédit et une colonne balance: basiquement, balance= somme(débit - crédit). Ce qui plombe ce calcul c'est l'utilisation de fonctions de domaine au lieu de SQL. Merci encore de votre intéret. |
|
|
00
|
|
|
#8 | ||
|
Membre Expert
![]() Inscription : avril 2006 Messages : 1 050 ![]() |
Bonjour,
je n'y connais pas grand chose en compta, pourquoi affectes-tu à chaque ligne la balance totale d'une date donnée. De plus, la balance étant un champ calculé tu peux aisément t'en penser dans la table, il s'agît plus d'un champ supplémentaire dans une requête de présentation. Code :
|
||
|
|
00
|
|
|
#9 |
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Merci Ilank pour ta réponse rapide,
(En plus j'ai apris une syntaxe que je ne connaissais pas en posant un alias sur un nom de table -A - B). Cela dit, une balance comptable permet d'avoir la position d'un compte à une date donnée (tenant compte, bien sûr de l'antériorité). ce qui, basiquement veut dire que si hier, mon solde chez tel ou tel tiers dans ma compta, était de : hier (débit=20 - crédit=10)= balance = 10 aujourd'hui (débit=10 - crédit=15)= balance = 5 (et non -5) Le top serait d'avoir une requête mise à jour qui me permettrait de calculer et mettre à jour la balance de toute la table en une seule opération SQL (rapide). Merci encore |
|
|
00
|
|
|
#10 | ||
|
Membre Expert
![]() Inscription : avril 2006 Messages : 1 050 ![]() |
Bonjour,
d'accord la requête devrait plus ressembler à ceci : Code sql :
|
||
|
|
00
|
|
|
#11 | ||
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Bonjour ilank
Je me suis emballé un peu vite ce matin en considérant ta réponse comme valable. Tout compte fait lorsque je regarde les valeurs renvoyées par ta requête j'ai quelque chose de la forme Code :
|
||
|
|
00
|
|
|
#12 |
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Je continue de chercher une solution "pure SQL": peux-tu me commenter ton:
dans le "LEFT JOIN" du "FROM" ? le QBE ne pouvant pas représenter ce type de requêtes, je me trouve un peu désarmé pour le bidouiller... |
|
|
00
|
|
|
#13 |
|
Membre Expert
![]() Inscription : avril 2006 Messages : 1 050 ![]() |
Bonsoir,
Code sql :
B.CCpt=A.CCpt AND B.CCDat<=A.CCDat C'est sûrement le critère qui pose problème puisqu'il limite la balance par compte. |
|
|
00
|
|
|
#14 |
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Bonsoir,
Le champ CCpt est un auto-incrément, clé unique de cette table , je ne pense pas qu'il puisse poser un problème dans le LEFT JOIN dans ce cas. Ou alors quelque chose m'échappe? Pour moi ce qui semble ne pas s'effectuer comme opération c'est le critère de la jointure: et d'ailleurs ce qui s'affiche dans le champ "Balance" est issu du Débit-Crédit de la même ligne, sans tenir compte des dates antérieures. Pour info j'y ai passé l'après-midi en essayant plusieurs variantes dont la création de requêtes temporaires "A" et "B" sur lesquelles porte ton bout de code, sans plus de résultat...
|
|
|
00
|
|
|
#15 | ||
|
Membre Expert
![]() Inscription : avril 2006 Messages : 1 050 ![]() |
Bonjour,
si le champ CCpt est unique dans la table, le critère de jointure Code sql :
B.CCpt=A.CCpt AND B.CCDat<=A.CCDat La requête doit être : Code sql :
|
||
|
|
00
|
|
|
#16 |
|
Membre actif
![]() Richard Ingénieur développement logiciels Inscription : août 2004 Messages : 166 ![]() |
Effectivement,
J'ai modifié en ce sens la requête ce matin dès mon arrivée au bureau. Cà a l'air de fonctionner car la requête se lance sans tousser, par contre j'ai dû l'interrompre car le temps de traitement est encore plus long que par code (sur une table qui pour l'instant ne comporte que 5300 lignes). |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com