Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1418 connectés 

  FORUM HardWare.fr
  Programmation
  VB/VBA/VBS

  Detection et remplacement string

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Detection et remplacement string

n°2299463
daniel-12
Posté le 20-04-2017 à 21:02:57  profilanswer
 

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:

mood
Publicité
Posté le 20-04-2017 à 21:02:57  profilanswer
 

n°2299482
Marc L
Posté le 21-04-2017 à 10:42:48  profilanswer
 

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

n°2299507
daniel-12
Posté le 21-04-2017 à 22:44:26  profilanswer
 

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
n°2299512
Marc L
Posté le 22-04-2017 à 02:43:03  profilanswer
 

 
            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).
 

n°2299539
daniel-12
Posté le 22-04-2017 à 17:19:06  profilanswer
 

ç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

n°2299604
Marc L
Posté le 23-04-2017 à 21:42:15  profilanswer
 

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

n°2299796
daniel-12
Posté le 25-04-2017 à 17:12:13  profilanswer
 

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
n°2299813
Marc L
Posté le 26-04-2017 à 00:44:46  profilanswer
 

 
           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


 

n°2300125
Marc L
Posté le 03-05-2017 à 13:50:27  profilanswer
 

 
           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
n°2300135
daniel-12
Posté le 03-05-2017 à 17:18:08  profilanswer
 

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

mood
Publicité
Posté le 03-05-2017 à 17:18:08  profilanswer
 

n°2300148
Marc L
Posté le 04-05-2017 à 00:28:15  profilanswer
 

 
           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 ?
 

n°2300209
Marc L
Posté le 04-05-2017 à 19:16:07  profilanswer
 

 
           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
n°2300216
daniel-12
Posté le 04-05-2017 à 23:38:23  profilanswer
 

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

n°2300218
Marc L
Posté le 05-05-2017 à 00:33:47  profilanswer
 

 
           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 …
 

n°2300222
daniel-12
Posté le 05-05-2017 à 08:44:04  profilanswer
 

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

n°2300223
Marc L
Posté le 05-05-2017 à 08:58:01  profilanswer
 

 
           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 …
 

n°2300317
Marc L
Posté le 06-05-2017 à 17:44:54  profilanswer
 

 
           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

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  VB/VBA/VBS

  Detection et remplacement string

 

Sujets relatifs
script perl pour remplacement des chiffre en motsApplication de detection de mouvement
comparaison string perlprobleme detection Adblock en Javascript+PHP tourne pas rond
Simplifier une ligne de push_back (string) répétitifsConvertir binaire en string (noob) [résolu]
[Python] Replace string tupleUWP et détection usb
détection d'IP en phpArchitecture en D3 JS (detection collision)
Plus de sujets relatifs à : Detection et remplacement string


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR