XL 2013 [Besoin d'aide] Recherche de valeurs dans un fichier CSV

M92_

XLDnaute Junior
Bonjour à tous,

J'ai un fichier CSV (avec des valeurs séparées par un point virgule) qui pèse plus de 3Go et je souhaite récupérer quelques lignes (analyser son contenu) sans avoir besoin de l'ouvrir.

Prenons l'exemple d'un fichier CSV de 3 colonnes et 10 lignes :
Colonne_A;Colonne_B;Colonne_C
Hautes-Pyrénées;65;Tarbes
Seine-Et-Marne;77;Melun
Seine-Et-Marne;77;Meaux
Alpes-Maritimes;06;Nice
Alpes-Maritimes;06;Antibes
Paris;75;Paris
La-Moselle;57;Metz
Ile-et-Vilaine;35;Rennes
La-Gironde;33;Bordeaux
La-Gironde;33;Arcachan

Je souhaiterais par exemple avoir un nouveau fichier CSV qui ne décrit que les lignes qui contiennent les chiffres "06" ou "33".

Dans ce cas je dois avoir :
Colonne_A;Colonne_B;Colonne_C
Alpes-Maritimes;06;Nice
Alpes-Maritimes;06;Antibes
La-Gironde;33;Bordeaux
La-Gironde;33;Arcachan

Y'aurait-il un moyen de faire ça, s'il vous plaît ?

Merci par avance.

Cdlt,
M92
 

patricktoulon

XLDnaute Barbatruc
bonjour
oui c'est possible
mais vu la taille du fichier mieux vaut l'ouvrir en mémoire et lecture ligne par ligne
un exemple adapté de mon tuto 2011 à ta demande
te reste plus qu'a adapter les chemins de fichier
VB:
'exemple mixte lecture ecriture
'regrouper plusieurs fichiers text

Sub test()
    Dim x1 As Integer, x2 As Integer, i As Long, dataline As String
    x1 = FreeFile
    fichier1$ = "C:\Users\polux\Desktop\monfichier.txt"
    fichierfinal$ = "C:\Users\polux\Desktop\fichierfinal.txt"
    Open fichierfinal For Append As #x1
    x2 = FreeFile    'déclarer toujours le 2d freefile apres avoir ouvert le premier fichier
    Open fichier1 For Input As #x2
    While Not EOF(x2)    'lecture ligne par ligne dans une boucle while/wend
        Line Input #x2, dataline    'on est tranquille on a pas a se soucier de la taille du  fichier il est lu ligne par ligne
              If dataline Like "*;33;*" Or dataline Like "*;06;*" Then Print #x1, dataline
    Wend
    Close #x2
End Sub
 

M92_

XLDnaute Junior
bonjour
oui c'est possible
mais vu la taille du fichier mieux vaut l'ouvrir en mémoire et lecture ligne par ligne
un exemple adapté de mon tuto 2011 à ta demande
te reste plus qu'a adapter les chemins de fichier
VB:
'exemple mixte lecture ecriture
'regrouper plusieurs fichiers text

Sub test()
    Dim x1 As Integer, x2 As Integer, i As Long, dataline As String
    x1 = FreeFile
    fichier1$ = "C:\Users\polux\Desktop\monfichier.txt"
    fichierfinal$ = "C:\Users\polux\Desktop\fichierfinal.txt"
    Open fichierfinal For Append As #x1
    x2 = FreeFile    'déclarer toujours le 2d freefile apres avoir ouvert le premier fichier
    Open fichier1 For Input As #x2
    While Not EOF(x2)    'lecture ligne par ligne dans une boucle while/wend
        Line Input #x2, dataline    'on est tranquille on a pas a se soucier de la taille du  fichier il est lu ligne par ligne
              If dataline Like "*;33;*" Or dataline Like "*;06;*" Then Print #x1, dataline
    Wend
    Close #x2
End Sub

Bonjour @patricktoulon,

Merci beaucoup pour votre retour.
Par contre, j'ai plus de 500 valeurs à rechercher dans le fichier CSV de 3GO.

Y'aurait-il un moyen de faire ça aussi ? Si non, j'ai pensé à diviser mon fichier à plusieurs fichiers CSV qui ne dépassent pas les 500MO. Qu'en pensez-vous ?

Cdlt,
M92
 

dysorthographie

XLDnaute Accro
bonsoir,
Code:
Sub test()
Const Path As String = "C:\Test\"
Dim cible As String, Source As String
Source = "Departement.csv"
cible = "Departement2.csv"

Const Champs As String = "Col1=Colonne_A Text" & vbCrLf & _
"Col2=Colonne_B Text" & vbCrLf & _
"Col3=Colonne_C Text" & vbCrLf

Dim Cn As Object
Set Cn = CreateObject("ADODB.Connection")
  Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & Path & "' ;Extended Properties=""text;HDR=YES;"""
   If Dir(Path & cible) <> "" Then Cn.Execute "Drop Table [" & Replace(cible, ".", "#") & "]"
   ShemaIni Path, Source, "Delimited(;)",Champs
  ShemaIni Path, cible, "Delimited(;)", Champs, True
  Cn.Execute "select * into [" & Replace(cible, ".", "#") & "]  from [" & Replace(Source, ".", "#") & "] WHERE [Colonne_B] in('06','33')"
  Cn.Close
  MsgBox "Fin"
End Sub

Public Sub ShemaIni(Rep As String, Fichier As String, Delimited As String, Optional Champs As String = "", Optional Append As Boolean= False, Optional NewCsv As Boolean = False)
Dim txt As String
txt = "[" & Replace(Fichier, "#", ".") & "]" & vbCrLf & "Format=" & Delimited
If Champs <> "" Then txt = txt & vbCrLf & Champs
Dim FSO, NewFichier
Set FSO = CreateObject("Scripting.FileSystemObject")
Set NewFichier = FSO.OpenTextFile(Rep & "\schema.ini", Array(2, 8)(Abs(Append)), True)
NewFichier.Write txt
NewFichier.Close
If NewCsv = True Then
    Set NewFichier = FSO.OpenTextFile(Rep & "\" & Replace(Fichier, "#", "."), 2, True)
    NewFichier.Write ""
    NewFichier.Close
End If
Set NewFichier = Nothing
Set FSO = Nothing
End Sub
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
@dysortographie
Bonjour Robert 👍
tu veux bien m'expliquer le besoins du ".ini"

sinon avec ma méthode ca donne ça
ajouter les éléments dans l'array
VB:
Sub test()
    Dim x1 As Integer, x2 As Integer, i As Long, dataline As String, expression
    expression = Array("06", "33")
    x1 = FreeFile
    fichier1$ = "C:\Users\polux\Desktop\Departement.csv"
    fichierfinal$ = "C:\Users\polux\Desktop\Departement2.csv"
    If Dir(fichierfinal) <> "" Then Kill fichierfinal
    Open fichierfinal For Append As #x1
    x2 = FreeFile    'déclarer toujours le 2d freefile apres avoir ouvert le premier fichier
    Open fichier1 For Input As #x2
    While Not EOF(x2)    'lecture ligne par ligne dans une boucle while/wend
        Line Input #x2, dataline    'on est tranquille on a pas a se soucier de la taille du  fichier il est lu ligne par ligne
        For i = LBound(expression) To UBound(expression)
            Debug.Print ";" & expression(i) & ";"
            If InStr(1, dataline, ";" & expression(i) & ";") > 0 Then Print #x1, dataline
        Next
    Wend
    Close #x2
 Close #x1
MsgBox "fin"
End Sub
 

M92_

XLDnaute Junior
@dysorthographie, @patricktoulon,

Merci beaucoup à vous deux. Les codes marchent à merveille.

Pardonnez moi mais est-ce que ça serait possible par exemple de préciser les numéros de colonnes (ou leurs noms/en-têtes) à exporter ?

Dans l'exemple ci-dessus, je souhaite récupérer que les deux premières colonnes :
Colonne_A;Colonne_B
Alpes-Maritimes;06
Alpes-Maritimes;06
La-Gironde;33
La-Gironde;33

Merci encore.

Cdlt,
M92.
 

patricktoulon

XLDnaute Barbatruc
re
j'en vois pas beaucoup l'utilité de preciser la colonne A puis chaque numéros correspond a son département

donc par exemple si tu choisi 06 ce sra toujours ""Alpes-Maritimes"
mais si tu y tiens
colonnes A et B
VB:
Sub test()
    Dim x1 As Integer, x2 As Integer, i As Long, dataline As String, colA, colB
    colB = Array("06", "33")
    colA = Array("Alpes-Maritimes", "La-Gironde")
    x1 = FreeFile
    fichier1$ = "C:\Users\polux\Desktop\Departement.csv"
    fichierfinal$ = "C:\Users\polux\Desktop\Departement2.csv"
    If Dir(fichierfinal) <> "" Then Kill fichierfinal
    Open fichierfinal For Append As #x1
    x2 = FreeFile    'déclarer toujours le 2d freefile apres avoir ouvert le premier fichier
    Open fichier1 For Input As #x2
    While Not EOF(x2)    'lecture ligne par ligne dans une boucle while/wend
        Line Input #x2, dataline    'on est tranquille on a pas a se soucier de la taille du  fichier il est lu ligne par ligne
        For i = LBound(colA) To UBound(colA)
             If InStr(1, dataline, colA(i) & ";" & colB(i) & ";") > 0 Then Print #x1, dataline
        Next
    Wend
    Close #x2
 Close #x1
MsgBox "fin"
End Sub
 

patricktoulon

XLDnaute Barbatruc
re
je n'avais pas bien compris la demandes au temps pour moi
tu veux juste récupérer la colonnes 1 et 2
VB:
Sub test()
    Dim x1 As Integer, x2 As Integer, i As Long, dataline As String, colonnes, colA, colB, X
    colB = Array("06", "33")
     colonnes = Array(1, 2) 'colonnes a récupérer
    x1 = FreeFile
    fichier1$ = "C:\Users\polux\Desktop\Departement.csv"
    fichierfinal$ = "C:\Users\polux\Desktop\Departement2.csv"
    If Dir(fichierfinal) <> "" Then Kill fichierfinal
    Open fichierfinal For Append As #x1
    x2 = FreeFile    'déclarer toujours le 2d freefile apres avoir ouvert le premier fichier
    Open fichier1 For Input As #x2
    While Not EOF(x2)    'lecture ligne par ligne dans une boucle while/wend
        Line Input #x2, dataline    'on est tranquille on a pas a se soucier de la taille du  fichier il est lu ligne par ligne
        X = Split(dataline, ";")
        For i = LBound(colB) To UBound(colB)
             If X(1) = colB(i) Then Print #x1, X(0) & ";" & X(1)
        Next
    Wend
    Close #x2
 Close #x1
MsgBox "fin"
End Sub
reste que je ne vois pas trop l'utilité de se retrouver avec un fichier ayant des lignes en doublons comme ça

mais bon c'est toi qui vois ;)
 

dysorthographie

XLDnaute Accro
Bonjour Mes3oud92 et Patrick,
Il nous ait souvent arrivé de lire sur le forum « j’ai une inversion du jour et du mois dans mes date » !

Il y a effectivement quelques différences entre VBA et EXCEL ;

Pour ce qui concerne les fichiers texte et ado c’est pareil ?

Si j’exécutai la requête sans fichier .ini j’aurai un message me disant que le séparateur de colonnes est le même que le séparateur décimal !

En effet si pour nous le séparateur de colonne est le « ; » pour Windows c’est le « , »

Pour corrigé ça il y à deux solution aller bricoler la base de registre de tous les PC qui utiles la macro où utiliser un fichier .ini.

Dans ce fichier. ini on défini le (s) fichier(s) concerné(s) le format {séparateur, fixe, etc.}

Il est possible si le CSV ne possède d’entête de colonnes d’en définir dans le .ini car je n’arrive pas à imaginer que quelqu’un est affublé ce pauvre CSV d’entête du genre
« Colonne_A;Colonne_B;Colonne_C » !

Perso j’aurai vue « Département ;CodeDep ;Ville » !

Il est donc possible de définir le nom des champ et leur type pour ne pas laisser ado choisir. Par exeple on peut définir CodeDep en texte pour éviter que le ‘06’ se convertissse en 6

bref pas de ADO CSV sans shema.ini

[Departement.csv]

Format=Delimited( ; )

Col1=Colonne_A Text

Col2=Colonne_B Text

Col3=Colonne_C Text

[Departement2.csv]

Format=Delimited( ; )

Col1=Colonne_A Text

Col2=Colonne_B Text

Col3=Colonne_C Text

VB:
'que les colonnes A et B
Cn.Execute "select Colonne_A,Colonne_B into [" & Replace(cible, ".", "#") & "]  from [" & Replace(Source, ".", "#") & "] WHERE [Colonne_B] in('06','33')"
 
Dernière édition:

Statistiques des forums

Discussions
312 322
Messages
2 087 275
Membres
103 504
dernier inscrit
Marie28