Compter les lignes lors d'un 'replace'

Résolu
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008
-
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008
-
Bonjour,


j'utilise la fonction 'replace' dans un script et j'aurais besoin de
connaitre le numéro de la ligne où la chaine à remplacer a été
trouvée...

J'ai réussi à compter les lignes lors de l'exécution avec :
FileLineCount = Ubound(Split(objTextStream.ReadAll, vbLf))
Reste à trouver le moyen de savoir à quelles lignes s'effectuent les changements...

Quelqu'un aurait une idée SVP

Merci d'avance

18 réponses

Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
133
Bah pourtant, c'est pas bien dur :

Dim sAvant As String
Dim iFileLineCount As Integer
Dim sText() As string
Dim sApres As String

sText = Split(objTextStream.ReadAll, vbLf)
iFileLineCount = Ubound(sText )

For i = 0 to iFileLineCount
   
    sAvant = sText(i)
    Replace(sText(i), "CeQueTuVeuxRemplacer", "Par quoi le remplacer")
    sApres = sText(i)
    if sAvant <> sApres Then
       'C'est différent !
    end if
Next i
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
133
ben si tu fait un replace de vbLf, il suffit de compter le nombre de ligne.

Maintenant, si tu fais un replace sur chaque ligne, tu peux comparer le nombre de caractère avant et après le remplacement pour savoir quelles sont les lignes modifiées (plus rapide) ou sinon, l'égalité entre la ligne avant et après le replace (plus long).
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Ouais ouais ouais,

en fait je ne vois pas trop là!!!

Le replace ne se fait pas sur toutes les lignes mais en fonction de ce
que je lui donne dans l'inputbox, ça dépend des fichiers...

Je ne vois pas comment comparer avant et après, le nombre de ligne sera
identique, a priori, et si je remplace 'toto' par 'titi' le nombre de
caractères aussi..

Peux-tu m'éclairer un peu STP?

Merci
Messages postés
129
Date d'inscription
jeudi 28 octobre 2004
Statut
Membre
Dernière intervention
23 mai 2009
1
Si tu veux savoir le nombre de caractères à remplacer si tu peux mettre avant ton replace 
c = Split(Textedelaligne, "ceux que tu veux remplacer")
 MsgBox UBound(c)

Si c'est un fichier texte tu peux travailler ligne par ligne et les compter
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Merci Darksidious, le seul problème c'est que ça me donne le résultat
complet (tout le fichier modifié) et non ligne par ligne....

En fait je voudrais insérer une ligne de remarque avant chaque ligne
modifiée, et là je ne vois pas trop en fait. Il faudrait connaitre
chaque ligne pour laquelle le 'replace' intervient et faire un
(ligne-1) pour insérer la nouvelle ligne. Oui je sais, je suis
chiant... lol
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
133
Bah où est la difficulté ???

Je t'ai donné la méthode pour tester LIGNE PAR LIGNE lesquelles sont modifiées, et non le résultat complet comme tu le dit.

Essaye un peu les codes qu'on te donne aussi, on est pas là pour tout faire à ta place.
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Ouh là mais on se calme!! biensûr que j'ai essayé le code que tu m'as
donné et mon debugger me renvoie la valuer totale du fichier et non
ligne par ligne.... Désolé mais je suis autodidacte et franchement
moyen en vbscript, ce qui te paraît facile ne l'est pas forcément pour
les autres. Je sais que vous n'êtes pas là pour tout faire à ma place,
c'est clair, mais j'essaye d'expliquer au mieux mon cas, voilà quoi...
Peut-être un peu trop Dark le Sidious aujourd'hui ...
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
133
Bon je vais reprendre plus calmement alors, mais je persiste à dire qu'il n'y a aucune difficulté : lorsque tu lit le bout de code que je t'ai donné... tu as la réponse dedans !

Dim sAvant As String 'stocke la chaîne avant la fonction replace
Dim sApres As String 'stocke la chaîne après la fonction replace
Dim iFileLineCount As Integer 'stocke le nombre de ligne dans le fichier
Dim sText() As string 'stocke les lignes du fichier
dim iNombreLigneModifiée As Integer 'stocke le nombre de lignes modifiées par la fonction replace

sText = Split(objTextStream.ReadAll, vbLf) 'on lit le fichier et on récupère les lignes de celui-ci
iFileLineCount = Ubound(sText ) 'on récupère le nombre de lignes

For i = 0 to iFileLineCount 'on parcourt les lignes une à une
   
    sAvant = sText(i) 'on stocke la ligne AVANT la fonction replace
    Replace(sText(i), "CeQueTuVeuxRemplacer", "Par quoi le remplacer") 'on applique la fonction replace
    sApres = sText(i) 'on stocke la ligne APRES la fonction replace
    if sAvant <> sApres Then 'on teste si les deux chaînes sont différentes
       'C'est différent !
       'tu n'as plus qu'à faire ce que tu veux sur la ligne en question (index de la ligne : i)
       iNombreLigneModifiée =
iNombreLigneModifiée + 1 'incrémentation du compteur de lignes modifiées

    end if
Next i

MsgBox iNombreLigneModifiée

Voilà, après exécution, la variable iNombreLigneModifiée contient le nombre de lignes modifiées et uniquement le nombre de lignes modifiées.
Tu n'as plus qu'à faire les traitements sur tu veux dans le "c'est différent" puisque c'est dans la ligne i où la fonction replace à vraiment remplacer quelque chose.
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Merci Darksidious, j'avais compris à peu près. ça marche mais à quelques détails prêt:


sText = Split(objTextStream.ReadAll, vbLf)

iFileLineCount = Ubound(sText )


For i = 0 to iFileLineCount

  sAvant = sText(i)

    If instr(trim(strtmp(i)),Saisie1) Then

     sText(i) = Replace(sText(i), "CeQueTuVeuxRemplacer", "ParQuoiLeRemplacer")

    End If

    If sAvant <> sApres Then

      ' c'est different!

    End If

Next


Pour la partie "c'est différent", j'ai un blème: je suis oblige de faire un objTextStream.Close pour réouvrir le fichier en ForWriting. Le hic c'est qu'il me vire tout ce qu'il y a dans le fichier à part la ligne modifiée....

c'est pénible forcément. désolé d'être un peu lourd mais j'apprend...
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
133
Mais c'est quoi ton objTextStream au juste ???

Pourquoi n'utilise-tu pas directement les fonctions de lecture de VB, ce sera plus simple :
Open "NomDeTonFichier" For Input As #1
Line Input #1, laLigneARecuperer
Close #1

Comme cà en plus, ca laisserai ton fichier comme à l'origine.
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Mon objTextStream c'est un fichier texte. Le problème c'est que je suis en VBScript et pas VB: pas pareil!!
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Voilà le code, ce sera plus clair....


For Each fichier in fichiers

   If fso.GetExtensionName(fichier) = Saisie3 Then


   Dim objTextStream

   Set objTextStream = Fso.OpenTextFile(GetPath & fichier.Name, ForReading)

   Resultat = objTextStream.ReadAll

   strtmp = split(Resultat, vbLf)

  

   For i = 0 to Ubound(strtmp)

       If instr(trim(strtmp(i)),Saisie1) Then

           strtmp(i) = Replace(strtmp(i), Saisie1, Saisie2)

       End If

           objTextStream.Close

           Set
objTextStream = Fso.OpenTextFile(GetPath & fichier.Name,
ForWriting, True)

           objTextStream.Write strtmp(i)

   Next

   objTextStream.Close

   End If

Next


Et chaque fois qu'une ligne du  fichier est modifiée, je voudrais
insérer une ligne avant pour un commentaire (Saisie4). Voilà, j'espère
que c'est plus clair.
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Rectification:   sText = Split(objTextStream.ReadAll, "") dans mon code sinon ça plante...
Messages postés
15814
Date d'inscription
jeudi 8 août 2002
Statut
Modérateur
Dernière intervention
4 mars 2013
133
Attention, ta façon de faire ne marchera pas aussi facilement : je présume que le FSO (jamais utilisé pour écrire dans un fichier) réagit de la même façon que vb : lorsque tu lui dit d'écrire quelque chose, il efface tout avant de le faire !

Donc le truc : traîte ta chaîne dans une variable String, et ensuite, et seulement ensuite, écrit la dans le fichier :

