web-dev-qa-db-fra.com

Lire ligne par ligne un fichier txt avec VBS

J'essaie ce code:

filename = "test.txt"
listFile  = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
For Each line In listLines
   WScript.Echo line 
   'My Stuff
Next

Ou cet autre:

filename = "test.txt"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.OpenTextFile(filename, ForReading)
    Do Until f.AtEndOfStream
      myLine = f.ReadLine
      WScript.Echo myLine
      'My Stuff
    Loop

Pourquoi dans les deux cas cela fait écho à toutes les lignes à la fois, et bien sûr je ne peux pas travailler ligne par ligne? Une idée?

9
Mark

Votre fichier contient des marqueurs EndOfLine amusants. Supposons que les lignes se terminent par vbLf:

>> fn = "lf.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbLf)
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>>    WScript.Echo ts.ReadLine
>> loop
>>
a
b
c

Comme vous pouvez le voir, .ReadLine peut gérer vbLf (unix). Votre Split () sur .ReadAll (), cependant, échouera:

>> t = goFS.OpenTextFile(fn).ReadAll()
>> a = Split(t, vbCrLf)
>> WScript.Echo UBound(a)
>> WScript.Echo a(0)
>>
0
a
b
c

t ne contient pas un seul vbCrLf, donc Split () renvoie un tableau avec UBound () == 0, contenant t comme élément unique. .Echoing qui ressemblera au moins à 3 (4) lignes. Vous pouvez Split () sur vbLf, si vous avez vraiment besoin d'un tableau de lignes.

Mais si vos fichiers contiennent des terminaisons vbLf, alors la boucle .ReadLine devrait fonctionner correctement.

.ReadLine () ne peut pas faire face à vbCr (mac):

>> fn = "cr.txt"
>> goFS.CreateTextFile(fn).Write Replace("a b c ", " ", vbCr)
>>
>> set ts = goFS.OpenTextFile(fn)
>> do until ts.AtEndOfStream
>>    WScript.Echo ts.ReadLine
>> loop
>>
c

Le b + cr "écrase" le a + cr et est ensuite "écrasé" par c + cr. L'approche .ReadAll () échouera également, sauf si vous utilisez vbCr comme séparateur.

Mais si vos fichiers contiennent des terminaisons vbCr, alors aucun de vos extraits ne peut "faire écho à toutes les lignes à la fois".

Votre fichier vient-il de l'espace?

Mettre à jour le commentaire:

Vous ne pouvez pas lire UTF-8 en utilisant le Filesystemobject . Soit convertir le fichier en UTF-16 et utiliser l'option Unicode du paramètre format lorsque .OpenTextFile, ou travailler avec un flux ADODB.

Il serait toujours intéressant de savoir quel marqueur EOL est utilisé.

11
Ekkehard.Horner

Votre code semble bien fonctionner. Je l'ai légèrement modifié pour montrer que les lignes sont en fait lues ligne par ligne:

Set fso=CreateObject("Scripting.FileSystemObject")

filename = "test.txt"
listFile = fso.OpenTextFile(filename).ReadAll
listLines = Split(listFile, vbCrLf)
i = 0

For Each line In listLines
   WScript.Echo CStr(i) + " : " + line 
   i = i + 1

   'My Stuff
Next

Je suppose que fso est défini quelque part dans votre script, mais j'ai ajouté cette ligne supplémentaire juste pour être complet.

Vous devez vérifier que votre fichier d'entrée comporte effectivement plusieurs lignes séparées par vbCrLf. Le compteur i aide à déboguer chaque ligne car il affiche l'index de la ligne lors de la lecture des lignes.

3
xxbbcc