scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007
-
9 mai 2007 à 18:19
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 2011
-
15 mai 2007 à 17:38
Bonjour,
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.
Comment pourrais-je faire au mieux ?
Merci
A voir également:
Supprimer une ligne en double dans un fichier excel
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 9 mai 2007 à 19:57
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
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 9 mai 2007 à 19:28
Salut,
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~
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 9 mai 2007 à 19:43
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.
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 9 mai 2007 à 21:58
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 ?
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 9 mai 2007 à 23:09
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
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 10 mai 2007 à 02:43
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...
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 10 mai 2007 à 08:33
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.
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 10 mai 2007 à 12:03
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
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 10 mai 2007 à 13:38
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) ?
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 11 mai 2007 à 10:36
Salut,
oui, c'est adaptable. Je test pas mais en gros :
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~
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 15 mai 2007 à 16:57
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.
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 15 mai 2007 à 17:00
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~
scortek
Messages postés61Date d'inscriptionmardi 4 mai 2004StatutMembreDernière intervention 1 août 2007 15 mai 2007 à 17:29
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) ...
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 15 mai 2007 à 17:38
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~