comparaison de fichiers textes avec des tableaux en mémoire.

comparaison de fichiers textes avec des tableaux en mémoire. - VB/VBA/VBS - Programmation

Marsh Posté le 20-05-2006 à 12:29:51    

 
Bonjour,
 
Dans un cadre professionnel j'ai régulièrement besoin d'identifier les différences de paramétrage d'un progiciel travaillant sur une base de donnée sybase entre une base recette et une base préprod ou prod.
 
Les paramétrages sont extraits via des utilitaires dans des fichiers textes au format ascii.
Ces fichiers "ascii" sont convertis en "text" par un utilitaire sous unix
 
J'ai ensuite commencé a traivailler sur une macro permettant de lister les fichiers d'un répertoire (recette) puis de comparer chaque fichier au fichier equivalent de l'autre répertoire (production) pour enfin réécrire les lignes en différence dans chacun des répertoires.
 
Ca marche bien mais c'est lent, ca traite un mégaoctet de donnée a la minutes alors que sur des gros sites client on peut avoir plusieurs centaines de Mo de texte à comparer. SI ca prends une journée c'est pas top.
 
 
Pour rentrer dans le détails :
 
Une fois que mes fichiers sont chargés dans un tableau en mémoire, pour chaque ligne du premier tableau je balaye toutes les lignes du second tableau pour la rechercher, si je la trouve je les flag toutes les deux comme étant rapprochées sinon je la print dans un fichier.
Apres je balaye toutes les lignes non flagées du second tableau et je les print dans un autre fichier.
 
Je pense que cette partie pourrait être optimisée mais au vu de mes connaissances en vb je ne voie pas comment (déja pour l'utilisation des tableau j'ai beaucoup tatonné ...) Si on pouvait acceder au tableau via une sorte d'index pour retrouver dirrectement la ligne recherche ce serait royal est ce possible ?
 
Merci d'avance pour tous conseil relatif a l'optimisation de ce petit bout de code.
 
A+
 
 

Code :
  1. Option Explicit
  2. '----------------------------------------
  3. '----- Déclarations propres au module  --
  4. '----------------------------------------
  5. ' --- Les variables ---
  6. Dim Typerecherche As String
  7. Dim PathOrigine As String
  8. Dim PathDestination As String
  9. Dim ToLoadMask As String
  10. Dim ToDeleteMask As String
  11. Dim FileMask As String
  12. Dim FileSourceOrigine As String
  13. Dim FileSourceDestination As String
  14. Dim FileResultatOrigine As String
  15. Dim FileResultatDestination As String
  16. Dim ContenuResultatOrigine As String
  17. Dim ContenuResultatDestination As String
  18. Dim MaxLigneOrigine As Long
  19. Dim MaxLigneDestination As Long
  20. Dim TotalLigne As Long
  21. Dim NombreOccurence As Long
  22. Dim NombreOccurenceTotal As Long
  23. Dim NombreOccurenceErreur As Long
  24. Dim MaxRecherche As Long
  25. Dim Chaine As String
  26. Dim Path As String
  27. Dim File As String
  28. Dim Flag As Boolean
  29. Global ListeLigneOrigine As ListeLigne
  30. Global ListeLigneDestination As ListeLigne
  31. Type ListeLigne
  32.    Ligne() As String
  33.    Flag() As String
  34.    Nombre As Long
  35. End Type
  36. Public Sub Lister()
  37.     ' --- Initialisation des variables ---
  38.     NombreOccurence = 0
  39.     NombreOccurenceTotal = 0
  40.     NombreOccurenceErreur = 0
  41.     ResultatRecherche.Nombre = 0
  42.    
  43.     ' --- Lecture des paramètres de la recherche ---
  44.     PathOrigine = Range("Path_origine" ).Value
  45.     PathDestination = Range("Path_destination" ).Value
  46.     FileMask = Range("File_mask" ).Value
  47.     ToLoadMask = Range("To_load_mask" ).Value
  48.     ToDeleteMask = Range("To_Delete_mask" ).Value
  49.    
  50.     ' --- Constitution du tableau ---
  51.     BarRecherche.LabelProgress.Width = 0
  52.     BarRecherche.Show
  53. End Sub
  54. Public Sub Progression()
  55.     With BarRecherche
  56.         .FrameProgress.Caption = Format(a / TotalLigne, "0%" )
  57.         .LabelProgress.Width = a / TotalLigne * (.FrameProgress.Width - 10)
  58.     End With
  59.     DoEvents
  60.     If Range("Abort" ) = True Then
  61.         Unload BarRecherche
  62.         Exit Sub
  63.     End If
  64. End Sub
  65. Public Sub Bar_Lister()
  66.     ' --- Déclaration des variables ---
  67.     Dim r As Long
  68.     Dim l As Long
  69.     Dim o As Long
  70.     Dim d As Long
  71.     Dim a As Long
  72.     Dim fs, FD, FO
  73.     ' initialisation des variables
  74.     TotalLigne = 0
  75.     a = 0
  76.     ' --- Recherche de tous les fichiers ---
  77.     Set fs = CreateObject("Scripting.FileSystemObject" )
  78.     NombreOccurence = Rechercher(PathOrigine, "*" + FileMask, ResultatRecherche)
  79.        
  80.     ' --- Premiere passe pour estimer le temps de traitement ---
  81.     For r = 1 To ResultatRecherche.Nombre
  82.         FileSourceOrigine = Trim(ResultatRecherche.Chemin(r)) & Trim(ResultatRecherche.Fichiers(r).cFileName)
  83.         Open FileSourceOrigine For Input Access Read As #1
  84.         While (Not EOF(1))
  85.             Line Input #1, Chaine
  86.             If Chaine <> "" Then
  87.                 TotalLigne = TotalLigne + 1
  88.             End If
  89.         Wend
  90.         Close #1
  91.         FileSourceDestination = ReplaceString(Trim(ResultatRecherche.Chemin(r)), PathOrigine, _
  92.             PathDestination) & Trim(ResultatRecherche.Fichiers(r).cFileName)
  93.         Open FileSourceDestination For Input Access Read As #1
  94.         While (Not EOF(1))
  95.             Line Input #1, Chaine
  96.             If Chaine <> "" Then
  97.                 TotalLigne = TotalLigne + 1
  98.             End If
  99.         Wend
  100.         Close #1
  101.     Next r
  102.    
  103.     ' --- 2eme passe pour effectuer le traitement
  104.     For r = 1 To ResultatRecherche.Nombre
  105.         ' Réinitialisation des variables
  106.         ListeLigneOrigine.Nombre = 0
  107.         ListeLigneDestination.Nombre = 0
  108.        
  109.         ' Lectures des fichiers
  110.         FileSourceOrigine = Trim(ResultatRecherche.Chemin(r)) & Trim(ResultatRecherche.Fichiers(r).cFileName)
  111.         Open FileSourceOrigine For Input Access Read As #1
  112.         While (Not EOF(1))
  113.             Line Input #1, Chaine
  114.             If Chaine <> "" Then
  115.                 ListeLigneOrigine.Nombre = ListeLigneOrigine.Nombre + 1
  116.                 ReDim Preserve ListeLigneOrigine.Ligne(1 To ListeLigneOrigine.Nombre)
  117.                 ReDim Preserve ListeLigneOrigine.Flag(1 To ListeLigneOrigine.Nombre)
  118.                 ListeLigneOrigine.Ligne(ListeLigneOrigine.Nombre) = Chaine
  119.                 ListeLigneOrigine.Flag(ListeLigneOrigine.Nombre) = ""
  120.                 MaxLigneOrigine = ListeLigneOrigine.Nombre
  121.             End If
  122.         Wend
  123.         Close #1
  124.         FileSourceDestination = ReplaceString(Trim(ResultatRecherche.Chemin(r)), PathOrigine, _
  125.             PathDestination) & Trim(ResultatRecherche.Fichiers(r).cFileName)
  126.         Open FileSourceDestination For Input Access Read As #1
  127.         While (Not EOF(1))
  128.             Line Input #1, Chaine
  129.             If Chaine <> "" Then
  130.                 ListeLigneDestination.Nombre = ListeLigneDestination.Nombre + 1
  131.                 ReDim Preserve ListeLigneDestination.Ligne(1 To ListeLigneDestination.Nombre)
  132.                 ReDim Preserve ListeLigneDestination.Flag(1 To ListeLigneDestination.Nombre)
  133.                 ListeLigneDestination.Ligne(ListeLigneDestination.Nombre) = Chaine
  134.                 ListeLigneDestination.Flag(ListeLigneDestination.Nombre) = ""
  135.                 MaxLigneDestination = ListeLigneDestination.Nombre
  136.             End If
  137.         Wend
  138.         Close #1
  139.         ' Identification des différences & écritures des fichiers
  140.         FileResultatOrigine = ReplaceString(FileSourceOrigine, FileMask, ToLoadMask)
  141.         Set FO = fs.CreateTextFile(FileResultatOrigine)
  142.         For o = 1 To MaxLigneOrigine
  143.             Flag = False
  144.             For d = 1 To MaxLigneDestination
  145.                 If ListeLigneDestination.Flag(d) <> "Y" And ListeLigneOrigine.Flag(o) <> "Y" Then
  146.                     If ListeLigneOrigine.Ligne(o) = ListeLigneDestination.Ligne(d) Then
  147.                         ListeLigneOrigine.Flag(o) = "Y"
  148.                         ListeLigneDestination.Flag(d) = "Y"
  149.                         a = a + 2
  150.                         Flag = True
  151.                     End If
  152.                 End If
  153.             Next d
  154.             If Flag = False Then
  155.                 FO.writeline (ListeLigneOrigine.Ligne(o))
  156.                 ListeLigneOrigine.Flag(o) = "N"
  157.                 a = a + 1
  158.             End If
  159.             Call Progression
  160.         Next o
  161.         FileResultatDestination = ReplaceString(FileSourceDestination, FileMask, ToDeleteMask)
  162.         Set FD = fs.CreateTextFile(FileResultatDestination)
  163.         For d = 1 To MaxLigneDestination
  164.             If ListeLigneDestination.Flag(d) = "" Then
  165.                 FD.writeline (ListeLigneDestination.Ligne(d))
  166.                 a = a + 1
  167.             End If
  168.             Call Progression
  169.         Next d
  170.     Next r
  171.    
  172.     Unload BarRecherche
  173. End sub


 
 
