Insérer nouvelle feuille avec date dans l'odre chronologique

Bonjour le forum !

J'ai un userform qui me permet de créer, via les CommandButton1 (liste des mois) et 2 (liste des années), une nouvelle feuille ayant pour nom "mois année". Cette feuille est créée par copie d'une feuille "modèle". Jusqu'à là, pas de problème ...

Le problème arrive quand j'utilise la fonction "Sheets("Modèle").Copy after:=" car je n'arrive pas à trouver la bonne syntaxe du code qu'il faut pour trouver la page déjà existante du mois précédent. Par exemple, si je créée la page "janvier 2015", je dois trouver par ce code la page "décembre 2014".

Si quelqu'un a une idée, je suis preneur

Bonjour,

si tes noms de mois sont bien ceux d'excel :

Worksheets(Format(DateSerial(CLng(an), CLng(mois) - 1, 1), "mmmm yyyy"))

eric

Bonjour,

Tout dépend de comment tu t'y es pris , dans ton code initial ...

Si tes années et tes mois sont bien des dates, tu peux facilement les trier ...

Par contre, si tu as généré des Variables du type String ... ce sera plus compliqué ...

Bonjour

Ma contribution

Sub test()
Dim Nom As String
Dim FeuilleAvant As String

  Nom = "janvier 2015"
  FeuilleAvant = Format(DateAdd("m", -1, CDate(Nom)), "mmmm yyyy")
  MsgBox "Feuille précédente : " & FeuilleAvant
End Sub

Ci-dessous une partie du code que j'utilise. J'ai temporairement utilisé des msgbox afin de voir si j'obtenais les résultats voulus avec mes variables. Ca fonctionne mais c'est la pertie "ActiveSheet.Move after:=" qui est en échec ...

Private Sub CommandButton1_Click()
Dim NomOnglet As String
Dim NomOngletAnterieur As String
If Me.ComboBox1.ListIndex = -1 Or Me.ComboBox2.ListIndex = -1 Then Exit Sub ' Si le jour et le mois non renseigné, sortir du Sub

If FeuilleExiste(Me.ComboBox1 & " " & Me.ComboBox2) = False Then
Worksheets("Modèle").Visible = True

   NomOnglet = Format(Me.ComboBox1 & " " & Me.ComboBox2, "mmmm yyyy")
   MsgBox NomOnglet

   NomOngletAnterieur = Format(CDate(Month(NomOnglet) & " " & Year(Date)) - 1, "mmmm yyyy")
   MsgBox NomOngletAnterieur

   Sheets("Modèle").Copy after:=Sheets("Décembre") ' Copie l'onglet modèlé caché
   ActiveSheet.Name = NomOnglet ' Renomme le nouvel onglet
   ActiveSheet.Move after:=NomOngletAnterieur
   ActiveSheet.Visible = True ' Rend le nouvel onglet visible
   NomOnglet = ActiveSheet.Name

Worksheets("Modèle").Visible = False

   Unload Userform1

 Else
    MsgBox "La date de production choisie existe déjà !" & vbLf & vbLf & "Merci de saisir une nouvelle date ou d'annuler la demande ..." 'Annule la création de l'onglet si déjà existant
End If

End Sub

Function FeuilleExiste(Nom As String) As Boolean
  On Error Resume Next
  FeuilleExiste = Sheets(Nom).Name <> ""
  On Error GoTo 0
End Function

Bonjour Banzai64, content de te retrouver dans ce forum ...

J'ai essayé la proposition d'Eriiic, ça ne passe pas pour une "incompatibilité de type"

Bonsai, j'ai adapté ton code à ma macro, la msgbox montre bien que le nom de la page précédente à bien été identifiée, mais lors de la copie de la page "modèle", ça plante ...

Ligne concernée :

Sheets("Modèle").Copy after:=NomOngletAnterieur ' Copie l'onglet modèlé caché

Message d'erreur : "la méthode copy de la classe worksheet a échoué"

Mon code actuel :

Private Sub CommandButton1_Click()
Dim NomOnglet As String
Dim NomOngletAnterieur As String
If Me.ComboBox1.ListIndex = -1 Or Me.ComboBox2.ListIndex = -1 Then Exit Sub ' Si le jour et le mois non renseigné, sortir du Sub

If FeuilleExiste(Me.ComboBox1 & " " & Me.ComboBox2) = False Then
Worksheets("Modèle").Visible = True

    NomOnglet = Format(Me.ComboBox1 & " " & Me.ComboBox2, "mmmm yyyy")
    MsgBox NomOnglet

    NomOngletAnterieur = Format(DateAdd("m", -1, CDate(NomOnglet)), "mmmm yyyy")
    MsgBox NomOngletAnterieur

    Sheets("Modèle").Copy after:=NomOngletAnterieur ' Copie l'onglet modèlé caché
    ActiveSheet.Name = NomOnglet ' Renomme le nouvel onglet

    ActiveSheet.Visible = True ' Rend le nouvel onglet visible
    ActiveSheet.Range("D1").Value = ActiveSheet.Name
    NomOnglet = ActiveSheet.Name

