Extraire données d'un classeur vers un autre

Bonjour le forum,

Premier post sur ce forum. Il faut savoir que je débute dans VBA, donc j'ai un peu de difficultés à comprendre mais je fais de mon mieux pour apprendre !

J'ai fais quelques recherches sur internet pour essayer de trouver une solution à mon problème, mais je ne suis pas parvenu à adapter les codes qui se rapprocheraient d'une solution.

Voici ma problématique :

Je souhaiterai via un bouton, extraire les données d'un fichier vers un autre (sans forcément ouvrir le fichier source).

J'ai 2 fichiers : le fichier principal 'Fichier Test' dans lequel j'ai une feuille 'ONGLET D'IMPORTATION' dans laquelle je souhaite importer les données d'un fichier 'RAPPORT_20210101-20211221'. Il faut savoir que ce deuxième fichier est en CSV. Et ceci est un premier problème : lorsque j'ouvre manuellement le CSV, le format est 'bon' (les colonnes sont bien séparées, etc), mais lorsque je l'ouvre via une macro, le format est en UNE SEULE colonne, ce qui pose problème pour l'extraction...

Deuxième problème : ce fichier 'RAPPORT_20210101-20211221' n'a pas un nom unique. C'est à dire que c'est un fichier issu d'une base de données en ligne, et donc je peux faire une extraction de données, ce qui me donne ce fichier 'RAPPORT'. Cependant, son nom est amené à changer. C'est pourquoi j'avais pensé à deux solutions : aller chercher manuellement le fichier, à l'aide de ce code (qui ne fonctionne pas en l'état car lorsque j'ouvre le CSV, le format est en 'colonne unique') :

Sub IMPORTER()

Dim i As Integer
Dim nom As String
Dim Nomdececlasseur As String
Dim Nomcopie As String
Dim chemin As Variant

Application.DisplayAlerts = False
chemin = Application.GetOpenFilename("Classeurs Excel (*.*), *.*")
Workbooks.Open (chemin)
'classeur à copier
Nomcopie = ThisWorkbook.Name
'on parcourt toutes les feuilles
For i = 1 To Worksheets.Count
Workbooks(Nomcopie & ".xls").Activate 'classeur à copier a adapter le nom
nom = Worksheets(i).Name
Nomdececlasseur = ThisWorkbook.Name
Sheets(nom).Select
Sheets(nom).Copy After:=Workbooks(Nomdececlasseur).Sheets(1) 'classeur à coller a adapter le nom
Sheets(nom).Move After:=Sheets(Sheets.Count)

Next

Workbooks(Nomdececlasseur).Sheets(1).Activate
Application.DisplayAlerts = True

End Sub

Ou bien une deuxième solution : télécharger les fichiers rapports dans un dossier spécifique, afin de pouvoir ensuite via le bouton, extraire les données du fichier le plus récent (en fonction de sa date d’enregistrement). De ce côté, je n'ai pas de début de code à vous proposer...

Vous l'aurez certainement deviné, lorsque j'effectue l'extraction, il faudrait que les données précédentes soient écrasées.

J'espère ne pas poser une question qui a déjà trouvé une réponse, mais il ne me semble pas avoir vu une question similaire circuler sur les forums.

Merci par avance de vos solutions ou bien de toutes pistes susceptibles de m'aider :)

Bonne journée et bonnes fêtes de fin d'années !

96fichier-test.xlsm (23.42 Ko)

Cdlt,

Bonjour JM dpl. Bienvenue sur le forum !

Tout d'abord bon courage ! car cela semble un projet assez important quand on débute en VBA, mais tu vas y arriver

lorsque j'ouvre manuellement le CSV, le format est 'bon' (les colonnes sont bien séparées, etc), mais lorsque je l'ouvre via une macro, le format est en UNE SEULE colonne, ce qui pose problème pour l'extraction...

Essayes d'utiliser l'enregistreur de macro en ouvrant le CSV et en le paramétrant comme tu le souhaites, l'enregistreur de macro devrais te générer une ligne de code .open avec les paramètres souhaités que tu peux venir coller dans le code que tu nous proposes.

ce fichier 'RAPPORT_20210101-20211221' n'a pas un nom unique

Est-ce possible de prédire le nom du RAPPORT ? par exemple avec un date est-ce toujours le même format ?

Sinon la solution la plus polyvalente et ergonomique selon mois est de

aller chercher manuellement le fichier

En espérant avoir apporté des premiers éléments de réponses.

A+

Bonjour à tous !

Avez-vous étudier la possibilité d'utiliser Power Query (nativement intégré à votre version Excel) ?

Je vous livre une proposition qui utilise cet outil.

Il vous faudra mettre à jour l'emplacement de votre fichier CSV puis actualiser pour obtenir l'intégration de votre fichier.

La requête utilise ici un fichier spécifiquement nommé. Mais on peut mettre en place des règles particulières pour déterminer le fichier à lire (le plus récent par exemple....)

