kwentinn
Messages postés27Date d'inscriptionmardi 13 mai 2003StatutMembreDernière intervention29 mars 2004
-
22 mars 2004 à 14:57
kwentinn
Messages postés27Date d'inscriptionmardi 13 mai 2003StatutMembreDernière intervention29 mars 2004
-
29 mars 2004 à 22:26
Salut à tous!
J'ai un programme qui doit utiliser un thread. J'ai donc créé un nouveau Thread, une nouvelle unité qui contient son code, et j'ai adapté mon code qui se faisait sur un bouton à ce thread. Actuellement, le thread n'arrive pas à fonctionner; j'ai l'impression qu'il s'arrête une dizaine de lignes après avoir démarré. Je vous met un bout du source de mon thread:
unit UThreadTraitement;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComObj, OleServer, Excel2000, Gauges, Menus, IniFiles;
type
ThreadTraitement = class(TThread)
private { Déclarations privées }
procedure UpdateProgress;
protected
procedure Execute; override;
end;
var itemIndex: integer;
implementation
{ Important : les méthodes et propriétés des objets de la VCL peuvent uniquement
être utilisés dans une méthode appelée en utilisant Synchronize, comme :
Synchronize(UpdateCaption);
où UpdateCaption serait de la forme
procedure ThreadTraitement.UpdateCaption;
begin
Form1.Caption := 'Mis à jour dans un thread';
end; }
{ ThreadTraitement }
uses Utypes, Unit1;
{ --- variables locales au thread -------------------------------------------- }
var
i,j, modelepos: integer;
StrTmp: String;
Checked: boolean; { note si la case à cocher est cochée ou non }
{ ---------------------------------------------------------------------------- }
{ ---------------------------------------------------------------------------- }
procedure ThreadTraitement.UpdateProgress;
begin
mainform.gauge1.Progress := mainform.Gauge1.Progress + 1;
end;
{ ---------------------------------------------------------------------------- }
{ - EXECUTION DU THREAD ---------------------------------------------------- }
procedure threadtraitement.execute;
var
vide: integer; { note le nb de lignes vides }
NonValide: integer; { note le nb de lignes non valides càd supprimées }
Dialogue : integer; { enregistre le choix de l'utilisateur }
DelLine : Boolean; { variable permettant de savoir si la ligne en cours est
à supprimer ou non }
OuiPourTout: Boolean; { var permettant de savoir si on affiche la boite de
dialogue de confirmat° en cas d'erreur sur la ligne }
NonPourTout : Boolean;{ permet de savoir si la boite de dialogue doit être
affichée et enregistre l'action à effectuer }
OLEOpened: boolean; { permet de savoir si l'objet OLE a été ouvert ou non }
Begin
//utiliser le modèle sélectionné pour la boucle for i:=1 to nbcolonnes
//initialisation des variables:
NonValide := 0;
OuiPourTout := False;
NonPourTout := False;
{utilisation d'un bloc try ... except pour intercepter les erreurs }
try
//initialisation des variables:
Infos.RefArt := '';
Infos.RefFour := '';
Infos.Des := '';
Infos.PA := 0;
{ ------ boucle qui parcourt ttes les lignes du fichier excel -------------- }
For i := 1 to NbLignesXL Do
begin//3
//la jauge est incrémentée de 1 à chaque passage:
synchronize(updateProgress);
//réinitialisation des variables:
StrTemp := '';
vide := 0;
Infos.Des :='';
Infos.RefArt := '';
Infos.RefFour := '';
{ ---- boucle qui parcourt ttes les colonnes d'1 ligne ----------------- } For j :1 to Modele.NbCol do //de i 1 jusqu'au nbre de col du modèle
Begin//4
{ on utilise StrTemp (Chaîne temporaire) qui contient
le contenu de la case en cours du fichier excel ouvert }
{ on récupère les infos de la feuille XL via le
tableau dynamique }
StrTemp := TabDyn[i,j];
If StrTemp = '' Then//StrTemp est vide
vide := vide + 1 { lorsqu'un champ est vide, on ajoute 1 à vide }
Else
Begin//5
If mainform.CheckBox1.Checked Then
SearchMotCle(FileMotsCles,MotCle,DelLine)
ELSE
Begin //checked
{ j est la position en cours lue
si j = au n° d'1 champ , alors on enregistre
son contenu...Mais attention aux exceptions..
(on utilise delchar pour suppr les car illégaux):
ici, on aurait pu utiliser un case, mais il
n'est pas accepté par delphi pr des var
de type entier}
{ Champ Référence Fournisseur : }
If j = Modele.RefFour Then
begin
DelChar(StrTemp);
Infos.RefFour := StrTemp;
end
Else
{ champ Référence Article : }
If j = Modele.RefArt Then
Begin
DelChar(StrTemp);
Infos.RefArt := StrTemp;
StrTemp := '';
End
Else
{ champ désignation: }
If j = modele.Des then
begin
Infos.Des := StrTemp;
StrTemp := '';
end
else
{ Champ Prix d'achat : }
if j = modele.PA then
begin //p.a.
Try
Infos.PA := StrToFloat(StrTemp);
StrTemp := '';
Except On EConvertError Do
begin
{ si l'utilisateur a cliqué sur le bouton 'Oui pour tout'
alors on n'affiche pas la boite de dialogue et on
supprime la ligne }
If OuiPourTout = True Then
DelLine := True
Else
{ S'il a choisi 'non pour tout' alors on n'affiche pas la
boite de dialogue et on ne supprime pas la ligne}
If NonPourTout = True Then
begin
DelLine := False;
infos.PA := 0;
end
Else
{ Cas où l'utilisateur n'a pas encore eu la boite de dialogue
de confirmation } If (OuiPourTout false) AND (NonPourTout false) Then
Begin
{ la variable dialogue enregistre le choix de l'utilisateur:
oui: dialogue = 6
non: dialogue = 7
oui pour tout: dialogue = 10
non pour tout: dialogue = 9 }
dialogue := MessageDlg('A la ligne ' + IntToStr(i) + ', il y a une erreur de type.' +#10+#13+ 'Pour le champ "Prix d''achat", la valeur entrée est '+ StrTemp + #10+#13+ 'Cette ligne contient les informations suivantes :'+ #10 + #13 + 'Référence Article :' + Infos.RefArt + #10 + #13 +'Référence Fournisseur:' + Infos.RefFour + #10 + #13 + 'Désignation: ' + Infos.Des + #10+#13+ 'Prix d''achat:' + StrTemp +#10+#13+ 'Voulez-vous supprimer cette ligne?',mtConfirmation,[mbYesToAll,mbNoToAll,mbNo,mbYes],0);
If dialogue = 6 Then
DelLine := True
Else
If dialogue = 7 then
begin
DelLine := False;
infos.PA := 0;
end
Else
If dialogue = 10 then
OuiPourTout := True
Else
If dialogue = 9 then
NonPourTout := False;
End;
end;
End;//try
end;//p.a.
End; //checked
End;//5
End;//4
{ ------ fin du parcours des colonnes du fichier --------------------- }
//si les chps les + importants sont vides, on suppr la ligne If (Infos.Des '') and (infos.RefArt '')
and(Infos.RefFour = '') Then
DelLine := True;
//si vide = le nb de col du modèle, alors
//la ligne est ignorée
If vide = Modele.NbCol Then
DelLine := True
Else
//s'il n'y a qu'un champ de rempli, on demande à l'utilisateur
If vide = Modele.NbCol - 1 Then
begin
{Permettre à l'utilisateur de choisir oui pour tous:
Par ex avec une variable de type booléen} If (OuiPourTout False) AND (NonPourTout False) Then
Begin
{ boite de dialogue demandant à l'utilisateur s'il
faut supprimer la ligne ou non:}
{ la variable dialogue enregistre le choix de l'utilisateur:
oui: dialogue = 6
non: dialogue = 7
oui pour tout: dialogue = 10
non pour tout: dialogue = 9 }
Dialogue := MessageDlg(IntToStr(vide) + ' champs (sur ' + IntToStr(Modele.NbCol) + ') de la ligne ' + IntToStr(i)+ ' sont vides.'+ #10+#13+'Cette ligne contient les informations suivantes :'+ #10 + #13 + 'Référence Article :' + Infos.RefArt + #10 + #13 +'Référence Fournisseur:' + Infos.RefFour + #10 + #13 + 'Désignation: ' + Infos.Des + #10+#13+ 'Prix d''achat:' + FloatToStr(Infos.PA) +#10+#13+ 'Voulez-vous supprimer cette ligne?',mtConfirmation,[mbNo,mbYes,mbYesToAll,mbNoToAll],0);
If Dialogue = 6 Then // oui
DelLine := True
Else
If Dialogue = 7 Then // non
DelLine := False
Else
If Dialogue = 10 Then // oui pour tout
OuiPourTout := True
Else
If Dialogue = 9 Then // non pour tout
NonPourTout := True;
End
Else
If OuiPourTout = True Then
DelLine := True
Else
If NonPourTout = True Then
DelLine := False;
end;
If DelLine = False Then
begin
If Modele.PA = 0 Then { on n'écrit pas le p.a. }
SL.Add(Infos.RefArt + #9 + Infos.RefFour + #9 + rien + #9 + Rien + #9
+ Rien + #9 + Rien + #9 + Rien + #9 + Rien + #9 + Rien + #9 + Rien
+ #9 + Rien + #9 + Rien + #9 + Rien + #9 + Infos.Des + #9 +
Modele.ProdFam + #9 + rien + #9 + rien + #9 + '2')
Else
SL.Add(Infos.RefArt + #9 + Infos.RefFour + #9 + FloatToStr(Infos.PA)
+ #9 +Rien + #9 + Rien + #9 + Rien + #9 + Rien + #9 + Rien + #9 +
Rien + #9 + Rien + #9 + Rien + #9 + Rien + #9 + Rien + #9 + Infos.Des
+ #9 + Modele.ProdFam + #9 + rien + #9 + rien + #9 + '2');
end
Else
NonValide := NonValide + 1; { suppression de la ligne: on n'écrit rien }
end;//3
{ ----- fin du parcours du tableau dynamique ------------------------------- }
mainform.ComboBox1.Clear; //efface le contenu de la combobox
MessageDlg('Nombre de ligne(s) supprimée(s) : ' + IntToStr(NonValide)+ #13+ 'Nombre de lignes écrites: '+ IntToStr(SL.Count) + #10 + #13 + 'Opération Terminée'+#13+ 'Veuillez sélectionner un fichier pour sauvegarder.',mtInformation,[mbOK],0);
If mainform.SaveDialog1.Execute Then
SL.SaveToFile(mainform.SaveDialog1.FileName); //sauvegarde la stringlist dans un fichier texte
mainform.gauge1.Progress := 0;
mainform.gauge1.MaxValue := 1;
mainform.gauge1.Visible := False;
MainForm.Close;//ferme la fenêtre
CloseFile(FCI);
except
begin
MessageDlg('Une erreur s''est produite...',mtError,[mbOk],0);
exit;
end;
end ;
end;
{ ---------------------------------------------------------------------------- }
end.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 22 mars 2004 à 20:47
Le code est complètement à revoir sauf la procédure UpdatProgress.
Dans la méthode Executre du thread, tu fais des références à Mainform alors que Borland précise ceci :
{ Important : les méthodes et propriétés des objets de la VCL peuvent uniquement être utilisés dans une méthode appelée en utilisant Synchronize, comme :
Synchronize(UpdateCaption);
où UpdateCaption serait de la forme
procedure ThreadTraitement.UpdateCaption;
begin
Form1.Caption := 'Mis à jour dans un thread';
end; }
Libre à chacun de ne pas tenir compte de cet avertissement mais, dans ce cas, il ne faut pas s'étonner qu'un thread secondaire batte de l'aile.
Enfin, comme le corps de la méthode Execute fait appel à des variables, structures ou objets déclarées (dans d'autres unités ? voir Infos, par exemple), il est difficile d'aider davantage que de donner des recommandations.
Un ultime conseil : pour améliorer la lisibilité du code et son efficacité, il serait judicieux de remplacer des constructions à base de if à rallonge par des structures Case comme :
If dialogue = 6 Then
DelLine := True
Else
If dialogue = 7 then
begin
DelLine := False;
infos.PA := 0;
end
Else
If dialogue = 10 then
OuiPourTout := True
Else
If dialogue = 9 then
NonPourTout := False;
kwentinn
Messages postés27Date d'inscriptionmardi 13 mai 2003StatutMembreDernière intervention29 mars 2004 23 mars 2004 à 07:44
Merci bien de me donner ces précieux conseils!!! :) Je vais essayer de mettre en pratique ce que tu m'as dit, je pense que ça devrait marcher :)
"Le code est complètement à revoir sauf la procédure UpdatProgress." > oula j'espère que je vais pas tout me retaper... car sinon ça serait vraiment bien long...
kwentinn
Messages postés27Date d'inscriptionmardi 13 mai 2003StatutMembreDernière intervention29 mars 2004 29 mars 2004 à 22:26
J'ai passé pas mal de temps à essayer de déboguer le thread, mais rien n'y fait! ça ne marche pas... Si qqn a la solution miracle, qu'il me la donne, sinon, je mettrai pas de thread dans mon prog..