Worksheets("Modèle").Visible = False

   Unload Userform1

Else
    MsgBox "La date de production choisie existe déjà !" & vbLf & vbLf & "Merci de saisir une nouvelle date ou d'annuler la demande ..." 'Annule la création de l'onglet si déjà existant
End If

End Sub

Function FeuilleExiste(Nom As String) As Boolean
  On Error Resume Next
  FeuilleExiste = Sheets(Nom).Name <> ""
  On Error GoTo 0
End Function

Aurais-tu une idée sur ce plantage ?

Dans ma proposition an = 2015 (ou "2015" comme tu parlais de textbox ou listbox) et mois = 1 (ou "1"), que tu peux obtenir avec l'index de la sélection dans la liste.

eric

J'ai simplement remplacé "an" et "mois" par les Me.ComboBox1 et 2 (résultats des choix des listes de mon Userform1 et j'obtient donc le message d'erreur "Incompatibilité de type"

NomOngletAnterieur = Worksheets(Format(DateSerial(CLng(Me.ComboBox2), CLng(Me.ComboBox1) - 1, 1), "mmmm yyyy"))

Mes listes sont définies telles quelles :

Private Sub UserForm_initialize()

  With ComboBox1
     .AddItem "Janvier"
     .AddItem "Février"
     .AddItem "Mars"
     .AddItem "Avril"
     .AddItem "Mai"
     .AddItem "Juin"
     .AddItem "Juillet"
     .AddItem "Aout"
     .AddItem "Septembre"
     .AddItem "Octobre"
     .AddItem "Novembre"
     .AddItem "Décembre"
 End With

  With ComboBox2
     .AddItem "2014"
     .AddItem "2015"
     .AddItem "2016"
     .AddItem "2017"
     .AddItem "2018"
     .AddItem "2019"
     .AddItem "2020"
     .AddItem "2021"
 End With

End Sub

Bonjour

Juste pour ma culture personnelle

As tu essayé le code que je t'ai fait ?

oui, clng("Mai") ça ne le fait pas.

Essaie avec combobox1.listindex+1

En plus ça t'affranchit des différences d'orthographe que tu as avec excel.

eric

Pour Banzai : oui, j'ai essayé ta méthode mais j, ai un message d'erreur que je t'ai noté plus haut.

Pour

Éric : je suis dans le bus, j'essaierai tout à l'heure chez moi !

Bonjour

Ouf j'ai eu peur j'ai cru que mon code était en cause

C'est la copie de feuille qui n'est pas bonne

Il faut utiliser

Sheets("Modèle").Copy after:=Sheets(NomOngletAnterieur)' Copie l'onglet modèlé caché

Désolé, je n'ai pas pu répondre avant, le temps de faire le trajet retour à chez moi ...

Pour Eric : comment veux tu que j'utilise ComboBox1.ListIndex+1 ? Dans quel partie du code VBA ?

Pour Banzai : Je t'avais déjà répondu plus haut, avec le nouveau code affiché.

Ca ne fonctionnait pas au niveau de la ligne de code suivante :

Sheets("Modèle").Copy After:=Sheets(NomOngletAnterieur)

J'avais un message d'erreur qui m'indiquait que l'indice n'appartenait pas à la selection.

Et j'ai compris pourquoi : mes anciennes feuilles ne comportaient que le "mois" dans leur nom et pas les "années".

Après avoir corrigé cela, ça a fonctionné ...

Je mettrais le code final de ce sub pour le partager, mais je dois d'abord le compléter pour ne pas avoir de plantage si la feuille du mois précédent n'existe pas(avec err=0 ou On Error Resume Next). Je garde le sujet ouvert ...


Ca y est, ça fonctionne !!! Mais je dois améliorer quelques chose avant de partager le code que je mettrais en ligne avant de fermer ce topîc ...

Voilà, j'ai trouvé un moment pour améliorer le code afin qu'il n'y ai pas de message d'erreur si la feuille du mois précédent n'existe pas.

Voici le code :

Private Sub CommandButton1_Click()
Dim NomOnglet As String
Dim NomOngletAnterieur As String
Dim ws As Worksheet

If Me.ComboBox1.ListIndex = -1 Or Me.ComboBox2.ListIndex = -1 Then Exit Sub ' Si le jour et le mois non renseigné, sortir du Sub

