Detection et remplacement string

Detection et remplacement string - VB/VBA/VBS - Programmation

Marsh Posté le 20-04-2017 à 21:02:57    

http://nsa37.casimages.com/img/2017/04/20/mini_170420091032473526.jpg
 
Bonsoir
j'ai 2 fichiers txt
-VDI.txt  (15mo, 30000 lignes)
-IPC.txt   (5mo, 100 000 lignes)
 
je voudrais, dans le fichier VDI.txt remplacer toutes les séquences de caractères situées devant bgf
ex : {"home/sb30/d53113317-200.bgf"}
 
a remplacer par  
{"home/sb30/d00000000-200.bgf"}
 
par contre si le n° est dans le fichier IPC.txt, je ne veux pas y toucher
{"home/sb30/d53113320-200.bgf"}  doit rester tel quel
 
j'imagine que c'est faisable en 10-20 lignes, mais je ne sais pas par ou commencer
 
vbs, vba
 
je sais déjà ouvrir un fichier et l'afficher ligne par ligne
tester si la ligne contient bgf
me reste plus que isoler le n° avant bgf, ouvrir le 2eme fichier, comparer, remplacer, reecrire
je sens que je vais faire une usine a gaz  :cry:

Reply

Marsh Posté le 20-04-2017 à 21:02:57   

Reply

Marsh Posté le 21-04-2017 à 10:42:48    

 
            Bonjour,
 
            ouverture du bon fichier, lecture d'une ligne - voir l'aide VBA de Line Input # par exemple - puis fonction Replace
 

Reply

Marsh Posté le 21-04-2017 à 22:44:26    

Bonsoir
j'ai un peu avancé
j'ouvre le premier fichier vdi.txt
je lis les lignes  
  si elle ne contienne pas bgf je les reecrit tel quel dans le fichier 2
  si elle contienne bgf, je les traite
 
j'isole donc le n° que je veux comparer  

Code :
  1. 'ligne => home/sb30/d53113031-200.bgf"
  2. 'sequence isolée:=>  d53113031
  3. If Mid(ligne, InStr(ligne, "bgf";) - 15, 2) = "/d" Then Print #2, Mid(ligne, InStr(ligne, "bgf";) - 14, 9)
  4. 'ligne => home/sb30/d53113031200.bgf"
  5. 'sequence isolée:=>  d53113031
  6. If Mid(ligne, InStr(ligne, "bgf";) - 14, 2) = "/d" Then Print #2, Mid(ligne, InStr(ligne, "bgf";) - 13, 9)


