Page 1 sur 1

[R] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 13:23
par judgefred
Bonjour,

Je ne sais pas si le titre est très clair... Je ne savais pas comment le tourner pour qu'il soit explicite...

J'utilise la fonction filemove de la manière suivante, par exemple:

Code : Tout sélectionner

filemove("C:\source\2000*.*","C:\2000", 0)
filemove("C:\source\2001*.*","C:\2001", 0)
filemove("C:\source\2002*.*","C:\2002", 0)

etc... avec attribut 0 car je ne souhaite pas que le fichier source écrase celui déjà présent dans le répertoire de destination.

Avec cette attribut, mon problème est que filemove s'interrompt dès qu'il rencontre un fichier déjà présent dans le répertoire de destination.

Je n'arrive pas à construire une sorte de boucle pour dire en gros (et désolé pour le vocabulaire...)

- Tu recherches les fichiers commencant par 2000 dans le dossier source

- Tu déplaces ces fichiers dans le dossier 2000

- Si le fichier est déjà présent dans le dossier 2000, ce n'est pas grave, tu le laisses ou il est et tu continues à rechercher les fichiers commencant par 2000 dans le dossier source pour les déplacer, etc. etc. etc.

Merci d'avance

Cordialement

JudgeFred

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 13:44
par Yogui
La réponse se trouve dans cette petite pharse :
Failure: Returns 0 if source cannot be moved or if dest already exists and flag=0.
Si la destination existe déjà Echec

solution de contournement :

Code : Tout sélectionner

FileCopy ("C:\source\2000*.*","C:\2000", 0)
FileDelete("C:\source\2000*.*")
Pour faire Vraiment bien il faudrait lister les fichiers à copier puis vérifier si un fichier à déjà le même nom dans la destination. si vrai alors supprimer le fichier sinon le déplacer. Je pense avoir ce genre de script je regarde.

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 13:53
par judgefred
solution de contournement :

Code : Tout sélectionner

FileCopy ("C:\source\2000*.*","C:\2000", 0)
FileDelete("C:\source\2000*.*")

Dans cet exemple, est ce que le(s) fichier(s) non copié(s) resteront dans le répertoire source?

Car il me faut absolument les conserver dans le dossier source pour le comparer avec celui déjà présent dans le dossier de destination.

Merci.

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 14:11
par Yogui
Je ne prendrai pas le risque de dire que les fichiers non copiés vont rester dans le repertoire cible.

je vais rechercher mon script de sauvegarde qui compare les fichiers cibles et destinations et qui ne supprime la source que si le fichier copier est identique

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 14:14
par judgefred
Merci d'avance.

Et voila pour la conquete du monde (\ _ /)
(='.'=)
(")-(")

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 14:27
par judgefred
Effectivement, filecopy, comme filemove, s'interrompt avec l'attribut 0 si le fichier est dejà existant dans le repertoire de destination. Et effectivement, l'ensemble du contenu du repertoire source est effacé avec filedelete.

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 14:52
par Yogui
je ne trouve plus mon script il doit être à la maison j'ai fait un premier jet :

Code : Tout sélectionner

$filtre = "C:\source\200*" ;ce que l'on recherche
$Source = "C:\source\" ;ou se trouvent les sources
$dest = "C:\2000\" ; ou l'on déplace les fichiers

$Search = FileFindFirstFile($filtre) ; pour plus d'info aller voir la doc :)


; Check if the search was successful
If $Search = -1 Then
    MsgBox(0, "Erreur", "Aucun fichier à déplacer")
    Exit
EndIf
While 1
    $file = FileFindNextFile($Search)
    If @error Then ExitLoop
    If FileExists($dest & $file) Then ;si le fichier et déjà présent de destination

        If FileGetSize($Source & $file) = FileGetSize($dest & $file) Then ;si la taille est la même je supprime la source
            FileDelete($Source & $file)
        ElseIf FileGetSize($Source & $file) > FileGetSize($dest & $file) Then ;si la source est plus grande je supprime la destination pour recopier le fichier
            FileDelete($dest & $file)
            FileCopy($Source & $file, $dest, 0)
            If FileGetSize($Source & $file) = FileGetSize($dest & $file) Then ;si la taille est la même je supprime la source
                FileDelete($Source & $file)
            Else
                MsgBox(0, "erreur", "Erreur avec le fichier :" & $Source & $file)
            EndIf
        EndIf
    Else ; sinon le fichier n'est pas dans le repertoire destination le le déplace
        FileMove($Source & $file, $dest, 0)
    EndIf
