Transfert de données d'un classeur vers un autre classeur Excel VBA

Bonjour Mesdames, Messieurs,

Via une macro, je souhaite transférer les données (numéro de facture, site, code site, montant TTC, montant HT) d'une première base de données (BASE A) vers une seconde base de données (BASE B).

Pour cela, je souhaite utiliser une macro qui me permet d'importer ces données : quand j'appuie sur mon bouton importer, une fenêtre s'ouvre pour que je sélectionne mon fichier de ma BASE A afin que celle_ci s'exporte vers ma BASE B.

J'ai réussi mon code qui me permet d'ouvrir une fenêtre qui me permet d'aller chercher mon fichier. Le voici ci-dessous:

' Boucle permettant de sélectionner plusieurs fichiers
    'Do                                             '<--- dédié à la boucle DO pour ouvrir plusieurs fichiers
        ' Sélection du classeur source à partir d'une fenêtre
        cheminfichier = Application.GetOpenFilename("Fichiers Excels (*.xlsm), *.xlsm")

        ' Si on clique sur Annuler dans la fenêtre, on sort de la boucle
        If cheminfichier = False Then
                'Exit Do                            '<--- dédié à la boucle DO pour ouvrir plusieurs fichiers
        End If
        'Ouverture du classeur source
        Workbooks.Open cheminfichier

        ' Récupération du nom du classeur + extension
        For i = Len(cheminfichier) To 1 Step -1
            If Mid(cheminfichier, i, 1) = "\" Then Exit For
        Next
        nomfichier = Mid(cheminfichier, i + 1, Len(cheminfichier))

Mais je n'ai pas réussi le code qui dit à la macro d'exporter de la BASE A, dans la feuille 1 et dans les cellules ("A1:B45") et d'importer vers la BASE B, dans la feuille 1 et dans les cellules ("A1:B45"). Une fenêtre apparait et me dit : Erreur d’exécution - L'indice n'appartient pas à la sélection.". Voici mon code ci-dessous:

Workbooks("nomfichier").Worksheets("Feuil1").Range("A2:AK33").Value = Workbooks("outils.xlsm").Worksheets("BDDengie").Range("C2:AM33").Value

Auriez-vous une piste pour m'aider à résoudre mon problème s'il vous plait ?

Cordialement,

Lucie.

Bonjour,

Cette erreur apparaît quand tu fais référence à un objet qui n'existe pas (ou du moins pas là où tu le cherche...).

Par exemple, dans ton cas :

  • Pas de classeur nommé "nomfichier" (je parie que l'erreur est ici, j'en dis plus après)
  • Pas de feuille nommée "Feuil1" dans ledit classeur
  • On peut supposer que la référence "A2:AK33" est valide dans tous les cas, et ne génère pas d'erreur
  • Idem avec l'autre classeur

Si on se concentre sur cette partie :

Workbooks("nomfichier") 'Ici on cherche un fichier qui porte très exactement le nom "nomfichier"

Ce n'est pas la même chose que :

Workbooks(nomfichier) 'Ici on cherche un fichier qui porte le nom stocké dans la variable nomfichier

Ce qui démontre l'importance des guillemets... Voir en exécutant le code de cet exemple :

Sub ComprendreGuillemets()

Nom = "Pedro"
i = 22

MsgBox Nom & i
MsgBox "Nom" & i
MsgBox "Nom & i"

End Sub

Merci beaucoup ! Votre solution a fonctionné ! Vous me sauvez la mise haha

Je me permets de vous embêter encore une fois :

Workbooks("outils.xlsm").Worksheets("BDDengie").Range("C2:AM33").Value = Workbooks(nomfichier).Worksheets("Feuil1").Range("A2:AK33").Value

Ce code me permet d'exporter les valeurs des cellules A2:AK33 de la feuille "Feuil1" du classeur lambda "nomfichier" et d'importer ces valeurs vers les cellules C2:AM33 de la feuille BDDengie du classeur outils.xlsm.

Je voudrais pouvoir ajouter dans la BDDengie d'autres extractions à partir des cellules C34 jusqu'aux cellules AM34 sans avoir à me soucier de modifier dans le code les coordonnées des cellules. J'ai pensé à une boucle qui réalise la macro : si "vide" remplir la cellule. Cependant, je n'arrive pas à la formuler Auriez-vous une idée de boucle qui pourrait répondre à ma problématique, s'il vous plait ?

