Macro Excel pour copier données depuis un onglet à d'autres

Bonjour,

Etant nouvel utilisateur des MACROS, j’ai besoin de votre aide s’il vous plaît après de nombreuses tentatives pas très réussies.

Voici l’objectif :

Nous sommes dans l’onglet « donnees ». Nous avons un tableau déjà rempli à gauche (gamma, beta…) et nous avons un tableau à droite qui sera rempli peu à peu par de futures personnes. Supposons que nous travaillons pour la colonne « onglet 1» , lorsque la personne mettra O pour la case en ligne 3 (donc oui), il devra renseigner obligatoirement la colonne « place » par T1, T2, T3,… Une fois ces deux paramètres entrés alors la macro entrera automatiquement dans l’onglet respectif (donc « onglet 1 » ici) la case « manger » présente en ligne 3 en jaune. Et précisément cette case devra être copiée dans la colonne_1 du tableau T1 de l’onglet 1.

Il faut que la macro balaie toute la liste en colonne C (en jaune) de l’onglet « donnees » afin de remplir les autres onglets dans les tableaux respectifs.

Je vous propose le code que j’ai écrit qui donne des résultats positifs une fois sur deux. Que faut-il rajouter, effacer, améliorer ou recommencer ?

L'Excel est aussi joint

Merci beaucoup

Sub Macro1()

''DECLARATION DES VARIABLES''

Dim rOF As Integer

Dim rCF As Integer

Dim sOF As Worksheet

Dim sCF As Worksheet

Dim sCF_two As Worksheet

''AFFECTATION DES VARIABLES''

Set sOF = Worksheets("donnees")

Set sCF = Worksheets("onglet 1")

Set sCF_two = Worksheets("onglet 2")

rCF = 10

''REMPLISSAGE''

For rOF = 3 To 1000 'valeurs quelconques pour avoir une plage max de rOF'

'****onglet_un****'

If sOF.Cells(rOF, "AH").Text = "0" Then 'test de la ligne en question'

If sOF.Cells(rOF, "AI").Text = "T1" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF.Cells(rCF, 3)

End If

If sOF.Cells(rOF, "AI").Text = "T2" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF.Cells(rCF, 4)

End If

If sOF.Cells(rOF, "AI").Text = "T3" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF.Cells(rCF, 5)

End If

If sOF.Cells(rOF, "AI").Text = "T4" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF.Cells(rCF, 6)

End If

rCF = rCF + 1

End If

'****onglet_deux****'

If sOF.Cells(rOF, "AJ").Text = "0" Then 'test de la ligne en question'

If sOF.Cells(rOF, "AK").Text = "T1" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF_two.Cells(rCF, 3)

End If

If sOF.Cells(rOF, "AK").Text = "T2" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF_two.Cells(rCF, 4)

End If

If sOF.Cells(rOF, "AK").Text = "T3" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF_two.Cells(rCF, 5)

End If

If sOF.Cells(rOF, "AK").Text = "T4" Then

sOF.Range(sOF.Cells(rOF, "C"), sOF.Cells(rOF, "C")).Copy sCF_two.Cells(rCF, 6)

End If

rCF = rCF + 1

End If

Next

Application.CutCopyMode = False

End Sub

26aide.zip (19.45 Ko)

Bonjour et bienvenue sur le forum

Essaie ce code :

Option Explicit

Dim i, j, Place, Texte, Onglet, Ln, k

Sub essai()

    For i = 3 To 12
        For j = 35 To Cells(2, 34).End(xlToRight).Column Step 2
            If Cells(i, j).Value <> "" Then
                Place = Cells(i, j).Value
                Texte = Cells(i, "C").Value
                Onglet = Cells(1, j - 1).Value
                With Sheets(Onglet)
                    Ln = .Range("B:C").Find(Place, lookat:=xlPart).Row
                    k = 0
                    While .Cells(Ln + 2 + k, "C").Value <> ""
                        k = k + 1
                        If k = 23 Then
                            MsgBox "Le tableau " & Place & " de l'" & Onglet & " est plein !", 16
                            End
                        End If
                    Wend
                    .Cells(Ln + 2 + k, "C").Value = Texte
                End With
            End If
        Next j
    Next i
End Sub

Bye !

Je te remercie beaucoup gmb. Tu m'as apporté une grande aide car ça fonctionne très bien

Cependant il y a un petit détail qui me gêne, je sais pas si tu l'as remarqué. Une fois qu'on a lancé la macro, les tableaux se remplissent parfaitement au bon endroit mais si on revient au fichier "donnees" et qu'on apporte une modification d'une ou plusieurs cases (par exemple: on met O à un endroit où il y avait N) et qu'on appuie ensuite à nouveau sur la macro; en jetant un coup d'œil dans les tableaux dans les autres onglets, on note que ces modifications n'ont pas écrasées les anciennes valeurs des tableaux mais elles les succèdent.

Exemple: cf le fichier joint où j'ai lancé une première fois la macro alors tout était bon. Puis j'ai mis "O" et "T1" pour "soleil ET aussi j'ai changé pour "hier" la place en mettant "T2"

Merci encore

26aide-suite.zip (21.86 Ko)

Tu écris :

on note que ces modifications n'ont pas écrasées les anciennes valeurs des tableaux mais elles les succèdent.

S'il faut écraser les anciennes valeur, c'est donc qu'il faut les nouvelles à la même place ?

Alors, un nouvel essai :

45aide-suite-v2.zip (23.96 Ko)

Excuse moi d'interrompre ce nouveau problème d'écrasement des anciennes données mais avant cela je voulais que tu m'expliques un peu le code que tu m'as proposé car je ne comprends pas toutes les commandes ( vu que je débute)

J'aimerais bien que tu m'expliques, si ça ne te déranges pas bien sûr, ce qui se passe dans la boucle j.

Dernière chose, c'est normal que l'instruction "with sheets" ne marche pas sur excel 2003, y-a-t-il un substitut?

Merci beaucoup vraiment du temps que tu me consacres

J'ai compris le problème du With.

En excel 2003 il faut écrire With Worksheets("Onglet 1")

On est obligé d'écrire onglet 1 sinon ça n'exécute pas . Conséquence le programme ne fonctionne pas correctement vu que ça distribue toutes les données dans l'onglet 1 uniquement au lieu de les distribuer à tous les onglets

Bonjour

Tu écris :

J'aimerais bien que tu m'expliques, si ça ne te déranges pas bien sûr, ce qui se passe dans la boucle j.

Pour qu’on se comprenne bien, je suis parti du deuxième fichier que je t’ai joint (il est plus simple).

For j = 35 To Cells(2, 34).End(xlToRight).Column Step 2

C’est le début de la boucle.

J est un numéro de ligne. On lui faire prendre une valeur sur deux (Step 2) depuis 35 jusqu’à la dernière valeur de la colonne que l’on atteint quand, dans la feuille on sélectionne la cellule AH2 ou cellule(2,34). Dans notre cas, ce sera 41

If Cells(i, j).Value <> "" Then

La valeur de la variable i reste fixe pendant toute l’exécution des boucles j. Elle représente la valeur de la ligne.

Supposons que i en soit à sa première boucle, donc i = 3 (car il va varier de 3 à 12)

La première valeur de j va être 35

La macro va donc regarder si la cellule (i, j) c’est-à-dire (3, 35) ou encore AI 3 est vide ou pas.

Si la cellule est vide, la macro saute les instructions suivantes et va sur le ''End if'' suivant et atteint l’instruction « Next j » qui lui fait recommencer la boucle j en donnant à j la valeur 37.

Si la cellule n’est pas vide, la macro exécute les instructions qui suivent le if.

Elle va donner des valeurs aux variables Place, Texte et Onglet en fonction des valeurs de i et de j.

Toujours pour la première valeur prise par j c’est-à-dire 35 on aura :

Place = ‘’ T1’’

Texte = ’’manger ‘’

Onglet = ‘’onglet ‘’ = Valeur le la cellule (ligne 1, colonne j-1) c’est-à-dire AH1

Ces 3 variables posées, on va en définir une quatrième : la valeur de la ligne où est écrit la variable Texte sur la feuille dont le nom est onglet. On sait que ce mot est écrit en colonne B mais comme il est sur une cellule fusionnée avec la cellule voisine de la colonne C, il faut le chercher dans ces deux colonnes.

Pour simplifier la compréhension du code j’ai posé ‘’ With Sheets(Onglet) » suivi de « End with »

Dans toutes les formules qui sont entre ces deux instructions, ‘’Sheets(Onglet)’’ est remplacé par un point.

La macro va ainsi chercher Place dans les colonnes B et C de la feuille Onglet et donner à Ln la valeur de la ligne où elle l’aura trouvé.

Il ne lui reste plus qu’à écrire la valeur de Texte dans la colonne C et i lignes au dessous.

Ensuite, elle attaque la boucle suivante avec j = 37 puis 39 puis 41.

Après que j ait pris la valeur 41, c’est i qui finit une boucle et en recommence une autre avec i = 4, et on repart avec une nouvelle série de boucles j, jusqu’à ce que i = 12

OK ?