Dim objTextStream
Dim iLineNumber As Integer
For Each fichier in fichiers
   If fso.GetExtensionName(fichier) = Saisie3 Then

  
       Set objTextStream = Fso.OpenTextFile(GetPath & fichier.Name, ForReading)
       Resultat = objTextStream.ReadAll
       objTextStream.Close
       strtmp = split(Resultat, vbLf)
       iLineNumber = UBound(strtmp) 'ca évite de recalculer à chaque tour de boucle !
       For i = 0 to Ubound(strtmp)
           If instr(trim(strtmp(i)),Saisie1) Then
               strtmp(i) = Replace(strtmp(i), Saisie1, Saisie2)
           End If
       Next

        Set objTextStream = Fso.OpenTextFile(GetPath & fichier.Name, ForWriting, True)
        For i = 0 to UBound(strtmp) 'écriture de toutes les lignes à la fois

            objTextStream.Write strtmp(i)
        Next i
       objTextStream.Close
   End If
  
Next
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Vraiment désolé, je viens d'essayer ton code, ça marche effectivement mais il écrit n'importe quoi....

Celui-là fonctionne à merveille:


Const ForReading 1, ForWriting 2, ForAppending = 8

Dim fso, Dossiers, fichier, fichiers, i, strtmp, Resultat

Set fso = CreateObject("Scripting.FileSystemObject")

Set Dossiers = fso.GetFolder(GetPath)

Set fichiers = Dossiers.Files


For Each fichier in fichiers

   If fso.GetExtensionName(fichier) = Saisie3 Then


   Dim objTextStream

   Set objTextStream = Fso.OpenTextFile(GetPath & fichier.Name, ForReading)

   Resultat = objTextStream.ReadAll

   strtmp = split(Resultat, "")

  

   For i = 0 to Ubound(strtmp)

       If instr(trim(strtmp(i)),Saisie1) Then

           strtmp(i) = Replace(strtmp(i), Saisie1, Saisie2)

       End If

           objTextStream.Close

           Set
objTextStream = Fso.OpenTextFile(GetPath & fichier.Name,
ForWriting, True)

           objTextStream.Write strtmp(i)

   Next

   objTextStream.Close

   End If

Next


'Fonction de récupération du répertoire courant

Function GetPath()

Dim path

path = WScript.ScriptFullName

GetPath = Left(path, InStrRev(path, ""))

End Function


Set objTextStream = Nothing

Set fso = Nothing
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Salut,


réponse acceptée mais ça ne résoud pas exactement mon problème... tant pis, je continue de chercher. Merci quand même.
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
26
 Bonsoir,

Suite à ton mail, si ça peut t'aider....
Un script que je suis en train de mettre en prod.

Si d'autres questions, repose un topic...

@+
jean-marc

'
'Modification, dans un fichier .txt, de l'occurence située après une occurence passée en variable
'
Option Explicit


