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→Formulaires Trucs et Astuces- Comment afficher une table ou une requête dans un contrôle Sous-formulaire sans créer de nouveau formulaire ?
- Comment ne pas enregistrer les données des contrôles d'un formulaire avant validation par l'utilisateur ?
- Comme faire pour que le survol du bouton Commande0 fasse apparaître le bouton Commande1 et que, si on repasse sur Commande0, le bouton Commande1 disparaisse à nouveau ?
- Comment centrer un formulaire ?
- Comment savoir si un contrôle existe dans un formulaire ?
- Comment faire défiler un texte dans un formulaire ?
- Comment empêcher la navigation entre formulaires via la barre des tâches ?
- Comment faire passer un formulaire ouvert en mode acDialog en arrière-plan ?
- Comment créer dynamiquement un formulaire ?
- Comment insérer une ligne blanche (enregistrement vide) dans un sous-formulaire affiché en mode feuille de données ?
- Comment passer en mode Edit dans un champ dont le format est différent du masque de saisie ?
- Comment savoir si nouvel enregistrement ou enregistrement modifié ?
- Comment positionner le curseur à gauche du champ ou sélectionner le contenu du champ ?
- Comment déterminer la position d'un formulaire à l'écran ?
- Comment vérifier à la sortie d'une InputBox que le type de donnée rentrée est bien du numérique ?
- Comment masquer un sous-formulaire vide ?
- Comment empêcher l'utilisateur de cliquer à l'extérieur du formulaire (comme pour une MsgBox) ?
- Comment enlever les boutons de navigation d'un formulaire en VBA ?
- Comment utiliser la saisie semi-automatique dans les contrôles de mes formulaires ?
- Dans un formulaire en mode continu, comment rendre invisible un bouton pour certaines lignes ?
- Comment "zoomer" sur le contenu d'un contrôle de type texte ?
- Pourquoi le temps d'ouverture de mes formulaires à onglets est-il trop important ?
- Comment transmettre le nom du formulaire appelant à l'ouverture d'un formulaire ?
- Complément au tutoriel de recherche multicritère de cafeine : comment enregistrer dans une requête le résultat de la recherche multicritère ?
- Comment créer dynamiquement des contrôles de type Rectangle sur le formulaire en cours ?
- Comment faire repartir un GIF qui a cessé de s'animer ?
- Comment ne pas ouvrir un formulaire si celui est vide ?
- Comment éviter l'erreur d'un paramètre non reconnu pour un graphique basé sur une requête paramétrée ?
- Comment compter le nombre d'enregistrements d'un sous-formulaire ?
- Comment savoir si les contrôles ont été remplis dans un formulaire ?
Une astuce pour créer un sous-formulaire de façon classique :
- mettez votre formulaire en mode création ;
- affichez votre fenêtre de base de données à côté de votre formulaire ;
- affichez la liste des requêtes ;
- faites un cliquer-glisser de l'icône de votre requête dans votre formulaire.
=> Cette méthode crée un nouveau formulaire qui s'insère dans le contrôle sous-formulaire...
=> Voici comment faire pour ne pas créer de nouveau formulaire :
- dans votre formulaire principal, créez un contrôle sous-formulaire/sous-état (sans assistant si possible) ;
- dans les propriétés de cet objet, allez dans l'onglet Données ;
- dans la propriété Objet Source, choisissez votre requête ou votre table.
Il faut mettre ce code dans l'événement Avant MAJ du formulaire ou du contrôle concerné :
If MsgBox("Valider la mise à jour ?", vbOKCancel) = vbCancel Then
MsgBox "L'opération de mise à jour a été annulée", vbInformation
Cancel = true ' annule l'opération
Exit Sub
And IfExit Sub permet de sortir de la procédure en cours c'est-à-dire celle de la mise à jour.
Option Compare Database
Option Explicit
Private AModifier As Boolean
Private Sub Commande0_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If AModifier Then
AModifier = False
Commande1.Visible = Not Commande1.Visible
Else
'rien à faire
End If
End Sub
Private Sub Détail_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
AModifier = True
End SubAModifier est une variable qui va servir de tampon.
En effet, la procédure MouseMove se produit tant que la souris se déplace sur le contrôle Commande0.
Donc, il faut réussir à éviter que la procédure se reproduise tant que ta souris n'est pas sortie du bouton.
Donc, il faut que, lors de la première exécution, on lui signale qu'il ne faut pas qu'elle se reproduise. La procédure commence donc par tester s'il faut modifier ou non :
If AModifier ThenSi c'est le cas, alors, il y a modification de la variable tampon, signalant ainsi qu'il ne faut plus modifier :
AModifier = FalsePuis on inverse la visibilité en cours de Commande1 :
Commande1.Visible = Not Commande1.VisiblePar contre, s'il ne faut pas modifier, aucune action n'est entreprise :
Else
' Rien à faire
End IfSupposons que Commande0 soit dans la section Détail. Dès que la souris va sortir du bouton, elle va donc passer sur le Détail. C'est ici qu'il va falloir jouer sur la valeur de la variable tampon afin de la remettre à vrai pour que, dès que la souris retournera sur Commande0, on puisse considérer qu'il faut modifier la visibilité de Commande1.
D'où le code MouseMove sur la section Détail :
Private Sub Détail_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
AModifier = True
End SubComme la variable AModifier est disponible pour deux procédures distinctes, il faut que sa portée soit sur le module. Il s'agit de la déclarer en tête de module :
Private AModifier As BooleanAprès avoir obtenu la position d'un formulaire, on va le centrer maintenant pour rendre "joli". Reprenons dès le début, on va créer un type POSITION pour la position de notre formulaire et ajouter quelques API Windows qui s'avèrent utiles pour déterminer les propriétés de l'écran et déplacer le formulaire. Dans la section des déclarations d'un nouveau module juste après Option Explicit, ajouter ce bout de code :
Private Type Position
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
' --Pour obtenir les coordonnées de la fenêtre parent
Public Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
' --Pour obtenir les coordonnées de notre formulaire
Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
lpRect As Position) As Long
' --Pour obtenir les coordonnées de l'écran
Public Declare Function GetDesktopWindow Lib "user32" () As Long
' --Pour positionner et dimensionner la fenêtre
Public Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal bRepaint As Long) As LongPour positionner au centre notre formulaire, on fait appel à une procédure Positionner() dont on passe le formulaire à centrer. Dans notre exemple, c'est un bouton qui centre le formulaire et donc on fait appel à la fonction avec Me.
Private Sub Centrer_Click()
Call Positionner(Me)
End SubRevenons au module précédent et ajoutons ce code commenté :
Public Sub Positionner(frm As Form)
Dim FParent As Position '--Fenêtre parent
Dim Fenetre As Position
Dim Largeur As Integer
Dim Hauteur As Integer
Dim LParent As Integer ' --Largeur fenêtre parent
Dim HParent As Integer ' --Hauteur fenêtre parent
Dim PParent As Long ' --Posion parent
On Error GoTo Erreur
' --Trouver les coordonnées de mon formulaire à centrer
PParent = GetParent(frm.hwnd)
' --Obtenir les coordonnées de mon formulaire et celles de son parent
Call GetWindowRect(frm.hwnd, Fenetre)
' --Si le parent est la fenêtre Access, pas de soustraction
If PParent <> Application.hWndAccessApp Then
Call GetWindowRect(PParent, FParent)
Else
' --Les coordonnées du Desktop
Call GetWindowRect(GetDesktopWindow(), FParent)
End If
' --Calcul de la largeur et de la hauteur du parent
With FParent
LParent = .Right - .Left
HParent = .Bottom - .Top
End With
' --Calcul de la largeur et de la hauteur de mon formulaire
With Fenetre
Largeur = .Right - .Left
Hauteur = .Bottom - .Top
.Left = (LParent - Largeur) \ 2
.Top = (HParent - Hauteur) \ 2
End With
' --Centrer mon formulaire
Call MoveWindow(frm.hwnd, Fenetre.Left, Fenetre.Top, Largeur, Hauteur, bRepaint:=True)
Exit Sub
Erreur:
MsgBox "Erreur : " & Err.Number & vbCrLf & Err.Description
End SubFunction ExistControl(ByVal frm As Form, ByVal ctlName As String) As Boolean
' frm contient le nom du formulaire, ctlName contient le nom du contrôle
On Error Resume Next
If IsError(frm.Controls(ctlName).Tag) Then
Err.Clear
Exit Function
Else
ExistControl = True
End If
End FunctionDans votre formulaire vous mettez une étiquette (lblInfos) contenant le texte voulu.
Mettre la propriété minuterie de l'onglet événements à 500 (ms).
En regardant bien les propriétés des événements du formulaire, vous trouverez la propriété Sur Minuterie.
Dedans, vous choisissez [Procédure événementielle], vous cliquez sur les 3... à droite et vous tombez dans la procédure :
Private sub Form_Timer()
lblInfos.Caption = Mid(lblInfos.Caption, 2) & Left(lblInfos.Caption, 1)
End SubMenu Outils/Options
Onglet Affichage : décocher Fenêtres dans la barre des tâches.
Lorsque l'on ouvre un état depuis un formulaire ouvert en mode acDialog, l'état apparaît derrière le formulaire, ce qui se révèle être un problème. On ne peut demander explicitement au formulaire d'aller en arrière-plan, il faut donc jouer sur sa propriété visible :
nous mettons la propriété visible à false à l'ouverture de l'état, puis à true lors de sa fermeture.
De cette manière, à la fermeture de l'état, le formulaire réapparaît à l'identique.
Pourquoi a-t-on besoin de créer dynamiquement un formulaire quand l'assistant d'Access le fait parfaitement et rapidement ?
Si on veut par exemple afficher une table en mode continu et que le nombre de colonnes de la table varie par exemple
ou quand on ne veut afficher que quelques colonnes d'une table, notre méthode sera appliquée comme filtre alors.
Soit sql la chaîne SQL contenant les colonnes d'une table à afficher :
sql ="SELECT T.CHAMP1, T.CHAMP2, T.CHAMP5 FROM T"Cette fonction permet de créer un formulaire dynamiquement et de le mettre en page, d'ajouter aussi des événements... il est conseillé d'utiliser un formulaire existant au lieu de créer un nouveau formulaire parce que Access aura du mal dans le cas de la création d'un nouveau formulaire à voir ce formulaire récemment créé. Dans cet exemple nous utilisons un formulaire existant soit "F_AFFICHAGE" que nous modifions à notre guise.
Public Function create_form(sql As String) As Boolean
Dim frm As Form
Dim rst As Recordset
dim ctl as control
dim i, j as integer
' --Ouvrir le formulaire en mode modification et caché
DoCmd.OpenForm "F_AFFICHAGE", acDesign
, , , , acHidden
' --Suppression de tous les contrôles avant de les créer à nouveau
For Each ctl In Forms!F_AFFICHAGE.Controls
DeleteControl "F_AFFICHAGE", ctl.Name
Next ctl
' --Source de données de mon formulaire
Forms![F_AFFICHAGE].RecordSource = sql
Set rst = Currentdb.OpenRecordset(sql)
' --Nous ne pensons pas que vous aurez plus de 100 contrôles
Dim controle(1 To 100) As Control
' --Création des contrôles
If rst.RecordCount <> 0 Then
i = 1
j = 1000
While i < rst.Fields.Count
' --Créer le contrôle i
Set controle(i) = CreateControl("F_AFFICHAGE", acTextBox)
' --Lui affecter un nom
controle(i).Name = "TXT_" & rst.Fields(i).Name
' --Le positionner sur le formulaire
controle(i).Left = 100 + j
' --Définir sa largeur
controle(i).Width = 1150
' --Définir sa couleur de fond
controle(i).BackColor = "14742270"
' --Définir son effet visuel
controle(i).SpecialEffect = 0
controle(i).BackStyle = 0
controle(i).BorderStyle = 1
' --Source de données de ce contrôle
controle(i).ControlSource = rst.Fields(i).Name
i = i + 1
j = j + 1150
Wend
End If
' --Création des en-têtes
j = 1000
i = 1
While i < rst.Fields.Count
Set controle(i) = CreateControl("F_AFFICHAGE", acTextBox, acHeader)
controle(i).Name = "HD_" & rst.Fields(i).Name
controle(i).Left = 100 + j
controle(i).Width = 1150
controle(i).Height = 700
controle(i).BackColor = "10081789"
controle(i).SpecialEffect = 0
controle(i).BorderStyle = 1
controle(i).TextAlign = 2
controle(i).FontWeight = 700
controle(i).ControlSource = "='" & rst.Fields(i).Name & "'"
i = i + 1
j = j + 1150
Wend
rst.close
set rst = Nothing
' --Sauvegarder le formulaire
DoCmd.Save acForm, "F_AFFICHAGE"
End FunctionVous pouvez enrichir cet exemple en vous rendant sur l'aide d'Access pour d'autres propriétés telles que SpecialEffect ou BorderStyle mais aussi ajouter un événement
tel qu'un double-clic en cherchant OnDblClick ou OnClick...
Voilà vous n'avez maintenant qu'à changer la requête SQL et votre formulaire est prêt en quelques secondes.
Tout le pas à pas qui suit concerne la source du sous-formulaire (SF).
Créer un champ Ordre (type numérique) qui servira de tri. Il n'est pas obligatoire qu'il soit physiquement présent dans le formulaire.
Code sur Double clic (le double-clic concerne le sélecteur du SF qui doit donc être affiché) :
Private Sub Form_DblClick(Cancel As Integer)
' Crée un enregistrement et insère un compteur dans le champ Ordre.
Dim Compteur As Integer
Application.Echo False
Compteur = Me![Ordre]
DoCmd.GoToRecord , , acNewRec
Me![Ordre].Value = Compteur + 1
Me.Requery
Numerotation_Click
Application.Echo True
End SubPour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Private Sub Numerotation_Click()
' Renumérote les enregistrements.
Dim rcs As DAO.Recordset
Dim i As Integer
Set rcs = Me.RecordsetClone
i = 1
rcs.MoveFirst
While Not rcs.EOF
rcs.Edit
rcs!Ordre = i
rcs.Update
rcs.MoveNext
i = i + 2
Wend
rcs.Close
Set rcs = Nothing
Me.Requery
End SubPour finir, sur le formulaire principal, événement sur Activation :
Private Sub Form_Current()
Me.NomDuSousFormulaire.Form.OrderBy = " Ordre"
Me.NomDuSousFormulaire.Form.OrderByOn = True
End SubCe qui active le tri sur le champ Ordre.
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
La touche clavier F2 permet de passer en mode Edit dans un champ. Vous pouvez l'utiliser en entrant dans votre champ l'instruction.
SendKeys "{F2}"Il faut que le test porte sur un contrôle dépendant que l'utilisateur doit obligatoirement remplir. Le formulaire concerné doit bien sûr être un formulaire lié.
If IsNull(Me.MonControleObligatoire.oldvalue) Then
' On est en ajout
Else
' On est en modification
End IfPositionner le curseur à gauche :
Private sub MonTXT_Click()
MonTXT.Selstart=0
End subSélectionner le contenu :
Private sub MonTXT_Click()
MonTXT.SelStart=0
MonTXT.SelLength=Len(MonTXT)
End subUne position est définie par quatre coordonnées : droite, gauche, bas et haut. Nous allons donc créer un type POSITION pour nos quatre coordonnées. Dans la section déclarations copier et coller ce code :
Private Type rect
Left As Long
Top As Long
Right As Long
Bottom As Long
End TypePour déterminer la position de notre formulaire actif, nous ferons appel à une API GetWindowRect. Toujours dans la section déclaration ajouter ce code :
Private Declare Function GetWindowRect Lib "User32" _
(ByVal hwnd As Long, lpRect As RECT) As LongDans un formulaire, ajouter un bouton dont le code de l'événement sur clic est le suivant :
Private Sub Position_Click()
Dim Position As rect
Call GetWindowRect(Me.hwnd, Position)
With Position
MsgBox "Position de mon formulaire" & vbCrLf & "Gauche:" & .Left & vbCrLf _
& "Droite:" & .Right & vbCrLf & "Inférieur:" & .Bottom & vbCrLf & "Supérieur :" & .Top
End With
End SubLa position du formulaire est donnée en pixels. Certainement vous vous dites ce que vous pourriez faire avec les positions du formulaire ? Justement c'est très utile si vous voulez "figer" un formulaire ou changer l'emplacement d'un formulaire sur l'écran, il suffit pour ça d'utiliser la fonction MoveSize de DoCmd et dont la traduction est DéplacerDimensionner. Un exemple d'utilisation de cette méthode :
DoCmd.MoveSize 2440, 2400, , 4000Attention, cette propriété prend les coordonnées en twips (1 twip = 1/20 de point). Pour plus d'informations et d'exemples sur toutes ces fonctions rendez-vous sur l'aide d'Access.
Voici une fonction qui vous permet de saisir une valeur numérique :
Function InputBoxNumeric(ByVal PromptZ As String, _
ByVal TitleZ As String, ByVal DefaultZ As String) As Double
' PromptZ : texte dans l'InputBox
' TitleZ : titre à donner à l'InputBox
' DefaultZ : valeur par défaut
Dim rep As String
Start01:
rep = InputBox(PromptZ, TitleZ, DefaultZ)
If Len(rep) > 0 Then
If IsNumeric(rep) Then
InputBoxNumeric = CDbl(rep)
Exit Function
Else
MsgBox "Une valeur numérique est attendue, merci de refaire la saisie"
GoTo Start01
End If
Else
MsgBox "une valeur numérique est attendue, merci de refaire la saisie"
GoTo Start01
End If
End FunctionMe.MonSousFormulaire.Visible = (Me.MonSousFormulaire.Form.RecordsetClone.RecordCount > 0)Il faut définir la propriété Fen modale du formulaire à Oui.
L'utilisateur ne pourra ainsi accéder à un autre formulaire tant qu'il n'aura pas fermé celui-ci.
Il n'est pas possible de le faire directement.
Cependant, voici comment obtenir un résultat similaire :
- [*]Première solution : remplacer les zones de texte par des zones de liste modifiables qui elles adoptent ce comportement par défaut ;
- [*]Deuxième solution : par DAO, ouvrir un Recordset sur la table, sélectionner le premier enregistrement et le mettre dans la zone de texte si c'est le seul. Sinon, laisser l'utilisateur continuer à taper.
Le truc, c'est de faire :
1/ Une table avec deux champs
ID Boolean
BTN OLEObject
Dans ID, Vrai sur la première ligne et Faux sur la seconde.
Dans BTN, en face de Vrai, l'image d'un bouton, en face de Faux un carré coloré, de la même couleur que le fond du formulaire.
2/ Une requête qui fait le test et renvoie une colonne contenant Vrai si le test est vérifié, Faux sinon.
3/ Une requête qui lie cette colonne calculée, booléenne, avec le champ ID de la table.
4/ Se servir de la seconde requête comme source du sous-formulaire.
Et voilà !
Après, en jouant sur l'ensemble des événements :
Sur souris enfoncée ;
Sur Souris relâchée ;
Sur Clic,
on peut tester si le champ ID est Vrai=> on fait l'action.
Si on fait l'action :
sur souris enfoncée, on affiche une image de bouton enfoncé ;
sur souris relâchée, on remet l'image standard du bouton ;
sur clic, on déclenche l'action.
Programmez les deux événements Sur Entrée et Sur Sortie.
Sur entrée, le format de police change en plus gros.
Sur sortie, le format de police change en plus petit.
Exemple ici pour une zone de texte se nommant "Texte1" :
Private Sub Texte1_Enter()
Texte1.FontSize = 18
End Sub
Private Sub Texte1_Exit(Cancel As Integer)
Texte1.FontSize = 8
End SubÀ noter que depuis Access 2000, il est possible d'utiliser la mise en forme conditionnelle et plus particulièrement ici, une condition de type Champ Actif (cf. lien ci-dessous).
Lien : La mise en forme conditionnelle sous Access 2000/XP/2003
En règle générale il est toujours intéressant de disperser le rapatriement des données.
Quand on a un formulaire à onglets, il vaut mieux rafraîchir les données sur chaque onglet plutôt qu'un gros chargement au début pour tous à la fois.
Ouvrir un formulaire grâce à la ligne de code :
DoCmd.OpenForm nomformulaire, , , , , , Me.NameDans le formulaire que vous venez d'ouvrir, vous pouvez alors suivant le formulaire appelant (dont le nom est contenu dans OpenArgs) exécuter un code différent :
Select Case OpenArgs
Case "frmX"
' Ici ce que vous voulez :
MsgBbox "frmX=" & openArgs
Case "frmY" :
' Ici ce que vous voulez :
MsgBox "frmY=" & openArgs
End SelectVous pouvez vous servir du résultat renvoyé par votre procédure de recherche multicritère pour créer ou modifier une requête enregistrée dans votre base de données.
La première étape consiste à récupérer l'instruction SQL définie par la procédure Sub RefreshQuery(). Vous avez plusieurs possibilités pour cela.
La première qui vient à l'esprit est de rendre la variable String SQL disponible aux autres procédures du module du formulaire de recherche.
Au lieu de faire :
Private Sub RefreshQuery()
Dim SQL As String
Dim SQLWhere As String
...
End SubFaire :
Dim SQL As String
Private Sub RefreshQuery()
Dim SQLWhere As String
...
End SubUne autre solution pour éviter d'étendre la portée de la variable SQL est de récupérer directement l'instruction SQL dans la propriété RowSource de la liste mise à jour par RefreshQuery(). Dans ce cas inutile de modifier le code du tutoriel.
La seconde étape consiste à utiliser du code DAO pour créer ou mettre à jour la requête grâce à l'objet DAO.Querydef.
Exemple pour deux boutons de commande à placer dans le formulaire de recherche :
Private Sub btnCréerRequête_Click()
'****************************
' Facultatif si la variable SQL mise à jour dans Sub RefreshQuery est de niveau module :
' Dim SQL As String
' SQL = Me!lstResults.RowSource
'****************************
Dim NomQDF as String
' Faites ici tous vos tests pour vous assurer d'un nom valide pour la requête à créer :
NomQDF = InputBox("Entrer un nom pour la recherche en cours :")
if NomQDF ="" then
msgbox "Vous n'avez pas indiqué de nom valide pour la requête."
exit sub
end if
' Création de la requête
CurrentDb.CreateQueryDef NomQDF, SQL
End SubPrivate Sub btnModifierRequête_Click()
'****************************
' Facultatif si la variable SQL mise à jour dans Sub RefreshQuery est de niveau module :
' Dim SQL As String
' SQL = Me!lstResults.RowSource
'****************************
' Modification de la requête
CurrentDb.QueryDefs("NomRequête").SQL = SQL
End SubLes codes sont donnés à titre d'exemple sans gestion des erreurs.
Ceci ne peut se faire sur un sous-formulaire ouvert, il faut donc passer par ces étapes :
- refermer le sous-formulaire ;
- l'ouvrir en mode création ;
- le modifier ;
- le fermer ;
- le rouvrir en mode normal.
Ce qui donne le code suivant :
Dim rct As Rectangle
Me.ssForm.SourceObject = "" 'on ferme le sous-formulaire
DoCmd.OpenForm "Formulaire", acDesign, , , , acHidden 'on le rouvre en mode création et caché
Set rct = CreateControl("Formulaire", acRectangle, , "", "", 200, 200, 3000, 9400) 'on trace le rectangle
rct.BackColor = vbBlack
DoCmd.Close acForm, "Formulaire" 'on ferme le formulaire
Me.ssForm.SourceObject = "Formulaire" 'on rouvre le sous-formulaire dans le formulaire principal
Set rct = Nothing 'on libère la mémoireOù "ssForm" est le nom du contrôle de sous-formulaire du formulaire principal et "Formulaire" le nom du sous-formulaire dans lequel nous créons le rectangle.
Lien : Est-il possible de créer dynamiquement des contrôles ?
Parfois lorsque l'on cache un formulaire, lorsque celui-ci réapparaît les GIF le composant restent inanimés.
La solution est de redéfinir la propriété filename du GIF pour le faire repartir :
gif.filename = gif.filename
Imaginons que nous appelions un formulaire sur clic d'un bouton d'un autre formulaire.
Le formulaire appelé est basé sur une requête ou une table.
Voici le code à mettre sur le bouton qui demande l'ouverture du formulaire (vous pouvez le mettre sur autre chose qu'un bouton bien évidemment) :
Private Sub btnOuvrir_Click()
On Error GoTo Err_btnOuvrir_Click
Dim stDocName As String
Dim stLinkCriteria As String
stDocName = "NomFormulaire"
' On ne veut que certains enregistrements dans le formulaire à ouvrir
' On ne veut donc que les enregistrements dont le champ ID est égal
' à la valeur du contrôle MonControleFiltre du formulaire
stLinkCriteria = "[ID]=" & Me![MonControleFiltre]
' On ouvre le formulaire en passant le filtre en paramètre
DoCmd.OpenForm stDocName, , , stLinkCriteria
Exit_btnOuvrir_Click:
Exit Sub
Err_btnOuvrir_Click:
If Err = 2501 Then Resume Exit_btnOuvrir_Click
MsgBox Err.Description
Resume Exit_btnOuvrir_Click
End SubEnsuite voici le code à mettre dans le formulaire que l'on veut ouvrir :
Private Sub Form_Open(Cancel As Integer)
If Me.RecordsetClone.RecordCount = 0 Then
MsgBox "Le formulaire ne s'ouvre pas car il est vide.", vbInformation
Cancel = True 'Annule l'ouverture
End If
End SubLe code que nous mettons sur l'événement Sur clic du formulaire appelant a pour seul but d'intercepter une erreur générée par le code de fermeture du formulaire.
Quand vous tentez d'associer une requête contenant un paramètre à un graphique, vous obtenez l'erreur :
"Le moteur de base de données Microsoft ne reconnaît pas '[Forms]![NomDuFormulaire]![NomDuChamp]' en tant que nom de champ ou expression correcte"...
Pour y remédier, il faut définir le paramètre dans la requête :
- en mode modification de la requête, dans le menu : Requête --> Paramètres : mettre le nom complet du paramètre :[Forms]![NomDuFormulaire]![NomDuChamp] et son type de donnée ;
- ce qui donne en SQL (pour un entier par exemple) :
PARAMETERS [Forms]![NomDuFormulaire]![NomDuChamp] Short;Lien : Comment définir un type pour les paramètres d'une requête ?
Lien : Quels sont les types de champ ?
Ce code vous permet de récupérer le nombre d'enregistrements d'un sous-formulaire :
With Forms("Mon formulaire principal").Controls("Mon sous-formulaire").Form.RecordsetClone
.MoveLast
debug.print .RecordCount
End withCe code vous permet de savoir si toutes les ComboBox ont été renseignées, et cela vous place dans le premier combobox non renseigné :
Sub TestCtrl()
Dim Ctrl As control
For Each Ctrl In Me.Controls
If TypeOf Ctrl Is ComboBox Then
If Ctrl.Value = "" Or IsNull(Ctrl.Value) Then
MsgBox "Toutes les listes doivent avoir une information", vbOKOnly + vbExclamation, "Sélection"
Ctrl.SetFocus
Exit Sub
End If
End If
Next Ctrl
End SubPour les TextBox, il vous faut changer la ligne :
If TypeOf Ctrl Is ComboBox Thenpar
If TypeOf Ctrl Is TextBox Then


