Icône de la ressource

VBA - Calendrier sur la base d'un UserForm V3

Dudu2

XLDnaute Barbatruc
Dudu2 a soumis une nouvelle ressource:

VBA - Calendrier sur la base d'un UserForm - Une fonction à appeler pour choisir une date dans le calendrier

Le fichier à télécharger contient:
  1. Le UserForm Calendrier à importer dans le projet VBA.
  2. Le Module_Test qui donne quelques exemples d'utilisation.
L'appel de la fonction:
VB:
Dim DateChoisie as Date
'
DateChoisie = UserForm_Calendrier.Display(...voir la description des paramètres dans le code...)

Les principales caractéristiques du calendrier:
  • ...

En savoir plus sur cette ressource...
 

sandralos

XLDnaute Nouveau
Bonjour,

tout d'abord merci infiniment pour ce fichier 🙏☺️

J'ai un petit soucis quand je l'intègre à mon fichier, je suis novice dans le VBA et pas trop bonne en anglais 🤪.
Lorsque j'essai de le mettre en route il me trouve une erreur et me met en surbrillance :
'------------
'Date choisie
'------------
Sub SetDateChoisie(ControlName)
'Valorisation de la variable globale
DateChoisie = DateSerial(Year(DateDisplay), Month(DateDisplay), Me.Controls(ControlName).Caption)

'Valorisation de l'objet cible
If Not p_TargetObject Is Nothing Then
On Error Resume Next
p_TargetObject.Value = Format(DateChoisie, p_TargetObjectEnglishDateFormat)

If Not Err.Number = 0 Then
Err.Clear
p_TargetObject.Caption = Format(DateChoisie, p_TargetObjectEnglishDateFormat)

If Not Err.Number = 0 Then
MsgBox "UserForm Calendrier - Fonction SetDateChoisie(): Impossible d'affecter la date au TargetObject !" & vbCrLf & vbCrLf & _
"Vérifier l'argument passé comme TargetObject."
End If
End If
On Error GoTo 0
End If

Call ChoixUtilisateurFait
End Sub

si une âme charitable peu m'expliquer le problème 🙏

Merci d'avance
Et bonne année 😉
 

Dudu2

XLDnaute Barbatruc
Bonjour,
Il faudrait que je puisse voir le fichier s'il n'est pas confidentiel.
Peux-tu le placer sur cjoint.com et m'envoyer le lien ?
 

sandralos

XLDnaute Nouveau
Bonjour,
Il faudrait que je puisse voir le fichier s'il n'est pas confidentiel.
Peux-tu le placer sur cjoint.com et m'envoyer le lien ?

Voila le lien du fichier

Donc le but étant d'avoir un calendrier qui s'affiche quand je clique dans la case date du formulaire pour sélectionner la date

et autre problème si jamais tu as la solution (ca fais 2 jours que je suis dessus 😅) j'aimerais que la case date de fin se débloque quand je sélectionne "plan de progrès" dans la combobox entretien et évidement que le calendrier s'affiche aussi pour sélectionner la date.

Je te remercie d'avance pour le temps que tu m'accorde.🙏😁
 

Dudu2

XLDnaute Barbatruc
Alors, tu n'as pas beaucoup lu...
En plus tu as modifié le code du UserForm Calendrier !

Il est d'abord écrit:
1704649152913.png

Tu as suivi le point 1 et tu as aussi importer le Module_Test sous le nom de ModuleCalendrier qui est simplement des exemples d'utilisation qui n'ont rien à voir avec ton code. Donc à supprimer de ton Projet VBA.

Ensuite il est écrit:
1704649393444.png

A aucun moment il est dit qu'il faut faire Calendrier.Show.

