Lenteur extrème d'exécution....

Lenteur extrème d'exécution.... - VB/VBA/VBS - Programmation

Marsh Posté le 15-06-2012 à 20:20:53    

Bonjour à tous et à toutes,
 
J'espère que l'un d'entre vous a déjà été confronté au problème que je vais vous exposer ou saura me dire l'origine de l'extrème lenteur (#30 à 45 minutes) de mon script vbs que je mettrai plus bas.
Ce script fonctionne nickel chrome tant que les chemins sont en local; mais dès qu'il s'agit d'un chemin réseau du genre \\toto\dossier ou \\@IP\dossier eh ben là bojour les dégats, il met extrement de temps avant d'afficher le résultat de la recherche.
 
 
Mon script VBS est le suivant :  
'**************************
'Declarations de variables
'**************************
'Chemin du bureau pour test
'Set WshShell = WScript.CreateObject("WScript.Shell" )
'MsgBox WshShell.SpecialFolders("Desktop" )
chemin = InputBox ("Saisisez l'adresse IP","Supression de tata.zut" )
 
'Chemin du dossier condition1
Dossiercondition1=  chemin  & "\VBS\condition1"
 
'Chemin du dossier condition2
'Set Shell = CreateObject("WScript.Shell" )
Dossiercondition2= chemin & "\vbstest\condition2"
 
'Extension à tester
strExtensionsToTest = "oki"
 
'Heure min pour suppression du tata.zut
heureMaximalFichiers = 4
 
'Initialisation des objets
Set fso = CreateObject("Scripting.FileSystemObject" )
 
'On verifie que le dossier condition1 existe
 
If (myName = Winrep = fso.FolderExists(Dossiercondition1)) = False Then
    Erreur = MsgBox("Le Dossier condition1 est introuvable !" )
    Wscript.Quit
End If
 
'On verifie que le dossier condition2  existe
If (myName = Winrep = fso.FolderExists(Dossiercondition2)) = False Then
    Erreur = MsgBox("Le Dossier condition2 est introuvable !" )
    Wscript.Quit
End If
 
 
'****************************************************************************
'Suppression du fichier tata.zut si :          *
' 1 le dossier condition1 est vide          *
' 2 pas de fichiers *.oki de moins de 4 heures        *
'****************************************************************************
'****************************************************************************
'****************************************************************************
'Nombre de fichiers présent dans le dossier condition1       *
'                 *
'****************************************************************************
 
Set Folder = fso.Getfolder(Dossiercondition1)
j=0
For Each File In Folder.Files    
j=j+1      
Next
 
 
'****************************************************************************
'                 *
'Vérifications qu'il n'existe pas de fichier *.oki de moins de 4 heures     *
'                 *
'****************************************************************************
 
Set Folder = fso.Getfolder(Dossiercondition2)
i=0
t=0
For Each File In Folder.Files
 
 
  for each strExt in SPLIT(UCASE(strExtensionsToTest),"," )
   if RIGHT(UCASE(File.Path),LEN(strExt)+1) = "." & strExt then
t=t+1
 If (DateDiff("h", File.DateLastModified, Now() ) > heureMaximalFichiers ) Then  
 
   
i=i+1
 
exit for
    END IF
   end if
  next
 next  
 
 
if t = i and j= 0 then
Cancel= MsgBox("Les conditions requises : " & chr(13) & ""& chr(13) & "1- Le dossier condition1 est vide" & chr(13) & "2- Pas de fichiers:  *.oki de moins de 4 heures"  & chr(13) & "pour supprimer le fichier tata.zut sont remplies" & chr(13) & "Cliquer sur OK pour supprimer tata.zut",4, "Conditions OK" )
 
If Cancel = vbYes Then  
on error resume next
Set obj = CreateObject("Scripting.FileSystemObject" )
obj.DeleteFile(chemin & "\lateteatoto\vbstest\tata.zut" )
MsgBox("Le fichier tata.zut est supprimé !" )
 
else
 
Dim codea
codea = MsgBox("Vous avez abandonné la suppression!" & chr(13) & "Aurevoir",vbExclamation,"Abandon Opérateur!!!" )
end if
 
else  
 
Dim code
code = MsgBox("Les conditions requises :  !" & chr(13) & "1 le dossier condition1 est vide" & chr(13) & "2 pas de fichiers *.oki de moins de 4 heures" & chr(13) & "pour supprimer le fichier tata.zut ne sont pas remplies" ,vbExclamation,"Conditions Non requises" )
end if
 
