Dans un formulaire Access, une zone de texte qui s'adapte à son contenu

Claude Leloup

Dans un formulaire, Access ne propose pas d'emblée la possibilité d'afficher à l'écran une zone de texte dont la hauteur s'adapte automatiquement à son contenu.

Voici une fonction qui pallie cette lacune dans le cas d'un formulaire affiché en mode simple.

Si vous souhaitez réagir : Commentez

- Titre : Dans un formulaire Access, une zone de texte qui s'adapte à son contenu

- Auteur : Claude Leloup

- Parution : 5 octobre 2014

- Mise à jour : 4 juin 2016

- 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 ® 2014 Claude Leloup. 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.

Sommaire

- I. Reconnaissance

- II. Avertissement

- III. Si vous êtes pressé, voici comment utiliser la fonction

- IV. Et si vous voulez savoir comment ça marche…

- IV-A. Il va falloir ruser ! Voici l'idée

- IV-B. La fonction AjusterZdt()

- IV-C. La syntaxe de l'appel

- V. Exemples d'application

- V-A. Dans un formulaire, positionner deux zones de texte extensibles l'une en dessous de l'autre

- 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 »

- V-B. Centrer verticalement une zone de texte « Auto extensible » dans un état Access

- V-B-1. Le but du jeu

- V-B-2. Le nœud du problème : la hauteur instantanée de la zone de texte

- V-B-3. Le code associé à l'événement « Au formatage » de la section de l'état qui contient ce contrôle

- VI. Téléchargement

- VII. Remerciements

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()

1. Option Compare Database

2. Option Explicit

4. Public Function AjusterZdt(NomZdt As String) As Long

5. On Error GoTo GestionErreurs

6. Dim frm As Form

7. Dim ctlEtiquette As Control

8. Dim iQuiAppelle As Integer

9. 'figer l'écran

10. Application.Echo False

11. 'Mémoriser le type d'objet qui appelle (formulaire ou état)

12. iQuiAppelle = CurrentObjectType

13. 'Créer un formulaire martyr

14. Set frm = CreateForm

15. 'Créer une étiquette dans sa section Détail.

16. Set ctlEtiquette = CreateControl(frm.Name, acLabel)

17. With ctlEtiquette

18. .Name = "lblTexteCible"

19. .Caption = "Cette étiquette doit contenir" & vbCrLf & "un retour chariot "

20. .SizeToFit 'pour ajuster sa taille

21. 'Affecter les propriétés de la fonte du texte de l'appelant

22. If iQuiAppelle = acForm Then 'c'est un formulaire qui appelle

23. .FontName = Forms(CodeContextObject.Name)(NomZdt).FontName

24. .FontSize = Forms(CodeContextObject.Name)(NomZdt).FontSize

25. .FontBold = Forms(CodeContextObject.Name)(NomZdt).FontBold

26. .FontItalic = Forms(CodeContextObject.Name)(NomZdt).FontItalic

27. .FontWeight = Forms(CodeContextObject.Name)(NomZdt).FontWeight

28. 'On fixe la largeur et on copie le texte de la zdt dans l'étiquette

29. .Width = Forms(CodeContextObject.Name)(NomZdt).Width

30. .Caption = Nz(Forms(CodeContextObject.Name)(NomZdt), " ")

31. Else  ' c'est donc un état qui appelle

32. .FontName = Reports(CodeContextObject.Name)(NomZdt).FontName

33. .FontSize = Reports(CodeContextObject.Name)(NomZdt).FontSize

34. .FontBold = Reports(CodeContextObject.Name)(NomZdt).FontBold

35. .FontItalic = Reports(CodeContextObject.Name)(NomZdt).FontItalic

36. .FontWeight = Reports(CodeContextObject.Name)(NomZdt).FontWeight

37. 'On fixe la largeur et on copie le texte de la zdt dans l'étiquette

38. .Width = Reports(CodeContextObject.Name)(NomZdt).Width

39. .Caption = Nz(Reports(CodeContextObject.Name)(NomZdt), " ")

40. End If

41. 'on ajuste

42. .SizeToFit

43. 'On récupère la hauteur

44. AjusterZdt = .Height

45. End With

46. 'Supprimer le formulaire martyr

47. DoCmd.Close acForm, frm.Name, acSaveNo

48. 'Rétablir l'écran

49. Application.Echo True

50. Exit Function

51. GestionErreurs:

52. Select Case Err.Number

53. Case 2176

54. 'Fermer le formulaire martyr

55. DoCmd.Close acForm, frm.Name, acSaveNo

56. MsgBox "Votre texte est trop long, il contient plus de 2040 caractères", vbCritical

57. AjusterZdt = 500

58. Case Else

59. MsgBox Err.Number & " " & Err.Description

60. End Select

61. 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.