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 :
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 :
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
' 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 :
Reports.monreport.moncontrole.nom_de_propriété
=
Reports.monreport.moncontrole.nom_de_propriété
' 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.
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.
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.
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.
=
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é
=
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.
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.
' 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.
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).
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.
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.
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.
En prenant l'exemple ci-dessus, nous allons développer une série de syntaxes pour accéder à chaque contrôle de texte.
' syntaxe module et module de classe
Forms.frm_principal.frm_sfrm1.Form.texte0
' syntaxe de module de classe
Me.frm_sfrm1.Form.texte0
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.
' 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.
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.
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.
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.
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.
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é
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.
- Créer une nouvelle base vierge.
- Décocher la case Outils/Options/Général/Effectuer correction automatique de nom.
- 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.
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.