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 SubCi-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 FunctionBonjour 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 FunctionAurais-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 SubBonjour
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 SubMerci 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 Subque 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 cpteric
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