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.
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
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
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 ^^
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.
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 .
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.