Multiselection et listes [Résolu]

Messages postés
3
Date d'inscription
lundi 9 septembre 2019
Statut
Membre
Dernière intervention
12 septembre 2019
-
Bonjour à tous !

Voilà, depuis une semaine je me suis mis à visual basic pour répondre à une demande en entreprise.
la problématique est la suivante :

j'ai 3000 fichiers textes (contenu désorganisé) contenant chacun 94 lignes (ce sont des résultats d'essais) soit 282000 lignes au total.
Or sur ces fichiers textes, j'ai besoin de récupérer uniquement quelques lignes (la 3 - 4 - et une dernière "flottante" correspondant à l'endroit ou le test à échoué) et ce pour chacun des 3000 fichiers.

Du coup je me suis beaucoup renseigné sur les aides, ce forum et d'autres pour parvenir à ce programme :

Imports System.IO
Imports System.Text
'DUT ANALYSER

Public Class Form1
    Dim chemin, path, bloc, x, y, z As String
    Dim testpos, i As Integer
    Dim pathwriter As StreamWriter
    Dim lst As New List(Of String)


    Private Sub odtbut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles odtbut.Click
        If path = "" Then
            MsgBox("Please, select first a destination file", MsgBoxStyle.Exclamation, "No destination file")
        Else
            'select only txt files
            OpenFileDialog1.Filter = "Text (*.txt)|*.txt"
            OpenFileDialog1.Multiselect = True

            If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then

                'open a window to choose the path of the TXT file
                chemin = OpenFileDialog1.FileName
                lst.Add(chemin)

                For Each chemin In lst

                    'the file is readed by this application
                    Dim file() As String = IO.File.ReadAllLines(chemin)
                    Dim nblignes = file.Length - 1

                    'lbl1.Text = file(4).ToString 'used to see if the programm worked
                    'lbl2.Text = file(94).ToString
                    'comparaison is done with the number of lines : the test stop automatically when it fails, so you always have
                    'less datas than a passed test : it means less lines
                    ' if the test is failed, this programm will search all lines where test failed
                    'test 
                    y = Mid(file(3), 45, 6) 'we take the serial number
                    z = Mid(file(4), 35, 6)
                    lbl1.Text = y
                    lbl2.Text = z
                    'we write in the TXT document we opened earlier (the final one)
                    pathwriter = New StreamWriter(path, True, Encoding.Unicode)
                    If nblignes < 94 Then
                        pathwriter.WriteLine(y & ";" & z & ";" & nblignes & "failed")
                        lbl3.Text = nblignes & "   " & "failed"
                    Else
                        pathwriter.WriteLine(y & ";" & z & ";" & nblignes & "success")
                        lbl3.Text = nblignes & "   " & "success"
                    End If
                    pathwriter.Close()
                    'print the number of files tested
                    i = i + 1
                    lbl5.Text = i
                Next
            Else
                MsgBox("No file selected, please choose one file", MsgBoxStyle.Exclamation, "No file selected")
            End If
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'we pick up the path of the tested folder
        'select only txt files
        OpenFileDialog2.Filter = "Text (*.txt)|*.txt"
        If OpenFileDialog2.ShowDialog() = Windows.Forms.DialogResult.OK Then
            path = OpenFileDialog2.FileName
            ' i is the counter of txt documents you analyse
            i = 0
            Button1.Enabled = False 'to avoid missclicks
        Else
            MsgBox("No file selected, please choose one file", MsgBoxStyle.Exclamation, "No file selected")
        End If

    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        path = ""
       
    End Sub
End Class