Dim NEW_CHAINE, Separator
Separator = "="
NEW_CHAINE = "ce texte remplacera le mot situé après l'occurence""" & Separator & """ et la suite de la ligne. Ici,     "


Dim Fso, Path, Fichier, Fic_Entree, Fic_Sortie, Fic_Temp, Fic_Sauv, lignes
Dim i, strtmp, strtmp_count, strtmp_count_ligne_courante, strtmp_count_lignes_modifiees Const ForReading 1, ForWriting 2, ForAppending = 8


Path   = "d:"
Fichier  = "test1.txt"
Fic_Sauv = Path & "sauv_" & Fichier
Fic_Temp = Left(Path & Fichier,Len(Path & Fichier)-4) & "_new.txt"


Set Fso = CreateObject("Scripting.FileSystemObject")
Set Fic_Entree = Fso.OpenTextFile(Path & Fichier, 1, False)
Set Fic_Sortie = Fso.OpenTextFile( Fic_Temp, 2, True)


Do While Not Fic_Entree.AtEndOfStream


   strtmp = Split(Fic_Entree.ReadAll, vbCrLf)   'création tableau du fichier
   strtmp_count = UBound(strtmp)                'nombre de lignes du fichier


'  For i = LBound(strtmp) to Ubound(strtmp)  ' ou ligne ci-dessous
   For i = 0 to Ubound(strtmp)
       strtmp_count_ligne_courante = strtmp_count_ligne_courante + 1


       Dim MyArray
       MyArray = Split(Trim(strtmp(i)), Separator, -1, 1) 'creation tableau de la ligne courante
  
       If UBound(MyArray) = 1 Then
       Dim Msg, New_Array
       Msg = MyArray(0) & Space(1) &  Separator & Space(1) & MyArray(1)


       New_Array = Split(Trim(MyArray(1)), " ", -1, 1) 'création tableau de la chaine à modifier


'MsgBox "ligne " & strtmp_count_ligne_courante & "   avant modif: " &vbCrLf& Msg &vbCrLf&vbCrLf&_
'       "ligne " & strtmp_count_ligne_courante & "   après modif: " &vbCrLf& Replace(Msg, New_Array(0), NEW_CHAINE) &vbCrLf&vbCrLf&_
'       "Longueur de la ligne avant modif: " & Len(Msg) &vbCrLf&_
'       "Longueur de la ligne après modif: " & Len(Replace(Msg, New_Array(0), NEW_CHAINE)) &vbCrLf&vbCrLf&_
'       "L'occurence   """ & New_Array(0) & """  située après """ & Separator & """ a été remplacée par """ & NEW_CHAINE & """"
   
       strtmp(i) = Replace(Msg, New_Array(0), NEW_CHAINE)
 
 
 'Exemple pour insérer une ligne
        strtmp(i) = "'la ligne " & strtmp_count_ligne_courante & " ci-dessous a été modifiée" &vbCrLf& strtmp(i)
         strtmp_count_lignes_modifiees = strtmp_count_lignes_modifiees + 1
 
 '       MsgBox strtmp(i)
 '     End If   
   End If
  


'      Call Fic_Sortie.WriteLine(strtmp(i))  ' ou ligne ci-dessous
       Fic_Sortie.WriteLine strtmp(i)
'      Fic_Sortie.WriteBlankLines 1       '    pour créer une ligne à blanc
   Next
Loop
Call Fic_Sortie.WriteBlankLines(2)
Call Fic_sortie.WriteLine("Nombre de lignes modifiées : " &  strtmp_count_lignes_modifiees)
Call Fic_Sortie.Close
Call Fic_Entree.Close


'Rename fichiers
'Fso.CopyFile Path & Fichier, Path & "sauv_" &  Fichier, True
Fso.CopyFile Fic_Temp, Path & Fichier, True
Fso.DeleteFile Fic_Temp


Set Fic_Sortie = Nothing
Set Fic_Entree = Nothing
Set Fso = Nothing
MsgBox "Script terminé" &vbCrLf& "Nombre de lignes modifiées : " &  strtmp_count_lignes_modifiees


'Contenu du fichier test1.txt avant
'ligne1 début du test
'ligne2
'
'tttt =      jean-marc_1 expression
'mot_1 = valeur_a_changer valeur_devant_rester
'
'autre cas: aaaa = jean-marc_2
'ligne8 com /1 mentai=/res
'ligne9 mot_1 = valeur_a_changer
'
'
'Contenu du fichier test1.txt après
'ligne1 début du test
'ligne2
'
''la ligne 4 ci-dessous a été modifiée
'tttt  =       ce texte remplacera le mot situé après l'occurence"=" et la suite de la ligne. Ici,      expression
''la ligne 5 ci-dessous a été modifiée
'mot_1  =  ce texte remplacera le mot situé après l'occurence"=" et la suite de la ligne. Ici,      valeur_devant_rester
'
''la ligne 7 ci-dessous a été modifiée
'autre cas: aaaa  =  ce texte remplacera le mot situé après l'occurence"=" et la suite de la ligne. Ici,    
''la ligne 8 ci-dessous a été modifiée
'ligne8 com /1 mentai = ce texte remplacera le mot situé après l'occurence"=" et la suite de la ligne. Ici,    
''la ligne 9 ci-dessous a été modifiée
'ligne9 mot_1  =  ce texte remplacera le mot situé après l'occurence"=" et la suite de la ligne. Ici,    
'
'
'
'
'Nombre de lignes modifiées : 5
Messages postés
78
Date d'inscription
vendredi 4 février 2005
Statut
Membre
Dernière intervention
6 octobre 2008

Salut,


de même que pour mon autre post, je regarde dès que possible, merci!!