Importer plusieurs classeurs Excel dans une table Access en VBA

Cet article fait suite à celui-ci : Importer plusieurs feuilles Excel dans une table Access en VBA.

Sur le même principe, on va voir ici comment importer les données de plusieurs classeurs Excel. Et pour garder la logique de l’article précédent, j’ai gardé la possibilité d’importer plusieurs feuilles de chaque classeur.

Le scénario

Je dispose de plusieurs classeurs Excel, dont les données doivent être importées dans Access. Pour que ça marche, les tableaux respectent un certain nombre de contraintes :

  • Les feuilles ont toutes la même structure (sinon, on ne va pas s’en sortir !).
  • Les feuilles peuvent avoir ou non des titres sur leur 1ère ligne (dans mon exemple, toutes les feuilles ont des titres).
  • La structure des feuilles correspond à la structure de ma table Access : les champs sont dans le même ordre, et les types de données sont compatibles.
  • Dans mon scénario, la 1ère colonne (Numéro Acteur) est clef primaire dans la table Access. Ça veut dire qu’il faut que les valeurs de Numéro Acteur, dans Excel, soient toutes différentes. Sinon, il y a aura des erreurs – normales – à l’importation.
  • Les classeurs sont tous placés dans le même dossier Windows.
  • Chaque classeur doit avoir le même nombre de feuilles à importer, et ces feuilles portent le même nom. Par exemple, si je veux importer les feuilles Acteurs1 et Acteurs2, tous les classeurs doivent avoir des feuilles portant ces noms.
  • Un classeur peut comporter d’autres feuilles (en nombre quelconque) qui ne seront pas concernées par l’importation.

Comme dans l’article précédent, la table Access a cette structure :

Le code

Voici une procédure VBA à recopier intégralement dans un module standard de votre base de données.

Important
La fonction AddBackslash() doit aussi être présente dans un module de votre base de données.

La procédure ci-dessus doit recevoir 4 paramètres pour fonctionner :

  1. Le chemin du dossier qui contient les classeurs Excel à importer.
    Tous les classeurs sont supposés d’extension XLS, mais vous pouvez adapter en XLSX sur Excel 2007/2010.
  2. La liste des feuilles à importer (au cas où certaines feuilles devraient être ignorées).
  3. Le nom de la table Access de destination.
  4. Une valeur booléenne (True / False) qui indique si les feuilles Excel ont des titres en première ligne.

Tester le code

Cette autre procédure (à recopier par exemple dans le même module) permet de tester l’import :

Bien sûr, vous adaptez les valeurs en fonction de votre configuration.
Exécutez ce deuxième bloc de code. Il vous sera demandé si vous souhaitez vider la table Access avant d’importer toutes les données.
Et hop !

Vous aimerez aussi...

23 réponses

  1. débutantmaisvaréussir dit :

    Bonjour,

    Je viens de trouver votre macro pour regrouper une multitude de fichiers avec 5 onglets à regrouper dans Access.

    Cependant, ou dois je mettre les 4 paramétres afin que cela fonctionne ?
    Je pense que c’est à la fin de ces 4 lignes ?
    Sub ImportExcelMulti( _
    ByVal strChemin As String, _
    ByVal varFeuilles As Variant, _
    ByVal blnNoms As Boolean, _
    ByVal strTable As String _
    )

    Ai je raison ? Et si oui, comment le mentionner ? Je fais juste un copier coller du chemin par exemple et le colle ?
    En procédant de cette manière, j’ai un message d’erreur.

    Merci d’avance pour votre aide

    • Hervé Inisan dit :

      La procédure ImportExcelMulti() n’a pas besoin d’être modifiée (donc pas besoin d’ajouter quoi que ce soit après les 4 lignes citées).
      Par contre, il faut écrire une autre procédure qui appellera ImportExcelMulti().
      Le plus simple est de reprendre celle qui est en bas de l’article (TestImportExcelMulti). Il suffit d’y remplacer les 4 paramètres donnés en exemple par les tiens.

  2. whiii dit :

    Bonjour,

    Merci pour votre code. Seulement est-il possible de contourner le besoin que la première colonne soit la clé primaire ? Car chaque tableau de mes feuilles Excel ont la même première colonne…

    Donc, l’importation fonctionne mais m’indique un message d’erreur à chaque fois qu’il passe à une nouvelle feuille… Est-il possible de contourner ça ?

    Merci en espérant que les utilisateurs sont toujours actifs…

    Bonnejournée !

    • Hervé Inisan dit :

      A priori, ça doit pouvoir passer avec une clef primaire placée ailleurs qu’en première colonne. Il faudrait dans ce cas que, dans la définition de table d’Access, elle soit à l’emplacement souhaité. C’est à tester (je n’ai pas eu le temps de vérifier).
      Mais c’est généralement une bonne idée de placer la clef en 1ère colonne, y compris dans Excel : ça permet notamment d’utiliser la fonction RechercheV() de façon plus efficace.

  3. Hervé Inisan dit :

    christophe vdw > OO : Open Office (également appelé OOo : openoffice.org)

  4. christophe vdw dit :

    bonsoir
    pouvez vous être plus précis sur »OO »
    merci

  5. Hervé Inisan dit :

    christophe vdw > De ce côté-là, rien à faire malheureusement. Open Office Calc n’est pas dans les formats supportés par DoCmd.TransferSpreadSheet. Il suffit ceci dit que les clients conservent le format d’origine (Excel), c’est en principe possible avec OO.

  6. christophe vdw dit :

    bonjour
    d’abord merci pour »export csv »
    j’ai mis en application ImportExelMulti ça marche super!!!! sauf que…..
    certains clients me retourne le classeur exel en OPEN OFFICE … et la ça marche plus!!!!!
    comment faire pour importer du WINDOS et de l’OPEN OFFICE si possible en tous venant? merci

  7. Hervé Inisan dit :

    christophe vdw > Je viens de poster un article pour montrer comment déplacer un fichier en VBA. Ça se passe par là. Ouala !

  8. christophe vdw dit :

    rebonjour! deja une question sur export csv!!!!!

    j’ai mis en appliquation ce module super le résultat!!!!!!merci

    j’ai le même problème que r3yn du5 juillet 2011….normal!
    pouvez-vous être plus précis « comment faire le cas 2 »?
    je veux que les classeur EXELL soit déplacés dans un dossier »archive ».
    d’avance merci

  9. Hervé Inisan dit :

    Justin > Content que tu aies trouvé une solution, et merci pour le retour. 🙂

  10. Justin dit :

    Bonjour,
    Bon j’ai réussi à me débrouiller avec mon code mon problème se situait sur ma boucle!!!Je vous met en ligne le code réadapté à ma problématique pour les personnes qui pourraient en avoir besoin

    Bien à vous

  11. Justin dit :

    Les données squeezées se manifestent de cette manière:
    sur mes 197 fichiers Excel la macro m’importe seulement 110 données issues des 197 fichiers alors que je devrai avoir les données issues des 197 fichiers…Il me manque 87 fichiers qui ne sont pas importé.
    J’ai vérifié la mise en forme et la bonne homogénéité de mes données au travers de tous mes fichiers qui est bonne, je suis réellement dans une impasse…
    Bien cdlt

  12. Hervé Inisan dit :

    Justin > A vue de nez, la macro proposée dans l’article devrait effectivement convenir. Quand tu dis que des données sont « squeezées », ça se manifeste de quelle manière ?

  13. Justin dit :

    Bonjour,
    Merci beaucoup de vos post qui me sont d’une grande aide depuis quelques mois…Etant néophyte dans l’utilisation des macro VBA, je rencontre quelques problèmes lors de l’importation de différentes feuilles xls sous access.

    Je vous explique ma problématique:
    Je dispose de données de fréquentation routière (197 fichiers excel )….
    Tous mes fichiers excel ont la même forme 12 feuilles par classeur correspondant à chaque mois de l’année nommées « Janvier », « Février »,… A l’intérieur des feuilles toutes mes données ont la même structure avec des données en 1/4 h en ligne (96lignes) et les jours en colonnes (~30 colonnes)…

    Je souhaite créer des tables sous Access pour chaque mois de l’années regroupant toutes les feuilles de mes fichiers excel pour un mois (Par exemple pour le Mois de Janvier je veux que le module aille me chercher automatiquement toutes les données de la première feuilles des différents fichiers excel, pour Février idem, Mars, ….)

    J’ai trouver votre post qui devrait s’adapter parfaitement à ma problématique néanmoins je n’arrive pas à importer les 197 feuilles à l’intérieur des tables. J’ai l’impression que la macro squeeze des fichiers, je pense que mon problème se trouve dans cette partie du code –>

    *****************************************************************************
    ‘ Parcourir tous les classeurs du dossier
    strClasseur = Dir(strChemin & « *.xls », vbNormal)
    While strClasseur <> «  »
    ‘ Procédure d’importation pour chaque feuille de chaque fichier excel
    For Each varFeuille In varFeuilles
    DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _
    strTable, strChemin & strClasseur, blnNoms, varFeuille & « ! », True
    Next

    ‘ Classeur suivant
    strClasseur = Dir
    Wend
    *****************************************************************************
    Comment puis-je contraindre le module a importer toutes les feuilles « Janvier », « Février », « Mars »,… de mes 197 fichiers excel sans me squeezer certain fichiers?
    En vous remerciant d’avance de votre aide
    Cordialement

    Justin

  14. Hervé Inisan dit :

    r3yn > Il faudrait créer une table des classeurs traités, avec sans doute un champ pour le chemin complet du classeur, et un champ pour la feuille.

    Ensuite, après chaque traitement de feuille, mémoriser le classeur et sa feuille dans cette table. Ça peut se faire par une instruction SQL (INSERT INTO...) ou par un Recordset.

    Enfin, il faut, avant chaque traitement de feuille, vérifier si le couple classeur/feuille existe ou non dans la table. En cas d’existence, on passe ; sinon, on traite la feuille.

  15. r3yn dit :

    Je vous remercie pour votre réponse. En effet, je pense que le cas 2 est la solution la plus simple quoique que j’aimerai plutôt essayer l’autre solution pour voir. Comment faire pour mémoriser les enregistrements (feuilles) déjà importé(e)s dans la table ?

  16. Hervé Inisan dit :

    r3yn > Tel qu’il est prévu, le programme scanne effectivement un dossier pour traiter tous les classeurs de ce dossier (le comportement est donc normal).

    Maintenant, pour revenir à la question : il s’agit de ne pas réimporter des feuilles ou des classeurs ?

    • Le cas 2 est un peu plus facile à traiter, si on part du principe qu’on déplace (ou supprime) les classeurs traités (on peut imaginer un déplacement dans un autre dossier).
    • Le cas 1 demandera sans doute de mémoriser les feuilles traitées (dans une table Access) pour ne pas les retraiter ensuite.
  17. r3yn dit :

    Bonjour,
    Merci beaucoup pour vos codes, ils m’ont été d’une très grande utilité. Cependant je rencontre un petit problème avec celui ci: lorsque je rajoute un nouveau classeur de le dit dossier et que par la suite je désire importer la nouvelle feuille (à partir du nouveau classeur), access importe toutes les feuilles depuis le début, c’est à dire même celles ayant été précédemment importées, et du coup je me retrouve avec des feuilles en double et j’aimerai savoir comment est ce qu’il serait possible d’éviter ces répétitions avec une ligne de code pour éviter de devoir supprimer ou déplacer les anciens classeurs ailleurs;
    Merci d’avance.

  18. Hervé Inisan dit :

    daisyr > Toutes les feuilles ont la même structure ?

    Et l’objectif n’est pas d’importer toutes les feuilles, seulement 1 au choix ?

  19. daisyr dit :

    Mon problème à moi, qui s’apparente à ceux des autres, c’est:
    – Un classeur EXCEL contient 15 Feuilles
    – Tous les classeurs sont structurés de la même manière, c’est-à-dire avec 15 feuilles chacun
    – Le nombre de classeur peut varier: je peux en ajouter un nouveau à tout moment
    – J’ai déjà créer les tables dans ACCESS: à chaque feuilles EXCEL correspond une table ACCESS
    ** je veux donc, dans un formulaire, spécifier les classeurs, puis les feuilles à importer (2 zones de textes ou liste déroulante,1= classeur – 2=feuille

  20. Hervé Inisan dit :

    wahebus > Est-ce que tu peux préciser ta question ?

  21. wahebus dit :

    J’ai le meme probleme si ce n’est que j’ai jamais utilisé Vba quelqu’un pourrait-t-il m’aider pour faire comment a fin de rentrer les nom de table d’un classeur et le nom de la table access pour faire la meme chose ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *