Une alternative à MsgBox (Ancienne version)

Alternative à MsgBox()

Bonjour à tous,

Voici, pour les férus de VBA, une alternative à la fameuse boîte de dialogue MsgBox(). Non que cette dernière ne soit pas utile, on est bien content de l'avoir, mais elle ne permet pas tout. Comme par exemple afficher des messages "Furtifs", que s'affichent et disparaissent au bout d'un certain temps, du texte long sur une seule ligne, de la couleur dans le message, des caractères de tailles différentes, des fenêtres plus grandes, etc.

La fonction "Dialogue" proposée ici, remplace la MsgBox(), et permet au développeur de définir ses propres choix pour l'affichage des messages. Ceux-ci sont définis au cœur même de la fonction ; ce qui en simplifie la gestion et permet une utilisation multiple du même message.

La fonction se charge, à partir du message (et de ses paramètres), de préparer le formulaire "Message" (hauteur/largeur), de centrer le message (les labels), de faire apparaître l'image associée et de placer les boutons demandés. Après validation par l'utilisateur final , elle retourne une valeur correspondant au bouton sélectionné ou un zéro pour signaler un abandon par la touche Echap ou une fermeture du formulaire par la croix.

Exemples d'appel de la fonction :

Var = Dialogue (N° Message, Type de validation)

If Dialogue (N° message, Type de validation) Then …

Select case Dialogue (N° message, Type de validation) …

Etc.

Var : C'est une variable numérique (Byte ou Integer) qui reçoit la réponse (0 à 3).

N° message : C'est le numéro du message défini dans la fonction.

Type de validation : Prend la valeur 0, 1, 2 ou 3 soit :

0 = Message Furtif (passant), celui-ci est affiché sans bouton et après un temps d'attente (1 seconde), la fenêtre disparaît en remontant vers le haut.

1 = Message avec validation par un bouton (Vu par défaut). Après validation, et comme pour la commande 0, la fenêtre disparaît en remontant vers le haut.

2 = Message avec choix de validation sur 2 boutons : Oui et Non (par défaut).

3 = Message avec choix de validation sur 3 boutons : Oui, Non et Abandon (par défaut).

Les boutons sont définis avec ces contenus par défaut En fonction du message, le texte de chaque bouton pourra être adapté à la situation (paramètres additionnels lors de la définition du message).

Valeurs Retournées par la fonction :

La fonction retourne le n° du bouton sélectionné (1, 2 ou 3) ou 0 pour un message "Furtif", l'utilisation de la touche Echap ou la fermeture du formulaire par la croix. D'où l'importance du nom des boutons.

Le bouton 1 (CommandButton1) sera égal à "Vu" pour un appel de type 1. Il sera centré dans la fenêtre. Pour un appel de type 2 ou 3, il sera égal à "Oui" (sauf si le texte est redéfini). Ce sera le 1er bouton dans la fenêtre en partant de la gauche.

Le bouton 2 (CommandButton2) sera égal à "Non" pour un appel de type 2 ou 3 (sauf si le texte est redéfini). Il sera placé à droite du bouton 1. Il sera ignoré pour les appels de type 0 ou 1.

Le bouton 3 (CommandButton3) sera égal à "Abandon" pour un appel de type 3 (sauf si le texte est redéfini). Il sera placé à droite du bouton 2. Il sera ignoré pour les appels de type 0, 1 et 2.

Les boutons sont placés en ligne, en bas de la fenêtre et centrés.

Récapitulatif :

Type de validationBouton 1
CommandButton1
Bouton 2
CommandButton2
Bouton 3
CommandButton3
Valeur Retournée
0Non visibleNon visibleNon visible0
1Visible & = "Vu"Non visibleNon visible1
2Visible & = "Oui"Visible & = "Non"Non visible1 ou 2
3Visible & = "Oui"Visible & = "Non"Visible & = "Abandon"1, 2 ou 3
Valeur retournée si sélection123

Exemples d'appels et résultat à l'écran :

M=Dialogue(1,0) – Affiche le message n° 1 en mode "Furtif". Il disparaît après 1,5 minute d'attente.

image

M=Dialogue(2,1) – Message n°2 avec validation "Vu" et 2ème ligne en Italique

image

M=Dialogue(3,2) – Message n°3 avec validation "Oui/Non" et 2ème ligne en rouge

image

M=Dialogue(4,3) – Message n°4 avec validation par 3 boutons. Ici le texte des boutons et la taille ont été redéfinis.

image

Avec ajout d'informations au message :
Dans la procédure appelante :

Mtxt(1) = "A1": Mtxt(2) = Format(Cells(1, 1), Fmt) ' Données pour le message

M=Dialogue(5,1)

image

Concernant les informations transmises à la fonction, j'ai personnellement fait le choix de passer par un tableau plutôt que d'inclure les données sources directement dans le message concerné. Ceci pour plusieurs raisons :

L'insertion des données sources dans le message alourdit le code de la fonction, rend la procédure appelante moins lisible (à moins de commenter suffisamment) et interdit l'usage du message pour une autre procédure. Dans l'exemple présenté, le message ne serait valable que pour une cellule "A1"

Autre exemple avec un message très long

Dans la procédure appelante :

Mtxt(1) = ActiveSheet.Name

M = Dialogue(6, 1)

image

(Le texte aurait pu être placé sur 2 lignes, en ajoutant un retour ligne dans le message. Cet exemple montre que le formulaire s'adapte au message et peut faire la largeur de l'écran)

Le formulaire et la fonction

Fournis en fichiers joints, ces deux éléments sont prêts à l'emploi. Pour les implémenter dans votre programme, il suffit d'importer le formulaire dans votre projet avec vos autres formulaires (Nom des fichiers : Message.frm & frx). Pour le code de la fonction (Nom du fichier : Module2.bas), il peut être importé tel quel et s'ajoutera au projet en tant que Module2. Vous pouvez aussi copier le code dans un module existant (en déplaçant les déclarations en tête de module).

Le Formulaire

image

On y trouve tous les contrôles utilisés par la fonction. La plupart des propriétés ont été fixées par défaut. La taille et le positionnement n'ont ici aucune importance (y compris pour le formulaire) puisque c'est la fonction qui se charge de cette tâche. Excepté pour les boutons, la taille et le style pourront être modifiés ; le positionnement sera effectué par la fonction

Les images sont numérotées de 1 à 4 : Image1=Sens interdit, Image2=Interrogation Image3=Exclamation, Image4=Information

C'est ce nom qui sera utilisé pour le paramétrage des messages.

Les labels 1 & 2 serviront au texte du message. Ici on utilise 2 labels pour pouvoir varier la présentation (par exemple le Label1 en noir et le Label2 en rouge). L'usage du Label2 est facultatif ; on peut se servir uniquement du Label1 en incluant au texte des retours chariot (Chr$(13)) pour une présentation sur plusieurs lignes. Par défaut le texte est centré, il peut être aligné à droite dans la définition du message.

Les Boutons, au nombre de trois, sont numérotés dans l'ordre :

CommandButton1 pour "Oui"

CommandButton2 pour "Non"

CommandButton3 pour "Abandon"

Leur taille est définie en 'dur' dans le formulaire. Au besoin on pourra la modifier au moment du paramétrage du message (lors du changement de texte par exemple). Cependant elle devra être identique pour les 3 boutons.

Le texte du bouton 1 ("Oui") ne devra pas être modifié (dans les propriétés). Pour le type d'appel 1 (validation avec un bouton), la fonction teste sa valeur (Caption) pour déterminer son texte.

Si = "Oui", il devient Vu sinon il est affiché en l'état.

Tous les contrôles sont masqués par défaut (Visible=False).

La Fonction

Le code étant suffisant commenté, je me contenterai de parler des différentes phases de traitement.

A l'entrée, les variables locales (Loc1 & Loc2) sont réaffectées aux variables publiques M1 et M2. Ainsi leurs valeurs peuvent être réutilisées ailleurs (notamment dans le code du formulaire).

Phase 1 :

Le formulaire et les labels sont agrandis pour éviter les décalages de texte. Les labels sont vidés de leur contenu (pour test au positionnement).

Phase 2 :

Définition des différents messages : Ils sont intégrés au cœur d'une instruction "Select Case". Le n° du message correspondra à la valeur testée.

A minima, un message sera composé des données suivantes :

.Label1="Texte du label 1…" : .Caption="Titre de la fenêtre" : Set Img= nom de l'image

Toutes les opérations se trouvant à l'intérieur d'une instruction de type "With", le point "." devant les contrôles est obligatoire.

L'instruction "Set" affecte à l'objet "Img" (de type Image) le contenu "Picture" de l'image choisie.

Tout ce qui suit est optionnel :

  • Utilisation du label2
  • Modification des styles
  • Redéfinitions des boutons (taille, texte …)

Des exemples sont fournis dans la fonction. Plus 2 messages pour le traitement des anomalies

Exemple de message plus élaboré : (également fourni dans la fonction)

Case 7
  .Label1 = "Texte label1 centré, en gros caractères, sur 2 lignes et en bleu (1ère ligne)" & Chr$(13) & "2ème ligne"
  .Label1.Font.Size = .Label1.Font.Size + 4: .Label1.ForeColor = &HC00000
  .Label2 = "Texte label2 aligné à gauche, en italique sur 3 lignes et en rouge (1ère ligne) ********************" & _
             Chr$(13) & "2ème ligne ********************" & Chr$(13) & "3ème ligne ********************"
  .Label2.TextAlign = fmTextAlignLeft: .Label2.Font.Italic = True: .Label2.ForeColor = &HFF&
  .CommandButton1.Caption = "Choix n°1": .CommandButton1.Width = 100
  .CommandButton2.Caption = "Choix n°2": .CommandButton2.Width = 100
  .CommandButton3.Caption = "Choix n°3": .CommandButton3.Width = 100
  .Caption = "Test": Set Img = .Image4

