Problème : extraire données d'un fichier sequentiel [Résolu]

Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 09:35 - Dernière réponse : cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention
- 26 mai 2011 à 16:18
Bonjour,

J'ai a ma disposition un fichier texte dans lequel sont référencés des articles. A chaque ligne correspond un article. J'ai la structure de tous les champs. Je m'explique : je sais par exemple que sur chaque ligne, de la position 2 à la position 3, j'ai une lettre correspondant a l'article, et de la position 200 à 210 j'ai le prix. Je connais aussi la structure de tous les autres champs mais ils ne me sont pas nécessaires. Je cherche juste a extraire quelques infos pour chaque ligne de produit et tout mettre dans un tableau tel que

A | 200
D | 300
E | 400


J'utilise visual basic, après de nombreuses recherches, j'ai trouvé un code :

Dim T() as string
...
Open "C:\Monfichier.txt" As #1 For Input
i = -1
While Not Eof(1)
  i = i + 1
  Redim Preserve T(i)
  Line Input #1, T(i)



Cependant, visual studio ne connais pas "open", j'ai donc opté pour :

Dim i As Integer
        Dim T(i) As String


        My.Computer.FileSystem.OpenTextFileReader("C\catalogue.txt")
        i = -1
        While Not EOF(1)
            i = i + 1
            ReDim Preserve (i)
            LineInput(1), T(i)

        End While


Mais VB m'indique : "Erreur 1 Les instructions 'ReDim' requièrent une liste entre parenthèses des nouvelles limites de chaque dimension du tableau. "


Auriez vous une idée ou une solution qui pourrait m'expliquer ou est mon erreur et comment pourrais je exploiter ce fichier ??

Cordialement,
Afficher la suite 

Votre réponse

27 réponses

Meilleure réponse
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 26 mai 2011 à 10:31
3
Merci
Je crois que y'a un mélange entre les deux méthodes de lecture de fichier.
Dans la 2ème méthode il ne faut pas un LineInput, mais un ReadLine()
Voilà à quoi peut ressembler ton code :

Dim T() As String
Dim i As Integer
Dim sr As StreamReader 
Dim ligne As String
sr = my.Computer.FileSystem.OpenTextFileReader("C\catalogue.txt")
i = 0
Do
ligne = sr.ReadLine()
If (Not ligne Is Nothing) Then
i = i +1
Redim Preserve T(i)
T(i) = ligne
End If
Loop Until ligne Is Nothing
sr.Close()


A noter :
- pas de gestion d'exception dans ce code, je te laisse le faire
- j'initialise i à 0 car il me semble que les indices commence à 1 en VB, et qu'un Redim Preserve T(0) doit pas enchanter le compilo ^^
- je suis pas expert VB, une méthode plus classieuse existe peut-être

Merci cs_jopop 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 82 internautes ce mois-ci

Commenter la réponse de cs_jopop
Meilleure réponse
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 26 mai 2011 à 10:45
3
Merci
oki,

dans l'absolu je ferai une classe de mapping (et oui, encore ^^)

Tu crées une simple classe avec les champs qui te vont bien (label et quantity a priori), et tu lui mets un constructeur qui prend ses valeurs en paramètre.

Ensuite tu remplace ton tableau de String par un tableau de ce nouvel objet.

Enfin, dans ta boucle, au lieu de faire :
 T(i) = ligne

tu fais :
 T(i) = New MonObjetDeMapping(Mid(ligne, 2, 2), Mid(ligne, 200, 11))


C'est sûrement la méthode que j'aurais choisi mais tu peux aussi :
- faire des tableau 2D (n, m) avec m constante correspondant aux nombre de champs,
- faire autant de tableau que tu as de champs à traiter

Merci cs_jopop 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 82 internautes ce mois-ci

Commenter la réponse de cs_jopop
Meilleure réponse
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 26 mai 2011 à 11:40
3
Merci
Pourquoi pas effectivement faire le traitement en aval.
Est-ce que c'est optimisé ? non
Est-ce que la différence sera sensible ? je pense pas, donc pas de souci

Sinon avec ma technique d'objet ça donnerait un truc comac :

Code de la classe de mapping :
Public Class Product
' les champs extraits
Public Reference As String
Public Price As Double
'le constructeur paramétré
Sub New(ByVal pref As String, ByVal pprice As Double)
Me.Reference = pref
Me.Price =  pprice
End Sub
End Class


Code de l'extraction des données :
Dim T() As Product
Dim i As Integer
Dim sr As StreamReader
Dim ligne As String
sr  = My.Computer.FileSystem.OpenTextFileReader("C\catalogue.txt")
i = 0
Do
ligne = sr.ReadLine()
If (Not ligne Is Nothing) Then
i = i + 1
ReDim Preserve T(i)
T(i) = New Product(Mid(ligne, 2, 2), Convert.ToDouble(Mid(ligne, 200, 11)))
End If
Loop Until ligne Is Nothing
sr.Close()

Merci cs_jopop 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 82 internautes ce mois-ci

Commenter la réponse de cs_jopop
Meilleure réponse
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 26 mai 2011 à 13:40
3
Merci
Voila une autre proposition
il faut tester
Private Structure lesdetails
     Public article As Char
     Public prix As Double
End Structure
Private listdetails As New List(Of lesdetails)
Private listitems As New List(Of String)
Private Sub ReadFile()
   Dim pathfichier As String
  'le chemin du fichier
   pathfichier = "C:\ReadFile\TEST.TXT"
   Try
       listitems = System.IO.File.ReadAllLines(pathfichier).ToList
   Catch ex As Exception
      MessageBox.Show(ex.Message)
  End Try
End Sub

Private Sub ExtraireDetails()
   Dim detail As lesdetails
   listdetails.Clear()
   For Each element In listitems
       
       detail.article = element.Substring(2, 1)
       detail.prix = element.Substring(200, 11)
       listdetails.Add(detail)
    Next
 End Sub

Merci cs_ShayW 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 82 internautes ce mois-ci

Commenter la réponse de cs_ShayW
Meilleure réponse
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 26 mai 2011 à 15:46
3
Merci
tout d'abord
dans un tableau les position commence par 0
la list est comme un tableau
tu peux t'addresser par index
list(0)
quand je lis ton fichier il est mis
dans listitems qui se comporte comme un tableau de chaine
listitems(0) la premiere ligne de ton fichier
Dim ch As Char
'dans ch j'ai le premier caractère de la premiere de ton fichier
ch = listitems(0)(0)

par ex je met les deux list dans une listbox nommée listX
ListX.Items.Clear()
        Dim str As String
        For iter As Integer = 0 To listdetails.Count - 1
            str = listitems(iter).Substring(1, 1) & " " _
            & listitems(iter).Substring(199, 11) & listdetails(iter).article & " | " & listdetails(iter).prix
            ListX.Items.Add(str)
        Next

j'espère avoir mieux expliqué

et aussi en net
VB 6 Commands and equivalents in net
Len = .Length
Mid = .SubString
Replace = .Replace
InStr = .IndexOf
UCase = .ToUpper
LCase = .ToLower
Split = .Split
Join = .Join

Merci cs_ShayW 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 82 internautes ce mois-ci

Commenter la réponse de cs_ShayW
Meilleure réponse
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 26 mai 2011 à 16:18
3
Merci
Attention
ne pas utiliser un messagebox dans une loop

bonne prog

Merci cs_ShayW 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 82 internautes ce mois-ci

Commenter la réponse de cs_ShayW
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 26 mai 2011 à 10:07
0
Merci
Salut,

dans le 2ème code que tu as retranscrit il manque le nom de ton tableau
ton code : ReDim Preserve (i)
ce qu'il faut : ReDim Preserve T(i)

le souci vient ptèt de là
Commenter la réponse de cs_jopop
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 10:12
0
Merci
Merci jopop de cette réponse rapide, en effet il manquait bien le nom du tableau, cependant quand j'essaye d'inserer la ligne dans un tableau avec : "LineInput(1, T(i))"

VB me dit "Arguments trop nombreux pour "Public Function LineInput(FileNumber as Integer) as string""

J'ai beau chercher sur le MSDN je ne trouve rien ...
Commenter la réponse de Moundir76
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 10:25
0
Merci
EDIT : Problème résolu,

Désormais je recupere -chaque ligne dans une variable. Je souhaite a partir d'autres variables extraire les données qui m'interessent. Ex reference = Strings.Mid(TextLine, 10, 20).

Cela ne me pose pas de souci mais je n'arrive pas a mettre ces données dans un tableau comme expliqué dans mon premier message...


Merci d'avance
Commenter la réponse de Moundir76
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 10:57
0
Merci
Merci pour tes réponses astucieuses, Je suis débutant dans le VB et je n'ai pas encore attaqué la programmation orientée objet.
Mais je pense qu'en créant un tableau 2D je vais réussir.
Le seul hic c'est que je ne vois pas comment je peux ajouter dans un tableau T( , ) d'une part X et d'une autre part Y

Ligne 1 du tableau => X | Y

J'opterais pour (Mid(ligne, 2, 2), Mid(ligne, 200, 11))

Mais je ne vois pas comment VB fait la différence entre X et Y dans le tableau pour la meme ligne !

Encore Merci Jopop
Commenter la réponse de Moundir76
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 26 mai 2011 à 11:06
0
Merci
Si on veut représenter les cells d'un tableau ça donnerait plutôt un truc comac :
X1Y1 | X1Y2
X2Y1 | X2Y2
X3Y1 | X3Y2
...

Par contre je viens de voir qu'apparemment en VB on ne peut redimensionner un tableau que sur sa dernière dimension. Du coup il faut voir la chose comac :
X1Y1 X1Y2 X1Y3
--- --- --- ...
X2Y1 X2Y2 X2Y3

Sinon j'ai trouvé sur ce site un topic sur les tableaux VB qui pourrait t'intéresser
Commenter la réponse de cs_jopop
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 11:17
0
Merci
Merci pour l'explication et le lien, mais je ne comprends pas sur le topic, je suis en train de réfléchir et de me dire si je ne suis pas mieux à mettre dans mon tableau à une seule dimension la concaténation des infos qui m'interessent puisque les champs ont toujours la même longueur.

x1 => A 200
x2 => D 300
...........

Je ne sais pas si c'est tres optimisé, car par la suite je vais devoir aller extraire chaque lettre et la comparer a une base de données afin d'inserer le prix de l'article correspondant directement dans la BDD...

Merci !
Commenter la réponse de Moundir76
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 11:56
0
Merci
Merci, cette méthode fonctionne aussi mais je n'arrive pas a interpreter comment sont stockées les données ... Est ce que VB va sélectionner l'article puis le prix et les concatener dans le tableau ou bien est ce que le tableau est séparé en 2 categories distinctes dans une seule ligne ???

Je ne comprends pas comment je peux exploiter ces données... Pour ma part j'avais vu ça comme ca :

Dim T() As String
        Dim i As Integer
        Dim sr As StreamReader
        Dim ligne As String
        sr = My.Computer.FileSystem.OpenTextFileReader("C:\catalogue.txt")
         i = 1
        Do
        ligne = sr.ReadLine()
        
        
             If (Not ligne Is Nothing) Then
                  i = i + 1
                   ReDim Preserve T(i)
                    T(i) = Mid(ligne, 64, 12) + Mid(ligne, 198, 11)
                                      End If
               Loop Until ligne Is Nothing
                sr.Close()


Ainsi sur chaque indice de tableau on trouvait : T(1) = A 200
etc...

