Aide excel VBA - Copier un onglet [Résolu/Fermé]

Signaler
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017
-
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017
-
Bonjour,
Je débute en VBA et je dois faire une macro qui copie un onglet modèle et le renomme .

J'ai écrit le code suivant :

Sub Copie_Modele()

Sheets("Modele").Copy , Sheets("Modele")

Sheets.Copy.Name = "Nouveau"

End Sub

Et évidemment ça ne marche pas, il y a une erreur dans la ligne où je veux renommer l'objet.

Quelqu'un peut me dire mon erreur?

Merci d'avance!


24 réponses

Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
Attention le nom devrait être mis dans un variable
car tu ne peux avoir deux feuilles portant le même nom.


Sub Copie_Modele()

Sheets("Modele").Copy , Before:=Sheets("Modele")
ActiveSheet.Name = "Nouveau"
Range("B26").Select
End Sub
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

Merci ça marche!

Par contre mon futur problème va être que je vais créer plusieurs onglets, en fonction d'une case remplie dans un autre tableau. (Chaque onglet aura le nom du contenu de la cellule remplie).

Du coup je pense que ActiveSheet.Name ne conviendra pas...

Donc si j'ai bien compris il faut que je créé une variable pour chaque nouvel onglet (type string) et que je lui attribue un nom?

Dernière question, pourquoi Range("B26").Select ? (j'ai compris ce que ça fait mais ce n'est pas obligatoire?)

Merci beaucoup en tout cas!
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
je m'en doutais....
Par contre mon futur problème va être que je vais créer plusieurs onglets, en fonction d'une case remplie dans un autre tableau. (Chaque onglet aura le nom du contenu de la cellule remplie). donc pas de probleme

Du coup je pense que ActiveSheet.Name ne conviendra pas... ben si car activesheet.name c'est le nom donné à la feuille active, et la feuille active
c'est celle que tu viens de copier.


Donc si j'ai bien compris il faut que je créé une variable pour chaque nouvel onglet (type string) et que je lui attribue un nom?
Tu peux faire une boucle for each qui parcours ta liste et va crée tes feuilles.

Dernière question, pourquoi Range("B26").Select ? (j'ai compris ce que ça fait mais ce n'est pas obligatoire?)
non c'est un oubli de copier / coller
pour éviter les erreurs de syntaxe ou fautes de frappes


si tu as besoin de plus d'explication....
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

ok merci,
je vais essayer d'avancer toute seule voir si j'ai bien tout compris!
Sinon je reviendrai poser mes questions!
Merci!
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
un exemple

Sub Copie_Modele()
Dim c As Variant
Dim maliste As Range
Set maliste = Sheets("Feuil2").Range("C2:C10")
For Each c In maliste

    Sheets("Modele").Copy , Before:=Sheets("Modele")
    ActiveSheet.Name = c.Value
Next
End Sub
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

Allez ça se complique encore!

Dans mon tableau, il y a des lignes avec un titre principal (1,2,3)
suivies de lignes avec des sous-titres (1.1, 1.2..2.1.....3.1).
Moi je veux créer des onglets seulement pour les lignes de sous-titre.
J'me suis dit que le plus simple était peut-être de créer un onglet pour toutes les lignes et ensuite de mettre dans la procédure de supprimer les onglets 1, 2 et 3...

Sachant que je ne sais pas à l'avance combien de lignes seront remplies, je dois utiliser While?

Merci encore!
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
si tu veux faire un onglet pour chaque ligne de sous-titre, pourquoi ne pas faire un
controle sur cette ligne? peux-tu faire un filtre sur les sous-titres?
qu'y aura -t-il ensuite dans les onglets?

on peut faire une boucle while mais le plus important c'est ce qu'il y a dans cette boucle n'est-ce pas?
je te rappelle que je ne vois pas ton fichier.
A+
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

hey tu m'as perdu là! qu'entends-tu par faire un contrôle sur cette ligne et faire un filtre des sous-titres?

Ma méthode ne marche pas car les titres 1, 2 ,3 sont sur des lignes fusionnées donc ça bug dans la copie des onglets.

Question bête : comment fait-on pour joindre un fichier?

Merci!
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

Sinon j'ai pensé à la solution de facilité :

Utiliser des MsgBox pour demander à l'utilisateur de le numéro des lignes avec des sous-titres, et réutiliser les réponses pour ma boucle....
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

j'ai finalement fait une feinte.
Je met une X devant chaque ligne à partir de laquelle je veux créer un onglet.

Sub Copie_Modele()


Dim lin As Long
Dim c As Variant
Dim maliste As Range
Dim NomOnglet As String


