par , 21/11/2021 à 01h58 (8724 Affichages)
La notion de CONTENEUR de formulaire
La subtilité avec les sous-formulaires c'est la notion de CONTENEUR de FORMULAIRE. Et au contraire des autres contrôles, il n'existe pas dans la liste des objets ActivX.
Le CONTENEUR est généré automatiquement quand le formulaire est placé dans un autre formulaire par Drag & Drop.
Et pour ajouter à la confusion, le nom du CONTENEUR est par défaut le même que celui du formulaire placé par Drag & Drop dans le formulaire père.
Mais il est tout a fait possible de renommer le CONTENEUR via sa propriété NAME (NOM) dans l'onglet AUTRE.
Le CONTENEUR permet l'instanciation du formulaire associé via l'OBJET SOURCE, propriété dans l'onglet DATA (DONNÉES)
Par conséquent, pour accéder aux contrôles du formulaire instancié dans le CONTENEUR, il faut d'abord appeler le CONTENEUR puis ensuite cibler les éléments du formulaire en partant toujours du formulaire père.
Il faut bien comprendre que le CONTENEUR est un contrôle du formulaire père.
Imaginons un formulaire qui affichent 2 sous-formulaires
Le formulaire frmMain affiche les formulaires
- frmEntreprise (feuille de données)
- frmFacture liées à l'entreprise sélectionnée (feuille de données)
Comme indiqué plus haut, les sous-formulaires frmEntreprise & frmFactures sont placés dans des CONTENEURS ayant par défaut le même nom que le formulaire suite au Drag & Drop des sous-formulaires dans le formulaire père.
Dans notre exemple, les CONTENEURS auront par défaut respectivement le nom de:
Donc pour éviter toute confusion entre les formulaires et les CONTENEURS , j'utilise le préfixe ctnr pour les identifier.
Les CONTENEURS via la propriété NOM dans l'onglet AUTRE sont renommés respectivement :
- ctnrEntreprise
- ctnrFacture
Pour rappel, quand on clique sur une ligne du formulaire frmEntreprise, le formulaire frmFacture affiche les facture de l'entreprise courante sélectionnée dans frmEntreprise.
N.B.:
La solution proposée n'est donc la création d'un champ dans frmMain faisant référence à un champ du formulaire Entreprise qui est ensuite associé via champ père/fils du CONTENEUR du formulaire frmFactures
La solution étudiée est de modifier le RECORDSOURCE du formulaire frmFacture .
Comment accéder aux sous-formulaires par l'exemple
Bien se rappeler qu'un CONTENEUR est un CONTRÔLE et non un formulaire.
Donc l'action de cliquer sur le formulaire frmEntreprise dans le CONTENEUR ctnrEntreprise doit modifier le RECORDSOURCE du formulaire frmFacture dans le CONTENEUR ctnrFacture.
Bien garder en tête qu'il faut le "chemin entier" depuis le formulaire père (frmMain) jusqu'au formulaire cible (frmFacture)
L'appel du père depuis frmEntreprise peut se faire de plusieurs façons
- forms("frmMain")
- forms![frmMain]
- Me.parent
Maintenant il faut modifier le RECORDSOURCE de frmFacture
En raison de l'équivalence entre ![ ] et .CONTROLS(""), il existe plusieurs possibilités pour appeler un CONTENEUR :
- .CONTROLS("ctnrFacture")
- ![ctnrFacture]
Mais le RECORDSOURCE est une propriété du formulaire, il faut donc "pointer" l'instance de frmFacture par .FORM d'ou
.FORM.RECORDSOURCE = "LaSource"
On obtient la commande complète suivante:
1 2
| forms("frmMain").form.controls("ctnrFacture").form.recordsource = "MaSource"
forms("frmMain").form.controls("ctnrFacture").form.requery 'pour rafraichir les données |
Mais en raison de l'équivalence de ![ ] avec .CONTROLS(""), il est possible d'écrire :
Forms("frmMain").form![ctnrFacture].form.recordsource = "MaSource
Il est possible de simplifier cette écriture car comme la COLLECTION CONTROLS est la collection par défaut de l'objet formulaire (Form) , .Form n'est pas nécessaire pour appeler .CONTROLS(" ")
Mais attention, cela n'est valable que pour CONTROLS. D'où la commande suivante:
Forms("frmMain")![ctnrFacture].form.recordsource = "MaSource
Par extension
Pour modifier une propriété d'un champ (couleur de fond par exemple), la commande serait toujours par principe de l'équivalence entre ![ ] et .CONTROLS(" ") et l'appel à la collection CONTROLS par défaut
1 2 3
|
lngWhite = RGB(255, 255, 255)
Forms("frmMain")![ctnrFacture]![textChamp].BackColor = lngWhite |
Sources:
Grenier access : sous-formulaires & container