WEnd

il est possible d'aller plus loint dans les vérifications mais après c'est être parano

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 16:04
par judgefred
Pour un premier jet, c'est vraiment très bien! Et cela m'a donné une idée par rapport à mon problème actuel. Je vous la soummets:

Code : Tout sélectionner

$filtre = "C:\source\2000*.*" ;ce que l'on recherche
$Source = "C:\source\" ;ou se trouvent les sources
$dest = "C:\2000\" ; ou l'on déplace les fichiers

$Search = FileFindFirstFile($filtre)
If $Search = -1 Then
    MsgBox(0, "Erreur", "Aucun fichier à déplacer")
    Exit
EndIf

For $i = 1 to 10000
$file = FileFindNextFile($Search)
FileMove($Source & $file, $dest, 0)
Next
Au final, avec cette boucle, terminée à 10000 pour les besoins de mon test (un petit _filelisttoarray ne serait pas mal...):

- Les fichiers déjà présent dans le dossier destination ne sont pas déplacés et restent dans le dossier source

- Les fichiers non présent dans le dossier de destination sont déplacés.

- Le script se termine et me permets de passer à une éventuelle suite

Voyez-vous une faille ou une erreur de syntaxe quelque part, enfin quelquechose qui pourrait rendre ce script très peu fiable? Je suis assez nul en boucle...

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 17:49
par judgefred
Comme je vous l'ai dit, je suis nul en boucle! La preuve! Avec ce script, d'autres fichiers qui ne commencent pas par 2000 dans le dossier source iront quand même dans le dossier 2009...

Voici la nouvelle mouture qui semble bien meilleure après divers essais et pour laquelle j'obtiens les résultats décrits ci dessus:

Code : Tout sélectionner

$Filtre = "C:\source\2000*.*" ;ce que l'on recherche
$Source = "C:\source\" ;ou se trouvent les sources
$Dest = "C:\2000\" ; ou l'on déplace les fichiers

$Search = FileFindFirstFile($Filtre)
If $Search = -1 Then
    MsgBox(0, "Erreur", "Aucun fichier à déplacer")
    Exit
EndIf

While 1
$file = FileFindNextFile($Search)
If @error Then ExitLoop
FileMove($Source & $file, $dest, 0)
WEnd
Qu'en pensez vous?

Merci d'avance.

JudgeFred

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : ven. 31 juil. 2009 22:27
par Yogui
j'en pense que le problème est le même si la destination existe déjà la source ne sera pas effacé et la destination ne sera pas fiable

petit test dans sources mettre un fichier 2000test.txt de 100 ko et mettre un fichier 2000test.txt de 1 ko dans le repertoire 2000 à la fin du script le fichier dans le répertoire 2000 ne fera toujours que 1 ko ce qui n'est pas le cas avec mon script

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : sam. 01 août 2009 11:31
par Tlem
Il est possible de faire ceci :

Code : Tout sélectionner

$Filtre = "2000*.*" ;ce que l'on recherche
$Source = "C:\source\" ;ou se trouvent les sources
$Dest = "C:\2000\" ; ou l'on déplace les fichiers
Local $Err

$Search = FileFindFirstFile($Source & $Filtre)
If $Search = -1 Then
    MsgBox(0, "Erreur", "Aucun fichier à déplacer")
    Exit
EndIf

While 1
    $File = FileFindNextFile($Search)
    If @error Then ExitLoop
    ; Le 1 est pour ecraser la destination.
    If Not FileMove($Source & $File, $Dest, 1) Then $Err &= $File & @CRLF
WEnd

If $Err <> '' Then MsgBox(16, "Erreur", "Les fichiers suivant n'ont pas été dépacés : " & @CRLF & $File)
Et sur la dernière partie faire un autre traitement sur les fichiers qui n'ont pas été déplacés (car occupés, verrouillés ...).

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : sam. 01 août 2009 17:20
par judgefred
Yogui a écrit :j'en pense que le problème est le même si la destination existe déjà la source ne sera pas effacé et la destination ne sera pas fiable