(j'ai commenté le code en anglais car je suis actuellement en Irlande)
Le code en soit fait parfaitement ce que je lui demande : le problème c'est qu'il gère le truc fichier par fichier et réitérer le processus 3000 fois est beaucoup trop pénible : et ce même si j'arrive à sélectionner tous les fichiers que je veux traiter dans l'openfiledialog.
j'ai tenté de rectifier ça avec une liste et une boucle for each mais elle retourne uniquement le dernier fichier lu.

Pourriez vous m'aider à adapter ce programme pour faire en sorte que tous les fichiers soient traités et pas uniquement le dernier ?

J'essaie pas d'avoir un truc tout cuit, mais franchement, un coup de main serait sympa.

Merci !
Afficher la suite 

6 réponses

Meilleure réponse
Messages postés
6421
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
5 décembre 2019
91
1
Merci
Bonjour,

Si tes fichiers sont dans le même répertoire tu peux utiliser filesystem.getfiles qui va parcourir tous les fichiers du répertoire. Il te suffit d’intégrer ton code dans la boucle

https://docs.microsoft.com/fr-fr/dotnet/api/microsoft.visualbasic.fileio.filesystem.getfiles?view=netframework-4.8

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CodeS-SourceS

Codes Sources 207 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_Le Pivert
Messages postés
14597
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
2 décembre 2019
137
1
Merci
Il ne faudrait pas écrire
OpenFileDialog1.FileNames
plutôt ?

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CodeS-SourceS

Codes Sources 207 internautes nous ont dit merci ce mois-ci

Heorhelm
Messages postés
3
Date d'inscription
lundi 9 septembre 2019
Statut
Membre
Dernière intervention
12 septembre 2019
-
Oui en effet, c'est la solution que j'ai retenue ^^
merci !
Commenter la réponse de NHenry
Messages postés
1979
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
5 décembre 2019
77
1
Merci
Bonjour
Tout d'abord tu avais posté ton message dans la section Visual Basic 6 : j'ai modifié en Visual Basic Net ( VB Net)
Ensuite ton code d'origine mélange VB6 et VB Net ( Msgbox, Mid par exemple sont des instructions VB 6)
Microsoft a laissé dans VB Net la possibilité d'utiliser des instructions VB6 mais cela est pour moi une aberration : c'était juste pour ne pas désorienter les nombreux programmeurs VB6 et les conserver dans le giron de Microsoft
Par contre pour faire du vrai DoNet il existe un moyen tout simple
1 ) aller dans le menu Projet
2) aller à Propriétés de "Nomdetonprojet"
3) Dans la fenêtre qui s'ouvre allez dans References
4) Dans les "espaces de noms importés" en bas tu décoches Microsoft VisualBasic
Ceci fait que tu n'auras plus accès aux instructions VB6 et tu programmeras en vrai VB Net .
En passant vas aussi dans l'onglet "Compiler" en haut à gauche et ouvres le .
Mets Option Strict et Option Explicit sur On .
Option Explicit t'oblige à ce que toutes les variables soient déclarées ;
Option Strict restreint les conversions de types de données implicites aux conversions étendues, interdit la liaison tardive et interdit le typage implicite qui produit un Object type.

Maintenant je t''ai écrit ce code en gardant les mêmes noms de contrôles que toi .
Teste le et dis moi ce qu'il en est !

Imports System.IO
Imports System.Text
'DUT ANALYSER

Public Class Form1

    Private path As String, i As Integer ' for this form

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        path = String.Empty

    End Sub

    Private Sub odtbut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles odtbut.Click

        Dim y, z As String ' for this procedure
        If path = String.Empty Then
            ' replace Msgbox en DoNet
            MessageBox.Show("Please, select first a destination file", "No destination file", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        Else
            'select only txt files
            With OpenFileDialog1 ' With permet de ne pas répéter Openfiledialog1
                .Filter = "Text (*.txt)|*.txt"
                .Multiselect = True
                If .ShowDialog() = Windows.Forms.DialogResult.OK Then
                    'open a window to choose the path of the TXT file
                    For Each chemin In .FileNames ' for all the files you have selected
                        'the file is readed by this application
                        Dim lines() As String = IO.File.ReadAllLines(chemin)
                        Dim nblignes = lines.Length - 1

                        'lbl1.Text = file(4).ToString 'used to see if the programm worked
                        'lbl2.Text = file(94).ToString
                        'comparaison is done with the number of lines : the test stop automatically when it fails, so you always have
                        'less datas than a passed test : it means less lines
                        ' if the test is failed, this programm will search all lines where test failed
                        'test 
                        y = lines(3).Substring(45, 6) 'we take the serial number (SubString to replace Mid function in DoNet) 
                        z = lines(4).Substring(35, 6)
                        lbl1.Text = y
                        lbl2.Text = z
                        'we write in the TXT document we opened earlier (the final one)
                        With New StreamWriter(path, True, Encoding.Unicode)
                            Dim chaine As String = If(nblignes < 94, "failed", "success") ' If compact in one line
                            .WriteLine(y & ";" & z & ";" & nblignes & chaine)
                            lbl3.Text = nblignes & "   " & chaine
                            .Close()
                        End With
                        'print the number of files tested
                        i += 1
                        lbl5.Text = i
                    Next
                Else
                    MessageBox.Show("No file selected, please choose one file", "No file selected", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                End If
            End With
        End If

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        'we pick up the path of the tested folder
        'select only txt files
        With OpenFileDialog2
            .Filter = "Text (*.txt)|*.txt"
            If .ShowDialog() = Windows.Forms.DialogResult.OK Then
                path = .FileName
                ' i is the counter of txt documents you analyse
                i = 0
                Button1.Enabled = False 'to avoid missclicks
            Else
                MessageBox.Show("No file selected, please choose one file", "No file selected", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End If
        End With

    End Sub

End Class

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CodeS-SourceS

Codes Sources 207 internautes nous ont dit merci ce mois-ci

Heorhelm
Messages postés
3
Date d'inscription
lundi 9 septembre 2019
Statut
Membre
Dernière intervention
12 septembre 2019
-
parfait ça marche du tonnerre !

Désolé d'avoir mélanger les codes, comme je le disais plus haut j'ai commencé il y a une semaine et franchement, si ça faisait ce que je voulais c'était déjà pas mal ^^

Merci à tous pour vos réponses !
Commenter la réponse de vb95
Messages postés
1979
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
5 décembre 2019
77
0
Merci
Bonjour
Petit oubli dans le code que je t'ai proposé
A la ligne 31 remplacez
Dim nblignes = lines.Length - 1

par
Dim nblignes as Integer = lines.Length - 1


Il faut déclarer la variable avec un type
Commenter la réponse de vb95
Messages postés
135
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
17 novembre 2019
2
0
Merci
Salut à tous,

Pour le VB5/6, j'ai l'habitude d'utiliser un "FileListBox" en aveugle (hors fenêtre).

Je paramètre le path, le tag d'extension en "*.txt", puis un "refresh" avant le process.

Il suffit de reprendre chaque élément de la liste… (for each...) et de traiter par lot.
Mais, il faut savoir qu'il existe des problèmes de version sur certains noms de fichier ( points multiples, accentuation et caractères spéciaux), qui peuvent "oublier" certains fichiers dans la liste. Donc, méfiez-vous des noms des fichiers traités.
Commenter la réponse de JeuDuTaquin
Messages postés
1979
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
5 décembre 2019
77
0
Merci
Bonjour JeuduTaquin
Ici dans l'exemple VB Net donné par le créateur de ce post et amélioré par moi-même inutile de rajouter un FileListbox .
La collection "OpenFileDialog1.FileNames" joue ce même rôle en interne et de façon transparente pour l'utilisateur ( seuls les fichiers sélectionnés sont dans cette collection )
De plus tu parles de VB 5/6 et ici nous sommes en VB Net
Donc hors sujet .
JeuDuTaquin
Messages postés
135
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
17 novembre 2019
2 -
Salut Vb95,
Effectivement, tu as peut-être raison. Il aurait été plus judicieux d'utiliser du C++ en mode console pour effectuer ces tâches répétitives… et lire le résultat dans une API VB. Le traitement en serai forcément plus rapide.
Commenter la réponse de vb95