VBA - Souci extraction contenu fichier .txt

cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009 - 27 janv. 2009 à 16:34
cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009 - 30 janv. 2009 à 15:02
Salut a tous

J'ai un gros fichier .txt environ 500 000 caracteres.

Contenu du type :
""magrandmereestpartievisitersasoeurdanslejuracetaittres
chouettemaisellesestcasseeunejambeetadu......................""

Donc c'est tout un bloc de concatene sans espaces ni retour a la ligne.
Mon souci est de recuperer ce bloc de texte dansune seule variable String
pour ensuite traiter le decoupage et l'analyse.

Origine du fichier .txt :
Donnees recuperees dans un fichier excel et enregistrees sous format .txt.
    Set FS = CreateObject("Scripting.FileSystemObject")
    Set A = FS.createtextfile("TEST_SAVE.txt", , True)
    A.write Contenu_fichier_excel
    A.Close

Au cas ou l'info serait utile, ce fichier comporte egalement des caracteres
asiatiques donc est enregistre avec option Unicode.

Merci d'avance de toute aide qui sera apportee.

V

12 réponses

b0uh34 Messages postés 56 Date d'inscription mercredi 6 février 2008 Statut Membre Dernière intervention 19 février 2009
27 janv. 2009 à 18:24
Dim l1 as String

Open "ton_fichier.txt" as Input #1
Line Input #1 , l1

'Et voila dans l1 t'as ta chaine de caractere...
Je garantis pas par contre mais ca peut peut-etre te servir.
0
cs_Orohena Messages postés 577 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 20 novembre 2010 4
27 janv. 2009 à 18:49
Bonjour

A mon avis, il faut éviter de charger 500 000 K dans une chaîne, surtout si tu dois la manipuler pour extraire des informations. Tu vas consommer énormément de ressources et ton temps d'exécution sera très long. Pourquoi poses-tu comme principe de départ de charger le bloc dans une seule variable ?

Amicalement
0
cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009
28 janv. 2009 à 00:17
 


Le texte etant compacte, il n'y a pas de reperes type coupure/saut de ligne donc la lecture au ligne par ligne ne se fait pas correctement.

la solution proposee par b0uh34 me retourne 330 caracteres pas plus. pire encore, dans la chaine renvoyee se trouvent des caracteres inconnus... donc le contenu n'est pas utilisable.
( caracteres inconnus constates : ÿþ en debut de chaine par exemple ou ensuite encore d'autre un peu plus loin )


Donc ma solution est de pomper l'integralite du texte en 1 fois pour appliquer le traitement approprie a la restitution du texte de base.


Constatation : les caracteres asiatiques semblent bugger egalement d'ou les caracteres inconnus en milieu
de chaine, par contre en debut de chaine, les fameux < ÿþ > sont bel et bien des ajouts et non des soucis
d'interpretation de caracteres asiatiques.

toraV
0
cs_Orohena Messages postés 577 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 20 novembre 2010 4
28 janv. 2009 à 02:59
Hello

Bon, dans ce cas, ouvre-le en binaire et charge le en entier :

Dim nf As Integer
Dim buffer As String
nf = FreeFile()
Open "big_mama.txt" For Binary As nf
buffer = Space(Lof(nf))
Get nf, 1, buffer
Close nf


Amicalement 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009
28 janv. 2009 à 07:34
merci Orohena ... mais je n'ai pas compris ou se trouvait le contenu du fichier ?
Est-ce dans buffer ? Si je fais Msgbox buffer je recois 3 caracteres .. (?)

buffer = ÿþµ

seul le dernier ( µ ) est reellement dans monf fichier .txt ...

merci encore

toraV
0
cs_Orohena Messages postés 577 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 20 novembre 2010 4
28 janv. 2009 à 20:19
Bonjour

Oui, le contenu se trouve bien dans la variable buffer.

Si un MsgBox ne t'affiche que les trois premiers caractères cela indique que le 4e est un caractère de contrôle. Tu auras le même résultat en ouvrant le fichier avec le Bloc Note qui, lui-aussi, ne gère que le texte brut (caractères ascii "affichables").

La présence de caractères de contrôle dans le fichier est assez logique puisque tu as enregistré le fichier avec l'option unicode. Je n'ai que des connaissances superficielles à ce sujet, mais je sais que les caractères spéciaux occupent plusieurs octets dont des caractères de contrôle.

Peux-tu ouvrir le fichier avec Word ou Wordpad ? Ils supportent le format unicode et, par conséquent, le fichier devrait apparaître en entier et être lisible. Vérifie que l'affichage ne contient pas de petit carrés, ce qui voudrait dire que le format du fichier n'est pas supporté.

Amicalement
0
cs_Orohena Messages postés 577 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 20 novembre 2010 4
29 janv. 2009 à 20:00
Salut

D'après ton MP, ton fichier est composé d'une suite de strings de codes séparés par un caractère. Le nombre de strings est variable et peut être très élevé. A mon avis, il vaut mieux lire le fichier de la façon dont on lit un flux de données dont on ne connaît pas la fin (et éventuellement sans fin), par blocs de <n> codes.

Voici un exemple :

Sub readCodeStream(chemin As String)
   Const n = 1024                  ' nombre de codes charges a chaque lecture du fichier
   Dim nf As Integer
   nf = FreeFile()
   Dim buffer As String * n      ' buffer de chargement du bloc de codes
   Dim reste As String           ' codes en fin de bloc non traites
   Open chemin For Binary As nf
   Do
         Get nf, , buffer
         reste = decodage(reste & buffer)
   Loop Until Seek(nf) >= LOF(nf)
   Close nf
End Sub



Function decodage(codeString As String) As String
   Dim i As Integer
   Const separateur = "€"
   i = 1
   Do
      i = InStr(i, codeString, separateur)
      If i > 0 Then
         MsgBox Left(codeString, i)
         codeString = Mid(codeString, i + 1)
      End If
   Loop Until i = 0
   decodage = codeString
End Function


Le fichier est lu par blocs de n = 1024 caracteres, et peu importe donc s'il fait 1K ou 10 MB. En particulier, si le fichier est énorme, les ressources nécessaires restent limitées et le temps de traitement est optimal (c.a.d. strictement proportionnel a la taille du fichier).

La fonction decodage "décode" les blocs et renvoie les codes "résiduels" non traités, et qui seront traités à l'appel suivant.

J'ai fait un test sur un fichier contenant le codeStream suivant
 
mnaaM§0305020401€mnaaM§0305020402€
il a été concluant avec <n> 5 et <n> 1024.

Je pense que <n> = 1024 est une bonne valeur ; en fait il suffit qu'il soit relativement grand par rapport à la longueur moyenne d'un string.

Peux-tu essayer sur ton fichier ?

Amicalement
0
cs_Orohena Messages postés 577 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 20 novembre 2010 4
29 janv. 2009 à 20:06
Oups, il faut lire :

 i = InStr( 1 , codeString, separateur)

au lieu de :

 i = InStr(i, codeString, separateur)

dsl
0
cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009
30 janv. 2009 à 00:17
hello hello,

merci encore mais je pense que ca doit encore etre different ...
je voulais voir quel etait le string retourne j'ai donc j'ai ajoute
une variable public string Recup pour visualiser le resultat en
fin de course. Voila le retour affiche en msgbox pour Recup :  ÿþµ

Sub readCodeStream(chemin As String)
   Const n = 1024                  ' nombre de codes charges a chaque lecture du fichier
   Dim nf As Integer
   nf = FreeFile()
   Dim buffer As String * n      ' buffer de chargement du bloc de codes
   Dim reste As String           ' codes en fin de bloc non traites
   Open chemin For Binary As nf
   Do
         Get nf, , buffer
         reste = decodage(reste & buffer)
   Loop Until Seek(nf) >= LOF(nf)
   Close nf
   MsgBox Recup
End Sub


Function decodage(codeString As String) As String
   Dim i As Integer
   Const separateur = "€"
   i = 1
   Do
      i = InStr(1, codeString, separateur)
      If i > 0 Then
        Recup = Recup & Left(codeString, i)
         'MsgBox Left(codeString, i)
         codeString = Mid(codeString, i + 1)
      End If
   Loop Until i = 0
   decodage = codeString
End Function

toraV
0
cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009
30 janv. 2009 à 00:21
bizarre comme retour alors que la machine marne pendant environ 8 secondes ...

toraV
0
cs_Orohena Messages postés 577 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 20 novembre 2010 4
30 janv. 2009 à 01:30
Au contraire, ces résultats sont tout à faits normaux et il semble que tout aille bien ! As-tu déjà oublié que ton fichier est unicode et donc contient non seulement des caractères affichables mais également toutes sortes de codes ASCII, que l'instruction MsgBox ne peut pas gérer ? Ton Msgbox recup s'arrête au 3e caractere tout simplement parce que le 4e est un code non affichable. Quand l'instruction Msgbox rencontre un caractère non affichable, il ignore le reste de la chaîne. Ton recup contient donc non pas 3 caractères, mais tout ton fichier, ce dont tu peux te rendre compte en remplaçant ton Msgbox recup par Msgbox Len(recup) : tu ne devrais pas avoir "3" mais quelquechose comme "500000".

Donc tout ce qu'il te reste à faire pour arriver au bout du tunnel, c'est de remplacer l'instruction Msgbox Left(codeStream, i) dans mon code, par l'appel d'une routine de décryptage de chaque string se trouvant dans Left(codeStream, i)

Cordialement
0
cs_tora Messages postés 15 Date d'inscription lundi 24 juin 2002 Statut Membre Dernière intervention 20 mars 2009
30 janv. 2009 à 15:02
malheureusement le resultat n'est pas encore ideal.
Il y a 2 caracteres en debut a supprimer, il y a des cases vides entre chaque caractere
et plus grave les caracteres asiatiques ( ici c'est japonais en fait ) buggent ... 
( les 2 caracteres de debut et les blancs je peux traiter mais les buggs de traduction je
 ne sais pas .... )

bouuuuu...

toraV
0