Ah p'tet pas
Mais chaque fois il faut un temps énormes pour analyser/remplacer 486578 lignes 29110 fois.
Si tous tes tests se sont basés sur 486578 * 29110 itérations alors ce n'est pas la peine de tout décrire, juste de confirmer ce point.
Ha c'est mieux le code, merci
J'ai aussi pensé que je pourrais peut-être effacer la donnée de la liste CSV #2 quand elle est trouvée.
Le premier élément de la liste 1 chercher dans les 29110 de la liste 2.
Si trouvé, l'élément est effacé des 2 listes. Dans ce quand, plus on avance, moins il y a d'articles dans la liste 2.
486578 *29110, 486578 *29109, 486578 *29108, etc.
Non, tu vas chercher de nombreuses valeurs inutilement.
Il ne faut chercher que celles qui sont dans le fichier de mise à jour.
On va commencer par un truc bourrin, l'idée est que si les fichiers sont triés, quand tu as trouvé la première référence, la seconde sera plus loin dans le fichier donc pas besoin de repasser les lignes précédentes.
Je tâche de te faire un exemple dans la soirée
J'ai trouvé !
L'opération se complète en 15 secondes.
Dim idsNotInB = dt2.AsEnumerable().[Select](Function(r) r.Field(Of String)("PART")).Except(dt1.AsEnumerable().[Select](Function(r) r.Field(Of String)("PART"))) Dim dt3 As DataTable = (From row In dt2.AsEnumerable() Join id In idsNotInB On row.Field(Of String)("PART") Equals id Select row).CopyToDataTable() DataGridView3.DataSource = dt3 dt3.Merge(dt1)
Merci beaucoup
Bonjour
des idées oui, mais peut-être celles que tu as déjà testées. On gagnerait donc du temps si tu décrivais tes essais ou que tu postais les codes correspondant.
Pour poster un code, il faut faire comme décrit là https://codes-sources.commentcamarche.net/faq/11288-poster-un-extrait-de-code
Question subsidiaire est ce que tu arrives à charger toutes les lignes dans un tableau avec File.ReadAllLines ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question1. J'ai ouvert chaque CSV dans un DataTable différent. J'arrive a charger toutes les données en quelques secondes (5-10) dans un DataGridView
'Création du DataTable 1 avec le CSV #2 Dim filepath1 As String = TextBox3.Text Dim sr1 As New StreamReader(filepath1) Dim f1 As File Dim fval1 As String() Dim dt1 As New DataTable Dim dr1 As DataRow sr1 = f1.OpenText(filepath1) fval1 = sr1.ReadLine().Split(",") For i As Integer = 0 To fval1.Length - 1 dt1.Columns.Add(New DataColumn(fval1(i).ToString())) Next dr1 = dt1.NewRow While sr1.Peek() <> -1 fval1 = sr1.ReadLine().Split(",") dr1 = dt1.NewRow For i As Integer = 0 To fval1.Length - 1 dr1.Item(i) = fval1(i).ToString() Next dt1.Rows.Add(dr1) End While DataGridView1.DataSource = dt1 MessageBox.Show("dt1 construit") 'Création du DataTable 2 avec le CSV #1 Dim filepath2 As String = TextBox4.Text Dim sr2 As New StreamReader(filepath2) Dim f2 As File Dim fval2 As String() Dim dt2 As New DataTable Dim dr2 As DataRow sr2 = f2.OpenText(filepath2) fval2 = sr2.ReadLine().Split(",") For i As Integer = 0 To fval2.Length - 1 dt2.Columns.Add(New DataColumn(fval2(i).ToString())) Next dr2 = dt2.NewRow While sr2.Peek() <> -1 fval2 = sr2.ReadLine().Split(",") dr2 = dt2.NewRow For i As Integer = 0 To fval2.Length - 1 dr2.Item(i) = fval2(i).ToString() Next dt2.Rows.Add(dr2) End While DataGridView2.DataSource = dt2 MessageBox.Show("dt2 construit")
2. Ensuite je crée une liste des valeurs en double a supprimer.
'Faire une list des doublons et les supprimer de dt2 Dim common As List(Of DataRow) = (From r1 In dt1.AsEnumerable() Join r2 In dt2.AsEnumerable() On r1("PART") Equals r2("PART") Select r1).ToList() Dim deletenumber As Integer = 0 MessageBox.Show(common.Count & " doublons") For Each dr As DataRow In common For i As Integer = dt2.Rows.Count - 1 To 0 Step -1 Dim drDelete As DataRow = dt2.Rows(i) If deletenumber = 1000 Then MessageBox.Show(deletenumber.ToString & " Doublons effacés") End If If deletenumber = 5000 Then MessageBox.Show(deletenumber.ToString & " Doublons effacés") End If If dr("PART").ToString() = dt2.Rows(i)("PART").ToString() Then deletenumber = deletenumber + 1 drDelete.Delete() End If Next dt2.AcceptChanges() Next MessageBox.Show(deletenumber.ToString & " Doublons effacés") DataGridView3.DataSource = dt2
3. Je rajoute les données du dt1 dans le dt2.
dt2.Merge(dt1, False)
Avec une petite quantité de données dans le CSV #2 ça fonctionne bien. Mais avec toutes les données c'est très long (J'ai arrêté après 15 minutes d'attente).
J'ai aussi essayé en chargeant les données de chaque CSV dans des DataGrid différents et enlever les lignes qui sont pareil.
C'est aussi long.
For i = dgv.Rows.Count - 1 To 0 Step -1 Dim srcRow As DataGridViewRow = dgv.Rows(i) 'find matched rows in DataGridView2 Dim rowsToRemove = DataGridView2.Rows. Cast(Of DataGridViewRow)(). Where(Function(row) row.Cells("PART").Value = srcRow.Cells("PART").Value). ToList() Dim x As Integer = rowsToRemove.Count For Each dstRow In rowsToRemove DataGridView2.Rows.Remove(dstRow) Next If x > 0 Then dgv.Rows.Remove(srcRow) Next
J'ai commencé à vérifier pour créer un dictionnaire avec les données du CSV #2 mais je ne suis pas sûr si ça accélère le processus. Je n'ai jamais travaillé avec ce processus avant non plus.
Pour la coloration, il faut choisir Basic.
OK.
Je ne vois pas trop l'intérêt de passer par une datable, d'autant que tu sais faire du linq qui marche pareil avec un tableau ou une liste.
Le Datagridview, oublie, c'est très lent, et pas pensé pour stocker les données, mais pour les afficher.
Est-ce que ton gros fichier est trié par "Part" ?
Si non, je suppose qu'il est utilisé par un autre logiciel. Est-ce que ça poserait un problème à ce logiciel qu'il le soit ?
Et du coup, est-ce que le petit fichier est trié ?
Si non, idem ?
Et pour ma question subsidiaire ?
Oui les 2 fichiers sont triés par "PART" dans le même ordre de A-9
Pour la question subsidiaire je vais essayer.
J'ai aussi pensé que je pourrais peut-être effacer la donnée de la liste CSV #2 quand elle est trouvée.
Le premier élément de la liste 1 chercher dans les 29110 de la liste 2.
Si trouvé, l'élément est effacé des 2 listes. Dans ce quand, plus on avance, moins il y a d'articles dans la liste 2.
486578 *29110, 486578 *29109, 486578 *29108, etc.
Ou peut-être une façon de ne plus chercher la ligne une fois trouvé puisqu'il est sûr que la valeur se retrouve qu'une seule fois dans la liste.
Donc si l'élément est trouvé à l'item 5 de la liste on sauve 29103 intéractions.
Pour coder vite, j'ai choisi de créer un 3eme fichier mis à jour.
Si cette solution te convient, tu pourras remplacer ça par l'ajout d'une ligne dans le datagridview si tu veux.
Mon fichier 1 de test
A,12 B,13 CC,12 D,12 E,14 F,15 G,15 H,9
Mon fichier 2 de test
A,99 CC,99 F,99 G,99
Et le code de première intention.
Private Sub MettreAJour() Dim sr1 As New StreamReader("Fichier 1.csv") Dim fval1 As String() Dim sr2 As New StreamReader("Fichier 2.csv") Dim fval2 As String() If File.Exists("Fichier mis à jour.csv") Then File.WriteAllText("Fichier mis à jour.csv", "") 'on vide le fichier s'il existe End If Dim sr3 As New StreamWriter("Fichier mis à jour.csv") fval2 = sr2.ReadLine().Split(",") While sr1.Peek() <> -1 fval1 = sr1.ReadLine().Split(",") If fval1(0) = fval2(0) Then sr3.WriteLine(String.Join(","c, fval2)) 'on prend la ligne à mettre à jour If sr2.Peek() <> -1 Then fval2 = sr2.ReadLine().Split(",") End If Else sr3.WriteLine(String.Join(","c, fval1)) End If End While sr1.Close() sr2.Close() sr3.Close() End Sub
Ça donne ça
A,99 B,13 CC,99 D,12 E,14 F,99 G,99 H,9
Je m'aperçois ce matin que tu ad posté ta solution pendant que je rédigeais mon message.
Très bien, t'avais pas besoin de moi finalement ;) !
Merci beaucoup pour ton temps.