Et donc, conformément à ce qui est dit, les paramètres d'appel sont décrits dans la fonction:
VB:
' -----------------------
' Affichage du Calendrier
' -----------------------
' Dim DateChoisie as Date
'
' DateChoisie = Calendrier.Display( _
' Optional DateInitiale As Date = 0,                Date à l'ouverture du calendrier. Si 0, alors ouverture se fait à la date courante
' Optional AfficherJoursFériés As Boolean = False,  True pour afficher les jours fériés
' Optional Texte As String = "",                    Texte d'information à afficher en bas du calendrier
' Optional TexteBackColor As Long = -1,             Couleur de fond du texte
' Optional TexteForeColor As Long = -1,             Couleur de caractère du texte
' Optional Left As Double = xlNone, _               Position gauche en points du coin supérieur gauche du UserForm, Left = xlNone (défaut) pour centrage standard
' Optional Top As Double, _                         Position haute en points du coin supérieur gauche du UserForm
' Optional TargetObject As Variant = Nothing,       Objet (Cellule, Shape, UserForm.Control) où placer la date choisie
' Optional TargetObjectEnglishDateFormat As String = "dd/mm/yyyy",  Format anglais (cause VBA) de la date à placer dans le TargetObject
' Optional FonctionSurChoixUtilisateur As String = "",              Fonction utilisateur à appeler lorsqu'un choix est fait dans le UserForm Calendrier
'                                                                   Elle sera appelée avec comme argument la date choisie (as Date).
' Optional GarderOuvert As Boolean = False,         Indique s'il faut ou non garder ouvert le UserForm Calendrier après le choix d'une date
' Optional ShowMode As Integer = vbModal            Mode (vbModeless ou vbModal) d'ouverture du UserForm Calendrier
'                                                   Le mode vbModeless n'est accepté que si:
'                                                   - soit TargetObject est valorisé
'                                                   - soit FonctionSurChoixUtilisateur est valorisé
'                                                   Car la fontion retourne immédiatement 0 et la date choisie ne peut être captée que par ces 2 moyens
' ) As Date
'
' Remarque:
' --------
' Tous ces paramètres, excepté le ShowMode, sont modifiables par la fonction Calendrier.Modify()
'
' ------------
' Return value
' ------------
' Date choisie par l'utilisateur ou 0 si aucune date choisie
Et plus encore.

Au final, je vais regarder ton fichier et le corriger.
Mais si tu veux utiliser des outils, regarde d'abord la description de leur utilisation.
De plus si des exemples sont donnés (ce qui est le cas avec le Module_Test) essaie de t'en inspirer.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Il faut savoir qu'avec les UserForms c'est extrêmement difficile de vérifier une donnée tout de suite après sa saisie. C'est d'ailleurs le coté très pénalisant des UserForms.

Il y a 2 évènements sur le Control (TextBox par exemple) qui permettent de le faire:
- AfterUpdate()
- Exit() le principal avec son paramètre Cancel qui empêche de passer à autre chose en cas d'erreur.
C'est à la fois un avantage et un inconvénient, car un clic sur bouton Quitter par exemple, ne sera pas traité tant que l'évènement Exit() n'aura pas été lui-même exécuté avec Cancel = False. Et quand bien même il aura été exécuté avec Cancel = False, il faudra re-cliquer sur le bouton Quitter !!!

L'évènement Change() est déclenché à chaque entrée clavier et ne permet donc pas un contrôle de la valeur finale et ça reste compliqué de contrôler caractère après caractère. De plus il n'est bloquant sur le Control.

J'ai fait une ressource qui permet de traiter ce problème mais un débutant ne saurait pas la mettre en place.

Alors il ne reste qu'une solution simple: effectuer le contrôle des données sur la touche Valider.
C'est ce que j'ai juste complété dans ton code pour les dates.

Comme je ne suis pas sûr de tes formats de dates, j'ai créé une constante de compilation:
#Const ANNÉE_SUR_4CHIFFRES = True (True si jj/mm/aaaa, False si jj/mm/aa qui ne se fait plus trop)
 

Pièces jointes

  • Classeur.xlsm
    90 KB · Affichages: 17
Dernière édition:

sandralos

XLDnaute Nouveau
Il faut savoir qu'avec les UserForms c'est extrêmement difficile de vérifier une donnée tout de suite après sa saisie. C'est d'ailleurs le coté très pénalisant des UserForms.

