CopyFolder [Résolu]

vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 29 juin 2016 à 11:45 - Dernière réponse : f0xi 4302 Messages postés samedi 16 octobre 2004Date d'inscriptionModérateurStatut 20 mars 2017 Dernière intervention
- 17 août 2016 à 16:01
Bonjour,

J'ai créé une FUNCTION me permettant de copier l'intégralité de mes fichiers présents dans un dossier et d'en faire une copie dans un autre fichier.
Ma question est la suivante :
- Je ne sais pas comment faire pour ne pas sélectionner les fichiers qui ne m’intéressent pas. (Fichiers volumineux qui n'auront pas d’intérêt dans la suite de mon application mais qui sont présents dans le dossier et qui ralentissent l'exécution du CopyFolder)

Voici le code que j'ai actuellement, et qui marche très bien.

//Copie de fichiers
FUNCTION CopyFolder(FromFld, ToFld: string): boolean;
VAR
fos: TSHFileopStruct;

BEGIN
// il faut supprimer les antislashs de fin sinon vous aurez droit à un message d'erreur
FromFld := ExcludeTrailingPathDelimiter(Trim(FromFld));
ToFld := ExcludeTrailingPathDelimiter(Trim(ToFld));

FillChar(fos, SizeOf(fos),0);
WITH fos DO
BEGIN
wFunc := FO_COPY;
pFrom := PChar(FromFld+#0);
pTo := PChar(ToFld+#0);
fFlags := FOF_SILENT or FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;
END;
Result := ShFileOperation(fos)=0;
END;

PROCEDURE Traitement.RecuperationDossier;
BEGIN
CopyFolder('\\Sertf1b\c\DatasBA', 'C:\Users\Administrateur\Desktop\Test');
END;


Je suis ouvert à toute proposition, même si je dois changer ma fonction.

Cordialement.
Afficher la suite 

13 réponses

Répondre au sujet
Cirec 4191 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 12 décembre 2017 Dernière intervention - 23 juil. 2016 à 15:27
+1
Utile
2
oh là ...
pas la peine de faire une usine à gaz

comme je l'ai déjà dit plus haut, tu as tout ce qu'il te faut et l'utilisation du code de f0xi est juste pour simplifier encore un peu plus.

***sur une Fiche: 2 TEdit (edt_From & edt_To) 1 TButton (btn_Copy)

  ... 
implementation

{$R *.dfm}
uses
  ExtFileOp;

procedure TUDemoMain.btn_CopyClick(Sender: TObject);
var
  aSL: TStringList;
begin
  aSL := TStringList.Create;
  try
    aSL.Delimiter := ';';
    aSL.DelimitedText := edt_From.Text;
    FastCopy(Self, aSL, edt_To.Text);
  finally
    aSL.Free;
  end;
end;



lance l'application.
dans edt_From tu mets: (par Ex.)
"C:\Program Files\Mon dossier\d*.*";"C:\Program Files\Mon dossier\c*.*"

et dans edt_To:
c:\TempCopy\d\


et appuyer sur le bouton ... ceci copiera tous les fichiers commençant par D et par C dans c:\TempCopy\d\

surtout ne pas oublier les guillemets et le point-virgule entre chaque mask de recherche dans edt_From


voilà rien de plus ... rien de moins ^^
Cette réponse vous a-t-elle aidé ?  
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 26 juil. 2016 à 10:33
Salut,

Effectivement, ta solution marche impeccable, est également bien plus rapide. (Du au nombre de traitement.) Je te remercie donc d'avoir rebondis ^^.

Une réponse amène une autre question (C'est l'inverse normalement mais bon) La barre des tâches qui charge pendant le traitement ne me dérange pas tant que ça au final, j'allais regardé pour faire une progressBar donc ... Impeccable.

La question est, est il possible de mettre par défaut "OUI" à la question qui demande s'il faut écrasé les dossiers existants portant le même nom ??

Encore merci pour la petite astuce qui me fait gagner la bagatelle de 5 bonnes minutes par traitement.

Cordialement.
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention > vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 26 juil. 2016 à 10:48
Je confirme, ton morceau de code marche de façon impeccable.
Le traitement dure difficilement plus de 15sec pour 6mins minimum avant.

Merci bien :)
Commenter la réponse de Cirec
Cirec 4191 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 12 décembre 2017 Dernière intervention - 26 juil. 2016 à 14:36
+1
Utile
1
re,
content que ça te plaise ;)

et pour répondre à la question suivante ... c'est oui, on peut contrôler tous les comportements.
la méthode FastCopy accepte un quatrième paramètre (facultatif) par le quel tu indiques quel comportement adopter face à tel situation.

en clair tu remplaces :
    FastCopy(Self, aSL, edt_To.Text);

par:
    FastCopy(Self, aSL, edt_To.Text, [ffNoConfirmation, ffAllowUndo, ffNoConfirmMkDir]);


tu trouveras la liste des options disponible en début de l'unité de f0xi
Cette réponse vous a-t-elle aidé ?  
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 27 juil. 2016 à 11:50
Salut.

Je te remercie pour ton aide.

Bilan, ça marche impeccable, sans latence, avec un code simplifié, et une progressbar.
Que demander de plus...

Merci encore. Au plaisir de te relire si tes conseils sont toujours autant avisés.

Cordialement.
Commenter la réponse de Cirec
Cirec 4191 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 12 décembre 2017 Dernière intervention - 29 juin 2016 à 13:12
0
Utile
Salut

regarde ce code il utilise la même méthode que toi mais en beaucoup plus complet ce qui inclus le choix des fichiers à copier/déplacer/supprimer ...
La prise en main est simplifié ... tu devrais t'en sortir avec ;)

Commenter la réponse de Cirec
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - Modifié par vico8000 le 29/06/2016 à 14:38
0
Utile
5
Merci pour l'indication.

J'arrive bien à récupérer et déplacer à l'aide de la classe de Foxi.
Je fais exactement pareil que le code si dessus.
Je ne vois à l'inverse, pas comment utiliser la lib pour ne pas récupérer les fichiers commençant par MES, par exemple, présents dans le dossier.

J'ai également une question suite au test fait à l'aide de la librairie.
Lors du copier/coller des fichiers, la boîte de dialogue inscrivant le temps restant s'affiche. N'y a t'il pas moyen de ne pas l'afficher ?

Lorsque nous voulons envoyer des fichiers dans un dossier mais que ces fichiers en question existent, une boîte de dialogue nous demande si nous voulons les remplacer. N'est-il pas possible de le mettre à oui par défaut et de ne pas avoir l'affichage de cette boîte de dialogue ?

L'idée à terme est d'avoir cette copie en automatique toute les heures . (sans personne pour valider les boîtes de dialogue)

Cordialement.
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 29 juin 2016 à 16:26
J'arrive à avoir exactement ce que je veux avec CopyFolder.
Mais la méthode n'est pas bonne.
Je m'explique:
Je charge tous les fichiers présents dans mon Dossier et je supprime les données qui ne m'interessent pas. Hors j'ai chargé ces données et elles m'ont fait perdre du temps. J'aimerai pouvoir continuer à optimiser en évitant ce procédé.

Voici mon code actuel :

//Copie de fichiers
FUNCTION CopyFolder(FromFld, ToFld: string): boolean;
VAR
fos: TSHFileopStruct;
I: Integer;

BEGIN

// il faut supprimer les antislashs de fin sinon vous aurez droit à un message d'erreur
FromFld := ExcludeTrailingPathDelimiter(Trim(FromFld));
ToFld := ExcludeTrailingPathDelimiter(Trim(ToFld));

