Boîtes de dialogue personnalisées sous Access

Thierry GASPERMENT

Enrichissez vos applications Access avec des boîtes de dialogue personnalisées.
Ces boîtes de dialogue basées sur des formulaires Access permettent une personnalisation complète de la saisie.

Commentez

- Titre : Boîtes de dialogue personnalisées sous Access

- Auteur : Thierry GASPERMENT

- Parution : 5 décembre 2013

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Thierry GASPERMENT. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.

Sommaire

- I. Boîtes de dialogue standards

- II. Création d'un formulaire pour une boîte de dialogue

- III. Ouverture du formulaire en mode dialogue

- IV. Ouverture du formulaire et attente de sa fermeture

- V. Fermeture de la fenêtre de dialogue sur minuterie

- VI. Création d'une fonction générique

- VII. Exemples

- VIII. Remerciements

I - Boîtes de dialogue standards

VBA fournit deux boîtes de dialogue : MsgBox et InputBox.
La première pour afficher un message et demander un choix à l'utilisateur (oui, non, annuler…).
La deuxième pour demander la saisie d'un texte.

Ces deux boîtes sont très limitées.
Il n'est par exemple pas possible de modifier la police de caractères ou les couleurs.
On ne peut pas non plus limiter la saisie avec un masque de saisie ou proposer un choix avec une liste de valeurs.

La solution pour proposer un dialogue plus ergonomique et sécurisé est de créer soit même des boîtes de dialogue avec des formulaires Access.

Pour une autre approche, vous pouvez également consulter ce tutoriel :
Créer un formulaire MSAccess MessageBox() paramétrable et auto-refermable.

II - Création d'un formulaire pour une boîte de dialogue

Créez un nouveau formulaire que l'on va nommer frmDiagInput1.
Lors de la création de ce formulaire, certaines propriétés par défaut ne sont pas appropriées à notre besoin.
Modifiez les propriétés du formulaire ainsi :

Propriété

Valeur

Description

Onglet Format

Barre défilement

Aucune

N'affiche pas de barre de défilement (à modifier en cas de boîte de dialogue de taille importante).

Afficher sélecteur

Non

Masque le sélecteur d'enregistrement à gauche.

Boutons de déplacement

Non

N'affiche pas les boutons de déplacement entre les enregistrements.

Diviseurs d'enregistrements

Non

N'affiche pas les lignes qui séparent chaque enregistrement.

Taille ajustée

Oui

Ajuste la taille du formulaire à son contenu.

Auto centrer

Oui

Centre le formulaire.

Style bordure

Trait simple fixe

Pas de redimensionnement possible.

Boutons MinMax

Aucun

N'affiche pas les boutons pour réduire ou agrandir le formulaire.

Onglet Autres

Fen indépendante

Oui

La fenêtre « flotte » par-dessus les autres.

Fen modale

Oui

Lorsqu'une fenêtre est modale, il n'est pas possible de cliquer sur une autre fenêtre tant que la première fenêtre est ouverte.

Le formulaire est totalement vierge et non redimensionnable.

Comme il est défini en fenêtre modale, on ne peut pas cliquer ailleurs que dans ce formulaire tant qu'il n'est pas fermé.

Sur ce formulaire vierge, ajoutez les contrôles nécessaires à la boîte de dialogue.

Nous allons commencer par une simple boîte semblable à une InputBox avec :

une étiquette lblMessage qui contient le texte d'information ;

- une zone de texte txtInput qui contient la saisie de l'utilisateur ;

- deux boutons de commande btnOK et btnCancel pour respectivement valider ou annuler la saisie.

Vous pouvez bien sûr personnaliser la boîte de dialogue en modifiant par exemple la couleur de fond et les polices de caractères.

Mettez la zone de texte txtInput en premier contrôle dans l'ordre de tabulation (menu Affichage => Ordre de tabulation…) pour ce contrôle soit actif à l'ouverture du formulaire.

III - Ouverture du formulaire en mode dialogue

Dans ce chapitre, nous allons utiliser des variables globales.
Dans le chapitre suivant, nous aborderons une méthode plus robuste et plus souple.

