FAQ MS-Access

FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
Sommaire→Formulaires- 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").IsLoadedSinon :
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 FunctionAutre 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 FunctionUn 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 SubLien : 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_AfterUpdateIl faut que la sub (ici Champ_AfterUpdate) soit déclarée comme Public :
Public Sub Champ_AfterUpdate()
'Code à exécuter
....
End SubIl 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.CloseOn 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 = FalseLien : 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 SubPuis 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.SetFocusou
DoCmd.SelectObject acForm, Form2, FalsePrivate Sub Form_Unload(Cancel As Integer)
If MsgBox("Êtes-vous certain ?", vbYesNo) = vbNo Then Cancel = True
End SubForms!NomAutreForm.NomSubNote : il faut que la procédure soit déclarée en Public Sub :
Public Sub NomSub()
' Code à exécuter
....
End SubUn 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 TableIl 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 FunctionEt 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, acNewRecInsérez ceci dans le code :
DoCmd.MinimizeLien : 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 SubLien : 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 SubAttention, 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 SubLe 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 SubPour 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 SubIl 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 SubConst 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 NomFormulaireNota : 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 SubCe 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 SubAprè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