petit test dans sources mettre un fichier 2000test.txt de 100 ko et mettre un fichier 2000test.txt de 1 ko dans le repertoire 2000 à la fin du script le fichier dans le répertoire 2000 ne fera toujours que 1 ko ce qui n'est pas le cas avec mon script
Effectivement, c'est ce que je souhaite: il faut ne faut pas que le fichier source soit effacé s'il existe déjà dans le répertoire de destination. Votre script, que j'ai déjà mis de coté, va m'être fort utile par la suite, mais dans le cas présent, en cas de "doublon" entre le fichier présent dans le répertoire source (non effacé) et le fichier présent dans le répertoire de destination, la comparaison sera effectué manuellement.

Par contre le script de Tlem est tout aussi interessant puisqu'il pourrait me permettre de générer un petit "log" en cas d'"erreur" de traitement.

Comme je ne souhaite pas l'écrasement du fichier exsistant dans le répertoire de destination, je me suis permis de remplacer:

Code : Tout sélectionner

If Not FileMove($Source & $File, $Dest, 1) Then $Err &= $File & @CRLF
par

Code : Tout sélectionner

If Not FileMove($Source & $File, $Dest, 0) Then $Err &= $File & @CRLF
Tout semble fonctionner correctement, mais le message ne renvoit que le dernier fichier qui n'a pas été déplacé.
Pourrait-on renvoyer dans cette msgbox tous les fichiers qui n'ont pas été déplacés?

Merci pour votre aide.

JudgeFred

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : sam. 01 août 2009 19:36
par Tlem
Cela devrait déjà être le cas puisque $Err &= $File & @CRLF incrémente $Err du nom du fichier + un retour à la ligne à chaque erreur de déplacement.

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : sam. 01 août 2009 19:54
par judgefred
C'est bien ce que je pensais...
J'ai du louper quelquechose.
Je vais reverifier demain matin.

Merci

Judgefred

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : dim. 02 août 2009 12:32
par judgefred
Tlem a écrit :Cela devrait déjà être le cas puisque $Err &= $File & @CRLF incrémente $Err du nom du fichier + un retour à la ligne à chaque erreur de déplacement.
Je suis désolé mais je n'y arrive pas.
Le $file retourné est celui du dernier "incident" de déplacement.

Par contre, en intégrant la msgbox dans la boucle, ça fonctionne, mais ne me donne pas une liste en "fin de traitement":

Code : Tout sélectionner

$Filtre = "2000*.*" ;ce que l'on recherche
$Source = "C:\source\" ;ou se trouvent les sources
$Dest = "C:\2000\" ; ou l'on déplace les fichiers
Local $Err

$Search = FileFindFirstFile($Source & $Filtre)
If $Search = -1 Then
    MsgBox(0, "Erreur", "Aucun fichier à déplacer")
    Exit
EndIf

While 1
    $File = FileFindNextFile($Search)
    If @error Then ExitLoop
    If Not FileMove($Source & $File, $Dest, 0) Then MsgBox(0,"", $file)
    WEnd
Donc pour exploiter les "erreurs de déplacement", je remplace

Code : Tout sélectionner

If Not FileMove($Source & $File, $Dest, 0) Then MsgBox(0,"", $file)
par

Code : Tout sélectionner

If Not FileMove($Source & $File, $Dest, 0) Then _FileWriteToLine("TEST.txt", "1", $file, 0)
pour me faire un petit "fichier log".

Est-ce inexact?
Ou sinon, comment puis-je faire fonctionner votre script en l'état?

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : dim. 02 août 2009 20:05
par Tlem
Je ne vois pas pourquoi cela ne fonctionne pas chez vous ...

Sinon, pour le fichier LOG vous pouvez remplacer

Code : Tout sélectionner

If Not FileMove($Source & $File, $Dest, 0) Then _FileWriteToLine("TEST.txt", "1", $file, 0)
par :

Code : Tout sélectionner

If Not FileMove($Source & $File, $Dest, 0) Then FileWrite("TEST.txt", $file)
Prenez soin d'effacer le fichier en début de script, si vous ne voulez pas garder l'historique, sinon rajoutez avant la boucle l'écriture de la date puis à la fin de la boucle un ou deux saut de ligne. Cela vous permettra d'avoir l'historique sur plusieurs jours et facilement lisible.

Re: [..] Comment intégrer "filemove" dans une boucle ?

Posté : lun. 03 août 2009 12:26
par judgefred
Je vous remercie tous BEAUCOUP car cette boucle était le dernier point noir de mon script ... J'ai eu mes réponses et mes solutions!
Sujet résolu!