Concevez un gestionnaire de Post-It pour vos applications Access
Date de publication : 28/07/2008 , Date de mise à jour : 28/07/2008
Par
Jean-Philippe AMBROSINO (home page)
Ce document a pour but de vous montrer comment concevoir un mini gestionnaire de Post-It pour vos
applications Access.
Au final, vous-même ou un utilisateur êtes informés d'une remarque que vous ou un tiers avez enregistrée
par l'apparition d'un message à chaque lancement de l'application ou chargement d'un formulaire en particulier.
Vous devez être relativement à l'aise avec Microsoft Access et connaître la conception de formulaires
mais également avoir des notions du langage Visual Basic for Application afin mettre en pratique cet exemple.
1.
Avant propos
1-1.
Niveau
1-2.
Contact
1-3.
Images
1-4.
Langue
1-5.
Versions
2. Présentation du projet
2-1. Idée de bouton pour générer un message
3. Gestion des messages
3-1. Création du formulaire de rédaction des messages
3-1-1. Mode création
3-1-2. Mode création (vue éclatée)
3-1-3. Tableau des contrôles du formulaire
3-2. Rédaction d'un nouveau message
4. Affichage, Masquage d'un message avec suppression du Post-It
4-1. Affichage du Post-It avec son message
4-2. Masquage du Post-It avec suppression optionnelle
5. Conception du formlaire Post-It
5-1. La table des Post-It
5-2. Le formulaire des Post-It
5-1-1. Mode création
5-1-2. Mode création (vue éclatée)
5-1-3. Tableau des contrôles du formulaire
5-1-3-1. Propriétés de la zone de texte txtPostItContent
5-1-3-2. Caractéristiques du formulaire
6. Le code Visual Basic du projet
6-1. Code du module de classe du formulaire de rédaction des messages
6-1-1. La fonction GetCurrentIDUser()
6-2. Code du module de classe du formulaire d'affichage des messages
6-3. Code du module de classe du formulaire parent
6-4. Module basPostIt : Définition dynamique de la hauteur du contrôle Textbox
7. Conclusion
8.
Remerciements
9. Définitions
1.
Avant propos
Ce document a pour but de vous montrer comment concevoir un mini gestionnaire de Post-It pour
vos applications Access.
Au final, vous-même ou un utilisateur êtes informés d'une remarque que vous ou un tiers avez enregistrée
par l'apparition d'un message à chaque lancement de l'application ou chargement d'un formulaire en particulier.
Ce petit plus qui enrichira votre application permettra de laisser un ou plusieurs messages
(
en quelque sorte privés) à un utilisateur de votre choix ou bien un message d'information
visant à l'avertir de ne pas oublier d'effectuer telle ou telle opération comme la mise à jour
d'une ou plusieurs fiches par exemple...
Pour réaliser ce tutoriel, je me suis intéressé de près au tutoriel de
Cafeine :
Un formulaire auto-extensible pour Access.
1-1.
Niveau
Ce tutoriel s'adresse plus particulièrement aux développeurs intermédiaires avec un bon
niveau d'approche de la base de données Access.
La notion de savoir faire en matière de programmation et de conception de
formulaires graphiques sont particulièrement requis.
Je vous recommande de lire le tutoriel sur
les conventions typographiques ;
cela vous permettra de mieux comprendre la nomenclature que j'adopte systématiquement pour nommer variables et contrôles...
1-2.
Contact
Pour tous renseignements complémentaires, veuillez me contacter directement
(
Argyronet) par MP.
Pour des questions d'ordre technique, ayez la gentillesse de poster sur le forum en priorité.
1-3.
Images
Les images représentant l'icône du bouton et le Post-It ont été dessinées à l'aide de Photoshop.
Elle ne sont pas disponibles en téléchargement.
1-4.
Langue
Les commentaires du code de ce tutoriel sont rédigés en français.
Les noms des contrôles et les procédures de codes sont, quant à eux, en anglais
1-5.
Versions
Ce tutoriel est applicable pour vos applications qui ont été développées à partir de la
version 97 de Microsoft Access
(avec quelques adaptations pour la version 97).
2. Présentation du projet
Lorsque j'ai créé l'application de "Gestion des traitements PeopleSoft" pour une
entreprise dans laquelle j'ai travaillé, j'avais implémenté un gestionnaire de Post-It pour
que les utilisatrices puissent se souvenir que telle tâche était à effectuer ou bien d'échanger avec
des collègues des messages qui ne concernaient que l'application elle-même.
Il faut bien entendu se mettre dans le contexte pour comprendre la philosophie de l'ERP PeopleSoft et
ce que les traitements nécessitent comme enrichissement d'informations et éviter d'oublier d'ajouter ou
modifier telle ou telle tâche pour un Job donné...
L'idée de mettre ce Mini Gestionnaire de Post-It permettait la mise en mémoire de messages pour
soi-même ou pour un collègue sans passer par la messagerie interne et ainsi, éviter d'encombrer
sa boîte à mails, qui plus est, avec le risque de ne pas les lire.
En effet, le gestionnaire de Post-It proposé ici est obligatoirement affiché pour l'utilisateur ciblé
dès le chargement de l'application et ne peut donc pas l'ignorer, si peu que vous ayez tout mis en
place pour.
C'est ce que je vais tenter de vous montrer dans ce tutoriel.
2-1. Idée de bouton pour générer un message
Dans l'illustration ci-dessous qui représente un menu principal (volontairement éclairci et floué),
j'ai mis en évidence le bouton d'appel du générateur de messages.
Un clic sur ce bouton exécute l'ouverture du formulaire de rédaction d'un nouveau message...
3. Gestion des messages
Pour mettre en oeuvre ce tutoriel, il est nécessaire de concevoir deux formulaires :
- Un pour la rédaction des messages ;
- Un pour l'affichage des Post-It en mode Popup à partir du formulaire de votre choix ;
Le formulaire dédié à la rédaction des messages est composé d'une liste déroulante qui contient les
utilisateurs potentiels de votre application associée à une case à cocher qui permet de libérer cette
liste pour choisir un autre utilisateur que vous-même.
Cette option est définie par défaut à l'ouverture du formulaire.
Il est effectivement sous-entendu dans ce projet, que l'affichage des Post-It est dédié plutôt à
vous-même comme un pense-bête. À partir du moment où vous affectez un message à un utilisateur en
particulier, c'est cet utilisateur qui verra son application ouverte avec un message au premier plan
avant qu'il puisse accéder à l'application.
En revanche, il n'est pas prévu dans ce projet de pouvoir choisir plusieurs destinataires d'un même
message mais rien ne vous empêche, et ce sans grosses modifications, de mettre cette option en place
auquel cas il faudra adapter le code d'une part et ajouter un contrôle de Zone de liste qui se
substituera à la Zone de liste déroulante.
Vous pourrez alors sélectionner un ou plusieurs utilisateurs, rédiger votre message et enfin l'enregistrer.
Le formulaire dédié à l'affichage des messages est un formulaire doté de propriétés
particulières en ce qui concerne l'alimentation de la zone de texte puisque celle-ci adapte sa hauteur
dynamiquement en fonction du contenu à afficher.
Pour ce faire, une procédure qui calcule la hauteur nécessaire en fonction de la police de
caractères est appelée systématiquement avant d'ouvrir le formulaire.
Sur ce formulaire, j'ai
également ajouté la possibilité de le faire glisser à l'aide de la souris du fait que celui-ci
est dépourvu de barre de titre.
3-1. Création du formulaire de rédaction des messages
Le formulaire permettant de rédiger des messages est composé de 11 contrôles...
Tant que le message est en cours de rédaction, vous avez la possibilité de choisir un autre
utilisateur ou d'annuler la rédaction de celui-ci.
3-1-1. Mode création
Pour réaliser ce formulaire, j'ai choisi une disposition
verticale pour rappeler une feuille au format A4 en mode portrait.
En haut du formulaire et en arrière-plan, se trouvent :
- Une image représentant une feuille cornée,
- Sur celle-ci, au premier plan vous disposerez une autre image représentant
l'illustration du bouton du menu principal vu ci-avant,
- Une étiquette dans lequel vous saisirez l'intitulé
"Créer un message"
- Et enfin, un champ texte caché dont la source de contrôle* est l'identifiant
du PostIt, à savoir IDPostit.
* Source de contrôle : propriété facultative
Juste en dessous de cette image à quelques pixels, vous poserez :
- Une case à cocher dont l'intitulé est "Pour un autre
utilisateur que moi..."
- La liste déroulante, quant à elle est disposée sur le même bord gauche que
la case à cocher et contient la liste des utilisateurs avec leur identifiant.
Exemple de requête pour alimenter la liste déroulante :
SELECT IDUtilisateur, Prenom & " " & NomFamille AS NomComplet
FROM TBLUtilisateurs
WHERE IDUtilisateur <> 123456789;
ORDER BY NomFamille
|
 |
Dans mon application, l'ID qui représente ma personne n'est pas, bien entendu 123456789, celui-ci
étant stipulé comme tel pour la forme.
Il vous appartiendra d'adapter la condition WHERE en conséquence
surtout si l'ID des utilisateurs de votre application est sous la forme Alphabétique ou Alphanumérique.
|
Cette requête liste tous les utilisateurs potentiellement enregistrés dans la base de données
en excluant intentionnellement l'utilisateur 123456789 qui est censé être vous-même
à partir du moment où la case est cochée.
Dans la première colonne, c'est-à-dire la Colonne 0, l'IDUtilisateur est inscrit
et la colonne est masquée.
En effet, la propriété Largeurs colonnes de la liste déroulante est égale à 0cm;4cm
C'est ce champ qui identifie l'utilisateur par une valeur unique en faisant office de Clé primaire.
Dans la seconde colonne, c'est-à-dire la Colonne 1, le champ NomComplet
représente la concaténation des champs Prenom et Nom.
On suppose bien entendu que vous avez fait
en sorte d'enregistrer ces informations avec la casse adéquate.
 |
Si ce n'était pas le cas, rien ne vous empêche de forcer la mise en forme des caractères dans
la requête elle-même avec respectivement les fonctions StrConv() et UCase().
|
Pour plus d'informations concernant ces deux fonctions, je vous invite à consulter l'aide
de Microsoft Access.
Vous dessinerez ensuite la Zone de texte devant recevoir le message juste en dessous de
cette liste déroulante et encore au-dessous de celle-ci, un Rectangle dans lequel vous
poserez :
- Un bouton de commande intitulé Annuler
- Un autre bouton de commande intitulé Enregistrer
Vous dessinerez enfin un autre Rectangle qui lui, détoure à la fois la zone de texte et
la zone des boutons et ferez en sorte de faire mourir la bordure Haut de cette zone
de texte sur la bordure Bas de l'image représentant la feuille cornée.