For lin = 31 To 500

ActiveWorkbook.Sheets("Tableau de Synthèse").Activate

If Cells(lin, 1) = "X" Then
NomOnglet = Cells(lin, 3).Value
Sheets("Modele").Copy , After:=Sheets("Modele")
ActiveSheet.Name = NomOnglet

End If

Next lin


End Sub


Par contre quand je met ActiveWorkbook.Sheets("Tableau de Synthèse").Activate
en dehors de la boucle il ne fait la boucle que une fois je comprends pas pourquoi....
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
j'ai finalement fait une feinte.
Je met une X devant chaque ligne à partir de laquelle je veux créer un onglet.

tu as installé un critère pour "filtrer" on ne s'est pas compris mais tu as su le faire.
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

ok!

Par contre je comprends pas pourquoi je dois mettre ActiveWorkbook.Sheets("Tableau de Synthèse").Activate après For pour que ça marche...

Et ça continue : Maintenant que j'ai créé mes onglets, pour chaque onglet je veux remplir des cases (l'information est stockée dans ma première feuille).

Mon problème est de savoir comment dire, que pour tous les onglets que je viens de créer, je vais affecter tel contenu à tel cellule.

Je pensais utiliser For each Next, mais pour cela je dois créer une collection avec les onglets que j'ai généré? On fait comment?

Merci
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
Par contre je comprends pas pourquoi je dois mettre ActiveWorkbook.Sheets("Tableau de Synthèse").Activate après For pour que ça marche...

de la maniere dont tu as écris la boucle For next
il est IMPERATIF de revenir sur la feuille de départ sinon
la(les) ligne(s) suivante(s) seront sans doute vide et l'onglet ne sera pas créer


Maintenant que j'ai créé mes onglets, pour chaque onglet je veux remplir des cases (l'information est stockée dans ma première feuille).

Mon problème est de savoir comment dire, que pour tous les onglets que je viens de créer, je vais affecter tel contenu à tel cellule.

tu pourrais remplir un tableau de string chaque que tu créé un onglet
puis parcourir ce tableau avec une boucle for next
pour te placer sur la bonne feuile, copier/écrire les données
puis passer au suivant



Je pensais utiliser For each Next, mais pour cela je dois créer une collection avec les onglets que j'ai généré? On fait comment?

c'est une solution... mais parfois il faut faire simple.


je te propose ça !


Sub Copie_Modele()


Dim lin As Long
Dim c As Variant
Dim maliste As Range
Dim NomOnglet As String

Dim tabloNomOnglet() As String 'le tableau
Dim I As Integer  ' le compteur
I = 0


For lin = 31 To 500

ActiveWorkbook.Sheets("Tableau de Synthèse").Activate

If Cells(lin, 1) = "X" Then
NomOnglet = Cells(lin, 3).Value
Sheets("Modele").Copy , After:=Sheets("Modele")
ActiveSheet.Name = NomOnglet
ReDim tabloNomOnglet(I)
tabloNomOnglet(I) = NomOnglet
I = I + 1

End If

Next lin

' pour la suite
For I = 0 To UBound(tabloNomOnglet)
Sheets(tabloNomOnglet(I)).Select
    'With ActiveSheet
    
    'End With
Next





End Sub
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

merci beaucoup! c'est sur je n'y aurais pas pensé!

Par contre il me met un message d'erreur pour cette ligne :

Sheets(tabloNomOnglet(I)).Select

erreur 9 : l'indice n'appartient pas à la sélection...
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

en mettant I-1 ça marche!

par compte j'ai pas compris pourquoi ;-)
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

j'ai toujours la même erreur d'exécution 9. (lindice n'appartient pas à la sélection)
Du coup il me copie bien les onglets mais il ne fait pas l'instruction d'après..

C'est cette ligne qui fait bugger... Sheets(tabloNomOnglet(I)).Select

Sub Copie_Modele()


Dim lin As Long
Dim maliste As Range
Dim NomOnglet As String

'délaration du tableau qui va stocker le nom des onglets créés

Dim tabloNomOnglet() As String 'le tableau
Dim I As Integer ' le compteur
I = 0


'Déclaration des variables à recopier

'Client
Dim col_tab_Client As Long, lin_tab_Client As Long, col_FA_Client As Long, lin_FA_Client As Long
col_tab_Client = 5
lin_tab_Client = 3
col_FA_Client = 5
lin_FA_Client = 2


For lin = 31 To 500

ThisWorkbook.Sheets(1).Activate

If Cells(lin, 1) = "X" Then

NomOnglet = Cells(lin, 3).Value
Sheets("Modele").Copy , Before:=Sheets("Modele")
ActiveSheet.Name = NomOnglet

ReDim tabloNomOnglet(I)
tabloNomOnglet(I) = NomOnglet
I = I + 1

End If

Next lin

'remplissage des onglets

For I = 0 To UBound(tabloNomOnglet)
Sheets(tabloNomOnglet(I)).Select

With ActiveSheet

'Nom du client
Cells(lin_FA_Client, col_FA_Client) = Worksheets(1).Cells(lin_tab_Client, col_tab_Client)


End With

Next I
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
excuse moi j'ai fait une erreur
j'ai supprimé une ligne quand j'ai fait le post... désolé
il fallait écrire redim preserve tablonomonglet(i) j'ai oublié préserve
donc tu n'avais qu'une seule valeur


Sub Copie_Modele()


Dim lin As Long
Dim maliste As Range
Dim NomOnglet As String

'délaration du tableau qui va stocker le nom des onglets créés

Dim tabloNomOnglet() As String 'le tableau
Dim I As Integer ' le compteur
I = 0


'Déclaration des variables à recopier

'Client
Dim col_tab_Client As Long, lin_tab_Client As Long, col_FA_Client As Long, lin_FA_Client As Long
col_tab_Client = 5
lin_tab_Client = 3
col_FA_Client = 5
lin_FA_Client = 2


For lin = 31 To 500

ThisWorkbook.Sheets(1).Activate

If Cells(lin, 1) = "X" Then

NomOnglet = Cells(lin, 3).Value
Sheets("Modele").Copy , Before:=Sheets("Modele")
ActiveSheet.Name = NomOnglet

ReDim Preserve tabloNomOnglet(I)
tabloNomOnglet(I) = NomOnglet
I = I + 1

End If

Next lin

'remplissage des onglets

For I = 0 To UBound(tabloNomOnglet)
Sheets(tabloNomOnglet(I)).Select

With ActiveSheet

'Nom du client
Cells(lin_FA_Client, col_FA_Client) = Worksheets(1).Cells(lin_tab_Client, col_tab_Client)


End With

Next I
End sub
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

pas de souci!
maintenant ça marche nickel!

Merci pour tout.
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

Re!

J'ai encore une question!!

Après cette procédure, je veux en faire une autre, pour faire plus ou mois la même chose mais dans l'autre sens. En gros, dans la première je crée des onglets (avec un peu de texte reporté). Une fois que j'ai créé mes onglets, je vais les remplir. Je veux reporter une partie de ce que j'ai écrit dans le premier tableau qui m'a servi à créer les onglets...

Ma question est : comment utiliser les mêmes variables? J'ai essayer en faisant un autre module pour ma deuxième procédure.
J'avais besoin de réutiliser le truc des tableaux. J'ai changé le Dim en Public mais ça me met des messages d'erreur...

Merci!
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
j'ai pas tout compris....
mais je peux expliquer ton erreur.
le fait de changer dim en public n'est pas suffisant.
Dim est une variable de dimensionée ou typée en locale
Public veut dir globale, mais celle -ci doit se trouver à l'estérieure de la sub.

je pense cependant que si tu fais une "nouvelle macro" ton tableau est sans doute vide d'ou ton erreur.
Explique un peu plus ce que tu veut faire et on repart à zéro.
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

ok je vais essayer d'être plus claire!

Mon travail consiste en deux étapes :

- la procédure Copie_Modele qui marche super!
- la procédure remplissage_tableau-synthèse qui ne peut être réalisée qu'une fois que la première procédure a été exécutée.

En effet, une fois que mes onglets sont créés, je les remplis, et certaines informations devront être reportées dans mon tableau de synthèse (le même qui m'a servi à déterminer le nombre et le nom des onglets).

Je vais donc devoir réutiliser mon tableau qui stocke le nom des nouveaux onglets, pour dire : pour tous mes onglets créés, le contenu de telle cellule est reporté dans l'onglet "tableau de synthèse".
Mais je ne sais pas comment comment réutiliser des variables de ma première procédure...
Déjà, le mieux est-il d'écrire ma nouvelle procédure à la suite ou de créer un nouveau module?

Merci !!
Messages postés
47
Date d'inscription
samedi 16 décembre 2006
Statut
Membre
Dernière intervention
15 mai 2017

j'ai recommencé en déclarant mes variables publics, au bon endroit cette fois, et ça marche!
Messages postés
1181
Date d'inscription
mardi 27 mai 2008
Statut
Membre
Dernière intervention
12 juillet 2012
254
Félicitations!
une bonne note pour tes progrès!