Encore merci beaucoup !

Lucie

Bonjour,

Je ne visualise pas très bien ce que tu souhaites (je n'ai pas encore prit mon café, c'est peut-être ça !). Peux-tu illustrer ton besoin avec un fichier commenté ?

Haha t'inquiète je comprends mais prends le temps de boire ton café !

Voici le fichier en PJ. J'espère m'être bien expliquée dans les petits commentaires que j'ai mis dans la feuille BDDexp1.

Merci encore !

752outils-copie.xlsm (72.29 Ko)

Haha t'inquiète je comprends mais prends le temps de boire ton café !

Voici le fichier en PJ. J'espère m'être bien expliquée dans les petits commentaires que j'ai mis dans la feuille BDDexp1.

Merci encore !

C'est beaucoup plus clair !

Il y a plusieurs manières de définir une plage de cellules sous VBA (liste non exhaustive !) :

  • Range("A1:C100")
  • Range("NomDeLaPlage")
  • Range("A" & LigDeb & ":C" & LigFin)
  • Range(Cells(1, 1), Cells(100, 3))
  • Range(Cells(LigDeb, 1), Cells(LigFin, 3))
...

Mes exemples 3 et 5 introduisent la possibilité d'utiliser un indice de ligne variable (c'est aussi faisable sur l'indice de colonne).

Si on continue, pour savoir où s'arrêtent les données (= dernière ligne), plusieurs possibilités également (encore une fois, la liste n'est pas exhaustive) :

DerLig = Range("A" & Rows.Count).End(xlUp).Row '(équivalent à CTRL + FLECHE DU HAUT à partir de la toute dernière cellule de ta colonne A)
DerLig = UsedRange.Rows.Count 'Compte le nombre de lignes utilisées, donc attention si présence de ligne vide avant ou dans les données

Une autre possibilité consiste à utiliser un tableau structuré, qui se manipule un peu différemment sous VBA.

D'accord alors ça fonctionne super bien mais il y a juste un petit hic : c'est que je dois commencer l'importation à partir de la ligne 2 car avant j'ai mes champs. J'ai essayé ça :

Range("C2" & ":AM" & LigFin).Value                                                                      
Range("C2" :" AM" & LigFin).Value
Range("C2:AM" & LigFin).Value

Mais aucun des trois codes ne fonctionnent ...

C'est mon expression qui est mauvaise ?

Merci encore !

D'accord alors ça fonctionne super bien mais il y a juste un petit hic : c'est que je dois commencer l'importation à partir de la ligne 2 car avant j'ai mes champs. J'ai essayé ça :

Range("C2" & ":AM" & LigFin).Value                                                                      
Range("C2" :" AM" & LigFin).Value
Range("C2:AM" & LigFin).Value

Mais aucun des trois codes ne fonctionnent ...

C'est mon expression qui est mauvaise ?

Merci encore !

Il y a quoi comme valeur dans ta variable LigFin ? Quel est le code erreur généré ?

Voici mon code

Sub rangecopy()

' Boucle permettant de sélectionner plusieurs fichiers
    'Do                                             '<--- dédié à la boucle DO pour ouvrir plusieurs fichiers
        ' Sélection du classeur source à partir d'une fenêtre
        cheminfichier = Application.GetOpenFilename("Fichiers Excels (*.xlsm), *.xlsm")

        ' Si on clique sur Annuler dans la fenêtre, on sort de la boucle
        If cheminfichier = False Then
                'Exit Do                            '<--- dédié à la boucle DO pour ouvrir plusieurs fichiers
        End If
        'Ouverture du classeur source
        Workbooks.Open cheminfichier

        ' Récupération du nom du classeur + extension
        For i = Len(cheminfichier) To 1 Step -1
            If Mid(cheminfichier, i, 1) = "\" Then Exit For
        Next
        nomfichier = Mid(cheminfichier, i + 1, Len(cheminfichier))

Workbooks("outils.xlsm").Worksheets("BDDengie").Range("C2:AM & LigFin").Value = Workbooks(nomfichier).Worksheets("ETAT DE LA LISTE DES FACTURES").Range("A2:AK33").Value

DerLig = UsedRange.Rows.Count 'Compte le nombre de lignes utilisées, donc attention si présence de ligne vide avant ou dans les données

End Sub

