Multiselection et listes

Résolu
Heorhelm Messages postés 3 Date d'inscription lundi 9 septembre 2019 Statut Membre Dernière intervention 12 septembre 2019 - Modifié le 9 sept. 2019 à 17:29
JeuDuTaquin Messages postés 250 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 23 mai 2023 - 13 sept. 2019 à 22:18
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 !

6 réponses

cs_Le Pivert Messages postés 7893 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 19 mai 2023 136
9 sept. 2019 à 18:28
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

1
NHenry Messages postés 15067 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 27 mai 2023 158
9 sept. 2019 à 20:05
Il ne faudrait pas écrire
OpenFileDialog1.FileNames
plutôt ?
1
Heorhelm Messages postés 3 Date d'inscription lundi 9 septembre 2019 Statut Membre Dernière intervention 12 septembre 2019
12 sept. 2019 à 09:46
Oui en effet, c'est la solution que j'ai retenue ^^
merci !
0
vb95 Messages postés 3417 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 20 mai 2023 165
9 sept. 2019 à 22:52
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

1
Heorhelm Messages postés 3 Date d'inscription lundi 9 septembre 2019 Statut Membre Dernière intervention 12 septembre 2019
12 sept. 2019 à 09:46
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 !
0
vb95 Messages postés 3417 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 20 mai 2023 165
13 sept. 2019 à 15:33
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
0

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

Posez votre question
JeuDuTaquin Messages postés 250 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 23 mai 2023 7
Modifié le 13 sept. 2019 à 19:37
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.
0
vb95 Messages postés 3417 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 20 mai 2023 165
13 sept. 2019 à 19:46
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 .
0
JeuDuTaquin Messages postés 250 Date d'inscription mardi 4 juillet 2017 Statut Membre Dernière intervention 23 mai 2023 7
13 sept. 2019 à 22:18
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.
0