************************************************************************************************************
Je n'ai pas trouvé d'autre solution que de compter le nombre total de fichier *.oki et de le comparer avec le nombre total de fichiers *.oki ayant plus de 4heures.
Mon objectif étant de supprimer le fichier tata.zut si et seulement si les conditions : 1 -Le dossier condition1 est vide et  
                                                                                                                         2 - Tous les fichiers *.oki du dossier condition2 ont plus de 4 h
 
Voiloù, si vous avez une idée pour qu'en indiquant un chemin réseau, l'exécution se fasse aussi rapidement qu'un chemin en local eh ben  u're welcome
P.S. : Bien entendu j'ai vérifier manuellement que je pouvais me connecter au poste sans problème par Démarrer > Exécuter > \\toto\dossier et par \\@ip\dossier..... donc pas de problème réseau!  :D  
 
 
 
 
 

Reply

Marsh Posté le 15-06-2012 à 20:20:53   

Reply

Marsh Posté le 15-06-2012 à 23:41:58    

Il faudrait que tu trouves la boucle la plus lente, mais je pense que c'est la deuxième.
 
Pour moi la première boucle est inutile, elle peut être remplacée par :

Code :
  1. j = fso.Getfolder(Dossiercondition1).Files.Count


 
 
 
Pour la deuxième l'algo est bien compliqué je trouve. En gros tu comptes tout + tu comptes les plus de quatre heure c'est ça ?

Code :
  1. For Each File In Folder.Files
  2.   for each strExt in SPLIT(UCASE(strExtensionsToTest),"," )
  3.       if RIGHT(UCASE(File.Path),LEN(strExt)+1) = "." & strExt then
  4.           t=t+1
  5.           If (DateDiff("h", File.DateLastModified, Now() ) > heureMaximalFichiers ) Then 
  6.              i=i+1
  7.              exit for
  8.           END IF
  9.      end if
  10.   next
  11. next


 
ça me parait bien compliqué car en fait s'il existe un fichier de moins de quatre alors tu peux t’arrêter tout de suite non ?
 

Code :
  1. FichierRecentTrouve = 0
  2. For Each File In Folder.Files
  3.   for each strExt in SPLIT(UCASE(strExtensionsToTest),"," )
  4.       if RIGHT(UCASE(File.Path),LEN(strExt)+1) = "." & strExt then
  5.           If (DateDiff("h", File.DateLastModified, Now() ) <= heureMaximalFichiers ) Then 
  6.              FichierRecentTrouve = 1
  7.              exit for
  8.           END IF
  9.      end if
  10.   next
  11.   ' arret immediat en fin de boucle
  12.   if(FichierRecentTrouve)then
  13.      exit for
  14.   end if
  15. next
  16. if (j=0) and FichierRecentTrouve=0 then
  17.      ...
  18. end if


 
Maintenant si c'est le foreach file qui est "lent", peut être que "dir" est plus rapide

