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

1) On va y arriver, mais je pense qu'il est important que tu comprennes le code, plutôt que de te proposer une solution clé en main que tu ne maîtrises pas et que tu ne saurais adapter à tes besoins.

2) Idem, on est parti pour faire ça, mais on va y aller étape par étape.

3) et 4) Je vais te donner un exemple :

  • Tu demandes à ton boulanger combien coûte un pain au chocolat et une baguette
  • Le boulanger fait le calcul dans sa tête

Si on s'arrête là, le calcul est fait, mais au final tu n'as toujours pas la réponse à ta question. Dans la macro, c'est pareil, tu peux calculer le n° de la dernière ligne, mais si tu t'arrêtes là, il sera perdu dans les oubliettes d'Excel à la fin de ta macro.

Toujours sur un exemple, l'ordre dans lequel tu donnes les instructions à VBA est primordial. Si je déménage, je dois d'abord charger les meubles dans le camion et ensuite l'emmener a ma nouvelle adresse.

D'accord ! Oui c'est mieux que je comprenne le code pour que je puisse l'expliquer plus tard.

3) et 4) donc dans mon code, je n'ai pas mis mes lignes dans bon ordre ?

Par conséquent, il aurait fallu que je mette :

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

Avant celle-ci :

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

?

Tu disais aussi que je devais mettre le nom de la feuille dans la première ligne de code : je le place ou dans la ligne de code ?

Reprenons :

VBA est un langage orienté objet. Tu travailles donc sur les objets : un classeur, une feuille, une cellule, la couleur d'une cellule, son contenu... Il existe une hiérarchie : les objets cellule se trouvent des objets feuilles qui se trouvent eux-même dans des objets classeurs.

On doit donc préciser à chaque fois l'objet sur lequel on travaille, en séparant ceux-ci par des points. Je souhaite écrire "bonjour" dans la cellule A1 de la feuille "Feuil1" de mon classeur "ClasseurBidon.xlsm" :

Sub Test()

   Workbooks("ClasseurBidon.xlsm").Sheets("Feuil1").Range("A1").Value = "Bonjour"

End Sub

Si l'objet n'est pas explicitement précisé, Excel travaillera par défaut sur l'objet actif. Cela n'aura aucune incidence si avant de lancer la macro, je me trouve déjà sur la bonne cellule de la bonne feuille du bon classeur.

Dans ce cas, les écritures suivantes seront équivalentes :

ActiveWorkbook.ActiveSheet.ActiveCell.Value = "Bonjour"
ActiveSheet.ActiveCell.Value = "Bonjour"
ActiveCell.Value = "Bonjour"

Ainsi,

DerLig = UsedRange.Rows.Count

Compte le nombre de lignes utilisées dans la feuille active. Dans ta macro, tu travailles sur différentes feuilles de différents classeurs, il est donc impératif de préciser l'objet sur lequel il faut compter les lignes.

Aussi, lorsque tu manipules certains objets sous VBA, tu peux utiliser leur nom ou leur indice (=position). Ainsi, les écritures suivantes sont équivalentes :

Sheets("Feuil1").Range("A1")
Sheets(1).Range("A1")

Plutôt que d'utiliser un nom défini à l'avance, il est souvent plus pratique d'utiliser une variable dans laquelle on peut modifier le nom ou la position de l'objet.

Sheets("Feuil1").Range("A1")

Est équivalent à :

NomFeuille = "Feuil1"
Sheets(NomFeuille).Range("A1")

Et :

Sheets(1).Range("A1")

Est équivalent à :

IndiceFeuille = 1
Sheets(IndiceFeuille).Range("A1")

ATTENTION : j'insiste encore car tu ne semble pas l'avoir bien compris. Les éléments entre guillemets sont interprétés par Excel et VBA comme du texte. Lorsque l'on utilise une variable, ce qui nous intéresse, c'est son contenu. Il ne faut donc pas la placer entre guillemets !

Je remets une fois de plus mon exemple, ayant l'impression que tu ne l'as pas testé pour en prendre conscience :

Sub ComprendreGuillemets()

Nom = "Pedro"
i = 22

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

End Sub

Autre éléments utiles, les structures :

If (condition1) Then
   'Série d'instructions si vrai
Else '(optionnel)
   'Série d'instructions si faux
End If
For Compteur = 1 To 100
   MsgBox "J'ai compté jusqu'à " & Compteur
Next Compteur
'En cas d'utilisation répétée d'un même objet :
With Workbooks("MonClasseur.xlsm").Sheets("Feuil1") 'Toute instruction commençant par "." s'y rattache
   LigMax = .Range("A60000").End(xlUp).Row + 1 'Trouve la première ligne vide en colonne A
   .Range("A" & LigMax).Value = "Bonjour" 'Mettre "Bonjour" dans la première cellule vide
   .Range("A" & LigMax).Font.Color = RGB(255, 0, 0) 'Mets le texte en rouge
End With

J'ai testé ton exemple mais je n'ai simplement pas compris car il me fait apparaître trois fenêtres successivement qui m'indique chacun des textes écrit dans le code "pedro22", "nom" et "nom & i" est cela que je dois comprendre ? que c'est un code qui fait apparaître le texte entre guillemets ?

J'ai testé ton exemple mais je n'ai simplement pas compris car il me fait apparaître trois fenêtres successivement qui m'indique chacun des textes écrit dans le code "pedro22", "nom" et "nom & i" est cela que je dois comprendre ? que c'est un code qui fait apparaître le texte entre guillemets ?

L'écriture du code est la même dans les 3 messages, seule la position des guillemets change. Tu peux donc voir comment VBA interprète le code en fonction de comment tu l'écrit. Les guillemets dans un code, c'est pour un nom, VBA ne l'interprète pas, il l'utilises tel qu'il est.

Par ailleurs, il est toujours instructif d’exécuter le code "pas à pas" dans VBA (grâce à F8), ce qui te permet de voir le contenu de chaque variable en passant la souris dessus.

D'accord ! Je suis entrain d'analyser tes codes et surtout celui-ci (je le teste sur EXCEL pour voir ce qu'il donne).

''En cas d'utilisation répétée d'un même objet :
With Workbooks("MonClasseur.xlsm").Sheets("Feuil1") 'Toute instruction commençant par "." s'y rattache
   LigMax = .Range("A60000").End(xlUp).Row + 1 'Trouve la première ligne vide en colonne A
   .Range("A" & LigMax).Value = "Bonjour" 'Mettre "Bonjour" dans la première cellule vide
   .Range("A" & LigMax).Font.Color = RGB(255, 0, 0) 'Mets le texte en rouge
End With

pour tester, j'essaie de changer une ligne de code, celle-ci :

   .Range("A" & LigMax).Value = "Bonjour" 'Mettre "Bonjour" dans la première cellule vide
  

Elle ne permet que de remplir la première cellule vide: quel élément dans ce code indique "remplir la première cellule vide"

Et si par exemple, je veux réutiliser cette ligne de code mais dire "remplir les cellules vides de la colonne A", qu'est-ce que je modifie ?

   .Range("A" & LigMax).Value = "Bonjour" 'Mettre "Bonjour" dans la première cellule vide
  

Quel élément dans ce code indique "remplir la première cellule vide"

Dans cet extrait seul, aucun. La manip se fait ici en 2 fois, j'identifie la dernière ligne du fichier, auquel j'ajoute 1 pour tomber sur la première vide, et j'affecte ce résultat dans une variable que j'ai appelé LigMax. C'est ensuite cette variable qui est utilisée dans la suite du code (et donc ici dans la partie que tu cites).

Si LigMax = 100, alors Range("A" & LigMax) correspond à la cellule A100. Si tu remonte plus haut dans mes explications, tu trouveras comment faire pour faire référence à une plage et pas seulement une seule cellule...

J'ai compris mais vraiment le seul truc qui me bloque c'est la plage de données: c'est le seul élément que je ne parviens pas à comprendre au final...

J'ai compris mais vraiment le seul truc qui me bloque c'est la plage de données: c'est le seul élément que je ne parviens pas à comprendre au final...

Une plage de données, dans le sens "plus d'une cellule" se définie en générale par 2 éléments :

  • Les coordonnées de la cellule supérieure gauche (exemple A1)
  • Les coordonnées de la cellule inférieure droite (exemple C100)

Sous Excel, elle s'écrit donc A1:C100, et peut s'écrire sous VBA Range("A1:A100"). Le problème de cette syntaxe est que les coordonnées sont fixées à l'avance.

On peut néanmoins utiliser des variables pour les coordonnées :

- 1ère écriture avec la variable du n° de ligne (NoLig) :

NoLig = 100 'Variable dans laquelle on affecte la valeur 100
Range("A" & NoLig - 99 & ":C" & NoLig) 'Correspond ici à A1:C100

- 2nde possibilité, qui permet aussi d'utiliser des n° de colonne plutôt que des lettres :

'Basée sur l'utilisation de : Cells(NoLigne, NoColonne)
NoLig = 100 
Range(Cells(NoLig - 99, 1), Cells(NoLig, 3)) 'Correspond ici à A1:C100

Cette dernière écriture permet aussi d'utiliser un indice de colonne variable

Merci pour tes codes !

Si je comprends bien, il n'existe pas de ligne de code qui ne nécessite pas des coordonnées fixes comme A1:C100 ?

Merci pour tes codes !

Si je comprends bien, il n'existe pas de ligne de code qui ne nécessite pas des coordonnées fixes comme A1:C100 ?

Suis-je vraiment si peu clair ?

A quoi tu penses comme manière d'écrire en disant ça ?

Non c'est pas toi t'inquiète haha

C'est moi: je baigne dans des lignes EXCEL que je ne comprends toute la journée depuis une semaine sans pause et j'ai un peu de mal à me concentrer et à comprendre

Mais merci d'essayer de m'aider, si je t'embête laisse tomber haha

Je pense à une simple coordonnée de cellule qui me dise par exemple .Range("A1","Jusqu'à ce que toutes les données soient entrées"), un peu comme .Range("A1", "infini")

Non c'est pas toi t'inquiète haha

C'est moi: je baigne dans des lignes EXCEL que je ne comprends toute la journée depuis une semaine sans pause et j'ai un peu de mal à me concentrer et à comprendre

Mais merci d'essayer de m'aider, si je t'embête laisse tomber haha

Si ça m'embêtais vraiment, je ne prendrais plus la peine de répondre... Mais je ne vois pas ce que tu entends par :

il n'existe pas de ligne de code qui ne nécessite pas des coordonnées fixes comme A1:C100 ?

J'ai fait un post de 2 km, ultra détaillé, pour expliquer qu'on peut utiliser des variables pour les coordonnées. Or, arrête moi si je dis une bêtise, mais variable ≠ fixe !

Je pense à une simple coordonnée de cellule qui me dise par exemple .Range("A1","Jusqu'à ce que toutes les données soient entrées"), un peu comme .Range("A1", "infini")

Alors qu'est ce qui t'échappes dans :

DerLig = Instruction pour déterminer la dernière ligne

Range("A1:A" & DerLig)

????

L'endroit dans le code ou je mets la position de ma feuille, de mon classeur

L'endroit dans le code ou je mets la position de ma feuille, de mon classeur

On tourne en rond... Je vais prendre la peine de te redire ce que j'ai déjà dit...

Si ta plage "A1:A100" est sur le classeur "MonClasseur.xlsm", dans la feuille "MaFeuille", alors dans le code, on y fera référence comme ceci :

Workbooks("MonClasseur.xlsm").Sheets("MaFeuille").Range("A1:A100")

Je pense qu'il est grand temps pour nous 2 de faire une pause, et pour toi de relire un peu plus tard les explications depuis le début. Tous les éléments sont là...

ça y'est j'ai enfin compris ce que tu souhaitais m'expliquer par rapport à ce code :

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

J'associe DerLig à une instruction et ensuite je peux insérer le DerLig dans une autre ligne de code comme tu l'as fait avec LigMax ?

Rechercher des sujets similaires à "transfert donnees classeur vba"