En fait c'est pas tout à fait une ligne en double que j'aimerais supprimer, mais plutôt renommer une ligne entière. Je m'explique, j'ai un fichier .csv de la forme suivante (c'est un exemple) :
colonne 1: colonne 2 : colonne 3 : ..........
ligne 1 : Date Time Name
ligne 2 : 09-05-2007 15:50:10 "ABCDEFG"
ligne 3 : 09-05-2007 15:55:30 "ABCDEFG"
[....]
Je cherche un moyen de balayer ce fichier jusqu'à la dernière ligne écrite afin de trouver deux ou plusieurs fois le même nom (colonne 3), et d'ainsi de renommer la ligne entière par une nouvelle ligne mais avec le jour et/ou l'heure le plus récent.
En fait dans cet exemple, la ligne 3 viendra remplacer la ligne 2, car l'heure dans la ligne 3 (colonne 2) est la plus récente.
Pourquoi partir de la fin, tout simplement parce que si tu supprimes une ligne, les autres au dessous remontent, et c'est comme ça qu'on passe au travers de possibles doublons, car la valeur suivante est incrémentée de 1 (en partant du haut) et donc la valeur remontée n'est pas lu.
Je t'ai fait un code exemple basé sur ton exemple cité plus haut, inspire-en toi si tes données sont plus élargies (en terme de colonne)
Private Sub test()
Dim i As Long, j As Long, DL As Long
For i = 2 To PLV
DL = PLV
For j = DL To i + 1 Step -1
If Cells(i, 3).Value = Cells(j, 3).Value Then
If Cells(j, 1).Value < Cells(i, 1).Value Then
Rows(j).Delete
ElseIf Cells(j, 1).Value > Cells(i, 1).Value Then
Cells(i, 1).Value = Range(Cells(j, 1), Cells(j, 3)).Value
Else
If Cells(j, 2).Value <= Cells(i, 2).Value Then
Rows(j).Delete
Else
Range(Cells(j, 1), Cells(j, 3)).Copy
Cells(i, 1).PasteSpecial (xlAll)
Rows(j).Delete
End If
End If
End If
Next j
Next i
End Sub
Private Function PLV() As Long
PLV = Range("C65536").End(xlUp).Row
End Function
heu sans dire de bétise, la logique (enfin, la mienne) voudrait que la valeur en doublon la plus récente soit toujours placée plus bas que les autres, non?
** Si oui, c'est simple, tu lis C2, ensuite tu compares avec Cx (x étant la dernière ligne), en remontant d'une ligne jusqu'à trouver la même valeur.
Quand c'est trouvé, Tu copies la ligne vers A2:C2 (vu qu'on a lu C2, au début). Ensuite, tu remontes encore jusqu'à la ligne 3, et supprime les éventuels autres doublons.
Ainsi de suite, C3, C4;, etc..
** Si non, bah suffit de faire presque pareil, à la différence près que dès que tu as trouvé un doublon (en partant du bas, donc), tu compares d'abord la date, puis l'heure, et copie si le doublon est plus récent. Ainsi de suite
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
C'est plutôt la deuxième solution, mais pourquoi commencer du bas ?
Coment coder cela, puis-je utiliser sheets et rows ici, dslé je ne connais pas bien le VBA...
Merci encore.
Comment puis-je utiliser du code VBA dans le compilateur IDE Visual Basic 6, ou bien l'adapter ?
Comment puis-je travailler ce fichier excel de la même façon qu'un fichier texte ? (do until EOF(1) ...)
Vous n’avez pas trouvé la réponse que vous recherchez ?
J'essaye d'utiliser la méthode ADO, à la place de FileSystemObject, d'après ce site : http://www.supinfo-projects.com/fr/2006/csv_vb6/3/ mais sans succès pour l'instant (j'ai une erreur d'exécution lié à Microsoft Jet)
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
strPathtoTextFile = "C:\Logfolder" 'ceci spécifie le chemin où les fichiers csv ce trouvent
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strPathtoTextFile & ";" & _
"Extended Properties=""text;HDR=YES;FMT=Delimited"""
objRecordset.Open "SELECT * FROM Log_LP_09.05.2007.csv", objConnection
Do Until objRecordset.EOF
Wscript.Echo "colonne 3: " & objRecordset.Fields.Item("colonne 3")
objRecordset.MoveNext
Loop
Pour ce que tu veux faire, je pense que le plus simple est d'importer ton fichier CSV dans Excel. De là, tu tries selon les critères nécessaires, à savoir la colonne 3 en premier, la colonne 2 en deuxième.
Ensuite, tu fais un peu comme Mortalino te disait.
En fait, comme ta liste est triée, tu n'as pas besoin de faire une double-boucle.
Tu pars de la fin et tu remontes en vérifiant si Cx = Cx - 1
Si oui, tu vérifies si Bx > Bx - 1
Si oui, ben là c'est pas clair... si tu remplaces la plus vieille heure par la plus récente, qu'est-ce que tu fais de l'autre qui devient identique ???
Si tu la supprimes, alors ça ne sert à rien de la remplacer; supprime la plus vieille heure immédiatement.
De toute façon, ton code avec WScript.Echo, je ne pense pas que ça pourra t'aider... à moins que tu n'aies pas tout dit...
Et ADO, je l'ai déjà expérimenté avec Excel et des fichiers textes (un peu comme des CSV finalement...), mais ça prenait un fichier "Schema.ini" qui contient la structure du fichier pour qu'ADO comprenne ce fichier comme si c'était une base de données (nom des colonnes et type de ces colonnes). Cette technique est intéressante si tu veux aller chercher seulement certains renseignements dans un fichier, mais pas pour le traiter comme tu veux le faire, je pense...
Si oui, ben là c'est pas clair... si tu remplaces la plus vieille heure
par la plus récente, qu'est-ce que tu fais de l'autre qui devient
identique ???
En fait, ce n'est pas juste une colonne que j'aimerais remplacer, mais la ligne entière en fait. Dans mon exemple, la L3 remplace la L2.
Quand tu dis importer le fichier dans excel, ça voudrais dire à chaque fois, pour chaque fichier éxécuter une macro ?
Le problème, c'est que j'ai des centaines de fichiers csv comme ceci, avec des centaines de lignes chacun. C'est pour cela que je voulais passer par VB6 et non VBA.
Pour le ADO, en effet, je ne pourrais que lire et non écrire, sinon faut que je passe par le filesystemobject, mais je ne sais pas comment je peut lire les cellules (y aller ligne par ligne, et dès qu'il y a un doublon, remplacer par celui par celui dont la date est plus récente ?).
J'avoue que c'est pas simple.
Merci encore.
Dans ce que tu dis, je ne vois pas l'utilité de passer par VB6 plutôt que VBA6, à moins qu'il y ait encore confusion entre VB6 et VB d'Excel (VBA6)...
Ce qu'il y a de simple avec Excel, c'est que tu peux importer ton fichier directement dans une feuille, trier les données et supprimer les doublons non-nécessaires dans une simple boucle.
Si tu ne veux pas passer par le copier/coller dans une feuille, il te faudra utiliser des variables String pour stocker ton fichier, utiliser Split pour lire chaque donnée de chaque ligne pour pouvoir comparer les heures, réécrire le fichier après suppression des lignes, ... et j'en oublie sûrement ...
C'est certainement faisable, mais je trouve ça bien compliqué par rapport au copier/coller dans Excel
Le fichier csv créé est toujours le même et est renommé en fonction de la date du jour. Chaque fois que l'utilisateur lance mon logiciel, des nouvelles données sont rajoutés à la fin du fichier (j'utilise for append as).
Et ce que je voulais faire, c'est éviter des doublons, et cela sans passer par excel.
Mais le soucis, c'est ce qu'il y a dans les colonnes change.
Est-ce qu'il y a un moyen d'inclure dans le fichier csv en question une macro VBA6 qui s'exécute automatiquement lorqu'on ouvre le fichier avec excel (éviter toute manipulation) ?
Private Sub test()
Dim i As Long, j As Long, DL As Long
Dim xlApp As New Excel.Application
Dim xlBook As Excel.WorkBook
Dim xlSheet As Excel.WorKSheet
Set xlBook = xlApp.WorkBooks.Open("C:\chemin\nomfichier.xls")
Set xlSheet = xlBook.Sheets("Nom Feuille")
For i = 2 To PLV
DL = PLV
For j = DL To i + 1 Step -1
If xlSheet.Cells(i, 3).Value = xlSheet.Cells(j, 3).Value Then
If xlSheet.Cells(j, 1).Value < xlSheet.Cells(i, 1).Value Then
xlSheet.Rows(j).Delete
ElseIf xlSheet.Cells(j, 1).Value > xlSheet.Cells(i, 1).Value Then
xlSheet.Cells(i, 1).Value = xlSheet.Range(xlSheet.Cells(j, 1), xlSheet.Cells(j, 3)).Value
Else
If xlSheet.Cells(j, 2).Value <= xlSheet.Cells(i, 2).Value Then
xlSheet.Rows(j).Delete
Else
xlSheet.Range(xlSheet.Cells(j, 1), xlSheet.Cells(j, 3)).Copy
xlSheet.Cells(i, 1).PasteSpecial (xlAll)
xlSheet.Rows(j).Delete
End If
End If
End If
Next j
Next i
End Sub
Private Function PLV() As Long
PLV = xlSheet.Range("C65536").End(xlUp).Row
End Function
Pense à cocher la référence à Excel
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
En fait, c'est plutôt cette ligne qui pose soucis : Set xlBook = xlApp.WorkBooks.Open("C:\chemin\nomfichier.xls")
Il n'y a pas de valeur retournée dans xlBook (runtime error). Par contre xlApp, pas de soucis.
Porrais-tu vérifier si t'y arrive de ton côté.
Je peux t'envoyé mon fichier csv si tu veux.
Merci encore.
Il faut que tu remplaces dans
xlApp.WorkBooks.Open("C:\chemin\nomfichier.xls")
le chemin et le nom du fichier, style
xlApp.WorkBooks.Open("C:\documents and settings\mortalino\Bureau\Test.csv")
@++
<hr size="2" width="100%" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
Quand même je sais que je suis débutant, mais quand même !
L'erreur retournée quand le compilateur arrive sur PLV = ..... est "Object doesn't support this property or method" due sans doute parce qu'il n'arrive pas à lire le fichier.
J'utilise Excel 2007 (référence Microsoft Object 12.0) ...
C'est bon j'ai trouvé, je viens de tester avec Excel 2007
Dim xlSheet As Excel.WorKSheet
enlève le de la procédure, et place le dans les déclarations, au tout début. Sinon, xlSheet n'est accessible que dans la procédure, et pas dans la fonction
@++
<hr size="2" width="100%" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~