FillChar(fos, SizeOf(fos),0);
WITH fos DO
BEGIN
wFunc := FO_COPY;
pFrom := PChar(FromFld+#0);
pTo := PChar(ToFld+#0);
fFlags := FOF_SILENT or FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;
END;
Result := ShFileOperation(fos)=0;
END;

PROCEDURE Traitement.RecuperationDossier;
BEGIN
CopyFolder('\\Sertf1b\c\DatasBA', 'C:\Users\Administrateur\Desktop\Test');
END;

PROCEDURE Traitement.SuppressionMES;
var
SL : TStringList;
I : Integer;
FileDelete : String;

BEGIN
//Récupération Date, transposage au bon format, Adaptation pour pouvopir selectionner les bons fichiers pour suppression
SL := TStringList.Create;
SL.Text := StringReplace(DatetoStr(Date()), '/', #13#10, [rfReplaceAll]);

Conversion := strtoint(SL[2]) - 2000;
Conversion := conversion * 10000 + strtoint(SL[1]) * 100 + strtoint(SL[0]);

//Suppression du fichier MesXXXX dézippé.
Filedelete := 'C:\Users\Administrateur\Desktop\test\DatasBA\Mes' + inttostr(Conversion) + '.txt';
deletefile(Filedelete);

//Suppression des fichiers MesXXXX.txt.rar
for I:=0 to 120 do
Begin
Filedelete := 'C:\Users\Administrateur\Desktop\test\DatasBA\Mes' + inttostr(Conversion) + '.txt.rar';
deletefile(Filedelete);
Conversion := Conversion-1;
End;

SL.Free;
END;


Cordialement.
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 21 juil. 2016 à 16:18
Finalement je le fais en automatique à l'aide d'un logiciel qui fait une récupération en automatique tous les jours.

Sujet Clos.
Yanb > vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 22 juil. 2016 à 13:23
Salut,
en fait il aurait fallu lister les fichiers que tu souhaitais recopier avec TFileRec je pense, ensuite les mettre dans le pFrom de la structure TSHFileopStruct...en pensant que le dernier fichier à copier fini par un double null. Pour plus d'explication il faut regarder la msdn de SHFileopStruct.
@+
vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention > Yanb - 22 juil. 2016 à 14:58
Je te remercie de te pencher sur mon sujet.
Ta solution à l'air efficace mais n'est, je pense, pas adaptée à mon problème.
Je ne connais pas les fichiers présents dans mon dossier. (Enfin si mais 4 sont supprimés chaque jour et 4 sont ajoutés chaque jour)
Je ne peux donc pas renseigner mon TFileRec. Il m'aurait fallut une fonction qui récupère tous les fichiers type txt dans le dossier par exemple (à l'exception d'un :p) ou une fonction qui me permettrait de récupérer tous les fichiers qui commencent par XX ou par YY par exemple. (Tous les fichiers qui m'intéressent ont le même début de nom).

Au final, avec ma solution logicielle (Utilisant un script style .bat) je peux récupérer en automatique tout mon dossier, sans provoquer de latence sur l'application. (récupère même avec le pc éteins 8) ) et moi sur mon application, je fais une récupération de 3 petits fichiers si j'ai besoin de faire une récupération à l'instant t, sinon pas de récupération.
Yanb > vico8000 288 Messages postés lundi 18 janvier 2016Date d'inscription 6 décembre 2017 Dernière intervention - 22 juil. 2016 à 15:47
Ok...la solution que tu as mis en place à l'air très simple et fonctionnelle ;)
Si tu n'avais pas trouvé cette solution tu aurais pu filtrer avec un TSearchRec, FindFirst...pour récupérer les fichiers.
Ensuite si tu avais voulu faire de la surveillance pour connaitre les nouveaux fichiers ou les fichiers supprimer avec Thread, OpenFile, FILE_NOTIFY_INFORMATION...
Mais bon les choses se compliquer pas mal :p
@+
Commenter la réponse de vico8000
f0xi 4302 Messages postés samedi 16 octobre 2004Date d'inscriptionModérateurStatut 20 mars 2017 Dernière intervention - 17 août 2016 à 16:01
0
Utile
Content de voir que ExFileOp est utilisée en 2016 :)

Pour ce qui est des fenètres de confirmation, progression, ça c'est windows qui gère puisque SHFileOperation c'est du pur windows.
Il y a des paramètres pour éviter les confirmations (comme dit par Cirec) mais on ne peut pas tout masquer (de mémoire).

Sinon, vous pouvez regarder ma source "Depoc" qui est basé sur SearchRec/Find (à l'ancienne donc), largement commenté pour bien comprendre chaque choses.
Commenter la réponse de f0xi

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.