Mise à jour d’une base Access par fichier CSV ou Excel – Episode 8
Suite de la série sur l‘importation de données CSV ou Excel dans Access.
L’article précédent a mis en place la classe
DatabaseUpdater
qui va permettre de « jouer » une série d’importations automatiquement. Voici comment tester cette classe.
Si vous avez manqué le début
Relisez la loooongue série d’articles précédents, si vous ne l’avez pas déjà fait, sinon, rien ne marchera. 😉
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 1
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 2
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 3
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 4
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 5
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 6
- Mise à jour d’une base Access par fichier CSV ou Excel – Episode 7
Les fichiers de test
- Sur mon bureau Windows, j’ai un dossier appelé «
Fichiers CSV
« , dont le chemin est donc :C:\Users\Hervé\Desktop\Fichiers CSV
. - Dans ce dossier, j’ai deux séries de fichiers : trois fichiers CSV, et trois fichiers Excel. Il s’agit de deux scénarios d’importation différents (on importera soit les fichiers CSV, soit les fichiers Excel).
La table de mise à jour
Comme l’idée est d’automatiser l’importation de ces fichiers, on va d’abord les référencer dans la table tbl Updates
, créée dans l’article précédent. Voici ma table de mises à jour :
Comme vous ne voyez rien sur la capture d’écran 😉 voici le détail de la première ligne :
Id
: numéro automatiqueSource
:C:\Users\Hervé\Desktop\Fichiers CSV\Dest01.csv
SourceType
:CSV
ExcelVersion
:9
(qui est la valeur de la constanteacSpreadsheetTypeExcel12
, Excel 2007 et plus)Target
:tbl Destinataires Newsletter
TempTable
: videHeaders
: cochéeImportSpecs
: videAutoClean
: cochéePriority
:1
Category
:Test CSV
- Les 2 lignes suivantes sont identiques, à part la
Source
(changez le nom de fichier), et la priorité (2, puis 3). - Les 3 lignes qui suivent concernent les fichiers Excel : les noms de fichiers changent, ainsi que
SourceType = EXCEL
.
Le code
Pour tester tout ça, recopiez le code qui suit dans un module standard de votre base de données :
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 |
' --- ' IMPORT DE FICHIERS CSV ' --- ' Sub TestNewsletterCSV() ' Pour les tests... CurrentDb.Execute "DELETE * FROM [tbl Destinataires Newsletter]" ' Mise à jour ImportationGlobale "Test CSV" End Sub ' --- ' IMPORT DE FICHIERS EXCEL ' --- ' Sub TestNewsletterExcel() ' Pour les tests... CurrentDb.Execute "DELETE * FROM [tbl Destinataires Newsletter]" ' Mise à jour ImportationGlobale "Test Excel" End Sub ' --- ' IMPORTATION ' --- ' Sub ImportationGlobale(ByVal strCategory As String) Dim dbu As New DatabaseUpdater ' Mises à jour If dbu.Update(strCategory) Then MsgBox "Mise à jour terminée !", vbInformation Else MsgBox "Mise à jour interrompue, des erreurs ont été détectées." _ & vbCrLf & vbCrLf & dbu.LastImport, vbExclamation End If Set dbu = Nothing End Sub |
Tester
- Placez le curseur dans la première procédure (
Sub TestNewsletterCSV / End Sub
). - Cliquez sur l’icône Exécuter Sub/UserForm.
- Faites la même chose avec la deuxième procédure.
Les 2 procédures de test appellent elles-mêmes la procédure ImportationGlobale
, qui déclenche l’importation proprement dite. Le principe consiste à :
- Créer un objet
DatabaseUpdater
. - Appeler la méthode
Update()
de cet objet, en lui passant une catégorie. La catégorie permet de ne traiter que certaines lignes de la tabletbl Updates
(les 3 lignes marquées «Test CSV
» pour le scénario CSV, et les 3 lignes marquées «Test Excel
» pour le scénario Excel).
Avec tout ce qui a été mis en place précédemment, il suffit maintenant d’une seule ligne (l’appel de ImportationGlobale
) pour déclencher une série d’importations. Pratique, non ?
Bonjour,
Merci pour ce blog et merci aussi à tous ceux qui ont commentés. Je cherche aussi à importer un fichier csv dans une table avec clé composée, je commente ici puisqu’on en parle. Tout d’abord, j’ai l’impression qu’il n’y a pas de possibilité de créer une specification d’importation avec une clé primaire composée ? C’est possible ?
Merci d’avance,
La spécification d’importation n’a pas nécessairement de notion de clef (il s’agit d’une liste de champs à importer). Donc a priori, si le fichier source contient une clef composée, ça peut passer.
Bonjour , je reviens vers vous pour d’autres contraintes , en fait je voulais savoir si possible de modifier le code pour que la mise à jour se fasse par ordre de colonne et non pas par libelle de l’entête de la colonne ET pour que les clé primaire composé de plusieurs champ soit prise en compte , c’est a dire les deux premières colonnes , c’est les clés primaires et le reste c des données normal
merci d’avance pour votre aide
Cordialement
Ce sont effectivement 2 adaptations possibles du code (un peu long à publier tout de suite, comme ça :)).
Par contre, autant la gestion de clefs composées est une ouverture pratique, autant le fait d’utiliser les champs par leurs index me semble moins pratique : si la table ou le fichier évoluent en structure, on risque de mettre toute la moulinette par terre (donc c’est compliqué en termes de maintenance).
Bonjour MAylo,
vous avez pu importer des fichiers avec clés composées ? ça me serait aussi très utile !!
J’ai cru avoir imaginé quelque chose d’acceptable en imaginant que la propriété PrimaryKey renverrait un tableau mais je n’arrive pas à l’écrire, j’ai des erreurs. De meme, je ne trouve pas la possibilité de créer une specification d’importation avec clée composée…
Merci beaucoup par avance
Dans mon exemple de code, j’ai fait (pour l’instant) le choix d’une clef primaire simple, ce qui fait que la propriété
PrimaryKey
est une chaîne. Sa valeur est précisémentIndexes("PrimaryKey").Fields(0).Name
. Mais on peut adapter le code en renvoyant directement la collectionIndexes("PrimaryKey").Fields
, ce qui permet d’avoir la liste de tous les champs de la clef.Bien sûr, ça ne suffira pas (il faut adapter les requêtes SQL également), mais c’est déjà une piste…
Je posterai sans doute une version avec clef composée un jour, mais je suis trop pris ces temps-ci pour le faire ces jours-ci. 🙁
Bonjour, magnifique article très clair et professionnel !
J’ai un petit problème, mes lignes s’importe dans la table temporaire avec un message erreur d’importation et une table se crée avec un problème de conversion de type sur des dates ! Avez vous deja eu ce genre de problème ?
Merci d’avance
De rien 🙂
Est-ce que la date, dans le fichier de départ, est dans un format compatible ?
Ou autrement dit : quel est le format de la date de départ ?
Format : 02/07/2014
Le champ correspondant, dans la table, est bien de type Date/Heure ?
j’ai le meme problème et le champ correspondant dans la table est bien de type date/heure je comprend plus rien
La date est dans le même format ?
Bonjour ,
J’ai suivi le tuto à la lettre et quand je lance l’importation sur plusieurs fichiers , j’ai un message d’erreur :
“Eléments non trouvé dans cette collection”
si quelqu’un peut m’aider a résoudre le problème , merci d’avance
Cordialement
Le programme s’arrête sur quelle ligne ?
il bloque sur la fonction importation globale
sur cette ligne :
‘ Mises à jour
If dbu.Update(strCategory) Then
et j’arrive pas à trouver ce qui ne va pas sur la fonction Update.
Voici ma base de test , si ca peut aider a trouver d’ou vient le problème. .
http://cjoint.com/14jn/DFyxmMpCjYx.htm
le module s’appel « import_Plusieurs_Excel »
Merci bcp pour votre aide .
mon problème a été résolu , c’est mon champ STARTTIME qui déconnait , j’avais mis Startime avec un seul « T » . :p
mille merci pour ce tuto 😉
Content que ça fonctionne. 🙂 Effectivement, quand il y a une erreur du type « Elément non trouvé dans la collection », ça indique souvent qu’un objet nommé (ici un champ) n’a pas été trouvé.
Bonjour,
D’abord très bon article qui répond partiellement à mon besoin,
J’ai suivi jusqu’ici, mais maintenant j’ai un cas particulier :
1- D’abord, je dois sélectionner plusieurs fichiers CSV à emporter à partir d’une Boite de dialogue (Sélectionner les Fichiers à importer)
2- Mes fichiers source CSV ne contiennent pas une ligne d’en-tête ==> Donc je dois mettre Headers : False et après qu’est ce que je dois faire ?
3- Je n’ai pas besoin de toutes Les informations contenues dans les fichiers CSV, je dois choisir lesquels je veux importer et aussi indiquer à quels noms de champs de la table Access ils correspondent.
(Aussi il faut que je fasse un test sur les dates car il sont de cette forme 20131224 ==> Donc je dois les transformer au format Date compris par la BD).
Exemple :
Les champs de la Table dans Access :
CODEOPERATION DATEMATURITE DATEOPERATION DATEVALEUR DEVISE MONTANTDEVISE MONTANTDINAR OPERATION TAUX BANQUE OPERATEUR
Exemple de ligne des fichiers CSV :
MM1335415608;20131220;20131223;20131224;PRET;CAD;2080000.00;339;BCT;;0.8125;46.94;Pret MM DVS;NABIL;
(Je dois sélectionner que les informations dont j’ai besoin)
Si c’est possible de m’envoyer un exemple qui peut le faire ce serait gentil,
Merci pour ton aide, c’est très urgent.
Vu les contraintes diverses sur le fichier source (pas d’en-têtes, des dates à reformater, des colonnes à sélectionner…), j’ai peur que son importation ne puisse pas se faire directement avec le code de ces articles (voir le 1er article de la série pour les différentes conditions à respecter).
Il va sans doute falloir passer par une importation sur mesure, par exemple :
Peut-être qu’une spécification d’importation peut également faire l’affaire (à vérifier pour les dates) ?
Merci pour m’avoir répondu,
Une spécification d’importation résout partiellement le problème sauf que je dois spécifier quel champ du CSV appartient à quel champ de la Table,
Donc l’idée est de découper les lignes du CSV avec le délimiteur « ; » et affecter à chaque partie un nom significatif, ensuite faire correspondre chacun au champ qui lui correspondant dans la Table.
==> Mais je ne sais pas comment appliquer ça en VBA.
C’est un peu long à expliquer dans un commentaire de blog. Dans les grandes lignes, il faudrait sans doute :
Pas simple dit comme ça, ça demande du code sur mesure… 😉
Bonjour,
J’apprécie vraiment votre article bien détaillé,
mais je ne retrouve pas dans la section Téléchargements du blog la base de données complète reprenant tous ces exemples ainsi que le fichier Clients.csv.
si vous ne l’avez pas encore posé, je vous prie de me les envoyer par mail :
sami.jilani1983@gmail.com
Merci pour votre aide.
Je n’ai pas encore eu le temps de finaliser la base d’exemple (il y a encore quelques articles à ajouter). C’est pourquoi elle n’est pas encore disponible en téléchargement.
angel > Sur quelle ligne est-ce que cela « casse » ?
Fab > Content que ça fonctionne ! 🙂
Merci! Effectivement maintenant cela fonctionne très bien une fois que j’ai neutralisé
‘If blnIncludeKey Then
‘strSQL = strSQL & » AND ([{2}] > 0) »
‘Else
‘strSQL = strSQL & » AND ([{2}] < 1) »
‘End If
Merci encore 😉
Fab > Merci pour le retour. 🙂 A priori, l’erreur viendra entre autres de cette partie :
…et de la suivante. Pour des raisons de gestion des NuméroAuto, je compare la clef primaire à 0 ou à 1, ce qui échouera sur ces champs Texte (ou non numériques de manière générale). Il faudrait adapter un peu le code pour adapter cette partie. J’ai noté la remarque, ça fera sans doute un article futur (mais il faut un peu de temps pour tester 😉 ).
Bonjour,
1er) super le projet! j’aime bien le cotés pédagogique.
2émé) j’ai juste un pb avec la clé primaire qui n’est pas numérique mais au format texte. J’ai un champs qui peut servir de clé primaire lettres et chiffres (xxxx-12345678). si je tronque sur les chiffres pas de pb ça marche au format numérique mais si je passe au format texte j’ai erreur lors de l’insertion de lignes. J’ai cherché mais pas trouvé ce qui m’en empêche. avez vous une idées?
Fab
Thomas> Merci pour le retour. 🙂 Et bonne visite sur le blog !
Bonjours,
Je suis un retraité qui essaie de comprendre:
j’ai suivi les huit étapes et à l’arrivée j’ai un message lors de l’importation
« Eléments non trouvé dans cette collection »
je ne parviens pas à trouver l’erreur
Pouvez vous m’aider ?
Cordialement
Félicitations pour votre blog, qui est d’une très grande clarté. Les exemples proposés me semblent particulièrement utiles, bien choisis et bien conçus.
Je n’ai encore rien testé, mais je suis convaincu par avance, rien qu’à la lecture.
Merci à vous.
Bonjour,
Merci pour toutes ces infos. c’est super sympa.
je viens de me créer dans le fichier de liaison entre SAP et Acces, un champ concatener, afin de pouvoir apposer une clé primaire dans Access.
cela me va bien pour l’instant.
Me plongeant juste dans le VBA, je préfére y aller doucement car j’ai besoin de cette base pour bosser donc petit à petit….
en tout cas merci Bcp pour vos eclaircissements.
ludo
Ludo34 > Il y a effectivement un peu d’adaptation à prévoir pour gérer une clef composée. En gros, partout dans le code où la propriété
PrimaryKey
est utilisée, il faudra des retouches. La structure objet du code fait que c’est très cloisonné, donc en principe plus adaptable… mais il y a quand même des retouches. 😉Parfait.
Je préférerais la piste N°1 mais vba et moi ce n’est qu’une nouvelle histoire qui commence. je vais donc essayer de m’y pencher en espérant ne pas y perdre ni mon latin ni trop de temps 🙂
merci
Ludo34 > Techniquement, il peut effectivement y avoir une clef primaire composée de plusieurs champs. L’important étant que l’ensemble des champs constitue une valeur unique. D’un point de vue Bases de données, c’est parfait…
Le seul problème est que ma moulinette, en l’état actuel, ne gère qu’une clef simple, non composée (voir le point 8 de l’introduction du premier article de la série). 😉 Il y a donc 2 pistes :
Bonsoir,
je viens de trouver deux champs :
– un champ pour le N° de document
– un champ pour la Position comptable dans ce document (1,2,3…) autant de numéro différent que de lignes dans un même N° de Document.
Apparemment d’aprés un collègue, on peut indiquer 2 clés primaires dans une même table, me permettant d’obtenir une clé unique pour chaque enregistrement.
les défauts possible pour ce genre d’utilisation ?
merci
Ludo34 > Mais dans ces données, il n’y a vraiment aucune info qui serve de clef ? Genre : un numéro de client, un numéro de produit… ? On n’a pas le choix des champs à inclure dans l’extraction ?
Sinon, la solution qui consiste à ajouter un numéro dans Excel n’est sans doute pas viable. Exemple :
Mais comment peut-on le savoir ?
Si solution 1, cela serait trop facile et donc moins marrant….
Les données enregistrées dans SAP peuvent bouger (financière et quantité) Il me faut donc trouver le moyen de créer une clé primaire entre SAP ==> Access.
Pas facile. Si je liais la feuille excel avec une formule de calcul dans la dernière colonne qui pourrait me donner un Numéro Unique de ligne cela pourrait le faire ?
Je t’avoues que je préférerais passer par du VBA si possible pour éviter de devoir créer une grosse feuille excel avec calul et peut-être risque d’erreurs.
Ludo34 > Il n’y a pas un champ, dans SAP, qui puisse être intégré à l’extraction, et qui soit déjà une clef primaire SAP ?
Sinon, avant de lancer des usines à gaz : est-ce que le but est :
Le premier scénario est plus simple et ne nécessite pas de clef primaire. Il ne nécessite d’ailleurs pas tout le code VBA de cette série d’articles. 😉
Bon et bien, je ne sais pas obtenir une numérotation unique de chaque ligne extraite de SAP qui pourrait me servir de clé primaire.
y aurait il un autre moyen ?
Peut-être en me créant une clé primaire automatique dans Excel qui serait reprise dans Access ?
par avance merci
Ludo34 > S’il n’y a pas de clef primaire dans la source, il n’y a aucun moyen fiable de comparer les données importées à celles existantes dans la base Access. N’est-il pas possible, lors de l’extraction, d’inclure la clef primaire des données de départ ? Sinon, qu’est-ce qu’on fait dans ce cas quand une ligne vient de SAP et qu’elle existe déjà dans Access ?
Si on incrémente un champ supplémentaire « à la volée », le problème est qu’il n’y aura pas de moyen de comparaison avec une importation future. Donc ça ne résout pas complètement le problème. 🙁
Bonjour et bravo pour votre Blog. Les passionés sont toujours de bons conseils et aides.
Je viens de suivre à la lettre votre procédure et tout fonctionne à merveille.
Pour mon utilisation personnelle par contre j’aurais une petite question.
J’ai une extraction de données d’une base (SAP) que je veux importer dans Access (csv ou excel). bien entendu je n’ai pas de clés primaire extraite de cette extraction.
Ma question : comment puis-je faire pour reussir à importer mes données dans ma table tout en incrémentant une clé primaire automatiquement et abscente de mon fichier source ?
je ne sais pas si j’ai été trés clair là pour le coup 🙂
merci pour votre support.
ludovic