Mise à jour d’une base Access par fichier CSV ou Excel – Episode 3

Suite de notre série sur l’importation de données CSV ou Excel dans une table Access. Aujourd’hui, il est temps de tester ce qui a été mis en place dans les articles précédents.
Si vous avez manqué le début
Relisez les articles suivants, si vous êtes arrivé sur cette page directement… 😉
- 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
Rappels
Si vous avez zappé l’épisode 1, je rappelle qu’on dispose au départ d’un fichier CSV appelé dest01.csv
qui contient ceci :
Id,Prénom,Nom,Email 8,Han,Solo,han.solo@rebels.com 9,Hervé,Inisan,webmaster@self-access.com 10,Luke,Skywalker, 11,Anakin,Skywalker,anakin.skywalker@darkstar.com 12,R2,D2,
Toutes ces données doivent être importées dans cette table de la base Access :
Un peu de configuration
Pour paramétrer un peu nos tests (et éviter de réécrire plusieurs fois les mêmes choses), faites ceci :
- Ajoutez un module standard (pas un module de classe, cette fois) à votre base de données.
- Nommez ce module
mod Configuration
, par exemple. - Recopiez-y ce qui suit.
- Modifiez selon vos besoins la constante
SOURCE_PATH
.
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 |
' ---------------------------------------- ' Module : mod Configuration ' Auteur : Hervé Inisan ' Description : Configuration de la base de données exemple. ' ---------------------------------------- Option Compare Database Option Explicit ' --- ' CONSTANTES ' --- ' Chemin des fichiers sources (CSV ou Excel) ' Modifiez le chemin en fonction de votre configuration. ' Si le chemin est absolu (C:...), il sera utilisé sans modifications. ' Si le chemin est relatif (pas de ":"), on suppose qu'il s'agit ' d'un sous-dossier par rapport à l'emplacement de la base Access. ' ' Conservez l'anti-slash final. ' Public Const SOURCE_PATH = "C:\Users\Hervé\Desktop\Fichiers CSV\" Public Const SOURCE_PATH = "Fichiers CSV\" ' --- ' CHEMIN DES FICHIERS SOURCES ' --- ' Public Function SourcePath() If InStr(1, SOURCE_PATH, ":", vbTextCompare) > 0 Then SourcePath = SOURCE_PATH Else SourcePath = CurrentProject.Path & "\" & SOURCE_PATH End If End Function |
Remarques sur la configuration
La constante SOURCE_PATH
définit le chemin où seront stockés les fichiers CSV (ou les fichiers Excel, plus tard). En fait, elle ne sera pas utilisée directement, mais plutôt au travers de la fonction SourcePath()
. L’idée est la suivante :
- Si
SOURCE_PATH
contient un chemin absolu (du style :C:...
ouP:...
), la fonctionSourcePath()
renvoie la constanteSOURCE_PATH
sans la changer. - Dans le cas contraire, on suppose qu’il s’agit d’un chemin relatif, et relatif à la base Access. Dans mon exemple ci-dessus, le chemin
"Fichiers CSV"
sera ajouté au chemin de la base de données. - Ce serait encore mieux en testant aussi les chemins réseau, démarrant par
\\serveur
😉
Le code de test
Voici enfin une petite procédure pour tester l’importation (en d’autres termes, pour tester la classe TableUpdater
des articles précédents).
- Créez encore un nouveau module standard (le mien s’appelle
mod Tests TableUpdater
). - Recopiez ce qui suit dans le module :
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 |
' ---------------------------------------- ' Module : mod Tests TableUpdater ' Auteur : Hervé Inisan ' Description : Tests de la classe TableUpdater. ' ---------------------------------------- Option Compare Database Option Explicit ' --- ' TEST DE MISE A JOUR DE TABLE - NEWSLETTER ' --- ' Sub TestTableUpdaterNewsletterCSV() Dim tu As TableUpdater ' Pour les tests, on vide la table avant d'importer ' les données externes CurrentDb.Execute "DELETE * FROM [tbl Destinataires Newsletter]" ' Initialisation d'un TableUpdater Set tu = New TableUpdater With tu ' Paramètres de l'importation .Headers = True .Source = SourcePath() & "dest01.csv" .SourceType = Csv .Target = "tbl Destinataires Newsletter" .TempTable = "tbl Destinataires Newsletter TEMP" ' Importation .Import End With ' Message final BilanImportation tu ' Libérer les ressources Set tu = Nothing End Sub ' --- ' MESSAGE DE FIN ' --- ' Private Sub BilanImportation(tu As TableUpdater) Dim strMessage As String ' Message final With tu If .LastError.Number = NoError Then strMessage = "Importation terminée !" & vbCrLf & vbCrLf _ & "Lignes ajoutées : " & .InsertedRows & vbCrLf _ & "Lignes mises à jour : " & .UpdatedRows MsgBox strMessage, vbInformation Else strMessage = StringFormat( _ "Une erreur s'est produite lors de l'importation.{0}" _ & "Erreur #{1} : {2}", _ vbCrLf, .LastError.Number, .LastError.Label) MsgBox strMessage, vbExclamation End If End With End Sub |
Quelques explications
La procédure importante est TestTableUpdaterNewsletterCSV
. Cette procédure déclare un objet TableUpdater
, le paramètre, lance l’importation, et enfin affiche un message de synthèse. L’objet TableUpdater
reçoit ces paramètres :
Headers
:True
si le fichier source contient une ligne d’en-tête,False
sinon. A priori, il faut que votre fichier CSV contienne des en-têtes, et que ceux-ci correspondent aux noms de champs de la table Access à mettre à jour.Source
: le chemin complet du fichier CSV ou Excel contenant les données à importer.SourceType
:Csv
ouExcel
, selon le format du fichier de données.Target
: la table à mettre à jour.TempTable
: nom de la table temporaire à utiliser pour importer le fichier source. Si vous n’alimentez pas cette valeur, elle prend un nom automatique dérivé du nom de la table cible.
Une fois les paramètres définis, la méthode tu.Import
lance l’importation proprement dite. En fin d’importation :
tu.LastError.Number
donne le numéro d’erreur, si erreur il y a eu (joli, non ?). La valeur vautNoError
si tout s’est bien passé. Dans le cas contraire, le nombre est l’une des valeurs de l’énumérationImportInfo
déclarée dans l’article précédent.tu.LastError.Label
donne le texte en clair de l’erreur.tu.InsertedRows
donne le nombre de lignes insérées. N’a d’intérêt que situ.LastError.Number = NoError
.tu.UpdatedRows
donne le nombre de lignes modifiées. Même remarque que ci-dessus.
La procédure BilanImportation
se charge d’afficher… le bilan de l’importation. J’ai extrait cette partie de la procédure principale de façon à pouvoir la réutiliser dans d’autres articles. Ça vous permet aussi, si l’affichage ne vous contient pas, de le remplacer plus facilement (vous pouvez utiliser autre chose qu’un MsgBox
).
Tester, enfin !
Placez le curseur quelque part dans la procédure TestTableUpdaterNewsletterCSV
(mais qui m’a donné des noms de procédures comme ça, qui ?! 🙂 ), et cliquez sur l’icône Exécuter / Sub/UserForm. Si ça fonctionne, vous obtiendrez le nombre de lignes ajoutées ou mises à jour. Sinon, un message d’erreur vous indiquera ce qui a échoué.
Consultez bien sûr la table, pour vérifier que tout est ok :
CurrentDb.Execute "DELETE ..."
pour conserver le contenu de la table, donc provoquer une mise à jour des lignes au lieu d’un ajout.
Bonjour et merci pour votre travail !
J’ai un msg d’erreur au niveau de .import -> Erreur d’exécution 52 , nom ou numéro de fichier incorrect !
Ma table à un ID. J’ai crée ma table en important manuellement mon fichier csv et sauvegarder ma table avec une clé primaire . Je ne crois pas que le problème vient de là.
Cordialement
Bruno
Est-ce que le chemin complet du fichier est valide ? (ce serait la première piste à suivre)
Bonjour
un grand merci pour votre aide !! moi aussi j’ai le mm soucis avec
.import -> Erreur d’exécution 52 , nom ou numéro de fichier incorrect !
Cordialement
j’ai pu régler l’erreur j’avais un souci au niveau du chemin de fichier.
mais après avoir exécuter le code il ne fait pas la mise a jour il écrase toutes les données que j’avais avant l’exécution
Cordialement
Il y a bien une clef primaire numérique dans la table (et du coup dans le fichier) ?
clé primaire alphanum
Ça pourrait venir de là : le code actuel ne gère que des clefs numériques (cf. autres articles de la série).
oui , je crois…
Public Const SOURCE_PATH = « T:\BE97732009098449.csv\ »
Si BE97732009098449.csv est le fichier à importer,
SOURCE_PATH
sera plutôt déclaré comme ceci :(il s’agit d’un chemin de dossier, pas d’un chemin complet de fichier)
Désolé , je comprends pas . Mon fichier Csv se trouve sur le disque T et se nomme « BE97732009098449.csv ».Dans source_path, je mets « T:\BE97732009098449.csv\ », logique ou pas ?
Pas si logique, en fait 🙂
SOURCE_PATH
est le chemin d’un dossier, pas le chemin d’un fichier. Donc il faut ici s’arrêter au nom du dossier qui contient le CSV, ici :T:\
.Le nom du fichier (à partir de ce chemin) est donné plus loin, sur la ligne 26 du 2ème listing :
Il faut remplacer
dest01.csv par
BE97732009098449.csv
.oui mais après il ne connaît pas le fichier à importer ! A quel endroit je dois mettre le le nom de fichier :’BE97732009098449.csv » ?
Je suis très nul , je sais …
Ok mais je nom de fichier , je le mets où ?
Merci
Voir ma réponse précédente. 😉
Sorry j’avais ton dernier msg
Bruno
j’avais pas lu ton dernier MSG, Suite au prochain n° !!!
Merci de ta patience
Maintenant , Erreur 3 , pas de clé primaire mais j’en ai une dans mes différentes tables, comprends plus rien….désolé
Est-ce qu’il y a bien une clef primaire dans la table qui sert pour l’importation ?
oui il y a un clé primaire . est ce que je peux vous envoyer la table et mon fichier csv , parce que je ne m’en sors pas
cardialement
Erreur #3 pas clé primaire définie.J’ai une clé primaire(Id) dans ma table d’importation, mais pas dans mon fichier .csv , si je fais la même opération avec un fichier équivalent Excell et que je rajoute un clé dans le fichier Excel , j’ai le même résultat 🙁
Cordialement
Bruno
Si j’ai suivi : il faut que la table ET le fichier CSV aient le même champ de clef primaire. Faute de quoi il n’est pas possible de comparer les données.
Cela ne fonctionne pas mais avec un fichier Excel,et même si je rajoute une clé primaire dans le fichier CSV ou Excell, 🙁
Cordialement
Après quelques jours de repos , je m’y remets mais cela ne fonctionne toujours pas même si j’ai un même champ de clef primaire. Est ce que je peux t’envoyer mes fichiers par mail?
Bruno
Pas ces jours-ci : j’ai pas mal de travail en ce moment, je n’aurais pas le temps de tester.
D’ici une quinzaine de jours ça devrait être possible.
Bonjour,
un grand grand merci pour tout ce travail !!
mon soucis pour l’importation (erreur #6), est que mon séparateur de fichier n’est ni une virgule « , » ni un point virgule « ; » mais un pipe « | » (AltGr+6).
Est-ce qu’il est possible de modifier / forcer la prise en compte de ce séparateur ?
D’avance merci pour vos retours
ah OK, je n’avais pas vu la page « Importation de données »… désolée !
Pas de souci ! 🙂
Bonjour,
lors de l’exécution du code j’obtiens le message d’erreur suivant :
« Erreur de compilation: Variable ou procédure attendue, et non un module » et me surligne strMessage=StringFormat.
Que dois-je faire?
merci pour votre aide
La fonction
StringFormat()
doit également être recopiée dans un module de la base de données (voir l’épisode 2 de la série).Ouala ! 🙂
Bonjour,
J’ai le même problème sauf que la fonction StringFormat() a bien été recopiée dans un module de la base créé à cet effet. Malgré cela, le problème persiste.
Merci par avance pour votre aide précieuse.
La fonction StringFormat() est bien dans un module standard (pas un module de classe) ?
Et sinon, le module s’appelle comment ?
Enfin, un petit test rapide : en cliquant sur Débogage/Compiler, est-ce que la compilation fonctionne, ou au contraire est-ce qu’elle s’arrête à un endroit précis ?
j’ai suivi les différentes étapes, mais j’ai un message d’erreur :
« Erreur de compilation »
« Sub ou Function non définie »
et j’ai cette ligne de surlignée
« Private Sub BilanImportation(tu As TableUpdater) »
Pouvez vous m’aider
Merci
Rank
Il doit te manquer un des bouts de code nécessaires à l’exécution. Essaie de faire un Débogage / Compiler pour voir où ça coince précisément.
je viens de régler mon probleme de ” Erreur #6 : Erreur lors de l’insertion de ligne”
le fichier CSV doit contenir des ( , ) et non pas des ( ; )
😀
Oui, ça correspond à ma réponse précédente. Ou sinon, s’il y a des « ; » il est possible de passer par une « spécification d’importation ».
Content que ça fonctionne. 🙂
Bonjour,
j’ai un message d’erreur ” Erreur #6 : Erreur lors de l’insertion de ligne”
et quand je vérifie la table Temp je trouve que toutes les données sont dans une seule colone !!
s’agit il de la clé primaire ?
si oui comment je indiqué la clé primaire dans un fichier CSV
et merci d’avance 😉
Est-ce que le délimiteur de colonnes est correct ? Voir l’épisode 5 si ça peut aider.
Merci infiniment pour votre aide , je suis nouveau dans ce blog et je trouve que c’est tres utile 😀
j’ai un autre problème situ peux m’aider à le résoudre
après l’importation du fichier CSV je doit faire un test entre la mise à jour précédente (les données de ma BDD acces) et la mise a jour actuel (la nouvelle importation) pour voir s’il ya un chagement dans les valeur de certain colonnes.
pour celà je doit faire une interface qui va m’affiché un rapport sur le test de la mise a jour et laisser la main a l’utilisateur soit de garder l’ancienne valeur qui existe dans la base de données ou d’accepter la nouvelle valeur de la mise à jour
merci encore une fois 🙂
Ça, c’est quelque chose qui n’est pas simple à automatiser. 😉 Une solution serait de créer une requête basée sur les 2 tables (les 2 tables jointes sur la clef primaire, dans cette requête), et de comparer les champs équivalents.
Bonjour,
Tout d’abord un grand merci pour toute la procédure d’importation, elle m’a fait gagner énormément de temps. J’ai cependant un problème depuis quelques temps :
J’avais testé votre procédure avec succès il y a quelques semaines mais ma tentative d’aujourd’hui est un échec, j’ai toujours l’erreur 3 clef primaire non définie.
J’ai beau essayé avec une table test comprenant 3 champs : un champs Id (défini comme clé primaire), nom, prenom, qui est vide au départ, et avec un fichier test.csv comprenant une dizaine de lignes avec un champs Id qui comporte bien des clés uniques, ça ne fonctionne pas.
J’ai testé manuellement pour voir si ce n’était pas le fichier mise en cause mais cela fonctionne normalement.
Je ne vois vraiment plus où chercher d’autant que tout marchait très bien il y a quelques semaines, j’ai peut être oublié de faire quelque chose ?
Merci d’avance
La clef primaire est bien définie dans la table ?
Oui :/ J’avais d’abord essayé avec ma base mais n’arrivant pas à résoudre ce problème, j’ai fait une base de test avec 3 champs dont le premier était clé primaire mais j’ai eu exactement le même problème au moment de l’importation
J’ai les 3 modules de classe : DatabaseUpdate, importerror et tableupdater et les 2 modules simples : modconfiguration et modtests. Le modconfiguration est bien configuré et la table est bien créé avec les champs de même nom que ceux du fichier csv. C’est bien tout ce qu’il faut pour faire fonctionner l’importation ?
Est-ce que c’est possible de poster ici les 1ères lignes du fichier CSV (titres compris), pour voir ?
Je vous avais répondu mais il semble que mon message n’a pas été transmis.Après plusieurs recherches et tests, il s’avère que mon problème vient des spécifications d’importation. Avec le séparateur virgule sans spécification, ça marche sans problème mais quand j’ai des points virgules et que je mets une spécification, j’ai l’erreur systématiquement, même en ayant recommencer tout depuis le début dans une nouvelle base :/
Je n’ai plus d’idée pour résoudre ce problème
Bonjour,
Je pense avoir finalement trouvé. L’erreur viendrait du fait que pour créer ma table, je suis passé par une spécification d’importation au lieu de la créer manuellement champ par champ. Je ne vois par contre la raison du problème étant donné que je ne vois pas de différence entre une table créée manuellement et une table créée à partir de données externes. Une idée ?
Il vaut mieux toujours créer les tables manuellement : ça permet de définir toutes les contraintes sur les champs plus précisément.
Dans le cas d’une création par données externes, Access doit généralement faire des choix par défaut. Par exemple : le type de champ est déduit des données, et la taille d’un champ Texte sera toujours 255. Ces choix par défaut peuvent donner des tables moins optimisées ou sources d’erreurs.
Bonjour,
Moi justement je voudrai savoir Comment on peut laisser à l’utilisateur d’aller choisir son fichier ? Car ma base sera en réseau et chaque utilisateur stock dans son espace personnel
Pouvez-vous m’aider
Merci beaucoup
Cet autre article devrait aider (il montre comment afficher une boîte Fichier/Ouvrir).
Il faut ensuite récupérer le choix fait par l’utilisateur, et le placer dans la propriété
.Source
. Du genre :angel > Est-ce que le chemin qui pointe vers le fichier est correctement orthographié ?
Merci beaucoup pour votre aide. Cependant je suis confronté à un tout autre problème tous comme @angel j’ai ce fameux message d’erreur. J’ai fait comme ceci
‘ Public Const SOURCE_PATH = « C:Users\Studio\Documents\IMPORT CSV »
Public Const SOURCE_PATH = « IMPORT CSV »
Cela n’as pas marché j’ai essayé sans les slash et cela ne fonctionne toujours pas.j’ai même essayé de faire comme ceci
‘ Public Const SOURCE_PATH = « C:Users\Studio\Documents\IMPORT CSV »
Public Const SOURCE_PATH = « C:Users\Studio\Documents\IMPORT CSV »
Merci pour votre aide
Quelques erreurs se sont glissées dans les chemins d’accès, après la migration récente du site. Je viens de corriger dans cet article (en principe !). Dans ton cas, le chemin devrait être quelque chose comme (avec le backslash final) :
Merci pour votre rapidité.
Je viens de corriger le problème mais le soucis c’est que le même message d’erreur s’affiche toujours. Serait – ce dû à une erreur dans de code dans d’autre module ?
Etant novice en la matière je ne serais trouver le problème.
Un grand merci pour votre aide !!
Si c’est une erreur de type « Fichier introuvable », c’est qu’un chemin est incorrect.
Qu’affiche ceci :
…en plaçant l’instruction avant le :
Alors voila le message que j’obtiens
« C:\Users\Studio\Documents\IMPORT CSV\dest01.csv »
J’ai bidouiller un peu le code de manière à obtenir: « C:\Users\Studio\Documents\IMPORT.csv »
En faisant :
.Source = SourcePath() ‘& « dest01.csv » et en remplaçant IMPORT CSV par IMPORT.csv
Le message d’erreur n’apparaît plus mais j’ai un nouveau message d’erreur » Erreur #6 : Erreur lors de l’insertion de ligne »
Sachant que mon fichier csv (à importer) ne comporte pas de ID car je souhaite qu’ Access détermine une fois la table importée un numéro ID automatique pour chaque enregistrement.
Je pense que cela peut être liée…
A priori, le message d’erreur a changé, ça veut dire que le chemin est correct cette fois.
Maintenant, l’absence de clef (ID) est sans doute la source du nouveau problème. Dans le premier article de la série, il est effectivement dit :
« La clef primaire doit être présente dans le fichier CSV. ».
mel > En tapant par exemple ceci (pour reprendre l’exemple de l’article) :
dans l’événement
Sur clic
du bouton.Salut, comment lié l’importation à un bouton de commande ?
Bonsoir,
J’ en suis à l’épisode 3 lorsque je teste Je ne parviens pas à transférer les données
j’ai un message d’erreur :
« Une erreur c’est produite lors de l’importation 1# Fichier source introuvable »
Ou es ce que je fait la faute ?
Pouvez vous m’aider
Cordialement