PS : la fonction rechercher (x,y,z) permet de lister tous les fichiers d'un répertoire et de ses sous répertoires ayant une extention donné dans un tableau "Liste.recherche" mais comme c'est pas la partie qui me pose problème ...

 

 
 
 

 


 

Reply

Marsh Posté le 20-05-2006 à 12:29:51   

Reply

Marsh Posté le 20-05-2006 à 21:32:49    

Comme à priori tu comptes le nb de ligne de texte de tes fichiers
tu peux dimensionner tes tableaux hors des boucles
et éviter les  ReDim Preserve qui s'effectuent à chaque incrémentation de ces boucles
Par curiosité si cela améliore les choses indique moi les temps avant/après
 
pour cela tu peux faire appel à :
Private Declare Function GetTickCount Lib "kernel32" () As Long
 
puis avec 2 variables Debut, Fin déclarées en Variant
    Debut = GetTickCount
    ........
    Fin = GetTickCount - Debut
    puis  Format(Fin / 1000, "0.0" ) pour afficher le temps passé


Message édité par kiki29 le 20-05-2006 à 22:48:59
Reply

Marsh Posté le 21-05-2006 à 11:47:35    

Merci, je vais essayer mais j'ai l'impression que le temps de chargement des fichier est négligeable et que c'est vraiment la partie comparaison qui pose problème.
 
En VB est il posible de déclarer un tableau et de retrouver une ligne de ce tableau sans le balayer en entier ?

Reply

Marsh Posté le 21-05-2006 à 16:45:01    

ListeLigneOrigine.Ligne(indice) par exemple  
 
il y a aussi à tenir compte de la declaration de depart  
Option Base pour redéfinir la valeur par défaut d'indice de tableau de base, égale à 0 en déclarant Option Base 1


Message édité par kiki29 le 21-05-2006 à 16:45:44
Reply

Marsh Posté le 22-05-2006 à 07:23:03    

Un lien peut être utile http://www.vb-helper.com/howto_qui [...] cates.html
mais à adapter


Message édité par kiki29 le 22-05-2006 à 07:24:50
Reply

Marsh Posté le 23-05-2006 à 01:37:38    

merci pour les exemples de scripts un peu compliqué mais j'apprendrais quelquechose en passant et il y a des trucs qui ont l'air tres intéressants.
 

Reply

Sujets relatifs:

Leave a Replay

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