Créez un module standard :

- dans l'éditeur VBA (ALT + F11) ;

- dans le menu : Insertion => Module.

Dans ce module on va créer une fonction qui ouvre notre formulaire de dialogue.

Function TestDialog1()
' Ouverture du formulaire en mode dialogue
DoCmd.OpenForm "frmDiagInput1", , , , , acDialog
End Function

Le paramètre acDialog permet de demander à VBA d'attendre que le formulaire soit fermé avant de continuer l'exécution du code.

Problèmes :

- on ne peut pas agir sur le formulaire depuis la procédure appelante TestDialog1 (pour par exemple modifier le titre, l'étiquette…) ;

- lorsque la procédure reprend, le formulaire est fermé et donc on ne peut plus lire la valeur saisie.

Pour pouvoir dialoguer entre la procédure appelante et le formulaire, on peut utiliser des variables globales.

Nous aurions pu utiliser la propriété OpenArgs de la méthode OpenForm.
Mais cette propriété n'accepte que du texte et ne permet pas de passer plusieurs valeurs facilement.
De plus la méthode OpenForm ne permet pas d'avoir un retour d'information.
Quitte à utiliser des variables globales pour le retour, on va donc les utiliser également pour l'aller…

Dans un nouveau module standard, que nous nommerons par exemple ModDialog, on définit trois variables :

Public gDiagCaption As String ' Titre de la fenêtre
Public gDiagValeur As String ' Valeur saisie
Public gDiagOK As Boolean ' Valeur validée

Ces variables sont publiques pour pouvoir être lues ou modifiées à la fois depuis la procédure appelant le formulaire de dialogue et depuis ce formulaire.

Avant d'ouvrir le formulaire, il est nécessaire d'initialiser ces variables :

' Initialisation des variables
gDiagCaption = "Ma fenêtre de saisie"
gDiagValeur = "Valeur par défaut"
gDiagOK = False

Ensuite, dans le formulaire, il faut gérer ces variables.

Ajoutez une procédure sur ouverture du formulaire :

- dans l'onglet Événement du formulaire ;

- sur la ligne Sur ouverture, choisir [Procédure événementielle] et cliquer sur les trois points à droite.

Dans la procédure qui est créée, on ajoute le code à exécuter à l'ouverture du formulaire :

- mise à jour du titre de la fenêtre ;

- mise à jour de la valeur saisie par défaut.

Private Sub Form_Open(Cancel As Integer)
Me.Caption = gDiagCaption ' Titre
Me.txtInput.Value = gDiagValeur ' Valeur par défaut
End Sub

Puis on gère les clics sur les boutons (événement Sur clic de chaque bouton).

Pour le bouton « Valider » (btnOK) :

- on met à jour la variable gDiagValeur avec la valeur contenue dans la zone de saisie (avec Nz pour gérer la valeur Null) ;

- on met le flag gDiagOK à Vrai, ce qui indiquera à la procédure appelante qu'on a validé la saisie ;

- on ferme le formulaire.

Pour le bouton « Annuler » (btnCancel) :

- on vide la variable gDiagValeur ;

- on ferme le formulaire.

' Sur clic sur Valider
Private Sub btnOK_Click()
gDiagValeur = Nz(Me.txtInput.Value) ' Valeur de la zone de texte
gDiagOK = True ' Flag OK
DoCmd.Close acForm, Me.Name ' Ferme le formulaire
End Sub

' Sur clic sur Annuler
Private Sub btnCancel_Click()
gDiagValeur = "" ' Pas de valeur retournée
DoCmd.Close acForm, Me.Name ' Ferme le formulaire
End Sub

Il est enfin facile de récupérer les valeurs de ces trois variables dans la procédure appelante.

Function TestDialog1()
' Initialisation des variables
gDiagCaption = "Ma fenêtre de saisie"
gDiagValeur = "Valeur par défaut"
gDiagOK = False
' Ouverture du formulaire en mode dialogue
DoCmd.OpenForm "frmDiagInput1", , , , , acDialog
' Test de la saisie
If gDiagOK Then
' si gDiagOK = True alors gDiagValeur contient la valeur saisie et validée
MsgBox "Valeur saisie : " & gDiagValeur
Else
' si gDiagOK = False alors gDiagValeur est vide, la saisie a été annulée
MsgBox "Saisie annulée"
End If
End Function

Attention à l'utilisation de variables globales.
Si elles ne sont pas correctement (et toutes) initialisées, cela peut entraîner des bogues dans le déroulement du traitement.

IV - Ouverture du formulaire et attente de sa fermeture

La méthode utilisée dans ce chapitre permet de :

- se passer de variables globales ;

- agir sur le formulaire (titre, valeur de contrôle, couleur…) avant son affichage ;

- ouvrir des boîtes de dialogue en cascade en utilisant le même formulaire.

Créez un formulaire frmDiagInput2 comme expliqué dans le chapitre  Création d'un formulaire pour une boîte de dialogue.

Il faut ensuite dans un premier temps ajouter un module au formulaire.
Dans les propriétés du formulaire, onglet Autres, définissez la propriété Avec module à Oui.

Vous pouvez alors voir dans l'explorateur de projet VBA le module attaché au formulaire, du nom du formulaire préfixé par Form_.

C'est ce module qui va nous servir à créer un nouvel objet formulaire.

Dans une nouvelle fonction, on crée un nouvel objet de type Form_frmDiagInput2.

Function TestDialog2()
' Création du formulaire
With New Form_frmDiagInput2
.Visible = True
End With
End Function

L'utilisation de With...End With est très pratique, car il n'est alors pas nécessaire de rappeler le nom de l'objet à chaque appel de méthode ou propriété.

Si vous n'avez pas l'habitude de cette instruction, l'équivalent avec la déclaration d'un objet est :

Function TestDialog2()
Dim loForm as Form_frmDiagInput2
Set loForm = New Form_frmDiagInput2
loForm.Visible = True
Set loForm = Nothing
End Function

Notez qu'un formulaire créé de cette manière avec New n'est pas visible par défaut.
Il faut définir sa propriété Visible pour qu'il soit affiché.
Cela permet d'ailleurs de faire des modifications sur le formulaire avant de l'afficher, par exemple :

Function TestDialog2()
' Création du formulaire
With New Form_frmDiagInput2
' Titre de la fenêtre
.Caption = "Ma saisie personnalisée"
' Message dans l'étiquette
.lblMessage.Caption = "Veuillez saisir une valeur..."
' Valeur par défaut dans la zone de texte
.txtInput.Value = "Valeur par défaut"
' Rend visible le formulaire
.Visible = True
End With
End Function

Si vous exécutez la procédure dans cet état, le formulaire s'ouvre et se referme aussitôt.
En effet, après l'instruction End With, l'objet représentant le formulaire est détruit (équivalent de Set loForm = Nothing).

Il faut maintenant mettre en place une attente dans notre code, afin qu'on puisse récupérer la valeur saisie avant que le formulaire ne se ferme.

L'astuce est de ne pas laisser le formulaire se fermer, mais le rendre invisible à la place.
Sur clic sur les boutons de validation et d'annulation, on masquera le formulaire avec .Visible = False.

Pour la fermeture du formulaire (que l'on gérera dans l'événement Sur libération) :

- si l'utilisateur ferme le formulaire avec le bouton de fermeture de la fenêtre : on va annuler sa fermeture et le rendre invisible à la place ;

- si la tentative de fermeture émane de la procédure appelante : on le laissera se fermer (ce qui sera le cas après le End With).

On sait si la fermeture est demandée par l'utilisateur ou par le code appelant en vérifiant la propriété Visible du formulaire.

Le formulaire invisible est toujours chargé et accessible par code VBA.

Dans l'événement Sur libération du formulaire, ajoutez le code nécessaire :

' Sur libération du formulaire
Private Sub Form_Unload(Cancel As Integer)
If Me.Visible Then ' Si le formulaire est visible
Me.Visible = False ' On le rend invisible
Cancel = True ' Et on annule sa fermeture
End If
End Sub

Puis ajoutez dans le formulaire une petite fonction d'attente.

' Attente de saisie
Public Sub DiagWait()
Do While Me.Visible = True
DoEvents
Loop
End Sub

Le code boucle tant que le formulaire est visible.
L'instruction DoEvents est indispensable pour redonner la main à l'application durant l'exécution du code.

Cette fonction d'attente sera exécutée par la fonction appelante qui attendra la fin de cette fonction avant de poursuivre :

Function TestDialog2()
' Création du formulaire
With New Form_frmDiagInput2
' Titre de la fenêtre
.Caption = "Ma saisie personnalisée"
' Message dans l'étiquette
.lblMessage.Caption = "Veuillez saisir une valeur..."
' Valeur par défaut dans la zone de texte
.txtInput.Value = "Valeur par défaut"
' Rend visible le formulaire
.Visible = True
' Attend la saisie
.DiagWait
End With
End Function

Puis on gère les clics sur les boutons (événement Sur clic de chaque bouton) :

Pour pouvoir ensuite déterminer si on a cliqué sur le bouton Valider ou non, on ajoute dans le code du formulaire une variable gDiagOK.
Cette valeur sera à Faux par défaut ; on la mettra à Vrai sur clic sur le bouton de validation.
Cette variable sera publique, mais sa durée de vie est de niveau module.
C'est-à-dire qu'elle est initialisée automatiquement à chaque ouverture du formulaire.
On n'a donc pas à la mettre explicitement à Faux.

La déclaration de variable suivante est à écrire en début du code du formulaire :

Public DiagOK As Boolean ' Flag pour validation

Pour le bouton « Valider » (btnOK) :

- on met à jour la variable gDiagOK, ce qui indiquera à la procédure appelante qu'on a validé la saisie ;

- on masque le formulaire.

Pour le bouton « Annuler » (btnCancel) :

- on masque le formulaire.

Masquer le formulaire permet de mettre fin à la boucle d'attente DiagWait tout en conservant le formulaire accessible par VBA.

' Sur clic sur Valider
Private Sub btnOK_Click()
DiagOK = True ' Flag OK
Me.Visible = False ' Masque le formulaire
End Sub

' Sur clic sur Annuler
Private Sub btnCancel_Click()
Me.Visible = False ' Masque le formulaire
End Sub

Il est enfin facile de récupérer dans la procédure appelante toutes les valeurs souhaitées.

Function TestDialog2()
' Création du formulaire
With New Form_frmDiagInput2
' Titre de la fenêtre
.Caption = "Ma saisie personnalisée"
' Message dans l'étiquette
.lblMessage.Caption = "Veuillez saisir une valeur..."
' Valeur par défaut dans la zone de texte
.txtInput.Value = "Valeur par défaut"
' Rend visible le formulaire
.Visible = True
' Attend la saisie
.DiagWait
' Test de la saisie
If .DiagOK Then
' si DiagOK = True => on a validé
MsgBox "Valeur saisie : " & Nz(.txtInput.Value)
Else
' si DiagOK = False =>  la saisie a été annulée
MsgBox "Saisie annulée"
End If
End With
End Function

Le formulaire de dialogue est tout à fait opérationnel.
Cependant, on a écrit une boucle d'attente qui a tendance à occuper le processeur.
Faites l'expérience en regardant le processus msaccess.exe dans le gestionnaire des tâches.
Le processeur est très sollicité alors qu'il ne se passe pas grand-chose.

Pour éviter cela on va ajouter un appel à une API Windows qui va attendre l'arrivée d'un message avant de redonner la main à notre code.
Cette API est WaitMessage.
Déclarez-la en début du module du formulaire :

#If VBA7 Then
Private Declare PtrSafe Sub WaitMessage Lib "USER32" ()
#Else
Private Declare Sub WaitMessage Lib "USER32" ()
#End If

Les déclarations précédentes fonctionnent avec Office 32bits et 64bits.

Et on ajoute donc un appel à cette fonction avant le DoEvents.

' Attente de saisie
Public Sub DiagWait()
Do While Me.Visible = True
WaitMessage
DoEvents
Loop
End Sub

Notre boîte de dialogue est maintenant terminée !

Voici le code complet du formulaire :

Option Compare Database
Option Explicit

#If VBA7 Then
Private Declare PtrSafe Sub WaitMessage Lib "USER32" ()
#Else
Private Declare Sub WaitMessage Lib "USER32" ()
#End If

Public DiagOK As Boolean ' Flag pour validation

' Sur clic sur Valider
Private Sub btnOK_Click()
DiagOK = True ' Flag OK
Me.Visible = False ' Masque le formulaire
End Sub

' Sur clic sur Annuler
Private Sub btnCancel_Click()
Me.Visible = False ' Masque le formulaire
End Sub

' Sur libération du formulaire
Private Sub Form_Unload(Cancel As Integer)
If Me.Visible Then ' Si le formulaire est visible
Me.Visible = False ' On le rend invisible
Cancel = True ' Et on annule sa fermeture
End If
End Sub

' Attente de saisie
Public Sub DiagWait()
Do While Me.Visible = True
WaitMessage
DoEvents
Loop
End Sub

Et celui de la fonction appelante :

Function TestDialog2()
' Création du formulaire
With New Form_frmDiagInput2
' Titre de la fenêtre
.Caption = "Ma saisie personnalisée"
' Message dans l'étiquette
.lblMessage.Caption = "Veuillez saisir une valeur..."
' Valeur par défaut dans la zone de texte
.txtInput.Value = "Valeur par défaut"
' Rend visible le formulaire
.Visible = True
' Attend la saisie
.DiagWait
' Test de la saisie
If .DiagOK Then
' si DiagOK = True => on a validé
MsgBox "Valeur saisie : " & Nz(.txtInput.Value)
Else
' si DiagOK = False =>  la saisie a été annulée
MsgBox "Saisie annulée"
End If
End With
End Function

Un peu perdu ?
Voici le déroulement du code en résumé :

- Création du formulaire
Le formulaire est invisible ;

- modification du formulaire
Modification des textes, des couleurs… ;

- affichage du formulaire ;

- boucle d'attente de saisie
A partir de ce point, on attend que le formulaire soit rendu invisible.
La procédure appelante est en attente ;

- saisie par l'utilisateur
L'utilisateur effectue la saisie dans la zone de texte (la saisie est possible grâce au DoEvents) ;

- validation par l'utilisateur de la saisie ou annulation
Si clic sur un des boutons, le formulaire est rendu invisible.
Si tentative de fermeture du formulaire, celui-ci est rendu invisible et la fermeture est annulée ;

- récupération des données saisies
La procédure DiagWait prend fin lorsque le formulaire est rendu invisible.
Le formulaire invisible étant toujours ouvert, on peut lire son contenu (contrôles, variables…) ;

- fermeture du formulaire
Le formulaire est fermé lorsque l'objet Form_frmDiagInput2 est détruit (après le End With).
Dans la procédure de déchargement du formulaire (Form_Unload), la fermeture n'est pas annulée, car le formulaire est invisible à ce stade.

Et en image :

Cette boîte de dialogue est simple, mais la méthode permet de faire beaucoup plus complexe.
On peut enrichir le formulaire à loisir.

V - Fermeture de la fenêtre de dialogue sur minuterie

Dans ce chapitre, nous ajoutons une fermeture automatique du formulaire après un délai défini.
On affichera également le temps restant avant la fermeture.

Modifiez pour cela le formulaire frmDiagInput2 du chapitre précédent.

Dans l'onglet Événement des propriétés du formulaire, définissez la propriété Intervalle minuterie par exemple à 5000.
Cette valeur est exprimée en millisecondes, donc 5000 correspond à 5 secondes.

Générez ensuite la procédure de l'événement Sur minuterie.

Lorsque la minuterie se déclenche, on va exécuter les mêmes opérations que sur un clic sur le bouton d'annulation.

' Sur minuterie
Private Sub Form_Timer()
btnCancel_Click ' Exécute la même procédure que sur clic sur Annuler
End Sub

Ensuite, pour être sûr que la minuterie ne va pas se déclencher une nouvelle fois, il faut initialiser la propriété Intervalle minuterie avant de rendre la main à la procédure appelante.
En effet le formulaire est rendu invisible mais est toujours chargé.
Le traitement pourrait se poursuivre dans la procédure appelante pendant plusieurs secondes avant de définitivement fermer le formulaire.

' Attente de saisie
Public Sub DiagWait()
Do While Me.Visible = True
WaitMessage
DoEvents
Loop
Me.TimerInterval = 0 ' Ajoutez ici l'arrêt de la minuterie
End Sub

Affichez la fenêtre de dialogue en exécutant la fonction TestDialog2 créée au chapitre précédent.
La fenêtre se referme après 5 secondes.

Cette méthode est très simple, mais on préférait pouvoir paramétrer le délai et visualiser le nombre de secondes restantes.

Pour faire cela on va d'abord réinitialiser la propriété Intervalle minuterie du formulaire à 0.

Ensuite définissez une variable (au début du code du formulaire) destinée à contenir le nombre de secondes restantes.

Private gMinuterie As Long ' Nombre de secondes avant fermeture

Cette variable va être initialisée avec le nombre de secondes à attendre, puis décrémentée à chaque seconde.

Ajoutez une propriété (en écriture) au formulaire :

' Initialisation de la minuterie
Public Property Let DiagMinuterie(pSec As Long)
End Property

DiagMinuterie est le nom de la propriété.
pSec est la valeur que l'on affecte à cette propriété.
Let signifie que c'est une propriété en écriture.

C'est-à-dire qu'on écrira :

LeFormulaire.DiagMinuterie = 10

Pour déclencher la propriété DiagMinuterie avec la valeur pSec = 10.

Dans le code de cette propriété, on va initialiser notre variable gMinuterie avec la valeur affectée à pSec.
Puis on définit l'intervalle de minuterie à 1000 pour déclencher l'événement Sur minuterie chaque seconde.

' Initialisation de la minuterie
Public Property Let DiagMinuterie(pSec As Long)
gMinuterie = pSec ' Nombre de secondes à attendre
Me.TimerInterval = 1000 ' Minuterie déclenchée chaque seconde
End Property

Et on modifie la procédure de l'événement Sur minuterie du formulaire (Form_Timer).

' Sur minuterie
Private Sub Form_Timer()
' Décrémente le délai
gMinuterie = gMinuterie - 1
' Modifie le texte du bouton Annuler
Me.btnCancel.Caption = "Annuler (" & gMinuterie & ")"
If gMinuterie = 0 Then
' Exécute la même procédure que sur clic sur Annuler
btnCancel_Click
End If
End Sub

On commence par décrémenter le délai.
Puis on modifie le texte du bouton Annuler pour ajouter le temps restant.
Et enfin si ce temps restant est arrivé à zéro, on exécute le code du bouton d'annulation pour annuler la saisie.

Pour finir, on initialise le délai dans la procédure appelante à l'aide la propriété DiagMinuterie.
Le délai est défini juste avant de rendre le formulaire visible.

' Délai avant fermeture
.DiagMinuterie = 5

Notre boîte de dialogue est maintenant autorefermable !

Voici le code complet du formulaire :

Option Compare Database
Option Explicit

#If VBA7 Then
Private Declare PtrSafe Sub WaitMessage Lib "USER32" ()
#Else
Private Declare Sub WaitMessage Lib "USER32" ()
#End If

Public DiagOK As Boolean ' Flag pour validation
Private gMinuterie As Long ' Nombre de secondes avant fermeture

' Initialisation de la minuterie
Public Property Let DiagMinuterie(pSec As Long)
gMinuterie = pSec ' Nombre de secondes à attendre
Me.TimerInterval = 1000 ' Minuterie déclenchée chaque seconde
End Property

' Sur clic sur Valider
Private Sub btnOK_Click()
DiagOK = True ' Flag OK
Me.Visible = False ' Masque le formulaire
End Sub

' Sur clic sur Annuler
Private Sub btnCancel_Click()
Me.Visible = False ' Masque le formulaire
End Sub

' Sur minuterie
Private Sub Form_Timer()
' Décrémente le délai
gMinuterie = gMinuterie - 1
' Modifie le texte du bouton Annuler
Me.btnCancel.Caption = "Annuler (" & gMinuterie & ")"
If gMinuterie = 0 Then
' Exécute la même procédure que sur clic sur Annuler
btnCancel_Click
End If
End Sub

' Sur libération du formulaire
Private Sub Form_Unload(Cancel As Integer)
If Me.Visible Then ' Si le formulaire est visible
Me.Visible = False ' On le rend invisible
Cancel = True ' Et on annule sa fermeture
End If
End Sub

' Attente de saisie
Public Sub DiagWait()
Do While Me.Visible = True
WaitMessage
DoEvents
Loop
Me.TimerInterval = 0 ' Arrête la minuterie
End Sub

Et celui de la fonction appelante :

Function TestDialog2()
' Création du formulaire
With New Form_frmDiagInput2
' Titre de la fenêtre
.Caption = "Ma saisie personnalisée"
' Message dans l'étiquette
.lblMessage.Caption = "Veuillez saisir une valeur..."
' Valeur par défaut dans la zone de texte
.txtInput.Value = "Valeur par défaut"
' Délai avant fermeture
.DiagMinuterie = 5
' Rend visible le formulaire
.Visible = True
' Attend la saisie
.DiagWait
' Test de la saisie
If .DiagOK Then
' si DiagOK = True => on a validé
MsgBox "Valeur saisie : " & Nz(.txtInput.Value)
Else
' si DiagOK = False =>  la saisie a été annulée
MsgBox "Saisie annulée"
End If
End With
End Function

VI - Création d'une fonction générique

Si vous utilisez plusieurs fois un même formulaire de saisie, vous ne souhaitez sans doute pas écrire de code complexe à chaque appel de ce formulaire.

Vous pouvez créer une petite fonction réutilisable, un peu comme la fonction InputBox de VBA.

Par exemple pour une fenêtre de saisie avec paramétrage de :

- le texte d'invite (Prompt) ;

- le titre de la fenêtre (Title) ;

- la valeur par défaut (Default) ;

- le masque de saisie (InputMask) ;

- la minuterie avant fermeture (TimeOut).

En reprenant le formulaire frmDiagInput2 du chapitre précédent, voici un exemple de fonction réutilisable :

Function InputBoxMask(Prompt As String, Optional Title As String, Optional Default As String, Optional InputMask As String, Optional TimeOut As Long) As String
' Création du formulaire
With New Form_frmDiagInput2
' Titre de la fenêtre
.Caption = Prompt
' Message dans l'étiquette
.lblMessage.Caption = Title
' Valeur par défaut dans la zone de texte
.txtInput.Value = Default
' Masque de saisie
.txtInput.InputMask = InputMask
' Délai avant fermeture
.DiagMinuterie = TimeOut
' Rend visible le formulaire
.Visible = True
' Attend la saisie
.DiagWait
' Test de la saisie
If .DiagOK Then
' si DiagOK = True => on a validé
InputBoxMask = Nz(.txtInput.Value)
Else
' si DiagOK = False =>  la saisie a été annulée
InputBoxMask = ""
End If
End With
End Function

Il suffit ensuite d'appeler cette boîte de saisie comme une InputBox standard.

Pour un mot de passe

vMotDePasse = InputBoxMask("Mot de passe :", "Demande d'accès", "","Password",10)

On affiche un formulaire de saisie de mot de passe grâce au masque de saisie Password qui cache le texte de saisie :

VII - Exemples

Télécharger la base de données d'exemples.

Elle contient les formulaires et codes de cet article.

Vous y trouverez également un exemple de saisie dans une zone de liste :

Et un exemple de saisie de date avec un calendrier :

VIII - Remerciements

Merci à tous ceux qui m'ont aidé à améliorer ce tutoriel par leur relecture technique ou orthographique.