Et le code erreur généré est "erreur d'exécution '1004' - Erreur définie par l'application ou par l'objet".

Bon,

On a du boulot

D'après toi, qu'est ce que tu fais avec ce morceau de code :

Range("C2:AM & LigFin")

Et avec celui-ci :

DerLig = UsedRange.Rows.Count

Haha !!!

Avec le premier je dis que je veux que mon importation se place entre la cellule C2 et la colonne AM jusqu'à la ligne de fin de l'extraction.

Avec le deuxième je dis que je veux le code insère les prochaines données dans la prochaine cellule vide.

C'est bien ça ?

Haha !!!

Avec le premier je dis que je veux que mon importation se place entre la cellule C2 et la colonne AM jusqu'à la ligne de fin de l'extraction.

Avec le deuxième je dis que je veux le code insère les prochaines données dans la prochaine cellule vide.

C'est bien ça ?

Perdu ! Sinon tu n'aurais pas d'erreur et le code fonctionnerai...

Pour le premier, tu cumules 2 erreurs :

- Pour la première, je te redonne un code à tester impérativement :

Sub ComprendreGuillemets()

Nom = "Pedro"
i = 22

MsgBox Nom & i
MsgBox "Nom" & i
MsgBox "Nom & i"

End Sub

- Pour la seconde, question bête, mais il y a quoi dans LigFin ?

Pour l'autre ligne de code, DerLig est juste une variable qui donne le nombre de lignes utilisées, MAIS :

  • Si tu ne précise pas la feuille où compter, ce sera la feuille active par défaut
  • Si tu ne l'utilise pas ensuite dans le code, ça te ferait une belle jambe de savoir qu'il y a 122 ou 1343 lignes d'utilisées dans la feuille...

Autre remarque, il faut prendre l'habitude de déclarer le type de données que l'on stocke dans les variables de la macro au début de celle-ci. Par exemple :

Sub MacroBidon()

Dim VarNombreEntier As Long, VarNombreDecimal As Single, VarChaineCaractères As String

VarNombreEntier = UsedRange.Rows.Count
VarDecimal = 1/3
VarChaineCaractères = ThisWorkbook.Name

End Sub

Merci beaucoup !

Ne m'en veux pas haha, je n'ai jamais touché à EXCEL ni VBA avant les trois derniers jours

et j'avoue que je ne comprends pas trop tes codes quand il n'y a pas les explications ...

Mais vraiment merci de prendre ton temps pour m'aider !

Merci beaucoup !

Ne m'en veux pas haha, je n'ai jamais touché à EXCEL ni VBA avant les trois derniers jours

et j'avoue que je ne comprends pas trop tes codes quand il n'y a pas les explications ...

Mais vraiment merci de prendre ton temps pour m'aider !

Dans ce cas, il est peut-être ambitieux de se lancer dans des macros complexes dès maintenant, sans s'intéresser d'abord aux fonctionnalités "classiques" d'Excel...

Je sais je sais mais je n'ai pas le choix: c'est ma mission en tant qu'apprentie et je n'ai pas beaucoup de temps...

Dans ce cas, redis moi sur quelles parties tu bloques, que l'on prenne le temps de détailler un peu plus.

Ils sont quand même "mignons" tes employeurs, de t'embaucher sans formation particulière sur Excel et te balancer une mission comme ça !

Oui c'est clair haha, je marche un peu à l'aveuglette pour l'instant ! Heureusement qu'il y a ce forum !

1) Je bloque toujours sur mon code pour faire en sorte que l'importation se réalise sur les cellules vides. J'ai essayé ton petit code avec Pedro mais à l'évidence, je ne comprends toujours pas comment placer les guillemets.

2) Dans LigFin: c''est soit la ligne de fin de la feuille EXCEL toute entière soit la ligne de fin de l'extraction que je veux importer.

3) Je n'ai pas compris pourquoi tu avais dit que mon code

DerLig = UsedRange.Rows.Count

n'était pas intégré dans le reste de mon code : pourtant je l'ai bien mis dans le Sub / End Sub.

4) Et je n'ai pas compris ce que tu entendais par là : "Si tu ne l'utilise pas ensuite dans le code, ça te ferait une belle jambe de savoir qu'il y a 122 ou 1343 lignes d'utilisées dans la feuille.."

Rechercher des sujets similaires à "transfert donnees classeur vba"