me reste plus qu'a la reecrire tel quel si le n° est présent dans IPC.txt
ou la convertir (remplacer /d par /x par exemple  (c'est le plus simple)
si le n° est absent de ipc.txt
 
mais là je sèche, car si je fait à ma méthode je vais ouvrir et fermer le fichier 10000 fois
 
ça, cela marche
'ligne = Replace(ligne, "d53113031", "dxxxxxxxx";)
 
 
bref  
comment changer ipc.txt en mémoire
et faire sorte qu'il me dise si la séquence isolé est ou n'est pas dans ipc.txt
 
 
ex:
si Mid(ligne, InStr(ligne, "bgf";) - 13, 9) est présent dans ipc.txt alors beep
 
comment traduire cela ?


Message édité par daniel-12 le 21-04-2017 à 22:45:14
Reply

Marsh Posté le 22-04-2017 à 02:43:03    

 
            Lire d'abord le fichier IPC afin de charger dans un dictionnaire les séquences précédant "bgf"
            (soit via l'objet Dictionary (VBA / VBScript, consulter la doc VBA ou encore celle sur MSDN)
             soit via une Collection du VBA mais là il faut prévoir une gestion d'erreur car il n'y pas de fonction testant l'existence d'une clef) …
             
            Lors du traitement du fichier VDI comparer avec le dictionnaire …
 
            Possibilité d'accélérer la lecture & l'écriture des fichiers textes via ADODB.Stream (cf doc sur MSDN).
 

Reply

Marsh Posté le 22-04-2017 à 17:19:06    

ça y est cela fonctionne (presque)
j'ai utilisé le dictionnaire au lieu d'une boucle pour la lecture d'un des fichiers
forcement je suis passé d'une exécution de 5mn a 20s
 
il me reste 2 soucis
-les séparateurs en fin de ligne
-les lignes qui contiennent plusieurs fois bgf

Reply

Marsh Posté le 23-04-2017 à 21:42:15    

 
            Sans information technique précise, je dirais de voir déjà du côté de la fonction  Split  …
 

Reply

Marsh Posté le 25-04-2017 à 17:12:13    

Bonjour
j'ai des string qui ressemblent a cela et que j'ai isolé
 
geometry {"home/sb30/d21212099000-flx03.bgf"}
geometry {"home/bes/asna3323-223.bgf"}
geometry {"home/sb3020/f53114036-200.bgf"}
 
Comment isoler facilement les caractères entre le dernier / et le point avant bgf
pour qu'en retour je reçoive :
d21212099000-flx03
asna3323-223
d53114036200
 

Code :
  1. Sub test1()
  2. Dim chaine As String
  3. 'geometry {"home/sb30/d21212099000-flx03.bgf"}
  4. chaine = "geometry {""home/sb30/d21212099000-flx03.bgf""}"
  5. chaine = Mid(chaine, InStr(chaine, "/d";) + 1, 9)    'ici j'ai mi 9, mais en fait j'aimerai tout prendre jusqu'au .bgf
  6. Debug.Print chaine
  7. End Sub


ca, ça marche, mais comme je peux avoir une autre lettre que d après le / je cherche une autre solution


Message édité par daniel-12 le 25-04-2017 à 22:19:59
Reply

Marsh Posté le 26-04-2017 à 00:44:46    

 
           Exemple avec la fonction  Split  :
 

Code :
  1. Sub DemoSPlit()
  2.    For Each V In Array("geometry {""home/sb30/d21212099000-flx03.bgf""}", _
  3.                        "geometry {""home/bes/asna3323-223.bgf""}", _
  4.                        "geometry {""home/sb3020/f53114036-200.bgf""}" )
  5.        Debug.Print Split(Split(V, "/" )(2), "." )(0)
  6.    Next
  7. End Sub


 

Reply

Marsh Posté le 03-05-2017 à 13:50:27    

 
           Suite au contexte technique précisé par messages privés, voici dans un premier temps une procédure VBA Excel
           devant être située dans un module ne contenant pas l'instruction  Option Compare Text  sinon l'exécution en sera plus longue …
 

Code :
  1. Sub Demo1()
  2.   Const B = "*.vdi", E = ".bgf", C = "*" & E & """}", M = "M ", R = ".err"
  3.     Dim CDic As New Collection, oStr(1) As Object, P$, S$, F, D, V, T!
  4.         P = ThisWorkbook.Path & "\"
  5.         S = M & B
  6.         F = Dir(P & B)
  7.   While F Like S
  8.         F = Dir
  9.   Wend
  10.      If F > "" Then D = Dir
  11.   While D Like S
  12.         D = Dir
  13.   Wend
  14.      If F = "" Or D > "" Then
  15.         ChDrive P:  ChDir P
  16.         F = Application.GetOpenFilename("Fichiers, " & B, , "    Fichier à convertir :" )
  17.         If F = False Then Exit Sub
  18.         P = Left(F, InStrRev(F, "\" ))
  19.         F = Replace(F, P, "" )
  20.      End If
  21.         V = P
  22.         D = Dir(P & "IPC.txt" )
  23.      If D = "" Then
  24.         D = Application.GetOpenFilename("Fichiers, *.txt", , "    Dictionnaire :" )
  25.         If D = False Then Exit Sub
  26.         V = Left(D, InStrRev(D, "\" ))
  27.         D = Replace(D, V, "" )
  28.      End If
  29.         Application.StatusBar = "        Chargement du dictionnaire …"
  30.         T = Timer
  31.    With CreateObject("ADODB.Connection" )
  32.             .Open "Provider=Microsoft.Jet.OLEDB.4.0;Text;Database=" & V
  33.        With .Execute("SELECT * FROM [" & D & "]" )
  34.                On Error Resume Next
  35.            For Each V In .GetRows
  36.                CDic.Add "", LCase(V)
  37.            Next
  38.                On Error GoTo 0
  39.               .Close
  40.        End With
  41.             .Close
  42.    End With
  43.         Application.StatusBar = "        Conversion en cours …"
  44. For V = 0 To 1
  45.     Set oStr(V) = CreateObject("ADODB.Stream" )
  46.         oStr(V).Charset = "x-ansi"
  47.         oStr(V).LineSeparator = 10
  48.         oStr(V).Open
  49. Next
  50.         oStr(0).LoadFromFile P & F
  51. With CreateObject("VBScript.RegExp" )
  52.        .Pattern = "[a-z]\d{8}"
  53.         On Error Resume Next
  54. Do Until oStr(0).EOS
  55.     S = oStr(0).ReadText(-2)
  56.  If S Like C Then
  57.    If .Test(S) Then
  58.        Err.Clear
  59.        V = CDic(.Execute(S)(0))
  60.        If Err.Number Then S = Replace(S, E, R)
  61.    Else
  62.        S = Replace(S, E, R)
  63.    End If
  64.  End If
  65.         oStr(1).WriteText S, 1
  66. Loop
  67.         On Error GoTo 0
  68. End With
  69.         S = P & M & F
  70.         oStr(1).SaveToFile S, 2
  71. For V = 0 To 1
  72.         oStr(V).Close
  73.     Set oStr(V) = Nothing
  74. Next
  75.     Set CDic = Nothing
  76.     Debug.Print "Demo1 : "; Format(Timer - T, "0.000s" )
  77.     Application.StatusBar = False
  78.     MsgBox "Création de" & vbLf & vbLf & S, vbInformation, "   Conversion"
  79. End Sub


Message édité par Marc L le 03-05-2017 à 14:21:11
Reply

Marsh Posté le 03-05-2017 à 17:18:08    

Merci
cela fonctionne  :)  
je vais étudier la méthode que tu as utilisée
je ne pense pas être capable de la refaire actuellement, mais il y a par ci par là des fonction nouvelle pour moi
 
j'ai remarqué que cette macro ne mettait pas la zizanie dans la mise en forme de mon fichier, c'est aussi un plus

Reply

Marsh Posté le 03-05-2017 à 17:18:08   

Reply

Marsh Posté le 04-05-2017 à 00:28:15    

 
           Comme attendu, cette procédure remplace juste l'extension des .bgf non désirés …
 
           Et du côté du temps d'exécution, cela donne quoi ?
 

Reply

Marsh Posté le 04-05-2017 à 19:16:07    

 
           Connaissant déjà la réponse avec des fichiers d'un volume important …
 
           Voici la version VBScript du code précédent (but final, VBA utile juste pour dégrossissage),
           quelques remaniements pour les particularités de VBScript mais aussi à cause d'une mauvaise gestion de Windows en 64 bits …
 

Code :
  1. Function GetFileExt(ByVal Init, Filter, Title)
  2.         S = Split(Init, "\" )
  3.         If UBound(S) < 1 Then Exit Function
  4.         E = Split(S(UBound(S)), "." )
  5.         If UBound(E) > 0 Then E(UBound(E)) = "*" & E(UBound(E))
  6.         S(UBound(S)) = Join(E, "." )
  7.         Init = Join(S, "\\" )
  8.     Set oDlg = CreateObject("WScript.Shell" ).Exec("mshta.exe ""about:<object id=d classid=clsid:" & _
  9.                "3050f4e1-98b5-11cf-bb82-00aa00bdce0b></object><script>moveTo(0,-9999);eval(new " & _
  10.                "ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).Read(" & _
  11.                 Len(Init) + Len(Filter) + Len(Title) + 39 & " ));function window.onload()" & _
  12.                "{var p=/[^\0]*/;new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1)" & _
  13.                ".Write(p.exec(d.object.openfiledlg(init,null,filter,title)));close();}" & _
  14.                "</script><hta:application showintaskbar=yes />""" )  
  15.         oDlg.StdIn.Write "var init='" & Init & "';var filter='" & Filter & "';var title='" & Title & "';"  
  16.         GetFileExt = oDlg.StdOut.ReadAll
  17.     Set oDlg = Nothing
  18. End Function
  19.         P = Replace(WScript.ScriptFullName, WScript.ScriptName, "" )
  20.         F = GetFileExt(P & "*.vdi", "", "        Fichier à convertir :" )
  21.      IF F = "" Then WScript.Quit 1
  22.         P = Left(F, InStrRev(F, "\" ))
  23.         F = Replace(F, P, "" )
  24.         D = P & "IPC.txt"
  25.  If Not CreateObject("Scripting.FileSystemObject" ).FileExists(D) Then
  26.         D = GetFileExt(P & "*.txt", "", "        Dictionnaire :" )
  27.      IF D = "" Then WScript.Quit 2
  28.  End If
  29.     Set oDic = CreateObject("Scripting.Dictionary" )
  30.         E = ".bgf"
  31.         R = ".err"
  32.   ReDim oStr(1)
  33. For V = 0 To 1
  34.     Set oStr(V) = CreateObject("ADODB.Stream" )
  35.         oStr(V).Charset = "x-ansi"
  36.         oStr(V).Open
  37. Next
  38.         oStr(1).LineSeparator = 10
  39.         oStr(0).LoadFromFile D
  40.         oStr(0).SkipLine
  41. Do Until oStr(0).EOS
  42.         oDic(LCase(oStr(0).ReadText(-2))) = ""
  43. Loop
  44.         oStr(0).LineSeparator = 10
  45.         oStr(0).LoadFromFile P & F
  46. With New RegExp
  47.        .Pattern = "[a-z]\d{8}"
  48. Do Until oStr(0).EOS
  49.     S = oStr(0).ReadText(-2)
  50.  If InStr(S, E) Then
  51.     If .Test(S) Then
  52.         V = .Execute(S)(0)
  53.         If Not oDic.Exists(V) Then S = Replace(S, E, R)
  54.     Else
  55.         S = Replace(S, E, R)
  56.     End If
  57.  End If
  58.         oStr(1).WriteText S, 1
  59. Loop
  60. End With
  61.         S = P & "M " & F
  62.         oStr(1).SaveToFile S, 2
  63. For V = 0 To 1
  64.         oStr(V).Close
  65.     Set oStr(V) = Nothing
  66. Next
  67.         oDic.RemoveAll
  68.     Set oDic = Nothing
  69. CreateObject("WScript.Shell" ).Run "mshta.exe vbscript:close(CreateObject(""WScript.Shell"" )" & _
  70.                                   ".Popup(""Création de " & S & """,3,""   Conversion"",64))"


           J'ai dû découper des lignes de code sur plusieurs lignes à cause de l'affichage du code balisé,
           ces lignes pouvant être regroupées en une seule dans le fichier final …


Message édité par Marc L le 04-05-2017 à 19:25:01
Reply

Marsh Posté le 04-05-2017 à 23:38:23    

Les 2 fonctionnent, mais en essayant de comprendre en faisant du pas a pas sur des petit fichier, j'ai des chose bizarres
 
ex:
je mets QUE cela dans un fichier vdi
geometry {"home/sb30/d53110391-200.bgf"}
 
logiquement il devrait me rendre
geometry {"home/sb30/d53110391-200.err"}
 
 
mais sur le gros fichier vdi, ce même n° est bien converti

Reply

Marsh Posté le 05-05-2017 à 00:33:47    

 
           Je viens de tester de mon côté via Notepad++ à partir d'un fichier .vdi
           afin de respecter la séquence de fin de ligne (LF) :  aucun souci !
 
           Donc je soupçonne ton fichier ne respectant pas cette norme des fichiers originaux …
 

Reply

Marsh Posté le 05-05-2017 à 08:44:04    

je pense aussi que c'est ça
le VBA n'arrive pas a le trouver
par contre le VBS y arrive
 
 

Reply

Marsh Posté le 05-05-2017 à 08:58:01    

 
           Cette dernière précision le confirme !
 
           En effet le code VBA recherchant les lignes se terminant par  .bgf"}  via l'opérateur  Like
           tandis qu'en VBScript est cherché la présence de  .bgf  dans les lignes via la fonction  InStr  …
 
           Utiliser NotePad++ (téléchargeable et gratuit), il permet de vérifier le résultat par exemple
           en comptant le nombre de .bgf ou de .err;  il permet aussi de s'entraîner aux expressions rationnelles …
 

Reply

Marsh Posté le 06-05-2017 à 17:44:54    

 
           Suite à ton autre discussion, ceci est plus rapide de mon côté :
 

Code :
  1. Function GetFileExt(ByVal Init, Filter, Title)
  2.         S = Split(Init, "\" )
  3.         If UBound(S) < 1 Then Exit Function
  4.         E = Split(S(UBound(S)), "." )
  5.         If UBound(E) > 0 Then E(UBound(E)) = "*" & E(UBound(E))
  6.         S(UBound(S)) = Join(E, "." )
  7.         Init = Join(S, "\\" )
  8.     Set oDlg = CreateObject("WScript.Shell" ).Exec("mshta.exe ""about:<object id=d classid=clsid:3050f4e1-98b5-11cf" & _
  9.                "-bb82-00aa00bdce0b></object><script>moveTo(0,-9999);eval(new ActiveXObject('Scripting." & _
  10.                "FileSystemObject').GetStandardStream(0).Read(" & Len(Init) + Len(Filter) + Len(Title) + 39 & " ));" & _
  11.                "function window.onload(){var p=/[^\0]*/;new ActiveXObject('Scripting.FileSystemObject')." & _
  12.                "GetStandardStream(1).Write(p.exec(d.object.openfiledlg(init,null,filter,title)));close();}" & _
  13.                "</script><hta:application showintaskbar=yes />""" )
  14.         oDlg.StdIn.Write "var init='" & Init & "';var filter='" & Filter & "';var title='" & Title & "';"
  15.         GetFileExt = oDlg.StdOut.ReadAll
  16.     Set oDlg = Nothing
  17. End Function
  18. With CreateObject("Scripting.FileSystemObject" )
  19.            F = GetFileExt("\*.vdi", "", "        Fichier à convertir :" )
  20.         If F = "" Then WScript.Quit 1
  21.            P = .GetParentFolderName(F)
  22.            D = P & "\IPC.txt"
  23.    If Not .FileExists(D) Then
  24.            D = GetFileExt(P & "\*.txt", "", "        Dictionnaire :" )
  25.         If D = "" Then WScript.Quit 2
  26.    End If
  27.            E = ".bgf"
  28.            R = ".err"
  29.            P = P & "\M " & .GetFileName(F)
  30.        Set oDic = CreateObject("Scripting.Dictionary" )
  31.        Set oRTF = .OpenTextFile(D, 1)
  32.            oRTF.ReadLine
  33.   Do Until oRTF.AtEndOfStream
  34.            oDic(LCase(oRTF.ReadLine)) = ""
  35.   Loop
  36.            oRTF.Close
  37.        Set oRTF = .OpenTextFile(F, 1)
  38.        Set oWTF = .OpenTextFile(P, 2, True)
  39. End With
  40. With New RegExp
  41.        .Pattern = "[a-z]\d{8}"
  42.   Do Until oRTF.AtEndOfStream
  43.        S = oRTF.ReadLine
  44.     If InStr(S, E) Then
  45.        If .Test(S) Then
  46.            V = .Execute(S)(0)
  47.            If Not oDic.Exists(V) Then S = Replace(S, E, R)
  48.        Else
  49.            S = Replace(S, E, R)
  50.        End If
  51.     End If
  52.            oWTF.Write S & vbLf
  53.   Loop
  54. End With
  55.            oRTF.Close:          oWTF.Close:          oDic.RemoveAll
  56.        Set oRTF = Nothing:  Set oWTF = Nothing:  Set oDic = Nothing
  57. CreateObject("WScript.Shell" ).Run "mshta.exe vbscript:close(CreateObject(""WScript.Shell"" )" & _
  58.                                   ".Popup(""Création de " & P & """,3,""   Conversion"",64))"


Message édité par Marc L le 06-05-2017 à 18:55:57
Reply

Sujets relatifs:

Leave a Replay

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