I. Reconnaissance▲
Cet article s'inspire très largement du tutoriel : Un formulaire auto-extensible pour Access de cafeine.
Grand merci à son auteur et à ceux qui ont participé à son élaboration.
II. Avertissement▲
Si vous souhaitez livrer une version protégée de votre application sous la forme d'un fichier exécutable (MDE/ACCDE), cette solution ne doit pas être envisagée.
En effet le fichier est alors compilé. Dès lors la création ou ouverture de formulaire, état ou module n'est plus disponible.
III. Si vous êtes pressé, voici comment utiliser la fonction▲
1° Vous téléchargez la base de données.
2° Dans votre base de données, vous importez le module mFonctions.
Soit en utilisant la barre des menus : <Fichier/Données externes/Importer et répondre aux invites>,
soit par glisser-déposer : vous affichez côte à côte la base jointe et la vôtre et vous faites glisser mFonctions depuis l'une vers l'autre.
3° Pour adapter la taille de votre zone de texte, saisissez ce code dans l'événement « Sur activation » de votre formulaire.
Private
Sub
Form_Current
(
)
'Ajuster la hauteur de la zone de texte
If
Not
IsNull
(
Me.LeNomDeVotreZoneDeTexte
) Then
Me.LeNomDeVotreZoneDeTexte.Height
=
AjusterZdt
(
"LeNomDeVotreZoneDeTexte "
)
End
If
End
Sub
4° Affichez les modules <ALT + F11>. Ensuite, dans la barre des menus Outils/Références… ajoutez la bibliothèque : Microsoft DAO x.x Object Library.
5° Vous compilez votre base : Débogage/Compiler…
Vous lirez peut-être la suite de l'article plus tard… Merci d'être passé par ici.
IV. Et si vous voulez savoir comment ça marche…▲
Dans les propriétés d'une zone de texte de formulaire, on trouve effectivement les propriétés « Auto extensible » et « Auto réductible ».
Cependant, si vous avez la bonne habitude d'utiliser la touche F1, vous savez que ce n'est pas la panacée :
IV-A. Il va falloir ruser ! Voici l'idée▲
Cafeine décrit l'astuce dans son tutoriel.
Dans un autre formulaire - appelons-le fMartyr - nous allons loger le contenu de notre zone de texte dans une étiquette - lblTexteCible - et utiliser la méthode .SizeToFit pour ajuster la taille.
Cette méthode est celle que vous utilisez lors de la construction d'un état ou d'un formulaire pour ajuster la taille d'un contrôle en cliquant droit sur celui-ci.
Cette méthode est uniquement disponible quand l'état ou le formulaire est en mode construction.
Access va alors redimensionner la hauteur de l'étiquette pour afficher l'entièreté du texte.
Il ne nous reste plus alors qu'à récupérer cette hauteur pour l'affecter à la zone de texte de notre formulaire.
On aura évidemment pris la précaution d'affecter au contenu de l'étiquette, la fonte de caractères adéquate : police (Arial, Courier…), taille (10, 12…), graisse (standard, gras…), italique (oui/non) et souligné (oui/non).
Ce formulaire aurait cet aspect :
Son contenu se limite à une étiquette :
- avec un texte quelconque ;
- mais écrit sur plus d'une ligne (présence d'un retour chariot indispensable) ;
- et dont la dimension a été ajustée au moyen de la méthode .SizeToFit décrite plus haut.
La ruse va consister à créer provisoirement ce formulaire, pendant une fraction de seconde : le temps d'utiliser son étiquette pour redimensionner notre zone de texte.
IV-B. La fonction AjusterZdt()▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
Option
Compare Database
Option
Explicit
Public
Function
AjusterZdt
(
NomZdt As
String
) As
Long
On
Error
GoTo
GestionErreurs
Dim
frm As
Form
Dim
ctlEtiquette As
Control
Dim
iQuiAppelle As
Integer
'figer l'écran
Application.Echo
False
'Mémoriser le type d'objet qui appelle (formulaire ou état)
iQuiAppelle =
CurrentObjectType
'Créer un formulaire martyr
Set
frm =
CreateForm
'Créer une étiquette dans sa section Détail.
Set
ctlEtiquette =
CreateControl
(
frm.Name
, acLabel)
With
ctlEtiquette
.Name
=
"lblTexteCible"
.Caption
=
"Cette étiquette doit contenir"
&
vbCrLf
&
"un retour chariot "
.SizeToFit
'pour ajuster sa taille
'Affecter les propriétés de la fonte du texte de l'appelant
If
iQuiAppelle =
acForm Then
'c'est un formulaire qui appelle
.FontName
=
Forms
(
CodeContextObject.Name
)(
NomZdt).FontName
.FontSize
=
Forms
(
CodeContextObject.Name
)(
NomZdt).FontSize
.FontBold
=
Forms
(
CodeContextObject.Name
)(
NomZdt).FontBold
.FontItalic
=
Forms
(
CodeContextObject.Name
)(
NomZdt).FontItalic
.FontWeight
=
Forms
(
CodeContextObject.Name
)(
NomZdt).FontWeight
'On fixe la largeur et on copie le texte de la zdt dans l'étiquette
.Width
=
Forms
(
CodeContextObject.Name
)(
NomZdt).Width
.Caption
=
Nz
(
Forms
(
CodeContextObject.Name
)(
NomZdt), " "
)
Else
' c'est donc un état qui appelle
.FontName
=
Reports
(
CodeContextObject.Name
)(
NomZdt).FontName
.FontSize
=
Reports
(
CodeContextObject.Name
)(
NomZdt).FontSize
.FontBold
=
Reports
(
CodeContextObject.Name
)(
NomZdt).FontBold
.FontItalic
=
Reports
(
CodeContextObject.Name
)(
NomZdt).FontItalic
.FontWeight
=
Reports
(
CodeContextObject.Name
)(
NomZdt).FontWeight
'On fixe la largeur et on copie le texte de la zdt dans l'étiquette
.Width
=
Reports
(
CodeContextObject.Name
)(
NomZdt).Width
.Caption
=
Nz
(
Reports
(
CodeContextObject.Name
)(
NomZdt), " "
)
End
If
'on ajuste
.SizeToFit
'On récupère la hauteur
AjusterZdt =
.Height
End
With
'Supprimer le formulaire martyr
DoCmd.Close
acForm, frm.Name
, acSaveNo
'Rétablir l'écran
Application.Echo
True
Exit
Function
GestionErreurs
:
Select
Case
Err
.Number
Case
2176
'Fermer le formulaire martyr
DoCmd.Close
acForm, frm.Name
, acSaveNo
MsgBox
"Votre texte est trop long, il contient plus de 2040 caractères"
, vbCritical
AjusterZdt =
500
Case
Else
MsgBox
Err
.Number
&
" "
&
Err
.Description
End
Select
End
Function
Commentaires du code
4 : le seul paramètre à passer à la fonction, c'est le nom de la zone de texte, on verra plus loin comment la fonction est capable de connaître le nom du formulaire qui la sollicite.
La fonction retourne un nombre entier qui représente la hauteur de l'étiquette (exprimée en twips).
10 : le processus va durer une fraction de seconde, l'utilisateur percevrait juste un scintillement de l'écran, le temps d'ouvrir fMartyr, torturer son étiquette, récupérer sa hauteur et refermer.
Pour éviter le scintillement, on gèle temporairement l'affichage, on le rétablira en fin de processus (instruction 49).
12 : cette fonction est conçue pour répondre à l'appel d'un formulaire ou d'un état. Dans la suite des commentaires, nous verrons qu'il faut pouvoir distinguer quel est le type de l'appelant pour déterminer le code. On mémorise dans iQuiAppelle - qui servira d'aiguillage - le type de l'objet appelant.
À cet instant, CurrentObjectType contient le type de l'objet actif, c'est-à-dire le formulaire ou l'état qui vient d'appeler la fonction.
14-47 : on créer un formulaire à la volée.
16 : on y ajoute une étiquette…
18 : … que l'on nomme « lblTexteCible »…
19 : … et une légende quelconque, mais qui contient un retour chariot…
20 : … on ajuste sa dimension avec la méthode .SizeToFit décrite plus haut…
22-40 : … on aligne ses propriétés de fonte sur celles de notre zone de texte, selon que l'appelant est un formulaire ou un état.
Remarquez comment le formulaire est référencé : Forms(CodeContextObject.Name).
Access dispose de la propriété CodeContextObject. Elle permet de déterminer dans quel objet, du code Visual Basic est en cours d'exécution.
Quand la routine AjusterZdt() s'exécute : CodeContextObject représente l'objet qui a déclenché l'exécution. Il hérite alors de toutes les propriétés de ce dernier.
Par exemple, si le formulaire fUnFormulaire appelle AjusterZdt(), nous aurons : CodeContextObject.name égal à « fUnFormulaire » pendant que AjusterZdt() s'exécute.
29-30 et 38-39 : on aligne sa largeur et sa légende sur celles de notre zone de texte.
42 : on la redimensionne. À ce stade, sa légende prend l'apparence que nous voulons obtenir dans notre zone de texte.
44 : on affecte à la fonction la hauteur (en twips) de l'étiquette remodelée.
47 : on ferme le formulaire martyr sans le sauver.
49 : on rétablit l'affichage.
52-57 : une erreur N° 2176 survient si le texte que l'on affecte à l'étiquette dépasse 2040 caractères.
L'aide Access renseigne pourtant une limite de 2048.
Je propose de ne pas ergoter sur les huit caractères, c'est probablement une conséquence du réajustement .SizeToFit.
D'autant plus que 2040 caractères c'est par exemple tout ceci :
Pas sûr que la limite de 2040 caractères soit une vraie contrainte, car encore faut-il que votre formulaire puisse accepter une zone de texte aussi grande ! Sinon ceci :
IV-C. La syntaxe de l'appel▲
C'est probablement dans l'événement « Sur activation » de votre formulaire que vous allez éprouver le besoin de redimensionner une zone de texte.
L'instruction sera simplement :
Private
Sub
Form_Current
(
)
Me.LeNomDeLaZoneDeTexte.Height
=
AjusterZdt
(
"LeNomDeLaZoneDeTexte"
)
End
Sub
N'oubliez pas d'ajouter la référence Microsoft DAO x.x Object Library.
V. Exemples d'application▲
V-A. Dans un formulaire, positionner deux zones de texte extensibles l'une en dessous de l'autre▲
Voir la question sur le forum.
V-A-1. Ceci comme résultat▲
V-A-2. Le formulaire en construction▲
V-A-3. Le code associé à l'événement « Sur activation »▲
Option
Compare Database
Option
Explicit
Private
Sub
Form_Current
(
)
On
Error
GoTo
GestionErreurs
'Ajuster la hauteur du commentaire1
If
Not
IsNull
(
Me.txtCommentaire1
) Then
Me.txtCommentaire1.Height
=
AjusterZdt
(
"txtCommentaire1"
)
Else
Me.txtCommentaire1.Height
=
0
End
If
'Positionner le commentaire2
Me.txtCommentaire2.Top
=
Me.txtCommentaire1.Top
+
Me.txtCommentaire1.Height
+
50
'Ajuster la hauteur du commentaire2
If
Not
IsNull
(
Me.txtCommentaire2
) Then
Me.txtCommentaire2.Height
=
AjusterZdt
(
"txtCommentaire2"
)
Else
Me.txtCommentaire2.Height
=
0
End
If
Exit
Sub
GestionErreurs
:
Select
Case
Err
.Number
Case
2100
' pas assez de place
MsgBox
"L'espace manque pour afficher la zone de texte !"
, vbCritical
Me.txtCommentaire1.Height
=
500
Me.txtCommentaire2.Height
=
500
'Positionner le commentaire2
Me.txtCommentaire2.Top
=
Me.txtCommentaire1.Top
+
Me.txtCommentaire1.Height
+
50
Case
Else
MsgBox
Err
.Number
&
" "
&
Err
.Description
End
Select
End
Sub
V-B. Centrer verticalement une zone de texte « Auto extensible » dans un état Access▲
La question posée sur le forum.
V-B-1. Le but du jeu▲
On a un texte d'une longueur variable logé dans une zone de texte auto-extensible.
On voudrait que cette zone de texte soit centrée verticalement par rapport à d'autres contrôles de l'état, comme ceci :
V-B-2. Le nœud du problème : la hauteur instantanée de la zone de texte▲
Si on connaissait la hauteur que prend la zone de texte lorsqu'elle a affiché le texte de l'enregistrement, on pourrait facilement calculer la position que doit prendre la zone de texte et coder la formule dans l'événement « Au formatage » de la section de l'état qui contient ce contrôle. En effet, à ce stade de l'édition de l'état, Access permet encore de modifier la position des contrôles avant de les imprimer.
Nous allons utiliser la fonction AjusterZdt() pour trouver « HauteurZdt ».
V-B-3. Le code associé à l'événement « Au formatage » de la section de l'état qui contient ce contrôle▲
Option
Compare Database
Option
Explicit
Private
Sub
Détail_Format
(
Cancel As
Integer
, FormatCount As
Integer
)
Dim
HauteurZdt As
Integer
'Déterminer la hauteur instantanée de la zone de liste
Me.LaZdt.Height
=
AjusterZdt
(
"LaZdt"
)
'Positionner la zdt
Me.LaZdt.Top
=
Me.ZoneDeReference.Top
+
(
ZoneDeReference.Height
-
Me.LaZdt.Height
) /
2
Exit
Sub
End
Sub
VI. Téléchargement▲
La base de données se trouve https://claudeleloup.developpez.com/tutoriels/access/zone-de-texte-extensible/ZdtExtensible.mdb.
VII. Remerciements▲
Merci à Jean-Philippe André et à Fabrice Constans (loufab) pour leur relecture technique et à Malick Seck pour la relecture orthographique.