Developpez.com

Plus de 2 000 forums
et jusqu'à 5 000 nouveaux messages par jour

Comment ajuster la taille d'un sous-formulaire en fonction du nombre de ses enregistrements

Voici une occasion pour vous familiariser avec les instructions VBA qui permettent de manipuler les propriétés d'un formulaire. 1 commentaire Donner une note à l'article (5) 

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Ce dont il s'agit

Imaginez un formulaire pour comptabiliser les opérations bancaires d'une association caritative.

Un formulaire père avec quatre fils qui détaillent les différents mouvements enregistrés à l'extrait de la banque. (Exemple repris de Tutoriel pour gérer une association avec Access)

Dans une première approche, ceci :

Image non disponible

Dans la section pied de chacun des sous-formulaires, deux infos (en gris foncé) :

- le nombre de postes détaillés ;

- le total de ces postes.

Le pied s'affiche au bas de l'espace que nous avons réservé au conteneur du sous-formulaire :

Image non disponible

Et ce, quel que soit le nombre de lignes que comporte le détail.

Ce que nous souhaitons, c'est que le pied soit collé juste en dessous de la dernière ligne de détail, comme ceci :

Image non disponible

Bref, ce que nous voulons, c'est que la hauteur de l'espace réservé aux conteneurs des sous-formulaires s'adapte automatiquement pour que la section Pied apparaisse juste en dessous du dernier détail (ou de l'espace réservé à l'encodage du suivant).

Et si le nombre de lignes de détail s'avère trop grand pour les afficher toutes, nous ajouterons une barre de défilement verticale au sous-formulaire concerné.

II. Préparons le terrain

II-A. Convention de nommage

Les conteneurs des sous-formulaires seront nommés : CTNRnomDuSousFormulaire.

Exemple

Image non disponible

II-B. Des repères pour indiquer la hauteur maximum des sous-formulaires

Nous insérons dans le formulaire principal un contrôle « Trait » par sous-formulaire pour indiquer la limite de sa hauteur maximale autorisée.

Nous convenons de nommer ces contrôles : « BasCTNRnomDuSousFormulaire » et leur propriété « Visible » est positionnée sur Non :

Image non disponible

III. Une sous-routine pour adapter la hauteur du conteneur de sous-formulaire

III-A. Le code

AmenagerTailleSF
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.
Option Compare Database
Option Explicit

Public Sub AmenagerTailleSF(LeForm As Access.Form, LeSF As Access.SubForm)
  Dim EspaceNecessaire As Long, EspaceLibre As Long, iAffichables As Integer
  On Error GoTo GestionErreurs
     
     With LeSF
     'Calculer l'espace nécessaire pour afficher tous les enregistrements
     .Form.RecordsetClone.MoveLast 'pour pouvoir ensuite compter le nbre d'enregistrements
     EspaceNecessaire = .Form.Section(acHeader).Height _
                  + .Form.Section(acFooter).Height _
                  + .Form.Section(acDetail).Height _
                       * (.Form.RecordsetClone.RecordCount - .Form.AllowAdditions) 'Ceci revient à ajouter 1 si ajout autorisé
                                                                              
     'Calculer l'espace disponible et le nbre d'enregistrements affichables
     EspaceLibre = LeForm("Bas" & LeSF.Name).Top - .Top
     iAffichables = Int(((EspaceLibre - .Form.Section(acHeader).Height - .Form.Section(acFooter).Height) / _
                    .Form.Section(acDetail).Height))
                    
     'Limitation au maximum possible
     If EspaceNecessaire > EspaceLibre Then  'trop pour tout afficher
         .Height = EspaceLibre
         .Form.InsideHeight = EspaceLibre
         .Form.ScrollBars = 2 'pour afficher une barre de défilement verticale
         'Afficher les derniers enregistrements de la liste
         .SetFocus
         DoCmd.GoToRecord , , acNewRec 'afficher l'emplacement de l'ajout si permis, sinon erreur 2105 et instruction suivante
         DoCmd.GoToRecord , , acLast
         DoCmd.GoToRecord , , acPrevious, iAffichables - 1 + .Form.AllowAdditions
         'se positionner sur le dernier
         DoCmd.GoToRecord , , acLast
       Else
        .Height = EspaceNecessaire
        .Form.InsideHeight = EspaceNecessaire
        .Form.ScrollBars = 0  ' pas de barre de défilement verticale
        'Afficher tous les enregistrements et se positionner sur le dernier
        .SetFocus
        DoCmd.GoToRecord , , acFirst
        DoCmd.GoToRecord , , acLast
     End If
  End With
GestionErreurs:
  Select Case Err.Number
      Case 0        'Pas d'erreur
        Exit Sub
      Case 3021     'Pas d'enregistrement dans le sous-formulaire
        Resume Next
      Case 2105 'Pas d'ajout permis dans le sous-formulaire
        Resume Next
      Case Else
        MsgBox "Erreur dans AmenagerTailleSF : " & vbLf & " erreur : " & Err.Number & " " & Err.Description, vbCritical
  End Select
End Sub

III-B. Explication du code

4 : la procédure demande deux paramètres : l'objet formulaire qui appelle et l'objet conteneur du sous-formulaire qui doit être redimensionné.

7 : les instructions With et End With (ligne 42) permettent d'abréger l'écriture. Entre ces deux instructions au lieu d'écrire par exemple
« LeSf.Form.Section(acHeader).Height »
on pourra abréger et n'écrire que « .Form.Section(acHeader).Height ».

9-14 : on calcule la hauteur qui serait nécessaire pour afficher tous les enregistrements.

Image non disponible

On additionne la hauteur de la section « En-tête », la hauteur de la section « Pied » et autant de fois la hauteur de la section « Détail » qu'il y a d'enregistrements à afficher.

On ajoute encore à cela une fois la hauteur de la section « Détail » pour l'espace (éventuel) d'un ajout d'un nouvel enregistrement.

N.B. Si les ajouts sont autorisés la propriété .Form.AllowAdditions vaut -1, sinon 0.

17 : par différence entre la propriété « Haut » du trait repère et celle du sous-formulaire, on détermine l'espace maximum que peut occuper le sous-formulaire déployé.

Image non disponible

18 - 19 : le nombre d'enregistrements qui pourront s'afficher ensemble égale la partie entière Ent() du quotient de la hauteur disponible divisée par la hauteur d'une section détail.

21 - 41 : de deux choses l'une :
- EspaceNecessaire > EspaceLibre => il n'y a pas assez de place pour tout afficher :

23 : on attribue au sous-formulaire la hauteur maximum disponible,

24 : on ajuste la fenêtre,

25 : on ajoute une barre de défilement verticale,

27 - 32 : on fait voyager le sélecteur pour afficher toutes les dernières lignes. Y compris la ligne vierge pour l'ajout éventuel. Une erreur 2105 sera levée si la propriété « Ajout autorisé » est à Non. Cette erreur éventuelle est trappée et on continue ;

- on a assez de place pour tout montrer :

34 : on attribue au sous-formulaire la hauteur nécessaire,

35 : on ajuste la fenêtre,

36 : sans barre de défilement,

38 - 40 : on met le focus sur le dernier enregistrement.

IV. Quand et comment déclencher cette sous-routine

IV-A. À chaque lecture d'un enregistrement du formulaire principal

Nous aurons donc, dans l'événement « Sur activation » :

 
Sélectionnez
Option Compare Database
Option Explicit

Private Sub Form_Current()
    'Moduler la taille des sous-formulaires
    Call AmenagerTailleSF(Me, Me.CTNRsfDons)
    Call AmenagerTailleSF(Me, Me.CTNRsfAutresRecettes)
    Call AmenagerTailleSF(Me, Me.CTNRsfFrais)
    Call AmenagerTailleSF(Me, Me.CTNRsfActionsHum)

End Sub

IV-B. À chaque ajout ou suppression d'enregistrement dans le sous-formulaire

Donc lors des événements « Après insertion » et « Après suppression » :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Option Compare Database
Option Explicit

Private Sub Form_AfterDelConfirm(Status As Integer)
    Call AmenagerTailleSF(Me.Parent, Me.Parent.ActiveControl): Me.Requery
End Sub

Private Sub Form_AfterInsert()
    Call AmenagerTailleSF(Me.Parent, Me.Parent.ActiveControl): Me.Requery
End Sub

On peut écrire plusieurs instructions sur une même ligne de code, en les séparant par un deux-points. (Par exemple, lignes 5 et 9.)

V. Téléchargement

L'exemple en version Access2000 peut être téléchargé ici.

VI. Remerciements

Merci à Pierre Fauconnier pour ses remarques techniques au sujet de la syntaxe des gestions d'erreurs (utilisation de Case 0 pour éviter des Exit Sub dans le corps de la procédure).

Merci à Arkham46 pour l'amélioration du code : passer les objets en paramètres, plutôt que leur nom. En l'occurrence écrire
Public Sub AmenagerTailleSF(LeForm As Access.Form, LeSF As Access.SubForm)
plutôt que
Public Sub AmenagerTailleSF(LeNomDuForm as String, LeNomDuSubForm As String).

Merci à f-leb pour la correction 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 © 2015 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.