Il y a 2 évènements sur le Control (TextBox par exemple) qui permettent de le faire:
- AfterUpdate()
- Exit() le principal avec son paramètre Cancel qui empêche de passer à autre chose en cas d'erreur.

L'évènement Change() est déclenché à chaque entrée clavier et ne permet donc pas un contrôle de la valeur finale et ça reste compliqué de contrôler caractère après caractère. De plus il n'est bloquant sur le Control.

J'ai fait une ressource qui permet de traiter ce problème mais un débutant ne saurait pas la mettre en place.

Alors il ne reste qu'une solution simple: effectuer le contrôle des données sur la touche Valider.
C'est ce que j'ai juste complété dans ton code pour les dates.

Comme je ne suis pas sûr de tes formats de dates, j'ai créé une constante de compilation:
#Const ANNÉE_SUR_4CHIFFRES = True (True si jj/mm/aaaa, False si jj/mm/aa qui ne se fait plus trop)
Merci infiniment !!!!!!!!!

Au top c'est pile ce que je voulais.


Merci encore
 

patricktoulon

XLDnaute Barbatruc
re
Bonjour @Dudu2
Il faut savoir qu'avec les UserForms c'est extrêmement difficile de vérifier une donnée tout de suite après sa saisie. C'est d'ailleurs le coté très pénalisant des UserForms.
je t'ai pourtant montrer plusieur fois que même avant la validation par enter ou l'exit ou l'afterupdate
il est tres facile d'intercepter la saisie pendant la saisie
 

Dudu2

XLDnaute Barbatruc
Salut @patricktoulon,
Je me souviens effectivement d'une discussion à ce sujet où tu prônais de faire ça sur l'Enter d'autres Controls mais rien de concluant sur la sortie de fin de saisie. On peut effectivement capter les _Change() ou les _KeyDown() mais à aucun moment on ne peut savoir, sauf sur l'_Exit() que la saisie du Control est terminée car l'utilisateur peut cliquer à tout moment dans un autre Control à sa guise.
Alors j'attends de voir ce que tu as en magasin.
 

patricktoulon

XLDnaute Barbatruc
re
sauf sur l'_Exit() que la saisie du Control est terminée car l'utilisateur peut cliquer à tout moment dans un autre Control à sa guise.
bien avant le exit avec le keydown et maxlength on peut contrôler touche par touche si le moindre caractère ne correspond pas a un format de chaine en particulier la touche peut être annulée et cela même avant le up de la touche
maintenant oui effectivement le seul ic c'est la saisie complète qui ne peut être valider qu'au exit
mais il y a une différence entre contrôler une saisie et le contrôle de la saisie complète
 

Dudu2

XLDnaute Barbatruc
Tu m'as fait penser que je devais simplifier la ressource qui permet de contourner ce problème.
Je suis assez fier de ce système car c'est un système qui permet de laisser passer l'évènement Exit() tout en captant un autre évènement dans la même séquence !
Elle possède toutefois un inconvénient qui est que sur tous les Controls CommandButtons Click(), il faut appeler une fonction qui permet de ne pas traiter l'évènement puisqu'un traitement d'erreur est en cours sur un Exit() d'un autre Control.
C'est peut-être améliorable avec une Classe sur le UserForm en interceptant ces évènements.
Ce que je ne sais pas (pas testé) c'est si la Classe du Userform artificiellement créée va couvrir / empêcher les mêmes évènements nativement programmés dans le UserForm par le développeur.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
les events d'une classe (dans un module classe ou classé dans le userform) n'ont rien a voir l'un avec l'autre
tu peux très bien avec un events d'origine exécutant un code
et même event l'event de la classe pour le même control exécutant un autre code
ça aussi je te l'ai déjà dit ;)
 

Discussions similaires

Statistiques des forums

Discussions
311 725
Messages
2 081 943
Membres
101 849
dernier inscrit
florentMIG