Copier les données d'un classeur dans un autre classeur sous certaines condition

Signaler
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011
-
Patrice H
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011
-
Bonjour,

J'ai deux classeurs : le A qui regroupe une liste d'élèves avec leur N° étudiant, leur code de groupe, leur nom, prénom, les heures facturables..
et le classeur B : où j'ai crée un onglet par formation dans le but de faire divers calculs

Ce que je voudrais c'est créer une macro qui permettrait d'alimenter automatiquement les différents onglets de mon classeur B en y inscrivant N° étudiant , prénom et nom des élèves, heures facturables.

Je suis novice dans VBA. Je regarde les discussions des forums pour essayer de trouver une solution mais je n'arrive à rien pour l'instant.

Merci pour votre aide

36 réponses

Messages postés
41
Date d'inscription
samedi 30 avril 2011
Statut
Membre
Dernière intervention
26 juin 2012

bonjour,

Il existe une fonction VBA
GetObject
qui permet de manipuler des données d'un classeur à l'autre, cependant Il faudrait avoir un exemple plus concret pour comprendre d'avantage ce que tu veux....
Peut être qu'un autre moyen plus simple serait possible!
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011

Si tu ne dispose pas de l'info sur la formation suivi dans le classeur A tu ne pourras pas copier cela dans le classeur B. Supposons cependant que ce soit le code de groupe (seule info que tu sembles ne pas reprendre dans ton classeur B), cela donnerait

Dans un module de programmation du classeur B (classeurB/outils/Macro/Visual Basic Editor)
Voici le sous programme nécessaire
Sub RemplirB
dim FeuilleA as worksheet, FeuilleB as worksheet
set feuilleA = Workbooks(ClasseurA).Worksheets(Feuille_A)

'On suppose que les éléves sont écrits ligne par ligne sans ligne vide, la première ligne est une ligne de titre
Dim LigneA as long, Formation as string, Numero as long, Nom as string, Prenom as string, Heures as double 
LigneA = 2
do
if FeuilleA.cells(ligneA,1)="" then exit do
Numero = FeuilleA.cells(LigneA,1)
Formation = FeuilleA.cells(LigneA,2)
Nom = FeuilleA.cells(LigneA,3)
Heures = FeuilleA.cells(LigneA,4)
set FeuilleB = WorkBooks(ClasseurB).Worksheets(Formation)
FeuilleB.cells(LigneA,1) = Numero
FeuilleB.cells(LigneA,2)=Nom
FeuilleB.Cells(LigneA,3)=Heures 
ligneA = LigneA + 1
loop


Set FeuilleA = nothing
set FeuilleB = nothing
end sub 


Il ne te reste plus qu'à trier chaque onglet sur le numéro d'étudiant.

Bien entendu c'est fait à la va-vite (5 minutes) mais tu devrais pouvoir t'y retrouver. Si tout cela te parait du chinois, alors laisse tomber et fait le à la main, tu gagneras du temps.

Une autre solution cependant sont les sommes conditionnelles : tu filtre tes données sur la formation et tu fait la somme des heures, voire tu copies les données dans l'onglet formation du classeurB.



Imagine le pire, tu n'es jamais déçu, il peut même t'arriver d'être heureusement surpris.
Si vous êtes intéressé par l'histoire, visitez mon site http://histoiremondiale.free.fr
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011

Si tu ne dispose pas de l'info sur la formation suivi dans le classeur A tu ne pourras pas copier cela dans le classeur B. Supposons cependant que ce soit le code de groupe (seule info que tu sembles ne pas reprendre dans ton classeur B), cela donnerait

Dans un module de programmation du classeur B (classeurB/outils/Macro/Visual Basic Editor)
Voici le sous programme nécessaire
Sub RemplirB
dim FeuilleA as worksheet, FeuilleB as worksheet
set feuilleA = Workbooks(ClasseurA).Worksheets(Feuille_A)

'On suppose que les éléves sont écrits ligne par ligne sans ligne vide, la première ligne est une ligne de titre
Dim LigneA as long, Formation as string, Numero as long, Nom as string, Prenom as string, Heures as double 
LigneA = 2
do
if FeuilleA.cells(ligneA,1)="" then exit do
Numero = FeuilleA.cells(LigneA,1)
Formation = FeuilleA.cells(LigneA,2)
Nom = FeuilleA.cells(LigneA,3)
Heures = FeuilleA.cells(LigneA,4)
set FeuilleB = WorkBooks(ClasseurB).Worksheets(Formation)
FeuilleB.cells(LigneA,1) = Numero
FeuilleB.cells(LigneA,2)=Nom
FeuilleB.Cells(LigneA,3)=Heures 
ligneA = LigneA + 1
loop


Set FeuilleA = nothing
set FeuilleB = nothing
end sub 


Il ne te reste plus qu'à trier chaque onglet sur le numéro d'étudiant.

Bien entendu c'est fait à la va-vite (5 minutes) mais tu devrais pouvoir t'y retrouver. Si tout cela te parait du chinois, alors laisse tomber et fait le à la main, tu gagneras du temps.

Une autre solution cependant sont les sommes conditionnelles : tu filtre tes données sur la formation et tu fait la somme des heures, voire tu copies les données dans l'onglet formation du classeurB.



Imagine le pire, tu n'es jamais déçu, il peut même t'arriver d'être heureusement surpris.
Si vous êtes intéressé par l'histoire, visitez mon site http://histoiremondiale.free.fr
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

Merci pour vos réponses Boomer11 et Patrice H ;)
Je vais tester les solutions que vous m'avez proposez et si j'ai un soucis je reviendrais vers vous.
Je vais essayer de mettre mes deux classeurs aussi sur le forum pour que vous y voyez plus clair
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

J'arrive pas à joindre mes deux classeurs mais je vais essayer de vous les décrire plus précisément.

Dans le classeur A, on trouve :
le numéro étudiant/le code du groupe de formation/le nom de l'élève/son prénom/son statut/la date de début de contrat/date fin contrat/date résiliation contrat/nombre d'heure.

Dans le classeur B :
Je veux pouvoir copier :
nom/prénom/statut/début de contrat/fin de contrat/date résiliation contrat/nombre d'heures
En fait, il y a un onglet pour chaque formation . La condition de copie des informations dans chaque onglet sera donc le code du groupe de formation.

J'espère que j'ai été assez claire dans mon explication
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
217
Bonjour,

Le plus simple me paraitrait personnellement de :
1) trier ton classeur A sur la colonne du code de groupe de formation (pour agiliser ensuite)
2) Une boucle pour analyser chaque ligne de la colonne triée et on constitue des plages
- tant qu'une cellule est la même que la précédente (on est donc dans le même groupe) ===>> on ajoute à la plage en cours la totalité de la ligne (utilisation de Union)
=> lorsque le contenu de la cellule change par rapport au précédent (on a donc changé de groupe) ===>> on copie la plage vers sa destination (méthode copy avec paramètre destination) et on supprime de la destination les colonnes superflues
on redéfinit totalement la plage et on continue la boucle comme en 2)

C'est à mon avis la solution la plus rapide et la plus simple à mettre en oeuvre.


____________________
Vous aimez Codes-Sources ? Il vous aide ? Cliquez ici pour l'aider à continuer
Cliquer sur "Réponse acceptée" en bas d'une solution adéquate est
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
217
Autre idée simple :
- tu copies la totalité de ta feuille "générale" de ton classeur A vers la première feuille (disons groupe1) de ton classer B
tu oublies maintenant totalement le classeur A pour la suite...
- dans la feuille "groupe1 de ton classeur B
1) tu supprimes les colonnes qui ne te servent pas, sauf la colonne du code groupe
2) tu tries la colonne du code groupe
3) une boucle sur cette colonne jusqu'à rencontrer un groupe différent. ===>> tu copies vers feuille "groupe2" tout ce qui suit la ligne de la "différence" constatée
=>> tu supprimes la colonne "code de groupe" de la feuille "groupe1

La suite est maintenant évidente :
tu vas sur la feuille "groupe2" de ton classeur B et y fais le même travail que défini en 3)
etc.. jusqu'à la fin


____________________
Vous aimez Codes-Sources ? Il vous aide ? Cliquez ici pour l'aider à continuer
Cliquer sur "Réponse acceptée" en bas d'une solution adéquate est
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

Merci de ta réponse ucfoutu
J'ai bien compris ta solution par contre la mettre en place en VBA ca risque d'être dure pour moi qui n'y connais rien.
Mais bon je vais essayer de me renseigner pour voir comment je dois m'y prendre pour mettre en place les différentes étapes de ta solution en VBA
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
217
Rectif/ajout (bien sûr)
3) une boucle sur cette colonne jusqu'à rencontrer un groupe différent. ===>> tu copies vers feuille "groupe2" tout ce qui suit la ligne de la "différence" constatée [u]et supprimes ces lignes dans ta feuille "groupe1"
/u


____________________
Vous aimez Codes-Sources ? Il vous aide ? Cliquez ici pour l'aider à continuer
Cliquer sur "Réponse acceptée" en bas d'une solution adéquate est
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

En fait le classeur A est généré automatiquement par le logiciel d'information de l'entreprise sur demande d'un utilisateur. Et il faudrait que chaque fois que le classeur A est généré, le classeur B s'actualise aussi.
Du coup je ne peux pas utiliser ta deuxième solution car le but s'est que tout se fasse automatiquement sans avoir de manipulation à réaliser
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
217
Du coup je ne peux pas utiliser ta deuxième solution car le but s'est que tout se fasse automatiquement sans avoir de manipulation à réaliser

Oui ? Et ?
Tout ce que je t'ai dit est à faire par des instructions VBA (non manuellement, donc) à lancer à la suite de la génération du classeur A.

____________________
Vous aimez Codes-Sources ? Il vous aide ? Cliquez ici pour l'aider à continuer
Cliquer sur "Réponse acceptée" en bas d'une solution adéquate est
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

Patrice, j'ai adapté ta solution à mes deux classeurs mais quand j'exécute ca me marque erreur d'éxécution 9 : lindice n'appartient pas à la sélection.
Je te copie le code : (Classeur A = Etat inscriptions par types contrat et la feuille du classeur Par formation et qualité) et (classeur B= CA formation avec par exemple la feuille ECD correspondant au code de groupe formation ECD). J'ai rajouté des variables mais je les ai peut-être mal déclarées.

Sub RemplirCA_formation()
Dim Par_formation_et_qualité As Worksheet, ECD As Worksheet
Set Par_formation_et_qualité = Workbooks(Etat_inscriptions_par_Types_contrat).Worksheets(Par_formation_et_qualité)


Dim LigneA As Long, Formation As String, Numero As Long, Nom As String, Prenom As String, Statut As String, Debut_contrat As Double, Fin_contrat As Double,Resiliation As Double, Heures As Double
LigneA = 10
Do
If Par_formation_et_qualité.Cells(LigneA, 1) = "" Then Exit Do
Numero = Par_formation_et_qualité.Cells(LigneA, 1)
Formation = Par_formation_et_qualité.Cells(LigneA, 2)
Nom = Par_formation_et_qualité.Cells(LigneA, 3)
Prenom = Par_formation_et_qualité.Cells(LigneA, 4)
Statut = Par_formation_et_qualité.Cells(LigneA, 5)
Debut_contrat = Par_formation_et_qualité.Cells(LigneA, 6)
Fin_contrat = Par_formation_et_qualité.Cells(LigneA, 7)
Résiliation = Par_formation_et_qualité.Cells(LigneA, 8)
Heures = Par_formation_et_qualité.Cells(LigneA, 9)
Set Feuil2 = Workbooks(CA_formation).Worksheets(Formation)
ECD.Cells(LigneA, 1) = Numero
ECD.Cells(LigneA, 2) = Nom
ECD.Cells(LigneA, 3) = Prenom
ECD.Cells(LigneA, 4) = Statut
ECD.Cells(LigneA, 5) = Debut_contrat
ECD.Cells(LigneA, 6) = Fin_contrat
ECD.Cells(LigneA, 7) = Resiliation
ECD.Cells(LigneA, 8) = Heures
LigneA = LigneA + 1
Loop


Set Par_formation_et_qualité = Nothing
Set ECD = Nothing
End Sub

Merci par avance pour ton aide
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

Autant pour moi! j'avais mal compris ^^
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011

Donc ton problème est résolu ?

Tu peux d'ailleurs créer dynamiquement par programmation les onglets formation du classeur B par la procédure
WorkBooks(ClasseurB).Worksheets.add
Ensuite tu nommes la feuille
ActiveWorksheet.Name = formation


Imagine le pire, tu n'es jamais déçu, il peut même t'arriver d'être heureusement surpris.
Si vous êtes intéressé par l'histoire, visitez mon site http://histoiremondiale.free.fr
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011

Tu peux d'ailleurs sensiblement améliorer le système en gérant la ligne à écrire sur le classeur B pour chaque onglet.
Tu devrais utiliser Option Explicit en début de chacun de tes modules d eprogrammation pour éviter les problèmes de variables.

Imagine le pire, tu n'es jamais déçu, il peut même t'arriver d'être heureusement surpris.
Si vous êtes intéressé par l'histoire, visitez mon site http://histoiremondiale.free.fr
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

Non ca indique toujours l'erreur au moment de l'éxécution.
Ca m'affiche en jaune la troisième ligne du code
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011

donc l'erreur se situe ici :
Set Par_formation_et_qualité = Workbooks(Etat_inscriptions_par_Types_contrat).Worksheets(Par_formation_et_qualité)

Tout d'abord explicitons les variables

Etat_inscriptions_par_Types_contrat est une variable. J'espère que tu l'as déclaré. Donc tu mets tout en haut de ton code (en première ligne Option Explicit et tu ré-essaie pour me donner l'erreur)

Cas 1 : tu n'avais pas mis option explicit et tu n'as pas déclaré la variable, c'est un variant valant nothing et bien entendu aucun classeur ne correspond

Cas 2 : tu as déclaré la variable
Dim Etat_inscriptions_par_Types_contrat '(tel quel c'est un variant, on peut le typé par as long ou as String)

Ensuite il faut l'initialiser (lui donner une valeur) dans cela il vaudra (nothing si c'est un variant, 0 si c'est un long, "" si c'est une string)

Tu vois tous les cas qui peuvent se produire, sachant que si Workbooks(Etat_inscriptions_par_Types_contrat) se réfère à un classeur non ouvert il te répondra erreur 9.

Faisons les choses proprement :

Ton classeur s'appelle par exemple "Etat_inscriptions_par_Types_contrat.xls", (c'est sa valeur pas la variable)
La feuille s'appelle par exemple : "Par_formation_et_qualité"

Il faut écrire
Set Par_formation_et_qualité = Workbooks("Etat_inscriptions_par_Types_contrat.xls").Worksheets("Par_formation_et_qualité")

En respectant les majuscules. Il faut de plus que le classeur "Etat_inscriptions_par_Types_contrat.xls" soit ouvert et la feuille "Par_formation_et_qualité" existe dans le classeur.

Ré-essaie avec ces changements (pense bien à Option explicit) et dis-moi ce que cela donne.

Ta prochaine erreur sera à mon avis à la ligne set feuille2

Imagine le pire, tu n'es jamais déçu, il peut même t'arriver d'être heureusement surpris.
Si vous êtes intéressé par l'histoire, visitez mon site http://histoiremondiale.free.fr
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

J'ai fait ce que tu m'as dis. Par contre, j'ai pas vraiment compris par rapport au fait qu'il faut déclarer Etat_inscriptions_par_Types_contrat.

je te colle ce que ca donne, mais je suis pas sure d'avoir bien fait parce que j'ai une erreur 9 alors que mes deux classeurs sont ouverts.

Sub RemplirCA_formation()
Dim Par_formation_et_qualité As Worksheet, Feuil2 As Worksheet
Dim Etat_inscriptions_par_Types_contrat As Long
Set Par_formation_et_qualité = Workbooks("Etat_inscriptions_par_Types_contrat.xls").Worksheets("Par_formation_et_qualité")



'On suppose que les éléves sont écrits ligne par ligne sans ligne vide, la première ligne est une ligne de titre
Dim LigneA As Long, Formation As String, Numero As Long, Nom As String, Prenom As String, Statut As String, Debut_contrat As Double, Fin_contrat As Double, Resiliation As Double, Heures As Double
LigneA = 10
Etat_inscriptions_par_Types_contrat = 0
Messages postés
43
Date d'inscription
dimanche 12 mars 2006
Statut
Membre
Dernière intervention
24 juin 2011

Peux-tu redonner ton code intégral. Tu n'as pas précisé si tu avais bien mis en début de code option explicit !!! (c'est très important pour pouvoir t'aider)
Tu n'indiques pas à quelle ligne est ton erreur.

Pour ta remarque sur la déclaration de variable, je n'ai pas été assez explicite en effet

Workbooks est un objet de Excell qui contient tous les classeurs ouverts, c'est une collection. Chaque obet de cette collection comporte un nom et un index (son rang dans la collection). le nom est une string, l'index est un entier non nul.
Pour accéder à l'un des classeurs ouvert on utilise Workbooks(Index) ou Workbooks(Nom)

Par exemple Workbooks("MonClasseur.xls") se réfèrera au classeur de nom MonClasseur.xls (attention la casse, majuscule/minuscule, compte°. Si le classeur "MonClasseur.xls" n'est pas ouvert tu auras une erreur 9, ce qui veut dire que "MonClasseur.xls" n'est pas un nom valide pour la collection des classeurs ouverts.

Autre exemple : Workbooks(2) se réfèrera au deuxième classeur ouvert. S'il n'y a qu'un classeur ouvert tu auras une erreur 9.

Enfin le nom, ou l'index, peuvent être entrés dans une variable
Dim NomFichierSource as dim
NomFichierSource = "MonClasseur.xls"
Workbooks(NomFichierSource) se réfère au classeur MonClasseur.xls

Tu as la même chose pour Worksheets pour chaque classeur. Pour un classeur donné Worksheets est l'ensemble des feuilles du classeur indexées par un entier ou par leur nom.




Imagine le pire, tu n'es jamais déçu, il peut même t'arriver d'être heureusement surpris.
Si vous êtes intéressé par l'histoire, visitez mon site http://histoiremondiale.free.fr
Messages postés
17
Date d'inscription
lundi 20 juin 2011
Statut
Membre
Dernière intervention
24 juin 2011

Merci pour tes explications ca me permet de comprendre mieux le code

Alors je te renvoie le code en intégralité. Et l'erreur se situe toujours au niveau de Set Par_formation_et_qualité = Workbooks("Etat_inscriptions_par_Types_contrat.xls").Worksheets("Par_formation_et_qualité". mais pourtant j'ai bien les deux classeurs d'ouvert

Option Explicit
Sub RemplirCA_formation()
Dim Par_formation_et_qualité As Worksheet, ECD As Worksheet
Dim Etat_inscriptions_par_Types_contrat As Long
Set Par_formation_et_qualité = Workbooks("Etat_inscriptions_par_Types_contrat.xls").Worksheets("Par_formation_et_qualité")



'On suppose que les éléves sont écrits ligne par ligne sans ligne vide, la première ligne est une ligne de titre
Dim LigneA As Long, Formation As String, Numero As Long, Nom As String, Prenom As String, Statut As String, Debut_contrat As Double, Fin_contrat As Double, Resiliation As Double, Heures As Double
LigneA = 10
Etat_inscriptions_par_Types_contrat = 0
Do
If Par_formation_et_qualité.Cells(LigneA, 1) = "" Then Exit Do
Numero = Par_formation_et_qualité.Cells(LigneA, 1)
Formation = Par_formation_et_qualité.Cells(LigneA, 2)
Nom = Par_formation_et_qualité.Cells(LigneA, 3)
Prenom = Par_formation_et_qualité.Cells(LigneA, 4)
Statut = Par_formation_et_qualité.Cells(LigneA, 5)
Debut_contrat = Par_formation_et_qualité.Cells(LigneA, 6)
Fin_contrat = Par_formation_et_qualité.Cells(LigneA, 7)
Resiliation = Par_formation_et_qualité.Cells(LigneA, 8)
Heures = Par_formation_et_qualité.Cells(LigneA, 9)
Set ECD = Workbooks("CA_formation.xls").Worksheets(Formation)
ECD.Cells(LigneA, 1) = Numero
ECD.Cells(LigneA, 2) = Nom
ECD.Cells(LigneA, 5) = Debut_contrat
ECD.Cells(LigneA, 3) = Prenom
ECD.Cells(LigneA, 4) = Statut
ECD.Cells(LigneA, 6) = Fin_contrat
ECD.Cells(LigneA, 7) = Resiliation
ECD.Cells(LigneA, 8) = Heures
LigneA = LigneA + 1
Loop


Set Par_formation_et_qualité = Nothing
Set Feuil2 = Nothing
End Sub
1 2