Vos recrutements informatiques

700 000 développeurs, chefs de projets, ingénieurs, informaticiens...

Contactez notre équipe spécialiste en recrutement

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

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 : 9 commentaires Donner une note à l'article (5) 

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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.

Image non 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.

Image non disponible

3° Pour adapter la taille de votre zone de texte, saisissez ce code dans l'événement « Sur activation » de votre formulaire.

 
Sélectionnez
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.

Image non disponible

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

Image non disponible

Cependant, si vous avez la bonne habitude d'utiliser la touche F1, vous savez que ce n'est pas la panacée :

Image non disponible

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.

Image non disponible

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

Image non disponible

Ce formulaire aurait cet aspect :

Image non disponible

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

 
Sélectionnez
1.
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

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

Image non disponible

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 :

Image non disponible

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 :

Image non disponible

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 :

 
Sélectionnez
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

Image non disponible

V-A-2. Le formulaire en construction

Image non disponible

V-A-3. Le code associé à l'événement « Sur activation »

 
Sélectionnez
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 :

Image non disponible

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

Image non disponible

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.

Image non disponible

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

 
Sélectionnez
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

VII. Remerciements

Merci à Jean-Philippe André et à Fabrice Constans (loufab) pour leur relecture technique et à Malick Seck pour la relecture orthographique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

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.