78jm-dpl-pq-v0.xlsx (76.37 Ko)

Bonjour Gabin,

Tout d'abord merci pour ton retour rapide.

J'ai essayé comme tu m'as dis l'enregistreur de macro : j'arrive juste à obtenir

Windows("RAPPORT_20210101-20211221.csv").Activate

lorsque j'ouvre le fichier puis que je le sélectionne. L’enregistreur n'a pas l'air de prendre en compte les étapes d'ouverture des fichiers.

Pour ce qui est du nom, lorsque j'effecture l'extraction des données via le logiciel en ligne, je peux saisir la plage de temps :

image

Ce qui va me donner par la suite obligatoirement dans le nom du fichier : RAPPORT_LeMoiDébutAnnée-LeMoiEnCours.csv

LeMoiDébutAnnée --> Janvier --> 20210101 (pour cette année 2021)

LeMoiEnCours --> Ici c'est Décembre --> 20211221

Il est donc possible de prédire les dates, mais uniquement si le fichier extrait est importé le jour même.

Je vais essayer de mon côté de récupérer le d'ouverture pour les CSV.

Cdlt,

Bonjour JFL,

Merci également de votre réponse.

Je ne connais pas du tout PowerQuery. Je me renseigne sur le sujet.

Merci !

Cdlt,

Re,

J'ai essayé comme tu m'as dis l'enregistreur de macro : j'arrive juste à obtenir

Oups... tu as raison cela ne fonctionne pas !

Pour résoudre le problème essayes d'ouvrir le CSV comme cela:

    Workbooks.Open Filename:= "C:\Users\GPETIT\Downloads\rapport-20210101-20211221.csv", local:=True

Si je ne dit pas de bétises, Le paramètre Local = true permet d'utiliser le séparateur par défaut utilisé par Excel en fonction de la langue utilisé

Cependant, à tester mais je pense que l'ouverture ne fonctionneras pas si tu utilises un Excel version English ou autre (à tester 🤷‍♂️) au cas ou tu souhaites exporter le programme dans des filiales ou que sait-je !

Sinon la solution de JFL seras sera sûrement plus pertinente ! Je suis totalement néophyte de Power..

Re GABIN

J'ai essayé ta proposition, cela fonctionne, le fichier s'ouvre dans le bon format.

J'ai même adapté avec le code précédent, comme ca pas besoin de chemin :

chemin = Application.GetOpenFilename("Classeurs Excel (*.*), *.*")
Workbooks.Open (chemin), local:=True

Le fichier s'ouvre bien, et dans le bon format.

De plus, il copie l'intégralité de la feuille dans le classeur voulu.

Une idée de comment faire pour plutôt que de copier l'intégralité de la feuille et créer une nouvelle feuille dans le classeur 'Fichier Test', que je puisse copier une plage de cellule et la coller dans les cellules correspondantes de la feuille : ONGLET D'IMPORTATION

Et un autre problème qui a son importance :

Nomcopie = "RAPPORT_20210101-20211221"

Cette ligne ne me permet que d'insérer le fichier portant exactement ce nom. Y aurait-il une solution pour que ceci fonctionne avec le fichier que j'ai sélectionné ? (que j'ai choisi d'ouvrir)

Le code :

Sub IMPORTER()

Dim i As Integer
Dim nom As String
Dim Nomdececlasseur As String
Dim Nomcopie As String
Dim chemin As Variant

Application.DisplayAlerts = False
chemin = Application.GetOpenFilename("Classeurs Excel (*.*), *.*")
Workbooks.Open (chemin), local:=True
'classeur à copier
Nomcopie = "RAPPORT_20210101-20211221"
'on parcourt toutes les feuilles
For i = 1 To Worksheets.Count
Workbooks(Nomcopie & ".csv").Activate 'classeur à copier a adapter le nom
nom = Worksheets(i).Name
Nomdececlasseur = ThisWorkbook.Name
Sheets(nom).Select
Sheets(nom).Copy After:=Workbooks(Nomdececlasseur).Sheets(1) 'classeur à coller a adapter le nom
Sheets(nom).Move After:=Sheets(Sheets.Count) 'on met les onglets dans l'ordre

Next

Workbooks(Nomdececlasseur).Sheets(1).Activate
Application.DisplayAlerts = True

End Sub

Merci par avance,

Cdlt,

47fichier-test.xlsm (35.93 Ko)

UPDATE :

J'ai réussi à copier uniquement la plage dont j'ai besoin...

Il ne me reste plus qu'à gérer le nom du fichier pour que ca s'applique à n'importe quel fichier du format :

RAPPORT_ANNEEMOIJOUR-ANNEEMOIJOUR
Sub IMPORTER()

Dim i As Integer
Dim nom As String
Dim Nomdececlasseur As String
Dim Nomcopie As String
Dim chemin As Variant

