Bonjour à tous,
J'ai écris un code qui me permet récupérer des données d'une base de données distante et de les insérer dans une BD locale.
Le problème, c'est que quand je lance la reconstitution de ma BD, toute l'application reste indisponible jusqu'à la fin du processus alors que j'aimerai utiliser les autres fonctionnalités pendant que ce processus s'exécute.
En résumé, j'aimerai savoir comment lancer cette tâche en arrière plan et avoir la possibilité de l'arrêter au besoin.
J'utilise Delphi 7 et SQL Server.
Je remercie par avance toute personne qui pourrait m'apporter une quelconque aide.
Voici mon code :
Procedure ExportToExcel(aGrid : TDBGrid);//Export vers ma bd locale
Var
I, J, nb_jrnl, nb_enreg: Integer;
Begin
with DM do
BEGIN//1
TListeTable.Close;
TListeTable.Open;
if not TListeTable.IsEmpty then
begin//1.1
TListeTable.First;
nb_enreg := TListeTable.RecordCount;
for j := 1 to nb_enreg do
begin//2
/////////////
//Préparation du fichier à télécharger
TFichier.Active := False;
TFichier.TableName := 'MON_EMPLACEMENT.'+TListeTable.FieldValues['code_table'];
TFichier.Open;
//Fin Préparation du fichier à télécharger
if not TFichier.IsEmpty then
begin//3
TFichier.First;
//Préparation de la table à charger
TTampon.Close;
TTampon.TableName := 'dbo.'+TListeTable.FieldValues['code_table'];
TTampon.Open;
if not TTampon.IsEmpty then
begin
TTampon.Close;
TTampon.EmptyTable;
TTampon.Open;
end;
//Fin Préparation de la table à charger
//Historiq_bebut
TJournal.Close;
TJournal.Open;
if TJournal.IsEmpty then
begin
TJournal.Insert;
nb_jrnl := 1;
TJournal.FieldByName('num_journal').AsInteger := nb_jrnl;
TJournal.FieldByName('nom_table').AsString := TListeTable.FieldValues['code_table'];
TJournal.FieldByName('debut_chargement').AsDateTime := Date()+Time();
TJournal.Post
end
else
begin
TJournal.Last;
nb_jrnl := TJournal.FieldValues['num_journal'] + 1;
TJournal.Insert;
TJournal.FieldByName('num_journal').AsInteger := nb_jrnl;
TJournal.FieldByName('debut_chargement').AsDateTime := Date()+Time();
TJournal.FieldByName('nom_table').AsString := TListeTable.FieldValues['code_table'];
TJournal.Post
end;
//Fin Historiq_bebut
//Transaction
if DM.dbLocal.InTransaction then DM.dbLocal.Rollback;
DM.dbLocal.StartTransaction;
try
//Remplissage de la table concernée
While Not TFichier.Eof Do
Begin
DM.TTampon.Insert;
For I := 0 To TFichier.FieldCount - 1 Do
If TFichier.Fields[I].Visible Then //A REVOIR POUR EVITER DE RATER LES CHAMPS DE MÊME TYPE
Begin
DM.TTampon.Fields[I].Value := TFichier.Fields[I].Value;
End;
DM.TTampon.Post;
TFichier.Next;
end;
//Fin Remplissage de la table concernée
//Historique_Fin
TJournal.Locate('num_journal',nb_jrnl,[]);
TJournal.Edit;
TJournal.FieldByName('fin_chargement').AsDateTime := Date()+Time();
TJournal.FieldByName('reussit').AsBoolean := True;
TJournal.Post;
//Validation
DM.dbLocal.Commit;
except
DM.dbLocal.Rollback;
raise;
end;//Transact
end;//3
////////////
TListeTable.Next;//Passage à la table suivante
end//2
end//1.1
END//1
End;
solilog
Messages postés273Date d'inscriptionsamedi 13 juin 2009StatutMembreDernière intervention18 avril 201510 23 sept. 2012 à 21:43
Bonsoir,
Une solution serait de faire un thread en tâche de fond.
Une autre, plus simple est de faire tourner ta procédure dans une autre Form que la Form active avec un bouton (ou autre) qui lance la proc dans l'autre fenetre et garder le focus sur la main form (chaque form est un thread).
Bonjour et merci de l'intérêt que vous portez à mon sujet,
A WALIDLAM : à quoi sert cette instruction (car j'arrive pas à afficher l'aide de Delphi sous win 7 ce qui est déjà un problème que j'ai pas encore pu régler)? et où la placer dans ma boucle?
A SOLILOG : pourriez vous me donner plus d'indications sur comment créer un thread en tâche de fond? En ce qui concerne le fait de mettre la procédure sur une autre forme, c'est ce que j'ai fait la première fois avec cette instruction :
solilog
Messages postés273Date d'inscriptionsamedi 13 juin 2009StatutMembreDernière intervention18 avril 201510 24 sept. 2012 à 19:03
Salut
- processmessages: dire au programme d'executer toutes les messages (ou tâches) en attente. Mais c'est pas super dans ce cas.
- Pour faire tourner ta proc dans une autre fenêtre ca semble pas super non-plus.
- thread: regarde dans le rep demo de D7, il y a un rep threads, une demo de 3 ex de tri qui s'executent en même temps (dans 3 threads). Et cherche dans le help tthread. Trop long sur le forum.
- tu peux aussi faire un programme à côté qui fait ta proc et tu le lances depuis ton programme principal. Et là ça marchera, sûr. Ce prog pourrait recevoir un param qui dirait quelle proc lancer, ainsi toutes les proc de "maintenance" pourraient y être :
dans le programme appelé:
var nomproc;
...
nomproc := lowercase(trim(paramstr(1)));
if nomproc = 'xxxxx' then XXXXX
else if nomproc = 'yyyyy' then YYYYY
....
else messagedlg('Tu t''es planté dans le nom de ta proc', mterror, [mbOk], 0);
regarde dans l'aide comment appeler un programme: shellexec (minimized)
Faut que tu bosses. Mais tu devrais t'en sortir.
Bon courage.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Une fois de plus merci à vous tous!
Particulièrement à Yanb pour l'aide de Delphi que j'arrive maintenant à ouvrir. Ça faisait longtemps mais la solution est plus simple quand on l'a prend sur le site du 01.net ici pour les 32 bitset là pour les 64 bits Encore plus à Solilog, j'ai pas encore tester la solution mais dès que c'est fait je donne les résultats.
A très bientôt j'espère.