Une dernière remarque : ‘’with’’ fonctionne exactement de la même façon avec Excel 2003 qu’avec Excel 2013. Je suis en 2013 mais j’ai gardé 2003 et j’ai testé : c’est pareil.

Je te remercie pour ton explication très clair.

Je pense avoir tout compris

J'aimerai bien l'améliorer du coup maintenant. Mais toujours avec un langage basique de VBA.

Voilà ce que j'aimerai faire:

Peut-être créer un bouton où l’utilisateur va entrer le nom de l'onglet qu'il veut remplir et après on va comparer le nom de cet onglet aux onglets déjà existants dans l'excel. Si pas même nom alors on passe à l’onglet suivant . Si même nom alors on amène l’utilisateur à l'onglet (ou on lui dit simplement qu’elle existe).

Si le nom de l'onglet qu'il demande n'existe pas dans les onglets présents dans l'excel alors il faut le créer à partir de template (qui est la structure de base d'un onglet.

Autre possibilité : on propose direct à l’utilisateur les onglets existants et après il n’a qu’à choisir. Alors on l’amène à la colonne de l'onglet où il doit travailler.

En instructions algorithmique, ça pourrait donner ça:

  • lire le nom de l'onglet (= nom_traitement)
  • boucle sur tous les onglets
  • récupère le nom de l'onglet
  • si nom onglet "différent" nom_traitement alors
créer onglet

fin si

- remplir l'onglet

fin boucle

Voilà ce que j'ai pour l'instant. Je veux garder le même style basique d'écriture du code car ça m'est plus facile à comprendre. Vu que je suis débutant, ces fonctions simples de VBA me satisfont. Mais le code qui suit n'est pas la solution de mon problème mais seulement un exemple de ce que j'attends.

Sub nom()

Dim nom_onglet As String

Dim occurence As Boolean

nom_onglet = Range("AJ20")

MsgBox (nom_onglet)

occurence = False

MsgBox (Worksheets.Count)

For i = 2 To Worksheets.Count

If ((Worksheets(i).Name) = nom_onglet) Then

' MsgBox ((Worksheets(i).Name) & " " & "variante déjà définie")

occurence = True

' Else

' MsgBox ((Worksheets(i).Name) & " " & "variante non définie; passage à la création")

End If

Next i

If (occurence = False) Then

MsgBox ("Création de l'onglet : " & nom_onglet)

Else

MsgBox ("Onglet déjà existant!!!")

End If

' worksheets(nom_onglet).activate()

End Sub

Je sais pas ce que t'en penses?

15classeur2.xlsm (40.46 Ko)

Bonjour

Tu écris :

on propose direct à l’utilisateur les onglets existants et après il n’a qu’à choisir. Alors on l’amène à la colonne de l'onglet où il doit travailler

Une proposition en ce sens.

Bye !

34classeur3.xlsm (54.05 Ko)

Oui j'aime beaucoup cette proposition.

Cependant je n'arrive pas à accéder au code que tu as composé car j'aimerai bien, VRAIMENT, le réutiliser sur un autre ordinateur par exemple.

De plus j'apprendrai plus sur la programmation VBA. Peut-tu me dire comment je peux accéder au code stp? En cherchant la mcro, voilà ce que cela m'affiche:

Sub ChangerDonglet()

UserForm1.Show

End Sub

donc pas de code malheureusement

Merci

Je viens de penser à une chose: le système de création d'onglet est intéressant mais peut-on l'améliorer en plaçant le nouvel onglet créé au bon endroit. Ex: si l'utilisateur crée l'onglet 3, alors is devra se placer après l'onglet 2 et avant l'onglet 4

Merci encore

Nouvelle version

Pour voir le code, tape simultanément sur les touches Alt et F11

Bye !

capture
11classeur3.xlsm (47.62 Ko)

Ok merci beaucoup pour toutes les solutions complètes que tu m'as proposé

Bonjour,

Je remercie déjà gmb pour toute l'aide apportée car son code m'est aujourd'hui encore très très utile.

Je suis de retour sur ce fil car je souhaiterais ajouter une amélioration du programme déjà évoqué dans ce fil.

L'amélioration concerne une problématique déjà évoquée ici. Nous avions parlé du fait que si on cliquait sur "insérer mot" alors ça ajoutait bien les mots; cependant lorsqu'on reclique dessus, ça les ajoute à nouveau à la suite des mots déjà existants dans les tableaux au lieu d'écraser ces mots déjà existants.

Du coup, voilà ce que je propose:

Une nouvelle colonne s'est ajoutée pour chacun des onglets, toujours dans la feuille "donnees", c'est la colonne: "mot déjà inséré".

Celle-ci sera remplie à la main par l'utilisateur par Oui ou Non (O et N).

Ainsi, je pense qu'il faudrait ajouter dans le code déjà existant de la macro "insérer mot" quelques lignes.

Il faudrait peut-être ajouter un balayage pour chaque mot, rechercher si oui ou non il a déjà été ajouté. Si oui alors ne rien faire et passer au mot suivant. Si non alors l'ajouter dans sa place correspondante.

Cette idée évite de faire l'écrasement des mots.

Voilà, je vous remercie d'avance de votre aide.

12aide-new.xlsm (48.22 Ko)

Bonjour

J’avoue que je ne comprends pas le rôle de cette nouvelle colonne que tu as ajoutée pour chaque onglet dans la feuille ‘’données ‘’.

A partir du moment où il y a écrit T1 à la cellule AI 6, par exemple, on sait que le mot ‘’arrêter’’ a déjà été ajouté sur la feuille ‘’Onglet 1’’ dans le tableau 1.

Pourquoi l’indiquer à la main dans une nouvelle colonne ?

Et si ton problème est de ne pas avoir 2 fois le même mot dans les tableaux T1, T2, T3 et T4 des feuilles ‘’Onglet 1’’ , ‘’Onglet 2’’ … alors, dis-le, on adaptera la macro.

A te relire.

Re,

Je t'explique le problème:

Supposons que toutes les colonnes de tous les onglets dans la feuille "donnees" soient vides. Alors je décide de commencer à les remplir en mettant des O et N dans la première colonne de chacun. Mais je ne termine pas de tout remplir. Je clique sur "insérer mot" et j'arrête mon ordinateur. Je reviens le lendemain sur mon ordinateur et décide de terminer de remplir les O et N restants. Et là si je reclique sur "insérer mot", ça remplira bien les nouveaux mots ajoutés aujourd'hui mais aussi ceux que j'avais entrés la veille. Et tous ces mots vont succéder les mots que j'avais la veille déjà insérés.

Pour empêcher cela, j'ai introduit une nouvelle colonne "mot déjà inséré" pour empêcher cette répétition des mots de la veille justement. Et donc à chaque fois que l'utilisateur va cliquer sur "insérer mot", il devra entrer manuellement dans cette nouvelle colonne: "O" pour les mots insérés. Ainsi si l'utilisateur revient le lendemain pour terminer d'insérer des mots, la macro va détecter les mots qui ont déjà été ajoutés la veille.

Je sais pas si ceci est la solution. T'en penses quoi?

Autre application de cette nouvelle colonne: si l'utilisateur décide un jour quelconque de modifier l'emplacement d'un mot en mettant T1 à la place de T2 par exemple; alors en cliquant sur "insérer mot" alors ça ajoutera seulement le mot changé (par contre il y aura le problème de supprimer le mot dans son ancien emplacement).

C'est un peu plus claire j'espère, sinon si t'as des questions je suis prêt à y répondre.

A te relire

Tu écris :

Je sais pas si ceci est la solution.

A mon avis non ! On va vers une usine à gaz.

Je te propose le nouveau fichier qui reste inchangé dans son format.

En revanche, chaque fois que tu valides l'entrée d'un nouveau mot, tous les onglets, de l'onglet 1 à l'onglet n sont réinitialisés et recalculés entièrement en fonction du tableau de la feuille ''donnees''

Ainsi, si tu commences à insérer des mots et que tu t'arrêtes jusqu'au lendemain, il te suffit d'enregistrer ton fichier puis, lorsque tu reprends, tu n'as plus qu'à continuer là où tu t'es arrêté.

Non ?

Bye !

19classeur-4.xlsm (56.75 Ko)

Salut gmb,

Excuse moi du retard.

J'ai bien vu ton code, vraiment je te remercie. En plus il ne demande pas beaucoup de lignes de code, c'est agréable.

Ta solution est peut-être la bonne finalement car elle résoudrait d'autres problèmes que j'ai rencontrés. Merci encore gmb.

Je souhaiterais solliciter ton aide peut-être pour la dernière fois car j'ai un nouveau projet pour ce même fichier excel.

Je ne voulais pas t'embêter encore parce que tu m'as déjà beaucoup aidé mais personne n'a réussi à répondre à ce nouveau projet. Je me tourne donc vers toi car j'ai l'espoir que toi tu ais un peu compris la philo de mon fichier.

Du coup je te demande si cela ne te dérange pas bien sûr, de m'aider à résoudre le problème que j'ai posté sous le nom de :

Apparition d'une Fenêtre de Comparaison.

Merci du temps que tu me consacre gmb.

20classeur5-v3.xlsm (35.79 Ko)
Rechercher des sujets similaires à "macro copier donnees onglet"