Aide excel VBA - Copier un onglet

Résolu/Fermé
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017 - 6 juil. 2010 à 10:43
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017 - 19 juil. 2010 à 14:23
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!


A voir également:

24 réponses

Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
6 juil. 2010 à 10:50
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
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
6 juil. 2010 à 10:58
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!
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
6 juil. 2010 à 12:02
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....
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
6 juil. 2010 à 12:05
ok merci,
je vais essayer d'avancer toute seule voir si j'ai bien tout compris!
Sinon je reviendrai poser mes questions!
Merci!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
6 juil. 2010 à 12:37
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
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 10:32
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!
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
7 juil. 2010 à 10:40
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+
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 11:06
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!
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 11:11
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....
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 12:20
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....
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
7 juil. 2010 à 13:55
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.
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 15:49
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
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
7 juil. 2010 à 16:12
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
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 16:39
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...
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 16:41
en mettant I-1 ça marche!

par compte j'ai pas compris pourquoi ;-)
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 18:52
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
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
7 juil. 2010 à 22:10
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
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
7 juil. 2010 à 22:15
pas de souci!
maintenant ça marche nickel!

Merci pour tout.
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
13 juil. 2010 à 10:48
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!
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
13 juil. 2010 à 11:00
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.
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
13 juil. 2010 à 11:08
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 !!
0
patate_560 Messages postés 47 Date d'inscription samedi 16 décembre 2006 Statut Membre Dernière intervention 15 mai 2017
13 juil. 2010 à 12:00
j'ai recommencé en déclarant mes variables publics, au bon endroit cette fois, et ça marche!
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 295
13 juil. 2010 à 13:24
Félicitations!
une bonne note pour tes progrès!
0