Ce qui donne à l'écran :

image

Exemple (simple !) d'utilisation du message d'erreur :

' Ouverture du fichier
On Error Resume Next
Workbooks.Open "Toto.xlsm"
M = Err.Number: Mtxt(1) = " n° : " & M & " - " & Err.Description  ' Sauve l'erreur et prépare le message
On Error GoTo 0
If M <> 0 Then
    ' Erreur détectée
    If M = 1004 Then
        ' Fichier absent
        M = Dialogue(2, 1)
        Exit Sub
    Else
        ' Autre erreur
        M = Dialogue(99, 1)
        Stop    ' ou autre traitement
    End If
End If

Phase 3 :

Mise en forme du formulaire :

La hauteur est déterminée par la taille du label1 (heigth) + taille du label2 (si <>"") + la taille des boutons (si boutons) + marges au-dessus et au-dessous.

Quant à la largeur, elle prend en compte la taille du plus grand label ou des boutons (avec espacements), de l'image et des marges de présentation (pour le visuel).

Phase 4 :

Les différents contrôles sont rendus visibles et placés dans la fenêtre du formulaire. Les labels sont centrés en largeur et positionnés en hauteur en tenant compte des marges et de la présence de boutons. L'image choisie (Img) est copiée dans l'image1 (Picture) et centrée en hauteur avec une marge à gauche. Seule l'image 1 est utilisée pour l'affichage.

Les boutons (si boutons) sont centrés en largeur avec un espace entre chaque. En hauteur ils sont placés à 10p au-dessus du bord inférieur de la fenêtre.

Phase 5 :

Le formulaire est affiché à l'écran selon le type de validation choisi : Modal pour les types 1,2 et 3, Non Modal pour le type 0.

Il est centré en largeur mais pas en hauteur. Pour un meilleur visuel, il est placé plus haut dans la fenêtre.

Pour un message "Furtif", il est affiché pendant 1,5 seconde puis disparaît en remontant vers le haut.

Pour les messages avec boutons, il disparait de la même façon après validation par l'utilisateur.

Phase finale :

Les variables sont remises à zéro et la fonction retourne à la procédure appelante le résultat. Soit 0, 1, 2 ou 3.

En conclusion

Avec la fonction Dialogue, la programmation des messages devient plus simple, ils sont regroupés au même endroit et un même message peut être utilisé plusieurs fois.

La présentation à l'écran s'en trouve améliorée et donne aux applications une autre image.

Le code et le formulaire fournis ne sont pas figés ; vous pouvez les modifier et les adapter à vos besoins. Par exemple changer les images si elles ne vous conviennent pas, ou en rajouter, disposer de boutons supplémentaires, revoir la position d'affichage à l'écran ou le mode de disparition, etc.

Bien sûr, cela demandera un peu de travail au niveau reprogrammation ; mais rien n'est gratuit !

Tout est possible en VBA !

Bonne utilisation

160source.zip (9.18 Ko)

Bonjour @Eric_angers

Un seule mot BRAVO

Très beau développement et belle fonction qui me sera très utile à l'avenir

Bon week-end

Merci, rien d'extraordinaire, mais ça peut rendre service.

Bon weekend également

Merci, c'est génial, je vais adopter

Bravo pour cet excellent travail

Merci

Bonjour à tous,

Bon début, je pense pour ma part. petites améliorations à venir.

Dissocier la gestion des message et l'affichage des messages à chacun son rôle.
Beaucoup de variables publiques pour ci peu de code.
Je ne vois pas à quoi servent Fmt et Fmt1.

La mise en place d'un formulaire alourdi le code, pourquoi ne pas prévoir la création du formulaire à la volée ? comme décris ici
J'aime bien l'utilisation d'images sans passer par les API Windows, même si je les trouves un peu criardes.

Donc bon boulot, à suivre.

Bonjour

Comme je le dis dans ma conclusion, rien n'est figé, chacun peut améliorer la fonction à sa convenance, en fonction de ses besoins.

Concernant Fmt et Fmt1, ce sont des constantes de format numérique. Cela évite de répéter le format (et parer aux erreurs de frappe) lors de l'écriture du code.

(voir dans la partie déclaration).

Bonne journée

Bonjour à tous,

Une nouvelle version de la fonction est disponible dans ce Forum :

https://forum.excel-pratique.com/astuces/une-alternative-a-msgbox-version-revisitee-186030

Rechercher des sujets similaires à "alternative msgbox ancienne version"