IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

VBA : Ouvrir un fichier .CSV et stocker son contenu dans un tableau


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 20
    Points : 14
    Points
    14
    Par défaut VBA : Ouvrir un fichier .CSV et stocker son contenu dans un tableau
    Bonjour à tous

    Actuellement en stage de fin de DUT Informatique, on me demande de prendre un fichier csv et faire des opérations dedans. Mon tuteur m'a donné des pistes comme essayer de stocker tout son contenu dans un tableau à deux dimensions. J'ai aussi à ma disposition de la documentation et un livre sur le VB, mais je n'ai pas encore trouvé la réponse à ce que je cherche.

    Je programme en VBA depuis maintenant quelques jours, et j'aimerai donc mettre mon fichier dans un tableau. J'ai essayé de l'ouvrir dans Excel en utilisant un Workbooks.Open("") mais non seulement la macro me l'affiche dans une feuille (normal), mais en plus les colonnes ne sont pas du tout respectés : Excel ne prend pas toujours les ";" comme des séparateurs de colonne.

    J'essaye actuellement d'utiliser les freefile, sans succès.

    Selon moi il me faudrait :
    - Charger le fichier en mémoire
    - Stocker "cellule" dans un tableau à double entrée --> Mais je ne sais pas comment ignorer les ";"
    - Récupérer une colonne par la suite
    - Faire des opérations dans celle-ci

    L'intérêt de ce fichier excel serait d'économiser du temps lors de calcul de fichiers de plusieurs milliers de lignes

    Cordialement

  2. #2
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut
    Bonjour !

    Citation Envoyé par Helpo Voir le message
    J'ai essayé de l'ouvrir dans Excel en utilisant un Workbooks.Open("") mais non seulement la macro me l'affiche dans une feuille (normal), mais en plus les colonnes ne sont pas du tout respectés : Excel ne prend pas toujours les ";" comme des séparateurs de colonne.
    Il manque donc le paramètre  Local:=True  !
    Sans compter les autres paramètres de cette méthode  Workbooks.Open  rien qu'en consultant sa documentation !

    Sans compter la méthode  OpenText  à consulter aussi dans l'aide VBA interne …

    ___________________________________________________________________________________________________________
    Je suis Paris, London, Istanbul, Berlin, Nice, Bruxelles, Charlie, …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  3. #3
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Citation Envoyé par Helpo Voir le message
    J'ai essayé de l'ouvrir dans Excel en utilisant un Workbooks.Open("")
    D'accord avec Marc, pour des fichiers texte (ce qui est le cas des CSV), il est préférable d'utiliser OpenText.
    https://msdn.microsoft.com/fr-fr/lib.../ff837097.aspx
    Il est bien plus facile de contrôler ce qu'on importe et de quelle façon c'est importé.

    Une fois le fichier sous forme de feuille de calcul, tu peux y faire facilement toutes les opérations que tu souhaites.

    Ensuite, tu n'as plus qu'à l'enregistrer avec un SaveAs en mettant FileFormat à xlCSV.
    https://msdn.microsoft.com/fr-fr/lib.../ff841185.aspx
    https://msdn.microsoft.com/fr-fr/lib.../ff198017.aspx

    et à le fermer.

    Ce serait bien moins compliqué que de le traiter en séquentiel pour mettre le contenu dans une variable tableau.
    Merci de cliquer sur pour chaque message ayant aidé puis sur pour clore cette discussion.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     Dim Cn As Object, txt As String
    Sub test()
    Dim rep As String
    txt = "[F.CSV]" & vbCrLf & _
    "Format=Delimited(;)"
    'rep = ChoixRepertoire()
    rep = "C:\MyRepertoire\Nouveau dossier"
    If rep = "" Then Exit Sub
    Set Cn = CreateObject("ADODB.Connection"): Cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rep & ";Extended Properties=""Text;HDR=YES;FMT=Delimited;"";")
    With Sheets("Feuil3")
        tbls = TableToutes
        If TypeName(tbls) = "Variant()" Then
            For i = 0 To UBound(tbls, 2)
                Importer rep, .Cells(.Cells.Rows.Count, "A").End(xlUp).Offset(1), CStr(tbls(2, i)), True
            Next
        End If
    End With
    End Sub
    Sub Importer(Repertoire As String, Destination As Range, Table As String, Entete As Boolean)
        With Cn
          If Table <> "" Then
                NewFichierTxt Repertoire & "\schema.ini", Replace(txt, "F.CSV", Replace(Table, "#", "."))
                If TableExiste(Table) Then Destination.CopyFromRecordset .Execute("SELECT * FROM [" & Table & "]")
                Kill Repertoire & "\schema.ini"
                End If
        End With
    End Sub
     
    Public Property Get PremiereTableAdo() As String
    With Cn.OpenSchema(20)
        If Not .EOF Then
            PremiereTableAdo = .fields("TABLE_NAME")
        End If
        .Close
    End With
    End Property
    Public Property Get TableExiste(TableName As String) As Boolean
    With Cn.OpenSchema(20)
        If Not .EOF Then
        Debug.Print .fields("TABLE_NAME")
          .Filter = "TABLE_NAME ='" & TableName & "'"
           TableExiste = Not .EOF
        End If
        .Close
    End With
    End Property
    Public Property Get TableToutes()
    TableToutes = False
    With Cn.OpenSchema(20)
        If Not .EOF Then
          TableToutes = .getrows
     
     
        End If
        .Close
    End With
    End Property
    Private Sub NewFichierTxt(Fichier, txt)
    Dim fso, NewFichier
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set NewFichier = fso.OpenTextFile(Fichier, 2, True)
    NewFichier.Write txt
    NewFichier.Close
    Set NewFichier = Nothing
    Set fso = Nothing
    End Sub
     
     
    Function ChoixRepertoire(Optional RepDefault = "52") As String
       Dim objShell As Object, objFolder As Object, oFolderItem As Object
        Dim Chemin As String
     
        Set objShell = CreateObject("Shell.Application")
        Set objFolder = objShell.BrowseForFolder(&H0&, "Choisir un répertoire", &H1&, RepDefault)
     
        On Error Resume Next
        Set oFolderItem = objFolder.Items.Item
        ChoixRepertoire = oFolderItem.Path
     
     
    End Function
    Dernière modification par Invité ; 07/04/2017 à 12h00.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 20
    Points : 14
    Points
    14
    Par défaut
    Bonjour

    Mon problème était en fait de pouvoir stocker le fichier dans un tableau sans avoir à l'ouvrir sous excel. J'ai finalement réussi à trouver une solution à mon problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     Sub remplir_tab()
     
    Dim var As Variant
     
     
        'ouvre et lie le fichier fastclose et le stocke en mémoire
        fich_in = Application.GetOpenFilename("Fichiers csv, *.csv")
    'vérification des données dans le fichier
     
    cpt = 0
    caract_en_erreur = "*?!%"
    erreur_lec = False
    num_fich = FreeFile
     
    Open fich_in For Input As #num_fich
        Do While Not EOF(num_fich)
     
     
            Line Input #num_fich, textline
        ' compteur
        cpt = cpt + 1
     
        ' boucle des caractères invalides
     
            For i = 1 To Len(caract_en_erreur)
                erreur_lue = Mid(caract_en_erreur, i, 1)
                caractere = InStr(1, textline, erreur_lue)
                    If caractere <> 0 Then
                    erreur_lec = True
                   End If
            Next i
     
        'dimensionnement des champs
        tab_lu = Split(textline, ";")
     
     
        'dimensionnement du tableau
        ReDim Preserve tab_val(UBound(tab_lu, 1) + 1, cpt)
     
        ' boucle de chargement des données
        For j = 1 To UBound(tab_lu, 1)
            tab_val(j, cpt) = tab_lu(j - 1)
        Next j
     
     
        Loop
    Close #num_fich
    MsgBox (tab_val(29, 15))
    MsgBox ("Fichier chargé")
     
    End Sub
    Merci pour vos réponses, j'aurai quand même réussi à en faire quelque chose !

  6. #6
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Ouvrir en séquentiel, c'est vraiment se compliquer la vie par plaisir.
    Merci de cliquer sur pour chaque message ayant aidé puis sur pour clore cette discussion.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par dysorthographie Voir le message
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     Dim Cn As Object, txt As String
    Sub test()
    Dim rep As String
    txt = "[F.CSV]" & vbCrLf & _
    "Format=Delimited(;)"
    'rep = ChoixRepertoire()
    rep = "C:\MyRepertoire\Nouveau dossier"
    If rep = "" Then Exit Sub
    Set Cn = CreateObject("ADODB.Connection"): Cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rep & ";Extended Properties=""Text;HDR=YES;FMT=Delimited;"";")
    With Sheets("Feuil3")
        tbls = TableToutes
        If TypeName(tbls) = "Variant()" Then
            For i = 0 To UBound(tbls, 2)
                Importer rep, .Cells(.Cells.Rows.Count, "A").End(xlUp).Offset(1), CStr(tbls(2, i)), True
            Next
        End If
    End With
    End Sub
    Sub Importer(Repertoire As String, Destination As Range, Table As String, Entete As Boolean)
        With Cn
          If Table <> "" Then
                NewFichierTxt Repertoire & "\schema.ini", Replace(txt, "F.CSV", Replace(Table, "#", "."))
                If TableExiste(Table) Then Destination.CopyFromRecordset .Execute("SELECT * FROM [" & Table & "]")
                Kill Repertoire & "\schema.ini"
                End If
        End With
    End Sub
     
    Public Property Get PremiereTableAdo() As String
    With Cn.OpenSchema(20)
        If Not .EOF Then
            PremiereTableAdo = .fields("TABLE_NAME")
        End If
        .Close
    End With
    End Property
    Public Property Get TableExiste(TableName As String) As Boolean
    With Cn.OpenSchema(20)
        If Not .EOF Then
        Debug.Print .fields("TABLE_NAME")
          .Filter = "TABLE_NAME ='" & TableName & "'"
           TableExiste = Not .EOF
        End If
        .Close
    End With
    End Property
    Public Property Get TableToutes()
    TableToutes = False
    With Cn.OpenSchema(20)
        If Not .EOF Then
          TableToutes = .getrows
     
     
        End If
        .Close
    End With
    End Property
    Private Sub NewFichierTxt(Fichier, txt)
    Dim fso, NewFichier
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set NewFichier = fso.OpenTextFile(Fichier, 2, True)
    NewFichier.Write txt
    NewFichier.Close
    Set NewFichier = Nothing
    Set fso = Nothing
    End Sub
     
     
    Function ChoixRepertoire(Optional RepDefault = "52") As String
       Dim objShell As Object, objFolder As Object, oFolderItem As Object
        Dim Chemin As String
     
        Set objShell = CreateObject("Shell.Application")
        Set objFolder = objShell.BrowseForFolder(&H0&, "Choisir un répertoire", &H1&, RepDefault)
     
        On Error Resume Next
        Set oFolderItem = objFolder.Items.Item
        ChoixRepertoire = oFolderItem.Path
     
     
    End Function
    Bonjour, et désolé de déterrer un ancien sujet, mais votre solution répond à la perfection à mon besoin ... enfin presque!

    Lorsque cette macro tourne, elle ne me donne jamais la première ligne des fichiers lus (Mes excel ne comportent pas d'entête).

    J'ai tenté 2 adaptations :

    - A la ligne 14 (Importer rep, .Cells(.Cells.Rows.Count, "A").End(xlUp).Offset(1), CStr(tbls(2, i)), True), j'ai remplacé la valeur de Offset à 0.
    Pour le premier fichier, j'ai toutes les données, mais à partir du second fichier, il recopie qu'à la seconde ligne de nouveau, et ce pour tous les fichiers.

    - Toujours à la ligne 14, j'ai remplacé le True par False (si j'ai bien compris, c'est un booléen pour savoir s'il y a un entête). Rien ne chaneg que ca soit True ou False.

    Pourriez-vous m'indiquer si je cherche au mauvais endroit ?

    Merci d'avance

  8. #8
    Invité
    Invité(e)
    Par défaut
    bonjour,

    HDR=YES/No détermine si la première ligne du CSV est l’entête de collons de la « Table » Yes ou pas No

    en revanche si HDR=No le nom des champs sont F1,F2,F etc...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set Cn = CreateObject("ADODB.Connection"): Cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rep & ";Extended Properties=""Text;HDR=YES;FMT=Delimited;"";"

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Avant toute chose, je tiens à vous remercier chaleureusement de votre rapidité de réponse à ce post, vraiment.

    Je n'avais absolument pas pensé regarder la connectionstring, merci pour cet indice. Cependant j'ai tenté de modifier le HDR=YES par HDR=NO, les résultats sont identiques, rien ne change. Dans le doute j'ai même tenté diverses tentatives (toujours avec la modification du booléen ou la modification de l'offset) mais le problème persiste.

    Ce qui m'etonne tout de même est que le premier fichier lui est complet, mais pas les suivants.

  10. #10
    Invité
    Invité(e)
    Par défaut
    test comme ça???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Importer rep, .Cells(.Range("A1").CurrentRegion.Rows.Count, "A").Offset(1) , CStr(tbls(2, i)), True

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Le problème est toujours présent malheureusement, malgré l'utilisation du HDR=NO et de la dernière ligne que vous avez mentionné

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Ouvrir un fichier dont le nom est contenu dans un autre
    Par camillerufu dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 28/04/2015, 16h50
  2. Réponses: 13
    Dernier message: 06/08/2013, 11h47
  3. [XL-2010] Ouvrir un fichier .txt et copier son contenu
    Par h12enri dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 14/11/2012, 13h37
  4. Réponses: 2
    Dernier message: 04/07/2007, 19h18
  5. Ouvrir une feuille excel et mettre son contenu dans VB6
    Par bb62 dans le forum VB 6 et antérieur
    Réponses: 18
    Dernier message: 17/01/2006, 09h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo