Microsoft 365 datepicker dynamique intra userform ou dans feuille 2 versions(frame dynamique)(toute version d'excel )

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

patricktoulon

XLDnaute Barbatruc
Bonjour à tous
suite a ta demande en Mp @JCabral j'ai ressorti mes archives
j'ai du ré ouvrir pas mal de zip pour le retrouver 🤪 🤪
j'ai bien entendu fait un peu de restructuration du code en effet il datait un peu
alors voila mon module classe pour avoir un calendar dynamique dans un userform et non un userform calendar en mode responsif comme ma ressource du même nom

cette classe va créer de toute pièce l'interface du calendrier a l’intérieur du userform
il n'y a pas de librairie particulière à activer
un module classe nommé:Dynamic_Calendrier
VB:
'*****************************************************************************************************
'    ___     _     _______  __      _   ____  _   _  _______  ___     _   _   _    ___     _     _.
'   //  \\  /\\      //    // \\   //  //    //  //    //    //  \\  //  //  //   //  \\  //|   //
'  //___// //__\    //    //__//  //  //    //__//    //    //   // //  //  //   //   // // |  //
' //      //   \\  //    //  \\  //  //    //  \\    //    //   // //  //  //   //   // //  | //
'//      //    // //    //   // //  //___ //    \\  //     \\__// //__//  //___ \\__// //   |//
'****************************************************************************************************
'                            Interface calendrier dans frame dynamique pour Userform By patricktoulon
'' Copyright (C) 2025
'' auteur:Patrick Verne sur developpez.com
'' Date version:22/06/2013
'' Mise à jour:
'' remastering complet du code version 2025
'' publié sur exceldownloads

Option Explicit

Dim cl(1 To 42) As New Dynamic_Calendrier
Public Datepicker As Object
Public WithEvents cbm As msforms.ComboBox
Public WithEvents cba As msforms.ComboBox
Public WithEvents Bt As msforms.Label
Public u As Object
Public cla As Dynamic_Calendrier '
Public CallerControl As Object
'--------------------------------
'Changez les couleurs ici
Const BackgroundColor = &HDACCC9
'les combobox
Const comboBackColor = &H808080
Const comboFontColor = vbYellow
'les titres de jour
Const headerBackColor = vbBlue
Const headerfontColor = vbYellow
'les jour de la semaine
Const DayBackColor = vbWhite
Const DayfontColor = vbBlue
'les jour weekend
Const WeekendBackColor = vbYellow
Const WeekendfontColor = vbRed
'les jour weekend
Const fériéBackColor = vbGreen
Const fériéfontColor = vbRed
'--------------------------------

Public Sub InitCalendar(uf)
    'Plaque du calendrier(frame
    Dim f, cbmois, cbyear, I&, B, T, E
    Set f = uf.Controls.Add("forms.Frame.1", "Calendar", True)
    Set Datepicker = f
    With f
        .Width = 150
        .Height = 120
        .Top = 10
        .Caption = ""
        .BackColor = &HDACCC9
        'combobox des mois
        Set cbmois = f.Add("forms.ComboBox.1", "cbmois", True)
        With cbmois
            .List = Application.GetCustomListContents(3)
            .Height = 15
            .ListRows = 12
            .Width = 50
            .Font.Bold = True
            Set cbm = cbmois
            Set u = uf
            cbmois.BackColor = comboBackColor
            cbmois.ForeColor = comboFontColor
        End With
    
        'combobox des années
        Set cbyear = f.Add("forms.ComboBox.1", "cbyear", True)
        With cbyear
            .List = Evaluate("row(1900:2050)")
            .Height = 15
            .ListRows = 12
            .Left = 85
            .Width = 50
            .Font.Bold = True
            Set cba = cbyear
            cbyear.BackColor = comboBackColor
            cbyear.ForeColor = comboFontColor
            .MatchEntry = 0
        End With
    
        'header de calendrier(les jours de semaines
        Dim jours As Variant, j As Variant
        jours = Application.GetCustomListContents(1)
        For Each j In jours
            Debug.Print j
            I = I + 1
            Set B = f.Add("forms.label.1", Left(j, 3) & "_", True)
            With B
                .Caption = Left(j, 3)
                .Width = 20
                .BorderStyle = 1
                .Height = 12
                .Left = (.Width + 1) * (I - 1)
                .TextAlign = 2
                .Top = 20
                .BackColor = headerBackColor
                .ForeColor = headerfontColor
                .Font.Bold = True
            End With
        Next j
    
        'les 42 positions de jours possibles
        T = 34
        For I = 1 To 42
            E = E + 1
            Set B = f.Add("forms.label.1", "j" & I, True)
            With B
                .Caption = "-"
                .Width = 20
                .BorderStyle = 1
                .Height = 12
                .Left = (.Width + 1) * (E - 1)
                .Top = T
                If E = 7 Then E = 0: T = T + 14
                .TextAlign = 2
                Set cl(I).Bt = B: Set cl(I).cbm = cbmois: Set cl(I).cba = cbyear: Set cl(I).u = uf
                Set cl(I).cla = Me: Set cl(I).Datepicker = f
            End With
        Next
    End With
    f.Visible = False
End Sub

Private Sub Bt_Click()
    'MsgBox DateSerial(cba, cbm.ListIndex + 1, Bt.Caption)
    cla.CallerControl = DateSerial(cba, cbm.ListIndex + 1, Bt.Caption)
    Datepicker.Visible = False
 
End Sub

Private Sub cba_Change()
    If cbm.ListIndex = -1 Or cba.ListIndex = -1 Then Exit Sub
    reloadmonth
End Sub

Private Sub cbm_Change()
    If cbm.ListIndex = -1 Or cba.ListIndex = -1 Then Exit Sub
    reloadmonth
End Sub

Sub reloadmonth()
    Dim d As Date, fin, X&, I&, E&
    d = DateSerial(cba, cbm.ListIndex + 1, 1)
    fin = Day(DateSerial(cba.Value, cbm.ListIndex + 2, 0))
    X = Weekday(d, vbUseSystemDayOfWeek)
    For I = 1 To 42
        With u.Controls("j" & I)
            .Caption = "-"
            .BackStyle = 0
            .ForeColor = vbBlack
        End With
    Next
    For I = X To X + fin - 1
        E = E + 1
        With u.Controls("j" & I)
            .BackStyle = 1
            .Caption = Day(d + (E - 1))
        
            .BackColor = DayBackColor
            .ForeColor = DayfontColor
        
            If Weekday(d + (E - 1), 2) >= 6 Then
                .BackColor = WeekendBackColor
                .ForeColor = WeekendfontColor
            End If
        
            If férié(d + (E - 1)) Then
                .BackColor = fériéBackColor
                .ForeColor = fériéfontColor
            End If
        End With
    Next
End Sub
Public Sub ShowCalendar(ctrl As Object)
    With Datepicker
        .Visible = True
        .Left = ctrl.Left + ctrl.Width
        .Top = ctrl.Top
    End With
    If IsDate(ctrl.Value) Then
        Dim A&, M&
        A = Year(CDate(ctrl.Value))
        M = Month(CDate(ctrl.Value)) - 1
    Else
        A = Year(Date): M = Month(Date) - 2
    End If
    cba.Value = A: cbm.ListIndex = M:
    cba.ListIndex = A - 1900
    reloadmonth
    Set Me.CallerControl = ctrl
End Sub
Function férié(d As Date) As Boolean
    férié = False
    Dim tbl(1 To 12) As Date, I&
    tbl(1) = DateSerial(Year(d), 1, 1)
    tbl(2) = CDate(((Round(DateSerial(Year(d), 4, (234 - 11 * (Year(d) Mod 19)) Mod 30) / 7, 0) * 7) - 6))
    tbl(3) = tbl(2) + 39
    tbl(4) = tbl(2) + 50
    tbl(5) = DateSerial(Year(d), 5, 1)
    tbl(6) = DateSerial(Year(d), 5, 8)
    tbl(7) = DateSerial(Year(d), 11, 11)
    tbl(8) = DateSerial(Year(d), 12, 25)
     tbl(9) = tbl(2) + 1
 For I = 1 To UBound(tbl)
        If (d) = (tbl(I)) Then férié = True: Exit For
    Next
End Function

exemple d'utilisation dans un userform
Code:
Dim cls As New Dynamic_Calendrier

Private Sub UserForm_Initialize()
    cls.InitCalendar Me
End Sub

Private Sub TextBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Button = 2 Then
        cls.ShowCalendar TextBox1
    End If
End Sub



demo3.gif

Les couleur peuvent être changée au niveau des constantes
VB:
'--------------------------------
'Changez les couleurs ici
Const BackgroundColor = &HDACCC9
'les combobox
Const comboBackColor = &H808080
Const comboFontColor = vbYellow
'les titres de jour
Const headerBackColor = vbBlue
Const headerfontColor = vbYellow
'les jour de la semaine
Const DayBackColor = vbWhite
Const DayfontColor = vbBlue
'les jour weekend
Const WeekendBackColor = vbYellow
Const WeekendfontColor = vbRed
'les jour weekend
Const fériéBackColor = vbGreen
Const fériéfontColor = vbRed
'--------------------------------
voila par de fenêtre calendar en plus mais le calendar est à l'intérieur du userform dans un frame
Patrick

Edit comme la discussion est longue je met ici en premier post le 4 versions
  1. la version frame pour userform dans une classe
  2. la version v 2.0 simple construite totalement avec des shapes pour les feuilles excel uniquement
  3. la version v3.0 avec possibilité de changer les couleur dynamiquemen(avec réécriture des valeur dans le Enum du module)
  4. la version 4.0 avec possibilité de changer les couleurs dynamiquement( les couleurs sont memorisé cette fois ci dans un name )
(condition (sine qua none pour la v 3): activer l'accès approuvé au modèle d'object du projet vbadans les options excel
 

Pièces jointes

Dernière édition:
moi je vous dit on marche sur la tête là
je bataille avec claude pour trouver une solution pour classer les deux combos
on a fini pas découvrir que le classement des combo créé in designmode(mano mano avec la boite à outils ) fonctionne parfaitement bien mais les combo dynamico NON!!!!
non serieux hahahahaha , je crée des combo mano mano et je vais les classer 🙃 🙃 🙃
ils picolent chez Ms hahahahaha
si encore il avaient tout bloqué je pourrais comprendre mais là c'est carrément l'inverse
ils doivent avoir un foi je vous dit pas hihihihihi
le lien vers la discussion avec claude
 
Bonjour @fanch55

j'ai appliqué une autre solution pour notre calendrier en shapes
  1. on vire le module classe
  2. on vire les event de la feuille
  3. on vire les comboboxs
  4. on les remplace par des simples shapes
  5. dans leur onAction on lance des menus popup
  6. dans les menu les items lancent deux subs qui serviront d'events
edit: et j'ajoute le placement du menumois en dessous le cbx_mois
et j'ajoute l'anti déplacement du calendrier de la plage visible de la fenêtre excel
Normalement il se pose a droite de la cellule
mais si la cellule est trop a droite le calendier se pose a gauche
si il est trop bas il se pose au dessus

et voila plus d'activX,plus d'events, plus de classe

un simple module standard à glisser dans les projets (un travail comme je les aimes)
demo3.gif


UN SIMPLE DOUBLE CLICK SUR LA CELLULE ET C EST BON 😉 😛
 

Pièces jointes

Dernière édition:
Eh bien !!! 🥳
Je reviens de ma journée de cure chimio et je vois que tu as fait un calendrier de feuille qui fonctionne correctement et avec des msoBarPopup, le luxe, je n'y avais pas pensé.
Bravo @patricktoulon , il ne te reste plus qu'à corriger le "System.Collections.ArrayList" pour que cela fonctionne pour la majorité .
Je te remercie de me citer dans ton cartouche, mais l'idée et les codes de base étaient et sont les tiennes, je n'ai fait que participer ....
C'est bien ça, un seul module même s'il faut un chouia de code incontournable dans la feuille .
 
Hi,
....
Bravo @patricktoulon , il ne te reste plus qu'à corriger le "System.Collections.ArrayList" pour que cela fonctionne pour la majorité .
...
Encore bon courage, force à toi 🤞
Pour l'histoire de "ArrayList", p'têt bien que PatT n'a pas vu ma petite intervention
PC nativement doté de W11, avec Office 2024, et les versions de "Framwork" d'origine...
Bonne soirée
 
re
avec le dico
Eh bien !!! 🥳
Je reviens de ma journée de cure chimio et je vois que tu as fait un calendrier de feuille qui fonctionne correctement et avec des msoBarPopup, le luxe, je n'y avais pas pensé.
Bravo @patricktoulon , il ne te reste plus qu'à corriger le "System.Collections.ArrayList" pour que cela fonctionne pour la majorité .
Je te remercie de me citer dans ton cartouche, mais l'idée et les codes de base étaient et sont les tiennes, je n'ai fait que participer ....
C'est bien ça, un seul module même s'il faut un chouia de code incontournable dans la feuille .
@fanch55
qu'importe tu es un des rares avec qui j'aime bien travailler et échanger
je considère qu'on est deux sur le coup et c'est tout a fait normal pour moi que tu soit cité

@Cousinhub
j'ai remplacé l'arraylist par un dico


on a donc deux modules un pour les userforms et un pour les feuilles
le principe étant le même mais fait avec des object différents s ci joint les deux exemples

voila sans userform
incroyable d'un petit trus que j'ai fait il y a très longtemps on a refait deux modelés actuels
et toujours selon ma philosophie de propagation ( un seul module à glisser)
 

Pièces jointes

Une petite interrogation: pourquoi un Escape après l'affichage du calendrier ?
Réaction bizarre de celui-ci ce matin au premier double-click, il m'a interrompu l'exécution de la macro ????
Impossible de le reproduire par la suite ... 🤔
 
Bonjour @fanch55
le ESC c'est pour sortir du mode édition quand on double clique sur la cellule
mais en effet il peut y avoir un soucis asynchrone et la touche esc s’exécute avant la fin de création du calendrier

autrement dit tu peux avoir une brève apparition (voir incomplète du calendrier)

à renforcer donc ; ou changer de méthode pour le double clic pour sortir du mode edition
 
J'ai un peu modifié le code de feuille pour ne pas afficher le calendar sur toutes les cellules,
finalement pas besoin de l'escape pour sortir de l'édition, mettre juste cancel=true ,
j'ai mis le delete du shape dans le module et coloré en or la case du jour de référence .

Bonjour à tous,

Le double clic fonctionne que s'il y a une date dans la cellule, ou j'ai loupé quelque chose ?
Et la coloration du jour "aujourd'hui" serait bien

Nicolas
 
Bonjour Patrick, Bonjour fanch55, bonjour le forum,

Super calendrier, super !
La cerise sur le gâteau serait qu'il s'ouvre au mois et année en cours (resterait le jour à sélectionner).
Qu'en pensez-vous ?
lionel 😉
Salut Lionel,
Actuellement, il s'ouvre à la date de la cellule de référence, c'est ce qui nous semblait le plus pertinent .
Si la cellule est vide ou non conforme à une date, ce devrait être effectivement le mois et l'année en cours ....
En vérifiant le code je vois qu'en fait, on affiche le mois de Janvier par défaut et l'année 2025 .
Ci joint le classeur corrigé, je pense que @patricktoulon ne m'en voudra pas .

Pièce jointe migrée au #76
 
Dernière édition:
Dernier module corrigé :
la date du jour sera affichée en bleu pale
Comme les gouts et les couleurs diffèrent, les couleurs sont toujours paramétrables en début de module .
un petit pb de positionnement quand la date était en colonne 1 a été résolu également .
( je n'ai pas mis à jour le cartouche )
 

Pièces jointes

- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour