Les syntaxes d'appel Interaction des formulaires et des états.

Fabrice Constans

La richesse d'une interface Microsoft ACCESS passe nécessairement par l'interaction des objets. Qu'il s'agisse de formulaires ou d'états, Microsoft ACCESS donne la possibilité de faire appel à l'intégralité des propriétés et des contrôles qu'ils contiennent. Au terme de ce tutoriel, vous serez à même de faire référence à n'importe quels contrôles et propriétés situés dans n'importe quels formulaires ou états de votre application.

- Titre : Les syntaxes d'appel Interaction des formulaires et des états.

- Auteur : Fabrice Constans

- Parution : 24 mars 2007

- Mise à jour : 1 octobre 2009

- Licence : Copyright ® 2009 Fabrice CONSTANS. 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. Avertissement

- II. La théorie

- II-A. Formulaires ou états même combat

- II-B. Affectation de valeurs

- II-C. Récupération de valeurs

- II-D. Interaction formulaires et états

- II-E. Tests

- III. Syntaxes et Situations

- III-A. Module de classe

- III-B. Module

- III-C. Expression dans les contrôles

- III-C-1. Pour une référence à un autre formulaire ou état

- III-C-2. Dans le même formulaire ou état

- III-D. Requêtes

- III-E. Cas particulier

- III-F. Variation autour de Forms/Reports

- III-F-1. La pile et son fonctionnement

- III-G. Autres listes

- IV. Sous-formulaire, sous-état

- IV-A. Descendre dans les niveaux

- IV-B. Remonter dans les niveaux

- IV-C. Utilisation avec une variable objet

- IV-D. Une erreur gênante

- V. Déclaration d'objets

- VI. Tableau récapitulatif

- VII. Remerciements

I - Avertissement

L'utilisation de la touche F1 est vivement conseillée à tous les stades de l'utilisation d'ACCESS. L'amélioration constante de l'aide en fait un partenaire de choix dans l'apprentissage permanent d'ACCESS. Personnellement, je ne peux m'en passer, ne serait-ce que pour mémoire.

II - La théorie

Les appels permettent de manipuler les objets formulaires, les états, les contrôles et les propriétés. Les usages sont multiples :

- vérification et modification de propriétés ;

- affectation et récupération de valeurs ;

- relation entre formulaires, sous-formulaires ;

- relation entre états, sous-états ;

- activation de contrôles, de formulaires, d'états ;

- récupération d'information pour les requêtes.

Toutes les manipulations sur les valeurs des contrôles doivent être faites sur des objets formulaires et états ouverts en mode normal.

Les propriétés des contrôles sont accessibles, quel que soit le mode d'ouverture du formulaire ou de l'état.

II-A - Formulaires ou états même combat

Qu'il s'agisse de formulaires ou d'états, la structure de la syntaxe d'appel est identique. Seuls les mots clefs différenciant formulaires et états changent. En effet, pour les formulaires, nous utiliserons Forms et pour les états Reports.

Tableau des mots clefs disponibles dans un contexte.

Contexte/Mots clefs

Forms, Reports

Formulaires, États

Contrôles

Oui

Oui

Requêtes

Oui

Oui

Macros

Oui

Oui

VBA

Oui

Non

Forms et Reports sont les mots clefs natifs. Préférez l'utilisation de ceux-ci, vous éviterez ainsi les mélanges entre terminologie française et anglo-saxonne. Formulaires et États sont propres à l'installation francophone d'Office.

Évitez les espaces et caractères réservés dans les noms des objets (formulaires, états et contrôles, requêtes, tables et champs) vous éviterez l'adjonction des crochets [] de délimitation des noms.

VBA n'ajoute pas les crochets [] de délimitation des noms, vous devez les ajouter manuellement. C'est une source d'erreurs et toujours une perte de temps.

Ci-dessous quelques exemples d'appels valides :

Appel

Description

Forms.monform

Désigne le formulaire monform quel que soit le contexte.

Formulaires.monform

Désigne le formulaire monform dans les contrôles et les requêtes.

Reports.monreport

Désigne l'état monreport quel que soit le contexte.

Etats.monreport

