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

VBA Access Discussion :

Import csv dynamique dans access


Sujet :

VBA Access

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut Import csv dynamique dans access
    Bonjour,
    Je vous sollicite aujourd’hui car j’ai beau cherché sur internet une solution à mon problème, mais malheureusement je ne la trouve pas.
    Je possède plusieurs tables csv dans différents répertoire que je souhaite relier à ma base acess, ces tables sont bien dynamique et c’est mon problème (se sont des exports machines avec le nombre de colonne variable c-a-d pour la même table si aujourd’hui j’ai 28 colonnes demain je peux avoir que 25….) donc je ne peux pas fixer mon entête avec la commande : SpecificationName, car mes requêtes ne marcheront pas vu que le nombre de colonne change.
    Bien évidemment je ne peux pas importer ces tables sur plusieurs machines manuellement
    Voici le code et merci de votre aide :

    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
    Sub import()
     
    'delete table
     
     
     
    Dim dbs As DAO.Database, tdf As DAO.TableDef
    Dim tbl As Object
     
    Set dbs = CurrentDb()
    For Each tbl In dbs.TableDefs
    If Len(tbl.Connect) > 0 Then
    'table attachée
    Debug.Print tbl.Name
    dbs.Execute "Drop Table [" & tbl.Name & "]"
     
     
    End If
    Next
     
    Set tdf = Nothing
    Set dbs = Nothing
     
    'import table
     
    DoCmd.TransferText TransferType:=acLinkDelim, SpecificationName:="GenericTabSpecification", TableName:="TABLE1", _
        FileName:="c:\bureau\bac\table1.csv", HasFieldNames:=False
     
    DoCmd.TransferText TransferType:=acLinkDelim, SpecificationName:="GenericTabSpecification", TableName:="TABLE2", _
        FileName:="c:\bureau\bac1\table2.csv", HasFieldNames:=False
    End Sub

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour

    Comme un fichier CSV est en fait un fichier texte avec séparateur je te propose peut-être une solution qui devrait fonctionner quelque soit le nombre d'éléments de ton fichier, en voici les étapes :

    1. Lire ton fichier texte en splitant la ligne dans un tableau.
    2. Lors de la boucle de lecture, lorsque tu es sur la première ligne tu crées dynamiquement ta table par DAO, tu as le nombre de champs (Ubound du tableau), et les entêtes de champ, puisqu'elles font parties de la première ligne de lecture.
    3. Une fois que ta table est crée, tu peux à l'aide d'une requête ajout et du parcours du fichier remplir ton tableau.


    Il s'agit donc d'une idée.

    Philippe

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut Re
    Bonjour Philippe,
    Merci de ta réponse j'ai deja testé cette solution ,le problème c'est le temps d'execution très important à cause de la boucle.
    Parcontre quand j'active le filedname et je n'enregistre pas l'en-tête dans avancé pendant l'import , j'ai bien l'en-tête présent mais à la 2 éme ligne de la table liée .s'il n'ya pas de solution,ma question est ce que c'est possible de requêters ces tables avec des requêtes ou l'en-tête est en 2 eme ligne ??
    Merci

  4. #4
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Bonjour,
    Une proposition (que j'ai utilisée par le passé) est de préparer la table cible avec un maximum de colonnes en format TEXTE
    par exemple 50 colonnes en texte dans ton cas.
    tu crées aussi un schéma d'importation qu puisse importer ces 50 colonnes (donc te créer un fichier bidon pour cela)
    ainsi ta commande DoCmd.TransferText marchera correctement pour tous les fichiers qui auront moins de 50 champs.

    Il te reste à identifier le nombre de colonnes et retrouver leur nom d'entete et leur type final. Mais ça tu peux peut-être le faire à côté.

    Cdlt
    "Always look at the bright side of life." Monty Python.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par micniv Voir le message
    Bonjour,
    Une proposition (que j'ai utilisée par le passé) est de préparer la table cible avec un maximum de colonnes en format TEXTE
    par exemple 50 colonnes en texte dans ton cas.
    tu crées aussi un schéma d'importation qu puisse importer ces 50 colonnes (donc te créer un fichier bidon pour cela)
    ainsi ta commande DoCmd.TransferText marchera correctement pour tous les fichiers qui auront moins de 50 champs.

    Il te reste à identifier le nombre de colonnes et retrouver leur nom d'entete et leur type final. Mais ça tu peux peut-être le faire à côté.

    Cdlt
    Bonjour ,
    Je crois que je n'ai pas bien compris votre solution , tu peux détailler ou me donner un exemple svp
    Merci,

  6. #6
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Tu crées une table qui sera la table de tes importations soit T_tmp_importCSV
    avec 50 champ Champ01, Champ02 ... Champ50 de type TXT(250)

    Ensuite tu crées un fichier CSV de quelques lignes avec 50 champs saisis.
    Cela te permet de créer en le sauvegardant le nouveau schéma d’importation (à la place deton "GenericTabSpecification") vers la table T_tmp_importCSV
    A toi de voir si tu veux retrouver les valeurs de la ligne d'entête (si présente dans le fichier CSV).

    Ensuite, tu n'a plus qu'à lancer la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DoCmd.TransferText acImportDelim, "specif_import_CSV", "T_tmp_importCSV ", strCsvFullFileName
    Alors, tu dois trouver tes valeurs importées dans la table T_tmp_importCSV.
    Est-ce clair ?
    "Always look at the bright side of life." Monty Python.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par micniv Voir le message
    Tu crées une table qui sera la table de tes importations soit T_tmp_importCSV
    avec 50 champ Champ01, Champ02 ... Champ50 de type TXT(250)

    Ensuite tu crées un fichier CSV de quelques lignes avec 50 champs saisis.
    Cela te permet de créer en le sauvegardant le nouveau schéma d’importation (à la place deton "GenericTabSpecification") vers la table T_tmp_importCSV
    A toi de voir si tu veux retrouver les valeurs de la ligne d'entête (si présente dans le fichier CSV).

    Ensuite, tu n'a plus qu'à lancer la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DoCmd.TransferText acImportDelim, "specif_import_CSV", "T_tmp_importCSV ", strCsvFullFileName
    Alors, tu dois trouver tes valeurs importées dans la table T_tmp_importCSV.
    Est-ce clair ?
    Bonsoir,
    l'import fonctionne par rapport à la liaison chose que je en savais pas le seul point négatif c'est la table d'erreur générée que je dois supprimer en vb et le temps de traitement qui augmente un peu.
    mai ça marche c'est l'essentiel merci

  8. #8
    Invité
    Invité(e)
    Par défaut
    Re

    Attention, si tu as une table d'erreur, c'est que certaines données ne sont pas importées correctement, ce qui peut nuire aux traitements ultérieures.

    Philippe

  9. #9
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    J'appuie ce que dit Philippe. Tu ne dois laisser passer aucune erreur à l'import.
    Donc analyser le contenu de la table, il est souvent signifiant ...
    Cdlt
    "Always look at the bright side of life." Monty Python.

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par micniv Voir le message
    J'appuie ce que dit Philippe. Tu ne dois laisser passer aucune erreur à l'import.
    Donc analyser le contenu de la table, il est souvent signifiant ...
    Cdlt
    bonjour
    O faite la solution d'import avec schéma de sauvegarde ne résout pas mon problème ,
    J'ai fais le test ce matin en supprimant des colonnes manuellement de mon fichier csv en entrée ,sur acess l'entetet ne change pas car il est enregistré dans le schéma d'import, mais les données se décalent'résultat c'est comme liée une table 😞😔 ...

  11. #11
    Invité
    Invité(e)
    Par défaut
    Re

    Une autre solution sera de crée dynamiquement le filtre d'import.

    Je m'explique, les filtres d'imports sont enregistrées dans des tables systèmes qui sont : MSysIMEXColumns et MSysIMEXSpecs.

    Il faudrait crée un filtre et étudier comment cela est conçu, ensuite prendre la méthode que j'ai signalé, mais uniquement pour la première ligne, crée le filtre, crée la table (avec entête de champ) et utiliser le DoCmd avec le filtre crée.

    Je pense que c'est un gros travail d'étude à faire, mais si ce que tu as à faire arrive souvent, cela en vaut peut-être la chandelle.

    Je sais que c'est un peu tordu comme idée.

    Philippe

  12. #12
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Si j'ai bien compris, tu disposes d'un certain nombre de fichiers Csv;

    C'est fichiers sont déjà liés à Access;

    Vba dispose d'un objet TableDefs qui contient toutes tes tables de ta base de données Access.

    Tu scan le tabedefs tu vérifies si c'est un table liée et tu rafraîchis le lien.ainsi le nombre d champs évoluera en fonction du Csv.

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut re
    Citation Envoyé par dysorthographie Voir le message
    Bonjour,
    Si j'ai bien compris, tu disposes d'un certain nombre de fichiers Csv;

    C'est fichiers sont déjà liés à Access;

    Vba dispose d'un objet TableDefs qui contient toutes tes tables de ta base de données Access.

    Tu scan le tabedefs tu vérifies si c'est un table liée et tu rafraîchis le lien.ainsi le nombre d champs évoluera en fonction du Csv.
    Bonjour,
    Je pense que c'est une bonne solution mais comment rafraîchir cette liaison?j'ai teste ce code que jai trouvé sur le forum, en modifiant le chemin et tablename,mais j'ai une erreur au niveau GetLinkedDBName acess ne la reconnait pas .
    CDLT

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim Tabl As DAO.TableDef
    chemin = Application.CurrentProject.Path & "\"
     
        For Each Tabl In CurrentDb.TableDefs
            If Tabl.Connect <> "" Then
                If GetLinkedDBName(Tabl.Name) = chemin & Tabl.Name & ".csv" Then
                    Tabl.Connect = ";DATABASE=" & chemin & Tabl.Name & ".csv"
                    On Error Resume Next
                    Tabl.RefreshLink
                    On Error GoTo 0

  14. #14
    Invité
    Invité(e)
    Par défaut
    Le nom de tes ficher change?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Each Tabl In CurrentDb.TableDefs
            If Tabl.Connect <> "" Then
                    On Error Resume Next
                    Tabl.RefreshLink
                    On Error GoTo 0

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par dysorthographie Voir le message
    Le nom de tes ficher change?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Each Tabl In CurrentDb.TableDefs
            If Tabl.Connect <> "" Then
                    On Error Resume Next
                    Tabl.RefreshLink
                    On Error GoTo 0
    bonsoir,
    Mes nom des fichiers non, les chemins non plus.
    Cdlt,

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par watred Voir le message
    bonsoir,
    Mes nom des fichiers non, les chemins non plus.
    Cdlt,
    Bonjour,
    quand j'utilise ce code pour connecter mes tables, j'ai une erreur 3343, format de base de donné non reconnu, je précise que mes fichier sont liées déjà manuellement mais je souhaite définir quand même leurs path (car je peux changer de machine donc le dossier du path change ) avant de rafraîchir la table .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Set dbs = CurrentDb()
    For Each tbl In dbs.TableDefs
    If Len(tbl.Connect) > 0 Then
    tbl.Connect = ";Database=" & "table1.csv"
    tbl.RefreshLink
    Cdlt,

  17. #17
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    il faut analyser les connections existante, regardes leurs construction dans le débuger!

    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
    Sub Test()
    With CurrentDb
        For i = 0 To .TableDefs.Count - 1
            With .TableDefs(i)
                If .Connect <> "" Then
                    Debug.Print .Name & " : " & .Connect
                    .RefreshLink              
                End If
            End With
            .TableDefs.Refresh
            DoEvents
       Next
    End With
    MsgBox "Fin"
    End Sub

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par dysorthographie Voir le message
    Bonjour,

    il faut analyser les connections existante, regardes leurs construction dans le débuger!

    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
    Sub Test()
    With CurrentDb
        For i = 0 To .TableDefs.Count - 1
            With .TableDefs(i)
                If .Connect <> "" Then
                    Debug.Print .Name & " : " & .Connect
                    .RefreshLink              
                End If
            End With
            .TableDefs.Refresh
            DoEvents
       Next
    End With
    MsgBox "Fin"
    End Sub
    Bonjour,
    voici ce que j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    table1: Text;DSN=table1 Spécification d'attache;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=850;DATABASE=D:\bureau\bac
     
    table2: Text;DSN=table2 Spécification d'attache;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=850;DATABASE=D:\bureau\bac\dossier1

    Comment je peux adapter ce chemin pour lier ma base?

    cdlt

  19. #19
    Futur Membre du Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Septembre 2016
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial

    Informations forums :
    Inscription : Septembre 2016
    Messages : 67
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par watred Voir le message
    Bonjour,
    voici ce que j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    table1: Text;DSN=table1 Spécification d'attache;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=850;DATABASE=D:\bureau\bac
     
    table2: Text;DSN=table2 Spécification d'attache;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=850;DATABASE=D:\bureau\bac\dossier1

    Comment je peux adapter ce chemin pour lier ma base?

    cdlt


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    'création de la nouvelle table t_externe issu du fichier classeur2.csv
    set tbl = db.createTableDef("t_externe")
    tbl.sourceTableName = "classeur2.csv"
    tbl.connect = "Text;DSN=specification;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=850;DATABASE=C:\Documents and Settings\user\Bureau"
    db.tabledefs.Append tbl
    db.tabledefs.refresh
    end sub

    tant qu'il ya une spécification, je pense qu' on ne peut pas importer des csv dynamique par ces méthodes, ces solutions restent fiable pour un csv fixe.
    Il s'agit d un bug acess des table liée, quand vous prenez un ficher csv vous le lier à votre base , ensuite vous rajouter ou supprimer une colonne dessus, et vous faite le rafraîchissement manuel ou en vba , acess garde le meme entete par defaut.
    je ne sais pas pour xls si on a le même soucis.
    Cdlt
    Cdlt,

  20. #20
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services à domicile

    Informations forums :
    Inscription : Décembre 2013
    Messages : 150
    Points : 98
    Points
    98
    Par défaut
    Bonjour à tous,

    je prends le train en marche ...

    pourquoi ne pas faire simplement par programmation un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, NomTable, NomCompletFichierDesinscription

    Cette commande crée un nouvelle table NomTable à partir du fichier Excel "NomCompletFichierDesinscription"
    Si les colonnes changent, il suffit à chaque fois:
    - de supprimer la table
    - de la re créer automatiquement avec la commande
    Les noms des champs se trouvent dans le premier enregistrement.

    Bon WE.

Discussions similaires

  1. [XL-2010] Rechercher tous les fichiers csv d'un repertoire et les importer en table dans Access
    Par Nestea dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 30/11/2011, 14h43
  2. Importer Feuil Excel dans Access
    Par beurnoir dans le forum Access
    Réponses: 4
    Dernier message: 21/10/2009, 16h46
  3. Import de fichier CSV automatique dans Access
    Par Jmar dans le forum Access
    Réponses: 4
    Dernier message: 20/01/2006, 10h48
  4. Pb import table dbf dans Access
    Par besly dans le forum Access
    Réponses: 10
    Dernier message: 28/12/2005, 20h51
  5. Importer Feuil Excel dans Access
    Par beurnoir dans le forum Access
    Réponses: 2
    Dernier message: 27/10/2005, 14h13

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