Bonjour, voila j'ai un code qui doit supprimer la ligne de texte comportant le mot prédéfini. Le problème est que le code génère l'erreur :
L'index était hors limites. Il ne doit pas être négatif et doit être inférieur à la taille de la collection. Nom du paramètre : index
A mon avis le RemoveAt(i) pose problème car il supprime une ligne et cela décale le n° des lignes et au final ca les suppriment toutes.
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*txt")
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For ' ne passe pas à la ligne de dessous mais remonte pour traiter le prochain fichier
For i As Integer = 0 To lines.Count - 1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
Next
Qu'en pensez-vous ?
Ma LV2 c'est le Visual Basic, et toi ?
A voir également:
Visual basic en ligne
Visual studio code supprimer retour à la ligne - Meilleures réponses
Supprimer le contenu d'un fichier python - Meilleures réponses
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For
For i = lines.Count - 1 To 0 Step -1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
System.IO.File.WriteAllLines(files, lines.ToArray)
Next
For i As Integer = 0 To lines.Count - 1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
Si ta ligne contient "toto", tu la retire, donc ça fait une ligne de moins.
Mais les bornes du For ne sont calculées qu'au début de la boucle, donc, une modification du nombre de lignes en cours de boucle, ne sera pas prise en compte.
2 solutions :
Soit un If pour faire un Exit For si i>Lines.count-1
soit plus fin, partir de la dernière ligne pour remonter :
For i As Integer = 0 To lines.Count - 1
deviendrait :
For i As Integer = lines.Count - 1 to 0 step -1
J'ai essayé la soluce de raffika, mais c'est toujours la même erreur
NHenry, j'ai essayé ta soluce n°2 qui donne la même erreur mais je comprend pas la n°1 :
Soit un If pour faire un Exit For si i>Lines.count-1
Vraiment bizard
Ma LV2 c'est le Visual Basic, et toi ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Ah oui ma solution ne marche pas,
mais comment ça se fait que si i est plus
grand que lines.count-1 la boucle for n'est pas stoppée ?
@aus3004 pour la première solution de NHenry, ça donnes :
For i As Integer = 0 To lines.Count - 1
If i > lines.Count - 1 Then
Exit For
End If
If lines(i).Contains("toto") Then
lines.RemoveAt(i) : i += 1
End If
Next
Pour la seconde, ça donne :
If lines(i).Contains("toto") Then
lines.RemoveAt(i) : i += 1
End If
Salutations
Merci raffika, j'ai essayé la soluce n°1 de NHenri mais rien ne ce passe !
Les deux documents texte ayant chacun une ligne comportant le mot prédéfini n'ont pas changés.
J'ai essayé les deux solutions de NHenry,
avec un fichier texte avec plusieurs lignes,
certaines contenant toto, ensuite
dans une boucle for je regarde le résultat :
for i=0 to lines.count-1
msgbox(lines(i))
next i '' donc après la modification bien sur
Qu'est ce que tu veux dire par ne marche pas ?
Quel résultat tu veux obtenir ?
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For
For i = lines.Count - 1 To 0 Step -1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
System.IO.File.WriteAllLines(TextBox1.Text, lines) '?
Next
Ah, dsl j'ai peut être pas été assez claire.
Il faut que tous les fichiers texte de la boucle soient modifiés avec :
toutes les lignes comportant le mot prédéfini soient supprimées.
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For
If lines.Count = 0 Then Continue For
For i = lines.Count - 1 To 0 Step -1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
System.IO.File.WriteAllLines(files, lines)
Next
Je reprend le code de Raffika (qui a utilisé la 2ième solution que j'évoquais) :
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For
For i = lines.Count - 1 To 0 Step -1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
System.IO.File.WriteAllLines(files, lines)
Next
Tu peux tenter ceci j'ai commenté pour expliquer, mais s'il te reste des questions n'hésite pas
Dim files(), lines() As String
Dim output As New List(Of String)
Try
' Récupère les chemins des fichiers
files = IO.Directory.GetFiles(TextBox1.Text, "*txt", IO.SearchOption.AllDirectories)
For Each file In files
' Vide la liste
output.Clear()
' Récupère les lignes du fichier
lines = IO.File.ReadAllLines(file)
For Each line In lines
' Si la ligne ne contient pas 'toto' on l'ajoute à la liste
If Not line.Contains("toto") Then
output.Add(line)
End If
Next
' Ne réécrit le fichier que si le contenu à changé
' autrement dit si son nombre de ligne a baissé
If output.Count < lines.Length Then
' Je réécris dans le même fichier, si tu ne le souhaites pas
' pense à changer le 1er paramètre
System.IO.File.WriteAllLines(file, output)
End If
Next
Catch ex As Exception
' En cas de problème (si un fichier est utilisé par une autre application par exemple)
MessageBox.Show(ex.Message, "Une erreur est survenue")
End Try
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
'' J'ai remis le point entre * et txt
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For
For i = lines.Count - 1 To 0 Step -1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
System.IO.File.WriteAllLines(files, lines)
Next
Une valeur de type 'System.Collections.Generic.List(Of String)' ne peut pas être convertie en 'Tableau à 1 dimension(s) de String'.
Dim files(), lines() As String
Dim output As New List(Of String)
' Récupère les chemins des fichiers
files = IO.Directory.GetFiles(TextBox1.Text, "*txt", IO.SearchOption.AllDirectories)
For Each file In files
' Vide la liste
output.Clear()
' Récupère les lignes du fichier
lines = IO.File.ReadAllLines(file)
For Each line In lines
' Si la ligne ne contient pas 'toto' on l'ajoute à la liste
If Not line.Contains("toto") Then
output.Add(line)
End If
Next
' Ne réécrit le fichier que si le contenu à changé
' autrement dit si son nombre de ligne a baissé
If output.Count < lines.Length Then
' Je réécris dans le même fichier, si tu ne le souhaites pas
' pense à changer le 1er paramètre
System.IO.File.WriteAllLines(file, output)
End If
Next
Une valeur de type 'System.Collections.Generic.List(Of String)' ne peut pas être convertie en 'Tableau à 1 dimension(s) de String'.
Il reste bien entendu cette dernière solution,
qui marches, selon le principe que la dernière ligne
contiendra obligatoirement un Environment.Newline
mais qui peut être modifié ...
For Each files In My.Computer.FileSystem.GetFiles(TextBox1.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.txt")
Dim lines As List(Of String) = System.IO.File.ReadAllLines(files).ToList
If lines.Count = 0 Then Continue For
If lines.Count = 0 Then Continue For
For i = lines.Count - 1 To 0 Step -1
If lines(i).Contains("toto") Then
lines.RemoveAt(i)
End If
Next
Dim resultat As String = "" '' On crée une variable string
For i = 0 To lines.Count - 1
resultat &= lines(i) & Environment.NewLine
'' on met les lignes de 'lines' une par unes suivies de
'' Environment.Newline (retour à la ligne)
Next
'' et on écrit le fichier selon la méthode Writealltext
'' qui écrit la string resultat dans le fichier files
System.IO.File.WriteAllText(files, resultat)
Next
J'ai pris le dernier code de NHenry, c'est impec !
@NHenry, mdr ta signature, moi je connais la Haute Autorité pour le Développement Optimal du Piratage sur Internet
Une dernière question, est-ce que cela marche avec tous les fichiers de texte à votre avis (dsl, je peux pas tester) ?