FAQ MS-Access
FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
- Comment faire une recherche multicritère ?
- Comment ouvrir un formulaire au démarrage ?
- Comment savoir si un formulaire est ouvert ?
- Comment désactiver la molette de la souris dans un formulaire ?
- Pourquoi un formulaire basé sur une requête s'affiche-t-il à l'écran comme une page blanche ?
- Comment ouvrir un formulaire en mode feuille de données ?
- Comment exécuter une procédure (sub) d'un sous-formulaire ?
- Comment ouvrir un formulaire en fonction d'une valeur contenue dans un autre formulaire ?
- Comment fermer un formulaire en VBA ?
- Comment interdire le clic droit dans un formulaire ?
- Comment utiliser une partie de code commune à plusieurs formulaires ?
- Est-il possible d'insérer un sous-formulaire en mode continu dans un sous-formulaire qui est déjà en mode continu ?
- Comment passer le focus d'un formulaire à un autre ?
- Comment empêcher la fermeture accidentelle d'un formulaire ?
- Comment exécuter une procédure (sub) d'un autre formulaire ?
- Pourquoi un message d'erreur : "Mémoire libre insuffisante" lors de l'utilisation d'un formulaire ?
- Comment récuperer la valeur d'une cellule dans un formulaire tabulaire ?
- Comment afficher une page Web dans un formulaire ?
- Comment ouvrir un formulaire en mode ajout ?
- Comment faire pour réduire un formulaire ? (effet du bouton tiret en haut à droite des fenêtres Windows)
- Comment changer le titre d'un formulaire ?
- Comment imprimer un formulaire au format Paysage ?
- Comment obtenir la description d'un formulaire ?
- Comment obtenir la date de modification d'un formulaire ?
- Comment fermer tous les formulaires ouverts ?
- Comment trier un formulaire tabulaire en cliquant sur l'étiquette de la colonne ?
- Comment modifier la propriété d'un formulaire en VBA ?
- Comment effectuer une action lors d'un changement d'enregistrement d'un sous-formulaire ?
- Comment définir l'inactivité d'un utilisateur dans un formulaire ?
- Comment conserver la modification d'une étiquette dans un formulaire en VBA ?
- Comment ouvrir un formulaire modal indépendant en mode continu de façon à visualiser tous les enregistrements ?
- Comment ajuster la taille d'un sous-formulaire en fonction du nombre d'enregistrements ?
- 7.1. Contrôles (89)
- 7.2. Données (26)
- 7.3. Présentation (28)
- 7.4. Formulaires Trucs et Astuces (30)
Dans le Tutoriel de recherche multicritère, cafeine, vous montre comment implémenter cette fonction indispensable qui rendra vos applications réellement productives.
Menu Outils/Démarrage et le menu déroulant Afficher le formulaire.
À partir d'Access 2000 vous pouvez faire :
currentproject.AllForms
(
"NomDuForm"
).IsLoaded
Sinon :
il suffit de mettre ce code dans un module :
Function
IsLoaded
(
ByVal
strFormName As
String
) As
Integer
' Retourne True si le formulaire spécifié est ouvert.
Const
conObjStateClosed =
0
Const
conDesignView =
0
If
SysCmd
(
acSysCmdGetObjectState, acForm, strFormName) <>
conObjStateClosed Then
If
Forms
(
strFormName).CurrentView
<>
conDesignView Then
IsLoaded =
True
End
If
End
If
End
Function
Autre solution :
Public
Function
is_form_opened
(
fname As
String
) As
Boolean
On
Error
GoTo
not_opened
Dim
LeFichier As
String
LeFichier =
Forms
(
fname).Name
is_form_opened =
True
Exit
Function
not_opened
:
If
(
Err
.Number
=
2450
) Then
is_form_opened =
False
err
.clear
End
If
End
Function
Un formulaire peut devenir pénible à utiliser car la molette de la souris fait défiler les enregistrements.
Cette solution fonctionne pour MS Access 2000 et 2003. (Si vous avez testé pour d'autres versions n'hésitez pas à nous le faire savoir.)
Il arrive cependant que l'erreur "nom ambigu détecté" se manifeste pour les versions 2002 et ultérieures. Référez-vous dans ce cas au tutoriel dont le lien est en bas de cet article.
1re étape
Ouvrir un module VBA, aller dans Outils/Références, cliquer sur Parcourir et localiser la dll MouseWheel.dll puis cliquer sur Ouvrir. Cela permet d'enregistrer la dll dans les Références Access.
2e étape
Mettre le code suivant dans chaque formulaire qui requiert un contrôle de la roulette de la souris.
' Déclaration dans chaque formulaire après Option Explicit et Option Compare Database
Private
WithEvents clsMouseWheel As
MouseWheel.CMouseWheel
' Procédure à ajouter dans chaque formulaire
Private
Sub
clsMouseWheel_MouseWheel
(
Cancel As
Integer
)
Cancel =
True
End
Sub
Private
Sub
Form_Load
(
)
' Code à ajouter dans l'événement chargement de chaque formulaire
Set
clsMouseWheel =
New
MouseWheel.CMouseWheel
Set
clsMouseWheel.Form
=
Me
clsMouseWheel.SubClassHookForm
End
Sub
Private
Sub
Form_Close
(
)
' Code à ajouter dans l'événement fermeture de chaque formulaire
If
Not
(
clsMouseWheel Is
Nothing
) Then
clsMouseWheel.SubClassUnHookForm
Set
clsMouseWheel.Form
=
Nothing
Set
clsMouseWheel =
Nothing
End
If
End
Sub
Lien : Gestion de la roulette de la souris dans les formulaires
Cela signifie que la requête source du formulaire ne retourne aucun résultat et que l'ajout est interdit. Il suffit donc de modifier les propriétés ou de prévoir ce cas.
DoCmd.OpenForm
"NomFormulaire"
, acFormDS ...
Call
Form_NomDuSousForm.Champ_AfterUpdate
Il faut que la sub (ici Champ_AfterUpdate) soit déclarée comme Public :
Public
Sub
Champ_AfterUpdate
(
)
'Code à exécuter
....
End
Sub
Il faut utiliser la commande DoCmd.OpenForm :
Aide Access (f1) :
DoCmd.OpenForm nomformulaire[, affichage][, nomfiltre][, conditionwhere][, modedonnées][, modefenêtre][, openargs]
C'est la condition Where (" conditionwhere ") qu'il faut modifier.
Si on veut ouvrir en fonction de la valeur d'un contrôle d'un autre formulaire :
"[nom_champ] ="
&
Forms![nom_formulaire]![nom_contrôle dans autre formulaire]
Si on veut ouvrir en fonction de la valeur d'un contrôle du formulaire en cours :
"[nom_champ] ="
&
Me.
[MonControle]
Lien : Comment inclure des champs d'un formulaire dans une requête ?
Lien : Pourquoi ma requête ne fonctionne-t-elle pas selon le type des variables qu'elle utilise ?
Il y a deux cas possibles.
On veut fermer le formulaire sur lequel on est :
DoCmd.Close
On veut fermer un autre formulaire :
DoCmd.Close
acForm, "F_MonForm"
Propriété du formulaire Menu contextuel à non.
Ou bien en passant par le code :
Me.ShortcutMenu
=
False
Lien : Comment interdire l'utilisation du clic droit de la souris sur un contrôle ?
Vous pouvez écrire du code dans un module et l'appeler depuis vos formulaires.
Exemple :
Dans un module écrivez le code suivant :
Sub
MonMessage
(
txt As
String
)
MsgBox
txt
End
Sub
Puis dans votre formulaire, écrivez simplement :
MonMessage "coucou"
Fonctionne pareillement avec les fonctions.
Oui, à condition d'afficher les sous-formulaires en mode feuille de données.
Forms!Form2!MonContrôle.SetFocus
ou
DoCmd.SelectObject
acForm, Form2, False
Private
Sub
Form_Unload
(
Cancel As
Integer
)
If
MsgBox
(
"Êtes-vous certain ?"
, vbYesNo
) =
vbNo
Then
Cancel =
True
End
Sub
Forms!NomAutreForm.NomSub
Note : il faut que la procédure soit déclarée en Public Sub :
Public
Sub
NomSub
(
)
' Code à exécuter
....
End
Sub
Un petit tour sur le site du fabricant s'impose.
http://support.microsoft.com/default.aspx?scid=kb;fr;236977
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Tout d'abord, il faut que les colonnes soient ordonnées dans le même ordre que la présentation des champs dans la requête.
Si on a :
Select
Nom, Prenom From Table
Il faut que la première colonne soit nom, la seconde prenom.
Ensuite dans le code du formulaire, coller la fonction suivante :
Private
function
Cells
(
Ligne as
integer
,Colonne as
integer
) as
string
On
error
goto
err
Dim
R as
dao.recordset
set
r=
me.recordsetclone
r.movefirst
While
Ligne>
0
r.movenext
ligne=
ligne-
1
Wend
Cells=
R.fields
(
Colonne).value
err
:
End
Function
On accède à une cellule avec une syntaxe de cette forme :
MsgBox
Cells
(
3
,4
)
N.B. Les indices commencent à 0. (La première colonne a pour numéro 0 et idem pour la première ligne.)
Si toutefois, vous ne voulez pas ordonner les colonnes comme les champs, cela donnera :
Private
function
Cells
(
Ligne as
integer
,Colonne as
string
) as
string
On
error
goto
err
Dim
R as
dao.recordset
set
r=
me.recordsetclone
r.movefirst
While
Ligne>
0
r.movenext
ligne=
ligne-
1
Wend
Cells=
R.fields
(
Colonne).value
err
:
End
Function
Et au lieu du numero de la colonne, on passera son nom :
MsgBox
Cells
(
2
,"Nom"
)
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Le contrôle ActiveX Microsoft Web Browser vous permet de faire cela.
DoCmd.GoToRecord
acDataForm, Me.name
, acNewRec
Insérez ceci dans le code :
DoCmd.Minimize
Lien : Comment mettre un plein écran une fenêtre de formulaire ?
En VBA :
Me.Caption
=
"Nouveau nom du formulaire"
Vous pouvez modifier le paramètre Orientation de l'objet Printer depuis Access 2002.
DoCmd.OpenForm
"F_AFFICHAGE"
Forms
(
"F_AFFICHAGE"
).Printer.Orientation
=
acPRORLandscape
DoCmd.PrintOut
DoCmd.Close
acForm, "F_AFFICHAGE"
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Vous pouvez vous inspirer de cet exemple. Attention, si la description n'a pas été renseignée, la propriété n'existe pas.
Public
Function
GetDescForm
(
strFormName As
String
) As
String
Dim
oDb As
DAO.Database
Set
oDb =
CurrentDb
GetDescForm =
oDb.Containers
(
"Forms"
).Documents
(
strFormName).Properties
(
"Description"
)
End
Function
Sub
test
(
)
MsgBox
GetDescForm
(
"Formulaire1"
)
End
Sub
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Public
Function
GetDateUpdatedForm
(
strFormName As
String
) As
Date
Dim
oDb As
DAO.Database
Set
oDb =
CurrentDb
GetDateUpdatedForm =
oDb.Containers
(
"Forms"
).Documents
(
strFormName).LastUpdated
End
Function
Sub
test
(
)
MsgBox
GetDateUpdatedForm
(
"Formulaire1"
)
End
Sub
Attention, un bogue est recensé sous Access 2000 : LastUpdated retourne la date de création du formulaire.
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Il faut parcourir la collection Forms de l'application.
Public
Sub
CloseAllForms
(
)
Do
WHILE
Forms.Count
Docmd.Close
acForm, Forms
(
0
).Name
Loop
End
Sub
Le code suivant permet de trier l'affichage d'un formulaire tabulaire en cliquant
sur l'étiquette d'une colonne.
Si l'orde est de A->Z lors du clic, l'ordre passe de Z->A et vice-versa
Global
gBol as
Boolean
Private
Sub
MonEtiquette_Click
(
)
Me.OrderByOn
=
True
If
gBol =
False
Then
Me.OrderBy
=
"MaColonne asc"
gBol =
True
Else
Me.OrderBy
=
"MaColonne desc"
gBol =
False
End
If
End
Sub
Pour modifier la propriété Description d'un formulaire,
il faut accéder à l'objet en DAO via la collection containers et l'objet document.
L'exemple suivant insère la date et l'heure courante dans la propriété Description du formulaire "MonFormulaire"
Il faut ajouter la référence : Microsoft DAO 3.x Object Library.
Sub
ecrireDecr
(
)
On
Error
GoTo
err
' Script qui affecte la date et l'heure à la propriété Description
' d'un formulaire
Dim
oDb As
DAO.Database
Dim
oDoc As
DAO.Document
Set
oDb =
CurrentDb
Set
oDoc =
oDb.Containers
(
"Forms"
).Documents
(
"MonFormulaire"
)
oDoc.Properties
(
"Description"
) =
Now
fin
:
Exit
Sub
err
:
Select
Case
err
.Number
Case
3270
' Si la propriété n'existe pas, la créer
With
oDoc
.Properties.Append
.CreateProperty
(
"Description"
, dbText, Now
)
.Properties.Refresh
End
With
Case
Else
err
.Raise
err
.Number
End
Select
Resume
fin
End
Sub
Il suffit de mettre votre code dans l'événement Sur Activation de votre sous-formulaire.
Ce code permet de tester, toutes les secondes, si le focus s'est déplacé ou si une touche a été enfoncée. Si ce n'est pas le cas, on incrémente de une seconde un compteur. Lorsque celui-ci atteint un seuil paramétré au départ, on affiche un message signalant la non-activité. On pourrait s'inspirer de ce code pour prendre d'autres actions telles que fermer le formulaire, fermer la base de données…
Voici le code du module du formulaire testé :
Option
Compare Database
Public
ExpiredTime
'
Sub
Form_Timer
(
)
' IDLEMINUTES détermine le temps d'inactivité avant de déclencher la procédure d'alerte.
Const
IDLEMINUTES =
0
.05
'correspond à 3 secondes (5/100 de 60 secondes)
Static
PrevControlName As
String
Static
PrevFormName As
String
Dim
ActiveFormName As
String
Dim
ActiveControlName As
String
Dim
ExpiredMinutes
On
Error
Resume
Next
' Capte le formulaire actif et le nom du contrôle
ActiveFormName =
Screen.ActiveForm.Name
If
Err
Then
ActiveFormName =
"No Active Form"
Err
=
0
End
If
ActiveControlName =
Screen.ActiveControl.Name
If
Err
Then
ActiveControlName =
"No Active Control"
Err
=
0
End
If
' Vérifie ce qui est actuellement actif et réinitialise temps expiration si :
' 1. Aucun enregistrement d'action encore (code roule pour
' la première fois);
' 2. Les noms précédents sont différents des noms courants
' (l'utilisateur a fait une action pendant l'intervalle de temps.
If
(
PrevControlName =
""
) Or
(
PrevFormName =
""
) _
Or
(
ActiveFormName <>
PrevFormName) _
Or
(
ActiveControlName <>
PrevControlName) Then
PrevControlName =
ActiveControlName
PrevFormName =
ActiveFormName
ExpiredTime =
0
Else
' ...si non, c'est que l'utilisateur a été inactif pendant ce laps de temps,
' dès lors, on incrémente ExpiredTime
ExpiredTime =
ExpiredTime +
Me.TimerInterval
End
If
' Le temps d'inactivité a-t-il dépassé la limite définie (IDLEMINUTES)?
ExpiredMinutes =
(
ExpiredTime /
1000
) /
60
If
ExpiredMinutes >=
IDLEMINUTES Then
' ...si oui, on remet le temps d'expiration à 0...
ExpiredTime =
0
' ...et appelle la sous-routine idletimedetected.
IdleTimeDetected ExpiredMinutes
End
If
End
Sub
Sub
IdleTimeDetected
(
ExpiredMinutes)
Dim
Msg As
String
Msg =
"Aucune activite "
Msg =
Msg &
ExpiredMinutes &
" minute(s)!"
MsgBox
Msg, 48
End
Sub
Private
Sub
Form_KeyDown
(
KeyCode As
Integer
, Shift As
Integer
)
If
Not
IsNull
(
KeyCode) Then
ExpiredTime =
0
End
If
End
Sub
Const IDLEMINUTES = 0.05 correspond à 3 secondes (pour les besoins de l'exemple).
Modifiez les propriétés du formulaire comme suit :
Aperçu des touches sur OUI ;
Intervalle minuterie = 1000.
Pour conserver le changement d'une étiquette après fermeture du formulaire, il faut d'abord l'ouvrir en mode création (acDesign) et caché (acHidden). Ensuite, on modifie le texte de l'étiquette, on sauvegarde le formulaire et on l'ouvre normalement.
DoCmd.OpenForm
NomFormulaire, acDesign, , , , acHidden
Forms![NomFormulaire]![NomEtiquette].Caption
=
"Nouvelle légende"
DoCmd.Close
acForm, NomFormulaire, acSaveYes
DoCmd.OpenForm
NomFormulaire
Nota : ne fonctionne pas pour les fichiers mde, ne fonctionne qu'avec des fichiers .mdb.
Le code suivant permet de redéfinir la hauteur du formulaire en fonction du nombre d'enregistrements :
Private
Sub
Form_Load
(
)
Me.InsideHeight
=
Me.Section
(
acHeader).Height
+
Me.Section
(
acFooter).Height
+
Me.RecordsetClone.RecordCount
*
Me.Section
(
acDetail).Height
End
Sub
Ce code permet d'ajuster la taille d'un sous-formulaire en fonction du nombre d'enregistrements qu'il contient.
Sur l'événement SurActivation du formulaire, il suffit de mettre le code suivant :
Private
Sub
Form_Current
(
)
Me.LeSousForm.Form.InsideHeight
=
Me.LeSousForm.Form.Section
(
acHeader).Height
_
+
Me.LeSousForm.Form.Section
(
acFooter).Height
_
+
Me.LeSousForm.Form.Section
(
acDetail).Height
_
*
(
Me.LeSousForm.Form.RecordsetClone.RecordCount
_
-
Me.LeSousForm.Form.AllowAdditions
)
Me.LeSousForm.Height
=
Me.LeSousForm.Form.WindowHeight
End
Sub
Après, s'il y a des zones de texte en dessous, il suffit de modifier leur position en fonction du sous-formulaire, par exemple :
Me.LazoneDeTexte.Top
=
Me.LeSousForm.Top
+
Me.LeSousForm.Height
+
AutantDeTwipsQuOnVeut
... et ainsi de suite !
Évolution de micniv
- limiter la hauteur du sous-formulaire à n lignes
- afficher quand nécessaire la barre de défilement vertical
Dim
objSousForm As
Object
Dim
frmSousForm As
Form
Dim
nbMaxLignes As
Long
' Vos déclarations
Set
objSousForm =
Me!LeSousForm
Set
frmSousForm =
objSousForm.Form
nbMaxLignes =
3
'limite la hauteur à n lignes et affiche la barre de défilement verticale
If
frmSousForm.RecordsetClone.RecordCount
<=
nbMaxLignes Then
frmSousForm.InsideHeight
=
frmSousForm.Section
(
acHeader).Height
_
+
frmSousForm.Section
(
acFooter).Height
_
+
frmSousForm.Section
(
acDetail).Height
_
*
(
frmSousForm.RecordsetClone.RecordCount
_
-
frmSousForm.AllowAdditions
)
objSousForm.Height
=
frmSousForm.WindowHeight
frmSousForm.ScrollBars
=
0
'aucune barre de défilement
Else
frmSousForm.InsideHeight
=
frmSousForm.Section
(
acHeader).Height
_
+
frmSousForm.Section
(
acFooter).Height
_
+
frmSousForm.Section
(
acDetail).Height
_
*
(
nbMaxLignes -
frmSousForm.AllowAdditions
)
objSousForm.Height
=
frmSousForm.WindowHeight
frmSousForm.ScrollBars
=
2
'barre de défilement verticale
End
If
' Après, s'il y a des zones de texte en dessous, il suffit de
'modifier leur position en fonction du sous-formulaire,
'par exemple :
Me.LaZoneDeTexte.Top
=
objSousForm.Top
+
objSousForm.Height
+
AutantDeTwipsQuOnVeut
Set
objSousForm =
Nothing
Set
frmSousForm =
Nothing