Peux tu m'expliquer la différence avec ta méthode ?
Commenter la réponse de Moundir76
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 26 mai 2011 à 12:05
0
Merci
Voilà comment accéder à tes données après les avoir extraites selon ma méthode :
'affiche le nom du 1er produit dans une popup, soit "A"
MsgBox (T(1).Reference)
'affiche le prix du 1er produit dans une popup, soit 200
MsgBox (T(1).Price)


La différence est simple : tu fais un tableau de string et chaque fois que tu vas vouloir une info en particulier il faudra découper cette string. Ma méthode fait le découpage en amont, tu n'auras plus besoin de le faire par la suite.

NB : Attention, je crois que l'opérateur de concaténation en VB est le '&' (et non le '+' comme en C# ou JS)
Commenter la réponse de cs_jopop
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 26 mai 2011 à 13:06
0
Merci
Salut
pas clair
quand tu dis
je sais par exemple que sur chaque ligne, de la position 2 à la position 3, j'ai une lettre correspondant

2 à 3 il y a deux caractères
et aussi as tu la position 0 ?
Commenter la réponse de cs_ShayW
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 13:40
0
Merci
En effet Jopop ta méthode me parait plus simple et optimisée pour ma recherche de données. Merci beaucoup. et sous VB pour concatener c'est bien "+" ;).

@ShayW

Pour être plus précis quand j'ai par exemple :

"A","1235                            ",


A la position 1 je suis avant mon premier guillemet. et donc entre la position 2 et la position 3 j'obtiens bien A
Commenter la réponse de Moundir76
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 26 mai 2011 à 13:53
0
Merci
plutot

  Private Structure lesdetails
     Public article As Char
     Public prix As Double
End Structure
Private listdetails As New List(Of lesdetails)
Private listitems As New List(Of String)
Private Sub ReadFile()
   Dim pathfichier As String
  'le chemin du fichier
   pathfichier = "C:\ReadFile\TEST.TXT"
   Try
       listitems = System.IO.File.ReadAllLines(pathfichier).ToList
   Catch ex As Exception
      MessageBox.Show(ex.Message)
  End Try
End Sub

Private Sub ExtraireDetails()
   Dim detail As lesdetails
   listdetails.Clear()
   For Each element In listitems
       
       detail.article = element.Substring(1, 1)
       detail.prix = element.Substring(199, 11)
       listdetails.Add(detail)
    Next
 End Sub                       
Commenter la réponse de cs_ShayW
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 14:08
0
Merci
Merci ShayW,

Ce que je comprends : Un procédure va lire le fichier afin de le mettre dans une "list" et une autre procédure va extraire de la liste uniquement les données qui m'interessent.
J'execute donc ces 2 procédures dans ma private sub load mais cependant je n'arrive pas a acceder a cette "listdetails" .......... Je ne comprends pâs sous quelle forme est stockée cette "list".

Merci
Commenter la réponse de Moundir76
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 26 mai 2011 à 14:24
0
Merci
comme tu as dis
ReadFile lis tout le fichier d'un bloc
et le met dans une list of string

que veux tu faire avec listdetais ?
pour accéder à chaque élement de listdetails

for each element as lesdetails in  listdetails
'que veux tu faire exactement ?
  element.article
  element.prix
next
Commenter la réponse de cs_ShayW
Moundir76 286 Messages postés dimanche 3 octobre 2010Date d'inscription 16 mai 2014 Dernière intervention - 26 mai 2011 à 14:35
0
Merci
En fait je souhaite afficher les resultats de la list element afin de verifier que tout y est. Sinon je ne comprends pas comment ils sont triés dans la liste. Par exemple je vais prendre chaque référence pour la comparer a une BDD SQL.

Exemple : A l'emplacement 1 ( Dans le cas du tableau T(1)=A) je voudrais trouver la valeur A et parcourir valeur par valeur cette liste.

Merci pour ton aide
Commenter la réponse de Moundir76

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.