Détail de la disposition des contrôles
Vous disposerez ce rectangle de manière à ce qu'il soit positionné en arrière-plan par rapport à
tous les autres contrôles comme le montre la figurine ci-dessus...
3-1-2. Mode création (vue éclatée)
Pour plus de commodités en ce qui concerne la mise en place des contrôles, je vous propose
de regarder la figurine ci-après qui représente la vue éclatée du formulaire.
Ainsi, vous pouvez avoir un meilleur aperçu des contrôles utilisés et mieux apréhender leur agencement.
Les informations détaillées qui concernent la disposition des contrôles se trouvent
dans le tableau ci-après.
3-1-3. Tableau des contrôles du formulaire
Dans le tableau ci-dessous sont listés les 11 contrôles nécessaires à l'élaboration
de ce formulaire.
Il y a donc :
- 2 contrôles Textboxes (Zone de texte)
- 2 contrôles Label (Étiquette) dont un attaché à sa Case à cocher
- 2 contrôles Image (Image)
- 1 contrôle Checkbox (Case à cocher)
- 1 contrôle ComboBox (Liste déroulante)
- 2 contrôles Shape (Rectangle)
- 2 contrôles CommandButton (Bouton de commande)
| Nom du contrôle |
Type du contrôle |
Haut* |
Gauche* |
Source de contrôle |
Visible |
Description |
| txtPostItContent |
Zone de texte |
150 |
1650 |
PostItContent |
Oui |
Zone de texte du message (avec barre de défilement verticale) |
| imgPostit |
Image |
30 |
30 |
- |
Oui |
Image représentant le Post-It corné |
| imgInfo |
Image |
120 |
90 |
- |
Oui |
Image représentant l'icône du bouton Post-It |
| lblTitle |
Étiquette |
1095 |
285 |
- |
Oui |
Intitulé "Créer un message" |
| lblOtherUser |
Étiquette |
375 |
975 |
- |
Oui |
Intitulé "Pour un autre utilisateur que moi..." |
| chkAnotherUser |
Case à cocher |
150 |
1005 |
Shown |
Non |
Détermine si le message est adressé à un tiers |
| cmbUsers |
ComboBox |
150 |
1275 |
- |
Oui |
Identifiant de l'utilisateur (dans le code) |
| txtIDPostit |
TextBox |
3570 |
180 |
IDPostit |
Non |
Identifiant du Post-It (Clé primaire) |
| cmdCancel |
Bouton |
2340 |
5760 |
- |
Oui |
Bouton d'annulation |
| cmdSave |
Bouton |
3540 |
5760 |
- |
Oui |
Bouton de création du Post-It |
| shpBorder |
Boîte |
45 |
885 |
- |
Oui |
Cadre du formulaire |
| shpButtons |
Boîte |
150 |
5670 |
- |
Oui |
Cadre des boutons |
 |