Application.DisplayAlerts = False
chemin = Application.GetOpenFilename("Classeurs Excel (*.*), *.*")
Workbooks.Open (chemin), local:=True
'classeur à copier
Nomcopie = "RAPPORT_20210101-20211221"
'on parcourt toutes les feuilles
For i = 1 To Worksheets.Count
Workbooks(Nomcopie & ".csv").Activate 'classeur à copier a adapter le nom
nom = Worksheets(i).Name
Nomdececlasseur = ThisWorkbook.Name
'Sheets(nom).Select
'Sheets(nom).Copy After:=Workbooks(Nomdececlasseur).Sheets(1) 'classeur à coller a adapter le nom
'Sheets(nom).Move After:=Sheets(Sheets.Count) 'on met les onglets dans l'ordre

Range("A3:X356").Select
Selection.Copy
Windows("Fichier Test.xlsm").Activate
Sheets("ONGLET D'IMPORTATION").Select
Range("B2").Select
ActiveSheet.Paste

Workbooks(Nomcopie & ".csv").Close

Next

Workbooks(Nomdececlasseur).Sheets(1).Activate
Application.DisplayAlerts = True

End Sub

Je te proposes ce code à adapter:

With Application.FileDialog(msoFileDialogFilePicker)
    .AllowMultiSelect = False
    .Title = "Titre de la fenêtre"
    .InitialFileName = "Par défaut ou si le chemin est incorrect: Mes documents"
    .Show
    If .SelectedItems.Count = 0 Then
        Exit Sub 'Ou message d'erreur et on recommence
    End If
        Book = .SelectedItems(1)
        Dim T
        T = Split(Book, ".")
        If Left(T(UBound(T)), 3) <> "csv" Then
            Exit Sub 'Ou message d'erreur et on recommence
        End If

        Call LaProcedure(.SelectedItems(1))
End With

Il permet d'aller directement sélectionner ton rapport. Il y a une gestion d'erreur si le fichier choisit n'est pas un .csv

ensuite dans le code proposé je choisit d'exécuter une procédure avec comme argument le fichier sélectionné mais libre à toi de lancer le code à la suite et d'adapter.

Je reste à dispo si besoin d'aide pour la suite :)

A+

Pour compléter ma réponse, le code pour ouvrir le csv après sélection ressemblerais à:

Workbooks.Open Filename:=.SelectedItems(1), local:=True

Re,

Je pense avoir réussi à trouver une solution :

Sub IMPORTER()

Dim i As Integer
Dim nom As String
Dim Nomdececlasseur As String
Dim Nomcopie As String
Dim chemin As Variant
Dim attention As Integer

Application.DisplayAlerts = False
chemin = Application.GetOpenFilename("Classeurs Excel (*.*), *.*")
Workbooks.Open (chemin), local:=True
'classeur à copier
Nomcopie = ActiveWorkbook.Name
'on parcourt toutes les feuilles
For i = 1 To Worksheets.Count
Workbooks(Nomcopie).Activate 'classeur à copier a adapter le nom
nom = Worksheets(i).Name
Nomdececlasseur = ThisWorkbook.Name
'Sheets(nom).Select
'Sheets(nom).Copy After:=Workbooks(Nomdececlasseur).Sheets(1) 'classeur à coller a adapter le nom
'Sheets(nom).Move After:=Sheets(Sheets.Count) 'on met les onglets dans l'ordre

attention = MsgBox("Etes-vous certain de vouloir remplacer les données existantes par celles du fichier :" & Nomcopie & " ?", vbCritical + vbYesNo, "ATTENTION")

If attention = vbYes Then

Range("A3:X400").Select
Selection.Copy
Windows("Fichier Test.xlsm").Activate 'Changer le nom du Fichier si besoin
Sheets("DONNEES - GAZ").Select 'Changer le nom de l'onglet si besoin
Range("B3").Select
ActiveSheet.Paste

MsgBox ("Export Terminé !")

Else

MsgBox ("Export Annulé !")
Workbooks(Nomcopie).Close

End If

Next

Workbooks(Nomdececlasseur).Sheets(1).Activate
Application.DisplayAlerts = True

End Sub

De cette manière les données sont bien importées

Le seul bug que j'ai trouvé pour le moment c'est si jamais j'annule la recherche du fichier... Erreur VBA à la ligne

Workbooks.Open (chemin), local:=True

En effet ton code fonctionne très bien... plus pratique que ce que j'avais proposé

Ajoutes simplement cette ligne après le GetOpenFilename pour plus avoir le msg d'erreur.

If chemin = "Faux" Then Exit Sub

A+

Parfait !!

Je pense pouvoir clôturer ce post, merci beaucoup en tout cas. Si je rencontre des problème dans le futur sur ce sujet, je r'ouvre un poste ou écris ici ?

Merci en tous cas pour l'aide, et bonnes fêtes de fin d'année !

Super !

je r'ouvre un poste ou écris ici ?

A toi de voir si c'est un nouveau problème qui commence à dériver du problème initial, je te conseil de créer un nouveau topic,

A+

Rechercher des sujets similaires à "extraire donnees classeur"