If FeuilleExiste(Me.ComboBox1 & " " & Me.ComboBox2) = False Then
Worksheets("Modèle").Visible = True

    NomOnglet = Format(Me.ComboBox1 & " " & Me.ComboBox2, "mmmm yyyy")

    NomOngletAnterieur = Format(DateAdd("m", -1, CDate(NomOnglet)), "mmmm yyyy")

    On Error Resume Next
    Set ws = Sheets(NomOngletAnterieur)
    On Error GoTo 0

    If Not ws Is Nothing Then
        Sheets("Modèle").Copy After:=Sheets(NomOngletAnterieur) ' Copie l'onglet modèlé caché

        ActiveSheet.Name = NomOnglet ' Renomme le nouvel onglet

        ActiveSheet.Visible = True ' Rend le nouvel onglet visible
        ActiveSheet.Range("D1").Value = ActiveSheet.Name

    Else
        MsgBox "Vous devez d'abord créer la feuille " & NomOngletAnterieur & " avant celle-ci !"
    End If

Worksheets("Modèle").Visible = False

   Unload Userform1

Else
    MsgBox "La date de production choisie existe déjà !" & vbLf & vbLf & "Merci de saisir une nouvelle date ou d'annuler la demande ..." 'Annule la création de l'onglet si déjà existant
End If

End Sub

Merci Banzai et Eric pour votre participation, je n'en était pas loin mais il me manquait le petit plus ...

Afin de clore le sujet, une petite question en plus : je cherche a créer une autre macro qui corrigerait automatiquement l'ordre chronologiques des onglets comportant une date ( dans un Private Sub Worksheet_Activate() ), ceci au cas où un utilisateur viendrait à déplacer une des feuilles. En effet, chaque feuille utilise des liens de type "application volatiles" vers leur feuille précédente respective et si l'ordre change, tout les calculs qui s'en suivent sont faussés.

Quelqu'un aurait-il déjà un template de ce type ?

Bonjour,

Une proposition, les onglets date sont mis en fin :

Sub triOngletsDate()
    'tri par date sur nom d'onglet
    Dim sh As Worksheet
    Dim nom(), tmp(2), cpt As Long, fini As Boolean, depl As Boolean

    ReDim nom(1 To 2, 1 To 1)
    For Each sh In Worksheets
        ' recup onglets date
        If IsDate(sh.Name) Then
            cpt = cpt + 1
            ReDim Preserve nom(1 To 2, 1 To cpt)
            nom(1, cpt) = sh.Name
            nom(2, cpt) = CDate(sh.Name)
        End If
    Next sh

    ' tri à bulle
    Do
        fini = True
        For cpt = 2 To UBound(nom, 2)
            If nom(2, cpt) < nom(2, cpt - 1) Then
                tmp(1) = nom(1, cpt): tmp(2) = nom(2, cpt)
                nom(1, cpt) = nom(1, cpt - 1): nom(2, cpt) = nom(2, cpt - 1)
                nom(1, cpt - 1) = tmp(1): nom(2, cpt - 1) = tmp(2)
                fini = False
                depl = True
            End If
        Next cpt
    Loop Until fini
    ' déplacer
    If depl Then
        Application.ScreenUpdating = False
        For cpt = 1 To UBound(nom, 2)
            Sheets(nom(1, cpt)).Move After:=Sheets(Sheets.Count)
        Next cpt
    End If
End Sub

que tu pourrais appeler de Workbook_Open() et Workbook_SheetActivate() de thisworkbook.

eric

Suer cool ta macro Eriiic !

Je vais prendre le temps de la décortiquer afin de la comprendre, dès que j'aurai quelques instant de libre ...

Par contre, je vais essayer de la modifier afin que les onglets comportant des dates soient en 1er plutôt qu'en dernier.

J'ai bien essayé de before au lieu de after, mais ça a planté le fichier ...

Bonjour,

essaie comme ça :

        For cpt = UBound(nom, 2) to 1 step -1
            Sheets(nom(1, cpt)).Move before:=Sheets(1)
        Next cpt

eric

Merci Eriiic, j'avais trouvé entre temps les arguments pour mettre les onglets de date en 1er.

Mais finalement, la macro ne fonctionne pas, et comme je n'ai jamais utilisé la fonction cpt, je vais l'étudier et essayer de l'adapter à mes besoins. C'est peut être lié au fait qu'il ne reconnait pas mes noms d'onglets comme étant des dates.

Je cherche et je te tiens au courant ...

Les 3 lignes étaient à remplacer dans la première macro (la dernière boucle), elles ne se suffisent pas à elles-même.

cpt est une variable que j'aurais pu appeler n'importe comment, pas une fonction.

eric

Rechercher des sujets similaires à "inserer nouvelle feuille date odre chronologique"