* Les valeurs des positions Gauche et Haut sont définies en
Twips
|
Notez que la bordure dessinée illustrant une feuille cornée autant que celle de la zone de
texte txtPostItContent sont de la même couleur. Toutefois, l'image ne possède pas de
bordure Bas (dessinée graphiquement dans l'image elle-même) mais seulement une
en haut, une à gauche et l'autre à droite.
Dans cet exemple, la couleur de bordure choisie est un gris semi-foncé (#8A8A61 en hexa).
Les autres contrôles voient leur bordure transparente.
Une fois créé, vous enregistrerez ce formulaire. Dans mon application, j'ai nommé ce formulaire : frmPopupPostIt_New.
L'ensemble du code de ce formulaire est vu
plus loin à la section 6.
3-2. Rédaction d'un nouveau message
Pour rédiger un nouveau message, il suffira de passer en Mode formulaire, de cocher éventuellement
la case si toutefois vous voulez affecter ce message à un autre utilisateur, le cas échéant,
le choisir dans la liste et enfin, saisir le message dans la zone de texte prévu à cet effet.
Dans cette même zone de texte, il n'est pas prévu d'appuyer sur la touche Entrée pour
passer à la ligne mais vous pouvez forcer cette option en utilisant la combinaison de
touches Ctrl+Entrée.
Au moment de l'ouverture du formulaire, seul le bouton Annuler est accessible ;
il permet ainsi d'annuler la rédaction du message pour retourner à l'écran précédent.
À partir du moment où vous avez commencé à saisir du texte, le bouton Enregistrer
est disponible et vous permet d'enregistrer votre message pour qu'il soit pris en compte.
 |
Il n'a pas été prévu de limitation ni de vérification en ce qui concerne le contenu du texte du message...
Il est sous entendu que ce module complémentant votre application doit être utilisé à bon escient,
même si de façon détournée, on peut à sa découverte s'amuser un peu avec, entre collègues...
Les messages sont stockés jusqu'à suppression par une confirmation.
|
4. Affichage, Masquage d'un message avec suppression du Post-It
Le message s'affiche automatiquement à l'ouverture d'un formulaire défini.
Il est impossible de travailler sur l'application tant que ce message n'est pas masqué...
4-1. Affichage du Post-It avec son message
Dès qu'un utilisateur ou vous-même possède au moins un message, c'est le second formulaire (vu ci-après) qui
est ouvert et s'affiche une fois que le formulaire appelant est lui-même chargé et affiché.
J'entends pas formulaire appelant, le formulaire depuis lequel vous rédigerez le code nécessaire
à l'appel de la vérification de la présence de messages en fonction de l'utilisateur en cours et le cas
échéant, appeler la procédure d'ouverture du formulaire Post-It.
4-2. Masquage du Post-It avec suppression optionnelle
La seule possibilité prévue pour masquer le Post-It, c'est d'appuyer sur la touche Echap.
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyEscape Then
End If
End Sub
|
Une procédure est alors appelée et affiche le message suivant :
Dans cette fenêtre est proposée de supprimer le message une fois ce dernier masqué.
Le bouton par défaut est le bouton Annuler.
- Si vous cliquez sur Oui, le message est effacé de la table et ne peut plus être récupéré
- Si vous cliquez sur Non, le message est conservé et le Post-It fera de nouveau son apparition dans les mêmes circonstances
- Si vous cliquez sur Annuler, rien ne se passe, la fenêtre est simplement masquée
5. Conception du formlaire Post-It
La conception du formulaire du Post-It nécessite une plus grande attention.
Il existe une grande similitude entre le formulaire de Rédaction des messages et le formulaire
d'Affichage des messages.
À la limite, pour gagner un petit peu de temps et éviter la redondance de travail, vous pouvez très
bien dupliquer le formulaire de rédaction des messages que vous venez de créer et l'enregistrer
sous le nom frmPopupPostIt ainsi que je l'ai fait dans mon application...
Vous n'aurez alors que peu de modifications à apporter, les plus grandes se résumant à la suppression des
contrôles inutilisés et la rédaction du code correspondant.
La petite difficulté qui se greffe à la conception de ce formulaire se situe au niveau de la zone
de texte qui contient donc le message : elle doit être disposée tout comme que vous l'avez fait tout à
l'heure avec le rectangle, à savoir, faire superposer sa bordure Haut juste en dessous
de la bordure Bas de l'image représentant la feuille cornée.
5-1. La table des Post-It
Il est d'abord nécessaire de créer la table dans laquelle seront stockés les enregistrements
correspondants à chacun des messages pour un utilisateur donné : chaque nouveau message
enregistré est stocké dans une table.

Table où sont stockés les messages
La Base de données
Il est important de noter que la base de données et l'application sont dissociées.
J'entends par là que vous devez, pour que le procédé de distribution des messages puisse
être mis en oeuvre, avoir une architecture base de données dorsale sur un serveur de fichiers
et les bases de données frontales qui sont en fait les applications clientes, sur chaque poste
de travail.
Dans un contexte autre, il ne sera pas possible de faire fonctionner le projet correctement.
Structure de la table
Cette table est composée de quatre champs dont la description est stipulée dans le tableau suivant :
| Nom du champ |
Type |
Description |
| IDPostit |
Entier long (Clé primaire) |
Ce champ identifie de façon unique un message |
| IDUser |
Entier long |
Ce champ identifie l'utilisateur destinataire du message |
| PostItContent |
Mémo |
Ce champ est le contenu du message |
| Shown |
Oui/Non |
Ce champ défini si le message a été vu par son destinataire |
La figurine ci-dessous représente la table en mode création :
Il n'y a pas de propriétés particulières à définir pour chacun des champs, vous
laisserez donc les propriétés par défaut qui s'affecteront d'elles-même au fur et à
mesure que vous choisirez le type de champ durant de la conception de la table.
Une fois créée, vous enregistrerez cette table. Dans mon application, j'ai nommé cette table tout simplement : TBLPostIt.
5-2. Le formulaire des Post-It
Le formulaire permettant de rédiger des messages est composé de 7 contrôles...
5-1-1. Mode création
Pour réaliser ce formulaire (si peu que vous ayez choisi de le créer plutôt que de
partir d'une copie), j'ai choisi une disposition horizontale.
Lorsque celui-ci sera affiché, la zone de texte contenant le message verra sa hauteur
s'agrandir dynamiquement en fonction du nombre de messages s'il y en a plusieurs.
La source de contrôle du formulaire est bien entendu, la table que vous avez créée précédemment.
En haut du formulaire et en arrière-plan, se trouvent :
- Une image représentant une feuille cornée,
- Sur celle-ci, au premier plan vous disposerez une autre image représentant
l'illustration d'une icône Infomation issue de la collection des icônes de la fonction MsgBox(),
- Une étiquette dans lequel vous saisirez l'intitulé
"Vous avez un message",
- Et enfin, deux champs texte cachés dont les sources de contrôle sont
respectivement :
- l'identifiant du PostIt est à savoir IDPostit.
- l'identifiant de l'Utilisateur est à savoir IDUser.
Juste en dessous de cette image à quelques pixels, vous dessinerez ensuite la
Zone de texte devant recevoir le message avec
une hauteur d'environ 1,6cm.
5-1-2. Mode création (vue éclatée)
Tout comme je vous l'ai proposé avec le précédent formulaire pour ce qui
concerne la mise en place des contrôles, la figurine ci-après représente la vue éclatée
du formulaire.
Les informations détaillées qui concernent la disposition des contrôles se trouvent
dans le tableau ci-après.
5-1-3. Tableau des contrôles du formulaire
Dans le tableau ci-dessous sont listés les 7 contrôles nécessaires à l'élaboration du formulaire.
Il y a donc :
- 3 contrôles Textboxes (Zone de texte)
- 1 contrôle Label (Étiquette)
- 2 contrôles Image (Image)
- 1 contrôle Checkbox (Case à cocher)
| Nom du contrôle |
Type du contrôle |
Haut |
Gauche |
Source de contrôle |
Visible |
Description |
| txtPostItContent |
Zone de texte |
45 |
900 |
PostItContent |
Oui |
Zone de texte du message |
| imgPostit |
Image |
30 |
30 |
- |
Oui |
Image représentant le Post-It corné |
| imgInfo |
Image |
105 |
90 |
- |
Oui |
Image représentant l'icône Info |
| lblTitle |
Étiquette; |
705 |
210 |
- |
Oui |
Intitulé "Vous avez un message" |
| chkShown |
Case à cocher |
3135 |
630 |
Shown |
Non |
Détermine si le message est masqué ou supprimé |
| txtIDUser |
TextBox |
1980 |
630 |
IDUtilisateur |
Non |
Identifiant de l'utilisateur |
| txtIDPostit |
TextBox |
885 |
630 |
IDPostit |
Non |
Identifiant du Post-It (Clé primaire) |
 |
* Les valeurs des positions Gauche et Haut sont définies en
Twips
|
De façon identique, les bordures illustrant la feuille cornée et celle de la zone de
texte txtPostItContent sont de la même couleur, à savoir un gris semi-foncé (#8A8A61 en hexa).
Une fois créé, vous enregistrerez ce formulaire. Dans mon application, j'ai nommé ce formualire : frmPopupPostIt.
5-1-3-1. Propriétés de la zone de texte txtPostItContent
Cette zone de texte se voit octroyer des propriétés particulières afin de réagir en
conséquence du texte qu'elle va contenir, quelle qu'en soit sa longueur.
J'ai mis en subrillance rose dans la fenêtre de propriétés ci-dessous, les valeurs des
propriétés que vous devez appliquer si vous voulez un rendu identique.
Rappel : la bordure dessinée illustrant une feuille cornée est de la même
couleur que la bordure de la zone de texte.
L'objectif ici est de positionner la zone de texte txtPostItContent un plan
en-dessous del'image imgPostit de manière à ce que la bordure Haut de la zone de
texte soit masquée par la bordure Bas de l'image...
5-1-3-2. Caractéristiques du formulaire
Le formulaire quant à lui doit posséder les propriétés suivantes :
Au niveau du format
Au niveau des données
Au niveau des événements
Au niveau des autres propriétés
L'ensemble du code de ce formulaire est vu
plus loin à la section 6.
Note :
1/ La propriété Aperçu des touches (KeyPreview) doit avoir la valeur Oui.
2/ Prenez en compte que la précision des positions des contrôles autant que la largeur
du formulaire déterminera la qualité graphique de votre Post-It.
6. Le code Visual Basic du projet
Ce projet, bien que coiffé de 2 petits formulaires relativement simplifiés, possède un jeu de lignes
de code assez conséquent.
Le code se décompose ainsi :
- Formulaire de rédaction des messages
- Formulaire d'affichage des messages
- Extrait du Formulaire appelant (ici, le Menu principal)
- Définition dynamique de la hauteur du contrôle Textbox
Chaque formulaire
désactive la molette de la souris à l'aide de la classe
MouseWheel.CMouseWheel()
Pour plus d'informations à ce sujet, veuillez vous reporter dans la
FAQ ou consulter les tutoriels concernés.
6-1. Code du module de classe du formulaire de rédaction des messages
Ce formulaire possède deux événements:
- Un événement de Chargement du formulaire
- Un événement de Fermeture du formulaire
Les autres événements sont régis par les différents contrôles du formulaire...
J'ai également posé des procédures privées qui sont appelées par certains de ces événements.
| Module de classe du formulaire frmPostitNew |
Option Compare Database
Option Explicit
Private WithEvents clsMouseWheel As MouseWheel.CMouseWheel
Private Sub chkAnotherUser_Click()
Dim oQDF As DAO.QueryDef
Dim SQLSelect As String
Dim lngIDUser As Long
Const QUERY_USERLIST As String = "qry_Combo_GetListOfUsers"
lngIDUser = GetCurrentIDUser()
SQLSelect = "SELECT TBL_Users.IDUser, [LastName] &" & Chr(34) & " " & Chr(34) & _
"& [FirstName] AS FullName"
SQLSelect = SQLSelect & vbCrLf & "FROM TBL_Users"
SQLSelect = SQLSelect & vbCrLf & "WHERE TBL_Users.IDUser <> " & lngIDUser & _
" AND TBL_Users.IDUser <> " & DATA_IDU_NONE & " AND TBL_Users.IsActivated=True;"
Set oQDF = CurrentDb.QueryDefs(QUERY_USERLIST)
oQDF.SQL = SQLSelect
If Me!chkAnotherUser Then
With cmbUsers
.RowSource = QUERY_USERLIST
.Enabled = True
.Locked = False
.SetFocus
.Dropdown
End With
Else
txtPostItContent.SetFocus
With cmbUsers
.RowSource = vbNullString
.Locked = True
.Enabled = False
End With
Me!cmbUsers = vbNullString
End If
End Sub
Private Sub clsMouseWheel_MouseWheel(Cancel As Integer)
Cancel = True
End Sub
Private Sub cmdCancel_Click()
If MsgBox("Souhaitez-vous annuler la création du PostIt ?", _
vbExclamation + vbYesNo, "Annuler") = vbYes Then
On Error Resume Next
DoCmd.RunCommand acCmdUndo
If err <> 0 Then err.Clear
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "frmMainMenu", acNormal, , , , acDialog
End If
End Sub
Private Sub cmdSave_Click()
Dim strFrom As String
Dim strDate As String
Dim SQLSelect As String
Dim lngIDUser As Long
Dim strPreviousMessage As String
Dim strPostItContent As String
Dim strNewMessage As String
Dim blnShown As Boolean
Dim blnAlreadyGotMessage As Boolean
Dim blnForMeOnly As Boolean
Dim oRS As DAO.Recordset
If IsNull(strPostItContent) Or Len(strPostItContent) < 3 Then
MsgBox "Un message doit être inscrit avant d'enregistrer !", _
vbExclamation, "Message requis"
Exit Sub
End If
strFrom = GetCurrentUserName(True)
strDate = "Le " & Format(Now, "d mmmm yyyy") & " à " & _
Left(Format(Now, "hh:mm"), 2) & "h" & Right(Format(Now, "hh:mm"), 2) & ", "
If IsNull(Me!chkAnotherUser) Then
lngIDUser = GetCurrentIDUser()
blnForMeOnly = True
Else
If Me!chkAnotherUser Then
lngIDUser = Me!cmbUsers
blnForMeOnly = False
Else
lngIDUser = GetCurrentIDUser()
blnForMeOnly = True
End If
End If
strPreviousMessage = GetStringFieldValueFromTable( _
"TBLPostIt", "IDUser", "PostItContent", lngIDUser)
blnAlreadyGotMessage = (Len(strPreviousMessage) > 0)
SQLSelect = "SELECT IDUser, PostItContent, TypeOfMessage, Shown, FormName, IDKeyCriteria"
SQLSelect = SQLSelect & vbCrLf & "FROM TBLPostIt"
If blnForMeOnly Then
If blnAlreadyGotMessage Then
strPostItContent = vbCrLf & vbCrLf & strDate & _
"je me suis de nouveau écrit ce message :" & vbCrLf & Me!txtPostItContent
SQLSelect = SQLSelect & vbCrLf & "WHERE IDUser = " & lngIDUser
Else
strPostItContent = strDate & "je me suis écrit ce message :" & vbCrLf & Me!txtPostItContent
End If
Else
If blnAlreadyGotMessage Then
strPostItContent = vbCrLf & vbCrLf & strDate & strFrom & _
" vous a écrit :" & vbCrLf & Me!txtPostItContent
SQLSelect = SQLSelect & vbCrLf & "WHERE IDUser = " & lngIDUser
Else
strPostItContent = strDate & strFrom & " vous a écrit :" & vbCrLf & Me!txtPostItContent
End If
End If
strNewMessage = strPreviousMessage & strPostItContent
blnShown = False
strFormName = vbNullString
lngIDKeyCriteria = 0
On Error GoTo L_ErrCannotAddData
Set oRS = CurrentDb.OpenRecordset(SQLSelect, 2)
With oRS
If blnAlreadyGotMessage Then
.Edit
Else
.AddNew
End If
.Fields("IDUser") = lngIDUser
.Fields("PostItContent") = strNewMessage
.Fields("Shown") = blnShown
.update
End With
Set oRS = Nothing
cmdCancel.Caption = CMD_CLOSE
cmdCancel.SetFocus
chkAnotherUser.Enabled = False
txtPostItContent.Locked = True
cmdSave.Enabled = False
L_ExCannotAddData:
Set oRS = Nothing
Exit Sub
L_ErrCannotAddData:
MsgBox Err.Description, vbCritical, Err
Resume L_ExCannotAddData
End Sub
Private Sub Form_Close()
On Error Resume Next
clsMouseWheel.SubClassUnHookForm
Set clsMouseWheel.Form = Nothing
Set clsMouseWheel = Nothing
End Sub
Private Sub Form_Load()
Set clsMouseWheel = New MouseWheel.CMouseWheel
Set clsMouseWheel.Form = Me
clsMouseWheel.SubClassHookForm
End Sub
Private Sub imgInfo_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub imgPostit_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub lblTitle_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub txtPostItContent_Change()
cmdSave.Enabled = (Len(Me!txtPostItContent.Text) > 0)
End Sub
Private Sub MoveForm(F As Form)
ReleaseCapture
SendMessageCapture F.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
End Sub
|
6-1-1. La fonction GetCurrentIDUser()
Cette fonction "maison" renvoie un
IDUtilisateur présent dans la table
des utilisateurs en fonction d'un
critère soumis à une condition
Where...
Cette table contient tous les champs relatifs aux informations concernant directement les
utilisateurs de votre application.
Parmi ces champs figure le
Login.
(
nom d'utilisateur de la session Windows)
Pour obtenir l'
ID, j'ai donc posé cette fonction qui, à l'aide de l'
API
GetUserName(), me
permet d'interroger la table via un objet
DAO.Recordset dans lequel je passe
une chaîne SQL
contenant le critère
Login = GetUserName()...
La valeur retournée par ma fonction est donc le champ que je souhaite, à savoir, le champ
IDUtilisateur, clé primaire de la table...
Vous ne devriez donc avoir aucune difficulté pour concevoir cette fonction...
6-2. Code du module de classe du formulaire d'affichage des messages
Ce formulaire possède quatre événements:
- Un événement de Chargement du formulaire
- Un événement d'Activation du formulaire
- Un événement de Fermeture du formulaire
- Un événement de gestion des séquences de Touche appuyée du clavier
Les autres événements sont régis par les différents contrôles du formulaire...
J'ai également posé des procédures privées qui sont elles aussi appelées par certains de ces événements.
|
Option Compare Database
Option Explicit
Private WithEvents clsMouseWheel As MouseWheel.CMouseWheel
Private Sub clsMouseWheel_MouseWheel(Cancel As Integer)
Cancel = True
End Sub
Private Sub Form_Close()
On Error Resume Next
clsMouseWheel.SubClassUnHookForm
Set clsMouseWheel.Form = Nothing
Set clsMouseWheel = Nothing
End Sub
Private Sub Form_Current()
Const MARGIN_HEIGHT As Integer = 32
Me.txtPostItContent.Height = GetTextLength(Me!txtPostItContent)
Me.Section("Detail").Height = Me.txtPostItContent.Top + _
Me.txtPostItContent.Height + MARGIN_HEIGHT
Me.InsideHeight = Me.Section("Detail").Height + MARGIN_HEIGHT
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Dim intAnswer As Integer
If KeyCode = vbKeyEscape Then
intAnswer = MsgBox("Voulez-vous supprimer ce message avant de fermer ?", _
vbQuestion + vbDefaultButton3 + vbYesNoCancel, "Supprimer")
Select Case intAnswer
Case vbCance
Exit Sub
Case vbNo
Me!chkShown = True
Case vbYes
DeleteMessage Me!txtIDUser
End Select
DoCmd.Close acForm, Me.Name
End If
End Sub
Private Sub Form_Load()
Set clsMouseWheel = New MouseWheel.CMouseWheel
Set clsMouseWheel.Form = Me
clsMouseWheel.SubClassHookForm
End Sub
Private Sub imgInfo_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub imgPostit_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub lblTitle_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub txtPostItContent_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MoveForm Me
End Sub
Private Sub DeleteMessage(ByVal IDUser As Long)
Dim oRS As DAO.Recordset
Set oRS = CurrentDb.OpenRecordset( _
"SELECT * FROM TBLPostIt WHERE IDUser = " & txtIDUser, dbOpenDynaset)
With oRS
If Not .EOF Then
Do While Not .EOF
.Delete
.MoveNext
Loop
End If
.Close
End With
Set oRS = Nothing
End Sub
Private Sub MoveForm(F As Form)
ReleaseCapture
SendMessageCapture F.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
End Sub
|
6-3. Code du module de classe du formulaire parent
C'est ce formulaire qui vous permettra à la fois de générer de nouveaux messages
et de les voir apparaître au moment du chargement grâce à la minuterie.
Vous exploiterez alors un seul événement pour l'affichage des messages :
- L'événement Timer du formulaire
Il existe également dans ce même formulaire, un bouton permettant de générer de nouveaux
messages.
- Ce bouton déclenche alors l'événement Click
Option Compare Database
Option Explicit
Private Sub cmdNewPostIt_Click()
DoCmd.OpenForm "frmPopupPostIt_New", , , , acFormAdd, acDialog
End Sub
Private Sub Form_Timer()
Dim intNBMessages As Integer
Dim lngCurrentUser As Long
Dim strSQL As String
Dim oRS As DAO.Recordset
Me.TimerInterval = 0
strSQL "SELECT COUNT(*) FROM TBLPostIt WHERE IDUser = " & GetCurrentIDUser()
Set oRS = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
With oRS
If Not .EOF Then
DoCmd.OpenForm "frmPopupPostIt", , , "[IDUser]=" & lngCurrentUser, acFormEdit, acDialog
End If
.Close
End With
Set oRS = Nothing
End Sub
|
6-4. Module basPostIt : Définition dynamique de la hauteur du contrôle Textbox
Il s'avère que la propriété Auto extensible ne réponde pas correctement au véritable
contenu du texte et ainsi, tronque une partie du texte.
Il a donc été nécessaire de mettre en place une routine qui le permette.
Pour définir dynamiquement la hauteur du contrôle Textbox contenant le message
du Post-It, le formulaire exploite la fonction GetTextLength() qui calcule la hauteur
nécessaire. Elle est écrite dans le module suivant :
| Module basPostIt |
Option Compare Database
Option Explicit
Public Declare Function ReleaseCapture Lib "user32" () As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const WM_NCLBUTTONDOWN = &HA1
Public Const HTCAPTION = 2
Private Declare Function GetDeviceCaps Lib "gdi32" ( _
ByVal lngDC As Long, ByVal nIndex As Long) As Long
Private Declare Function CreateIC Lib "gdi32" Alias "CreateICA" ( _
ByVal lpDriverName As String, ByVal lpDeviceName As String, _
ByVal lpOutput As String, lpInitData As Any) As Long
Private Declare Function DeleteDC Lib "gdi32" ( _
ByVal lngDC As Long) As Long
Private Declare Function SelectObject Lib "gdi32" ( _
ByVal lngDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" ( _
ByVal hObject As Long) As Long
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" ( _
ByVal lngDC As Long, ByVal lpStr As String, ByVal nCount As Long, _
lpRect As RECT, ByVal wFormat As Long) As Long
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" ( _
lpLogFont As LOGFONT) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" ( _
ByVal hwnd As Long, ByVal lngDC As Long) As Long
Private Type RECT
Gauche As Long
Haut As Long
Bottom As Long
Right As Long
End Type
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * 32
End Type
Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90
Private Const CLIP_LH_ANGLES As Long = 16
Private Const OUT_TT_ONLY_PRECIS As Long = 7
Private Const DT_Haut As Long = &H0
Private Const DT_Gauche As Long = &H0
Private Const DT_WORDBREAK As Long = &H10
Private Const DT_CALCRECT As Long = &H400
Public Function GetTextLength(ByVal FormControl As Control, Optional ByVal TextToCheck As String = "") As Long
Dim tyFONT As LOGFONT
Dim tyRECT As RECT
Dim lngDC As Long
Dim lngNewFont As Long
Dim lngOldFont As Long
Dim lngRet As Long
Dim strText As String
If Len(TextToCheck) = 0 Then
strText = FormControl.Value & Chr(0)
Else
strText = TextToCheck & Chr(0)
End If
lngDC = GetDC(0&)
tyRECT.Bottom = CountPixelsX(FormControl.Width)
With FormControl
tyFONT.lfClipPrecision = CLIP_LH_ANGLES
tyFONT.lfOutPrecision = OUT_TT_ONLY_PRECIS
tyFONT.lfEscapement = 0
tyFONT.lfFaceName = .FontName & Chr$(0)
tyFONT.lfWeight = .FontWeight
tyFONT.lfItalic = .FontItalic
tyFONT.lfUnderline = .FontUnderline
tyFONT.lfHeight = (.FontSize / 72) * -GetDeviceCaps(lngDC, 90)
lngNewFont = CreateFontIndirect(tyFONT)
End With
lngOldFont = SelectObject(lngDC, lngNewFont)
lngRet = DrawText(lngDC, strText, -1&, tyRECT, DT_CALCRECT Or DT_Haut Or DT_Gauche Or DT_WORDBREAK)
SelectObject lngDC, lngOldFont
DeleteObject lngNewFont
GetTextLength = CountTwipsX(tyRECT.Right) + 10
ReleaseDC 0&, lngDC
End Function
Private Function GetTwipsPerPixelsX() As Long
Dim lngDC As Long
lngDC = CreateIC("DISPLAY", vbNullString, vbNullString, vbNullString)
If lngDC <> 0 Then
GetTwipsPerPixelsX = 1440 / GetDeviceCaps(lngDC, LOGPIXELSX)
DeleteDC lngDC
End If
End Function
Private Function CountPixelsX(ByRef NbTwips As Long) As Long
CountPixelsX = NbTwips / GetTwipsPerPixelsX
End Function
Private Function CountTwipsX(ByRef NbPixels As Long) As Long
CountTwipsX = NbPixels * GetTwipsPerPixelsX
End Function
|
Vous ajoutez donc un module standard à votre projet que vous nommez basPostIt (par exemple) et
y recopierez l'intégralité du bloc de code ci-dessus.
7. Conclusion
Ce tutoriel peut s'avérer utile pour les développeurs qui souhaitent enrichir leurs applications avec des petits
plus pratiques...
Il apprend à concevoir des formulaires selon un jeu de conditions bien spécifiques avec une idée originale.
Je vous laisse vous entraîner avec cette pratique. Si vous rencontrez des difficultés ou si j'ai omis de préciser
quelque chose qui reste obscure, n'hésitez pas à m'en faire part.
8.
Remerciements
9. Définitions
Twip (Définition de l'aide Visual Basic)
Unité indépendante de l'écran, utilisée pour garantir que l'emplacement et la proportion des
éléments d'écran de votre application seront les mêmes quel que soit le système d'affichage.
Le twip est une unité de mesure d'écran égale à 1/20 point d'une imprimante.
On compte environ 1 440 twips dans un pouce logique ou 567 twips
dans un centimètre logique
(la longueur d'un élément d'écran étant égale à un pouce ou à un centimètre lorsqu'il est
imprimé).


Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.