Aide excel VBA - Copier un onglet

Résolu
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

Résumé de la discussion

Copier un onglet modèle et le renommer en VBA est au cœur de la discussion, où le code initial tente de dupliquer l’onglet Modele puis de renommer la copie. Plusieurs réponses explorent des solutions, notamment l’usage correct de Sheets('Modele').Copy avec les paramètres Before/After et la propriété ActiveSheet.Name pour donner le nouveau nom, et évitent l’erreur de syntaxe observée dans la ligne de renommage. D’autres messages détaillent des méthodes plus complexes impliquant des tableaux et des conditions d’activation, puis l’implantation d’un marqueur (X) pour créer uniquement les onglets souhaités. La méthode finale suggérée consiste à copier le modèle et nommer chaque nouvelle feuille selon une valeur de colonne, en utilisant Before/After et en évitant des activations répétées qui cassent la boucle.

Bobot (l’IA à votre service)
  1. 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
    1. 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
      1. 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
        1. ok merci,
          je vais essayer d'avancer toute seule voir si j'ai bien tout compris!
          Sinon je reviendrai poser mes questions!
          Merci!
          0
          1. 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
            1. 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
              1. 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
            2. 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
              1. 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
                1. 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
                  1. 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
                2. 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
                  1. 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
                    1. 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
                      1. en mettant I-1 ça marche!

                        par compte j'ai pas compris pourquoi ;-)
                        0
                        1. 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
                          1. 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
                            1. pas de souci!
                              maintenant ça marche nickel!

                              Merci pour tout.
                              0
                              1. 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
                                1. 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
                                  1. 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
                                    1. j'ai recommencé en déclarant mes variables publics, au bon endroit cette fois, et ça marche!
                                      0
                                      1. Félicitations!
                                        une bonne note pour tes progrès!
                                        0
                                    • 1
                                    • 2