Désigne l'état monreport dans les contrôles et les requêtes.

Forms.[mon form]

Dans le cas de l'utilisation des espaces dans le nom.

II-B - Affectation de valeurs

Lorsque la propriété d'un contrôle est modifiable, nous pouvons agir sur celle-ci de la manière suivante :

Affecter le contenu de la variable

Forms.monform.moncontrole.nom_de_propriété = Variable

Pour le contenu d'un contrôle, procédez de la même manière.

II-C - Récupération de valeurs

La récupération des valeurs des propriétés ou de contenus se fait de la manière suivante :

Récupérer la valeur dans la variable

Variable = Forms.monform.moncontrole.nom_de_propriété

II-D - Interaction formulaires et états

On peut communiquer entre formulaires, états, états et formulaires et vice-versa.

La syntaxe est : Récepteur = Émetteur

Formulaire vers formulaire

' 2 formulaires différents
Forms.monform1.moncontrole.nom_de_propriété = Forms.monform2.moncontrole.nom_de_propriété
' dans le même formulaire
Forms.monform1.moncontrole.nom_de_propriété = Forms.monform1.moncontrole.nom_de_propriété

Notez que le premier exemple peut être appliqué aux suivants :

État vers état

Reports.monreport.moncontrole.nom_de_propriété = Reports.monreport.moncontrole.nom_de_propriété

Formulaire vers état et vice-versa

' le formulaire reçoit la valeur de l'état
Forms.monform.moncontrole.nom_de_propriété = Reports.monreport.moncontrole.nom_de_propriété

' l'état reçoit la valeur du formulaire.
Reports.monreport.moncontrole.nom_de_propriété = Forms.monform.moncontrole.nom_de_propriété

II-E - Tests

Pour les tests de valeurs, la syntaxe est strictement identique.

comparaison de propriété

If Forms.monform.moncontrole.nom_de_propriété = Forms.monreport.moncontrole.nom_de_propriété then

III - Syntaxes et Situations

Quel que soit l'emplacement, vous pouvez utiliser les syntaxes précédentes. Il existe d'autres syntaxes que nous allons présenter dans leur situation.

III-A - Module de classe

Le module de classe est le module attaché à un formulaire ou à un état. Lorsque vous faites référence à l'un de ces deux objets ou à leurs contrôles à l'intérieur de leur module respectif, vous pouvez utiliser l'objet Me. Celui-ci est équivalent à la syntaxe vue précédemment Forms.nom_formulaire ou Reports.nom_état.

Lorsque vous tapez le point après Me, vous pouvez apercevoir qu'une liste très fournie apparait.

Liste déroulante

Cette liste contient les contrôles utilisateur, les méthodes et les propriétés disponibles pour le formulaire ou l'état courant.

Au contraire, la liste qui apparait pour Forms ou Reports est beaucoup moins riche.

Encore une liste…

Me ne fonctionne pas dans un module classique. Il fait toujours référence à son propriétaire direct, jamais à son parent.

III-B - Module

Dans un module classique, inutile d'utiliser Me. Il ne peut exister puisqu'il fait référence à un formulaire ou un état propriétaire.
Vous devez utiliser Forms ou Reports.

III-C - Expression dans les contrôles

Me n'est pas disponible dans les propriétés des contrôles.

III-C-1 - Pour une référence à un autre formulaire ou état

Le cas des expressions dans les propriétés des contrôles n'est pas particulier puisque l'on peut également utiliser Forms et Reports. Dans ce contexte, ceux-ci sont traduits automatiquement dans la langue d'installation. Pour les installations francophones, Forms devient [Formulaires] et Reports, [États]. Ils sont systématiquement bornés par les crochets lors de la traduction.

Dans la propriété source d'un contrôle

=forms.nom_form.name
' est automatiquement traduit en
=[Formulaires].[nom_form].[nom]

Notez que la propriété - Name dans l'exemple - est également traduite dans la langue d'installation.

III-C-2 - Dans le même formulaire ou état

Pour faire référence à un contrôle ou à une propriété de l'objet courant, vous pouvez omettre la syntaxe Forms.nom_form (Formulaires.nom_form pour les versions francophones) ou Report.nom_etat. Indiquez seulement le contrôle ou la propriété

Dans la propriété source d'un contrôle

=name
' est également traduit en
=[nom]

III-D - Requêtes

Dans les requêtes, vous pouvez également faire référence à un formulaire ou un état. Comme pour l'expression, utilisez Forms et Reports.

Requête SQL

SELECT Table.Champ, [forms].[nom_form].[nom_controle1] AS etiq
FROM Table
WHERE (((Table.Champ)=[forms].[nom_form].[nom_controle2]))
ORDER BY [forms].[nom_form].[nom_controle1];

On peut observer dans la requête précédente que les références à un formulaire peuvent se faire pour un champ, une condition ou un tri.

III-E - Cas particulier

Il existe deux syntaxes que nous n'avons pas abordées. Il s'agit de ActiveForm et ActiveReport. Celles-ci appartiennent à Application.Screen et désignent l'objet formulaire ou état actif à l'écran au moment de l'appel. Vous ne devez pas spécifier de nom de formulaire ou d'état.

Le cas ActiveForm et ActiveReport

' pour un formulaire
Application.Screen.ActiveForm
' pour un état
Application.Screen.ActiveReport

Elles sont disponibles dans les deux types de modules et dans les expressions.

Si vous utilisez ActiveForm ou ActiveReport à partir d'un sous-formulaire ou d'un sous-état, vous ferez systématiquement référence au formulaire ou état principal.

Dans les expressions, elles peuvent poser des problèmes à l'ouverture en affichant le message d'erreur #nom?.

Notez qu'il existe également ActiveControl qui fait appel au contrôle actif, quel que soit son propriétaire.

III-F - Variation autour de Forms/Reports

La richesse et la souplesse du langage VBA n'étant plus à démontrer, nous allons inventorier les différentes variations de Forms et Reports.

Syntaxe

Description

Forms.nom_form

Désigne le formulaire.

Forms!nom_form

Désigne le formulaire. Syntaxe propre à Microsoft ACCESS.

Forms("nom_form")

Désigne le formulaire. Le nom peut être remplacé par une variable String.

Forms(0)

Désigne le premier formulaire de la pile. 0 peut être remplacé par une variable Integer.

III-F-1 - La pile et son fonctionnement

La pile des formulaires et des états contient tous les formulaires et états ouverts. Ils sont rangés dans l'ordre chronologique de leur ouverture. 0 désigne le premier ouvert. Lorsque l'un d'eux est fermé, les suivants sont réorganisés en conséquence.

Notez que Option Base n'a aucune influence sur cette numérotation.

Lorsque le numéro est supérieur à celui admissible (nombre de formulaires ou états total ouverts -1), une erreur se produit.

Pour les formulaires :

2456 - Numéro de référence au formulaire non valide.

Pour les états :

2457 - Numéro de référence à l'état non valide.

Dans l'exemple de code suivant, nous listons le nom des formulaires ouverts.

Affiche le nom des formulaires et états ouverts

Sub ListeFormsOuvert()
Dim i As Integer
On Error Resume Next                 ' intercepte l'erreur
For i = 0 To Forms.Count -1          ' count est le nombre de formulaires ouverts
'Reports.Count -1      ' pour les reports
Debug.Print Forms(i).Name     ' pour les formulaires
' Debug.Print Reports(i).Name ' pour les reports
Next
End Sub

III-G - Autres listes

Après les listes de formulaires ou états ouverts, VBA met à notre disposition la collection AllForms et AllReports de l'objet CurrentProject. Ces deux collections contiennent tous les formulaires (AllForms) et tous les états (AllReports) du projet courant (CurrentProject).

Liste les noms des formulaires du projet. (Issu de l'aide ACCESS.)

Sub AllForms()
Dim obj As AccessObject, dbs As Object
Set dbs = Application.CurrentProject
' Recherche les objets AccessObject ouverts
' dans la collection AllForms.
For Each obj In dbs.AllForms
If obj.IsLoaded = TRUE then
' Affiche le nom de l'objet.
Debug.Print obj.Name
End If
Next obj
End Sub

Comme pour Forms, la collection AllForms dispose d'un éventail de syntaxes.

CurrentProjet n'est disponible qu'à partir de la version 2000.

Syntaxe

Description

AllForms(0)

Désigne le premier formulaire de la liste. 0 peut être remplacé par une variable Integer.

AllForms![nom_form]

Désigne le formulaire. Syntaxe propre à Microsoft ACCESS.

AllForms("nom_form")

Désigne le formulaire. Le nom peut être remplacé par une variable String.

IV - Sous-formulaire, sous-état

L'interaction entre formulaire et sous-formulaires ne s'arrête heureusement pas à la définition des propriétés Champs pères, Champs fils. En effet, Forms et Reports disposent de propriétés pour y accéder.

Appel vers sous-formulaire

Forms.nom_form.nom_sousform1.Form.nom_controle

La première partie de la commande n'a pas de secret pour nous, ses variations non plus. La seconde partie par contre mérite quelques commentaires.

Syntaxe

Description

Forms.nom_form

Désigne le formulaire contenant le sous-formulaire. Il peut être remplacé par Me dans son contexte et toutes les variations vues précédemment.

nom_sousform1.Form

Désigne le sous-formulaire nommé nom_sousform1. Ce formulaire est contenu dans un contrôle qui possède des propriétés. Pour indiquer que nous faisons référence à un contrôle ou une propriété du formulaire, il faut mettre le mot clef Form ou Report dans le cas d'un état.

.nom_controle

Désigne le contrôle situé dans le sous-formulaire.

Les mots clefs du langage VBA sont signalés en gras. Pour les états, remplacez Form par Report.

Appel vers sous-état

Reports.nom_report.nom_sousreport1.Report.nom_controle

IV-A - Descendre dans les niveaux

À partir de la syntaxe précédente, nous pouvons descendre de plusieurs niveaux dans les sous-formulaires ou sous-états.

sous-sous… formulaire.

En prenant l'exemple ci-dessus, nous allons développer une série de syntaxes pour accéder à chaque contrôle de texte.

1er niveau

' syntaxe module et module de classe
Forms.frm_principal.frm_sfrm1.Form.texte0
' syntaxe de module de classe
Me.frm_sfrm1.Form.texte0

2e niveau

Forms.frm_principal.frm_sfrm1.Form.frm_sfrm2.Form.texte0

On peut descendre dans les sous-formulaires jusqu'à la limite fixée par ACCESS. Cette limite est généralement indiquée dans l'aide ACCESS. Utilisez la recherche sur le mot Limitation pour avoir accès aux descriptifs des limitations de votre version.

IV-B - Remonter dans les niveaux

Suivant le contexte, remonter dans les niveaux se pratique de plusieurs manières. Dans un module, on peut utiliser la méthode pour descendre dans les niveaux.
Dans les modules de classe, il existe le pendant de Form et Report pour remonter dans la structure. Il s'agit du mot clef Parent dont l'utilisation est plus simple.

Module de classe

' descente d'un niveau
Me.Parent.texte0
' descente de deux niveaux
Me.Parent.Parent.texte0

Totalement inutile, la syntaxe suivante consiste à descendre dans le deuxième sous-formulaire pour remonter dans le premier sous-formulaire.

Module

Forms.frm_principal.frm_sfrm1.Form.frm_sfrm2.Parent.texte0

Cette syntaxe fait référence au contrôle Texte0 de frm_sfrm1. Elle est équivalente à la suivante.

Module

Forms.frm_principal.frm_sfrm1.Form.texte0

IV-C - Utilisation avec une variable objet

VBA Access permet également d'affecter un formulaire ou un état à une variable objet. Nous avons accès à l'ensemble de ses propriétés et contrôles, sous-formulaires ou sous-états.
Pour les formulaires et états du plus haut niveau, les avantages ne sont pas flagrants.

Objet Form et Formulaire

Function Appel_frm()
Dim frm As Form    ' ou Object
Set frm = Forms.frm_principal
Debug.Print frm.Name                  ' le nom du sous-formulaire
Debug.Print frm.frm_sfrm1.Form.Name   ' le nom du sous-formulaire
End Function

Vous pouvez utiliser le type Form pour les formulaires, Report pour les états ou Object pour l'un ou l'autre.

Plus intéressant, l'utilisation de l'objet pour y affecter un sous-formulaire ou sous-état en faisant abstraction de son ou ses parents. En effet, qui vous empêche d'utiliser un sous-formulaire dans plusieurs formulaires ? Dans ce cas, nommer explicitement le sous-formulaire dans un processus implique une redondance de procédures et de fonctions.
Dans l'exemple suivant, nous affectons un sous-formulaire à une variable objet.

Objet Form et sous-Formulaire

Function appelssf()
Dim sfrm As Form    ' ou Object
Set sfrm = Form_frm_sfrm3
MsgBox sfrm.Name
End Function

La déclaration est un peu particulière, car il ne faut pas indiquer le nom de l'objet tel qu'il est représenté dans la fenêtre Base de données, mais celui de l'Explorateur de Projet de la fenêtre Visual Basic Editor.

La fenêtre Explorateur de Projet

Retrouvez les préfixes disponibles dans le tableau suivant :

Type d'objet

Préfixe

Formulaire

Form_

État

Report_

Notez également que vous pouvez, dans un module de classe, affecter Me à la variable objet.

Exemple : Set frm = Me

IV-D - Une erreur gênante

Certaines versions d'ACCESS (constaté avec la version 2000 SP3) provoque une erreur lors d'appels complexes (sous-formulaire de 2e niveau par exemple) :
Erreur d'exécution '-214650094 (800f000e)':
La méthode 'Form' de l'objet '_SubForm' a échoué

Pas explicite ? et pourtant…

Après une recherche, c'est chez Allen Browne (Microsoft MVP. Perth, Western Australia) que j'ai trouvé la parade. Voici sa solution dont je vous livre la traduction.

1. Créer une nouvelle base vierge.

2. Décocher la case Outils/Options/Général/Effectuer correction automatique de nom.

3. Importer l'intégralité des objets Fichier/Données Externes…/Importer…

Il ajoute notamment que cette option est la source de nombreux problèmes.

Ce problème est résolu dans la version XP 2002 et supérieure.

V - Déclaration d'objets

Comme pour les recordsets ou les tables, les formulaires et états peuvent être contenus dans des variables objet.

Dans l'exemple suivant, le premier formulaire de la pile est stocké dans la variable objet. Son nom est ensuite affiché dans une boite de message.

Stocker un formulaire dans une variable Form

Sub objform()
Dim ofrm As Form
Set ofrm = Forms(0)
With ofrm
MsgBox .Name   'affiche le nom du formulaire
End With
End Sub

Dans l'exemple suivant, le formulaire ou l'état est passé en paramètre. Comme c'est un objet non typé (formulaire ou état), on peut utiliser cette procédure pour un état ou un formulaire.

Sub objform2(ofrm As Object)
With ofrm
MsgBox .Name
End With
End Sub

L'appel de cette fonction peut se faire de plusieurs manières.

' dans un module de classe
objform2 Me        'pour un formulaire ou un état

' dans un module
objform2 Forms(0)  'pour un formulaire
objform2 Report(0) 'pour un état

' autre forme d'appel dans un module de classe ou un module
objform2 Screen.ActiveForm   'pour un formulaire
objform2 Screen.ActiveReport 'pour un état

' avec la syntaxe décrite dans le chapitre IV-C
objform2 Form_frm_monfrm2
objform2 Report_rpt_monrpt2

VI - Tableau récapitulatif

Dans ce lien, retrouvez le tableau récapitulatif des différentes syntaxes. Ce fichier au format PDF est au format A3. Il pourra figurer en bonne place près de votre poste de développement.

VII - Remerciements

Je tiens à remercier : Heureux-Oli, Kikof pour leurs corrections.
Arkham46 pour ses suggestions.
Allen Browne pour sa solution.
À l'équipe de Developpez.com pour la qualité du site.
À Nono40 pour son super éditeur XML.
Je présente mes plus plates excuses à ceux que j'aurais omis de remercier.