Code :
  1. Set WshShell = CreateObject("wscript.shell" )
  2. ' le filtre peut être mis via *.oki aussi, plus un tri par date décroissante peut être utile
  3. Set oExec = WshShell.Exec("cmd /c dir """ & Dossiercondition2 & "\*.*""" )
  4. ' l'expression régulière est peut-être à adapter à ton envir, mais elle sert chez mois à séparer la date du nom du fichier
  5. Set parseFileLine = new RegExp
  6. parseFileLine.pattern = "^(\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}).{19}(.+\.(csv|oki|xls))$"
  7. Do Until oExec.StdOut.AtEndOfStream
  8.     line = oExec.StdOut.ReadLine()
  9.     ' controle d'extension et de structure de line (car "dir" renvoie un peu n'importe quoi)
  10.         Set parts = parseFileLine.Execute(line)
  11.         if(parts.count>0) then
  12.             ' Submatches(0) contient la date, submatches(1) le nom du fichier
  13.             strText = strText & chr(10) & chr(13) & parts.Item(0).Submatches(0) & "|" & parts.Item(0).Submatches(1)
  14.             ' Faire le controle de date ici sortir si Ko
  15.         end if
  16. Loop
  17. MsgBox strText


 
 
J'ai testé que le code fonctionne en local, mais faut tester que ça va "plus vite" chez toi car rien n'est moins sûr
Pour toutes les options de la commande "dir" tu peux essayer l'URL http://ss64.com/nt/dir.html
 
Aller bon courage

Message cité 1 fois
Message édité par dreameddeath le 15-06-2012 à 23:52:47
Reply

Marsh Posté le 16-06-2012 à 14:54:05    

dreameddeath a écrit :

Il faudrait que tu trouves la boucle la plus lente, mais je pense que c'est la deuxième.
 
Pour moi la première boucle est inutile, elle peut être remplacée par :

Code :
  1. j = fso.Getfolder(Dossiercondition1).Files.Count


 
 
 
Pour la deuxième l'algo est bien compliqué je trouve. En gros tu comptes tout + tu comptes les plus de quatre heure c'est ça ?

Code :
  1. For Each File In Folder.Files
  2.   for each strExt in SPLIT(UCASE(strExtensionsToTest),"," )
  3.       if RIGHT(UCASE(File.Path),LEN(strExt)+1) = "." & strExt then
  4.           t=t+1
  5.           If (DateDiff("h", File.DateLastModified, Now() ) > heureMaximalFichiers ) Then 
  6.              i=i+1
  7.              exit for
  8.           END IF
  9.      end if
  10.   next
  11. next


 
ça me parait bien compliqué car en fait s'il existe un fichier de moins de quatre alors tu peux t’arrêter tout de suite non ?
 

Code :
  1. FichierRecentTrouve = 0
  2. For Each File In Folder.Files
  3.   for each strExt in SPLIT(UCASE(strExtensionsToTest),"," )
  4.       if RIGHT(UCASE(File.Path),LEN(strExt)+1) = "." & strExt then
  5.           If (DateDiff("h", File.DateLastModified, Now() ) <= heureMaximalFichiers ) Then 
  6.              FichierRecentTrouve = 1
  7.              exit for
  8.           END IF
  9.      end if
  10.   next
  11.   ' arret immediat en fin de boucle
  12.   if(FichierRecentTrouve)then
  13.      exit for
  14.   end if
  15. next
  16. if (j=0) and FichierRecentTrouve=0 then
  17.      ...
  18. end if


 
Maintenant si c'est le foreach file qui est "lent", peut être que "dir" est plus rapide

Code :
  1. Set WshShell = CreateObject("wscript.shell" )
  2. ' le filtre peut être mis via *.oki aussi, plus un tri par date décroissante peut être utile
  3. Set oExec = WshShell.Exec("cmd /c dir """ & Dossiercondition2 & "\*.*""" )
  4. ' l'expression régulière est peut-être à adapter à ton envir, mais elle sert chez mois à séparer la date du nom du fichier
  5. Set parseFileLine = new RegExp
  6. parseFileLine.pattern = "^(\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}).{19}(.+\.(csv|oki|xls))$"
  7. Do Until oExec.StdOut.AtEndOfStream
  8.     line = oExec.StdOut.ReadLine()
  9.     ' controle d'extension et de structure de line (car "dir" renvoie un peu n'importe quoi)
  10.         Set parts = parseFileLine.Execute(line)
  11.         if(parts.count>0) then
  12.             ' Submatches(0) contient la date, submatches(1) le nom du fichier
  13.             strText = strText & chr(10) & chr(13) & parts.Item(0).Submatches(0) & "|" & parts.Item(0).Submatches(1)
  14.             ' Faire le controle de date ici sortir si Ko
  15.         end if
  16. Loop
  17. MsgBox strText


 
 
J'ai testé que le code fonctionne en local, mais faut tester que ça va "plus vite" chez toi car rien n'est moins sûr
Pour toutes les options de la commande "dir" tu peux essayer l'URL http://ss64.com/nt/dir.html
 
Aller bon courage


 dreameddeath je ne sais pas si tu es une femme, mais :love: ! Quand à moi  :cry:  et espèce d :sleep: que je suis!!!!
Mais bien sûr que le première boucle que tu propose suffit largement!
Quand à la seconde boucle, mais bien sûr qu'il suffit de s'arrêter dès qu'un fichier à moins de 4h!!!!
Sur ce coup là j'ai vraiment honte de moi!!!!!
Merci en tout cas pour ces corrections!
Je testerai dès lundi en environement "live" et te tient au courant!
Je m'étais orienter vers un code avec Set network = Wscript.CreateObject("WScript.Network" ) au lieu de Set wshshell = CreateObject("WScript.Shell" )......
Je regarderai aussi la solution du dir. Par contre avec dir là à chaud je ne vois pas comment faire un test sur le nombre d'heure d'existance...mais j'explorerai aussi cette piste!
En tout cas merci infiniment de ta réponse et du temps consacrer à me répondre!!!
Bon week-end!!

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed