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 atteindre un contrôle d'un sous-formulaire ?
- Comment atteindre un contrôle d'un autre formulaire ?
- Comment éviter la mention "#Supprimé" qui apparaît dans les contrôles d'un formulaire après avoir supprimé un enregistrement ?
- Comment changer la valeur de plusieurs contrôles en même temps ?
- Est-il possible de créer dynamiquement des contrôles ?
- Comment savoir si un contrôle du formulaire est vide ?
- Quand je suis sur le formulaire B, comment savoir quel bouton du formulaire A a été cliqué pour l'ouvrir ?
- Comment rendre (in)visibles un ensemble de contrôles ?
- Comment verrouiller le contrôle d'un formulaire ?
- Comment ajouter une nouvelle page sur le contrôle onglet ?
- Comment préremplir un champ d'un formulaire qu'on ouvre en fonction d'un autre formulaire ?
- Comment sélectionner une page d'un onglet en VBA ?
- Comment afficher une image dans une page d'onglet ?
- Comment définir la valeur par défaut d'un champ ?
- Peut-on sauter des champs dans un formulaire ?
- Comment détecter une modification dans n'importe quel champ (dépendant) d'un formulaire ?
- Existe-t-il un moyen de vérifier la saisie d'un utilisateur dans un champ via des expressions régulières ?
- Comment limiter le nombre de caractères à la saisie dans un champ ?
- Comment désactiver le bouton "précédent" lorsque l'on est sur le premier enregistrement ?
- Comment faire pour que la première lettre saisie dans un contrôle soit en majuscule, puis les autres en minuscules ?
- Comment atteindre un contrôle dont le nom est dans une variable ?
- Comment énumérer les contrôles d'un formulaire dans une boucle ?
- Comment contrôler la saisie, empêcher la saisie de certains caractères ?
- Comment définir en VBA la valeur par défaut d'un contrôle affichant une date dans un formulaire ?
- Comment éviter qu'Access ne corrige automatiquement les mots saisis dans un contrôle ?
- Comment empêcher l'utilisateur de saisir du texte dans un contrôle ?
- Comment déterminer sur quel contrôle se trouve le focus ?
- Comment forcer l'utilisateur à utiliser la virgule et non le point lors de la saisie de nombres ?
- Pourquoi mon code affiche-t-il un nombre décimal dans une étiquette, alors que le champ durée de la requête est en heure abrégé du type hh:mm ?
- Comment créer dynamiquement un contrôle dans un formulaire et lui associer du code VBA sur un événement ?
- Comment interdire l'utilisation du clic droit de la souris sur un contrôle ?
- Comment créer dynamiquement un contrôle dans un formulaire et lui associer du code VBA sur un événement ?
- Comment récupérer la position du curseur dans un contrôle ?
- Comment déterminer la position d'un contrôle par le code ?
- Comment déplacer le pointeur de la souris vers un contrôle ?
- Comment donner le focus à un contrôle d'un sous-formulaire ?
- Comment afficher une info-bulle pendant le survol d'un contrôle ?
- Comment modifier le pointeur de la souris lors du survol d'un contrôle ?
- 7.1.1. Zones de liste et zones de liste modifiable (31)
- 7.1.2. Zones de texte (12)
- 7.1.3. TreeView (5)
- 7.1.4. Onglets (3)
Exemple pour une zone de texte :
Forms![NomFormulaire]![NomSousFormulaire].Form
![MaZoneDeText]
Lien : Comment atteindre un contrôle d'un autre formulaire ?
Voici le code le permettant :
Forms![NomFormulaire]![MaZoneDeText]
Il suffit de rafraîchir les données du formulaire :
Me.Requery
Pour changer la valeur des zones de liste :
For
Each
ctrl In
Me.Controls
If
ctrl.ControlType
=
acCheckBox Then
ctrl.Value
=
0
End
If
Next
ctrl
Sinon, si vous respectez les normes de préfixes pour les noms de contrôles, voici une solution :
Dim
ctl As
Control
For
Each
ctl In
Me.Controls
' On vérifie les trois premières lettres du nom du contrôle
Select
Case
Left
(
ctl.Name
, 3
)
' Si c'est une case à cocher
Case
"chk"
ctl.Value
=
-
1
' Si c'est une étiquette
Case
"lbl"
ctl.Caption
=
"- * - * -"
' Si c'est une zone de texte
Case
"txt"
ctl.Visible
=
False
ctl.Value
=
""
' Si c'est une zone de liste
Case
"cmb"
ctl.Visible
=
False
End
Select
Next
ctl
Il faut donc respecter une certaine norme dans l'appellation des contrôles. Le nom d'une zone de texte commence par "txt" (ex. : txtNom), les étiquettes par "lbl"...
Lien : Comment normaliser le nom des champs, des contrôles et des objets ?
Oui, grâce à la fonction CreateControl()
Lien : Comment créer dynamiquement des contrôles de type Rectangle sur le formulaire en cours ?
Lien : Comment créer dynamiquement un contrôle dans un formulaire et lui associer du code VBA sur un événement ?
Utiliser la fonction Nz() :
If
Nz
(
Me.MonChamp
, ""
) =
""
Then
MsgBox
"Champ vide"
End
If
Ou alors la fonction len() :
If
Len
(
Me.MonChamp
) =
0
Then
MsgBox
"Champ vide"
End
If
Grâce à ce code :
Forms
(
"formulaireA"
).ActiveControl.Name
Placez un groupe d'options (contrôle appartenant à la boîte à outils), modifiez ses attributs :
-> Apparence à "À deux dimensions"
-> Style bordure à "Transparent"
De cette manière le Groupe d'options ne se voit pas.
Placez tous les contrôles dessus.
Si votre groupe d'options s'appelle MonGroupe, il suffit de faire :
MonGroupe.Visible
=
False
pour le rendre invisible et son contenu ;
MonGroupe.Visilble
=
True
pour le faire réapparaître et son contenu.
MonControle.Locked
=
True
Pour le rendre à nouveau modifiable :
MonControle.Locked
=
False
Il faut utiliser la méthode Add du contrôle onglet. L'ajout d'une page d'onglet doit se faire
dans le formulaire en mode création.
Ce code ouvre le formulaire 'NomDuFormulaire' en mode création et ajoute une page au contrôle onglet 'NomDuControlOnglet' .
DoCmd.OpenForm
"NomDuFormulaire"
, acDesign
Forms
(
"NomDuFormulaire"
)(
"NomDuControlOnglet"
).Pages.Add
Attaquons en essayant d'être le plus synthétique possible :
1- le langage VBA est un langage basé sur plusieurs bibliothèques. On peut les explorer en faisant F2 depuis un module quelconque. Pour gérer ces bibliothèques, il faut aller dans Outils/Références, où une boîte de dialogue liste les références actives dans le projet (la base de données...) et les autres références présentes sur l'ordinateur.
2- pour trouver de l'aide il faut prendre de bonnes habitudes : la rechercher d'abord dans l'aide en ligne. Pour cela, sur les mots que l'on ne connait pas, appuyer sur la touche F1. On obtient ainsi l'aide relative au mot sélectionné. C'est une partie extrêmement importante. Il faut lire beaucoup d'informations pour progresser en VBA. La rechercher ensuite dans les discussions existant sur le site. Pour cela, il y a un outil rechercher en haut de chaque page. Enfin, si après tout cela, on n'a toujours pas trouvé, alors il faut poser la question le plus clairement possible en donnant tous les moyens à ceux qui seraient amenés à y répondre, de comprendre ce que l'on veut.
On souhaite que, lorsque l'on clique sur un bouton d'un premier formulaire (formAuteurs), un autre formulaire (formLivres) s'ouvre et que ce dernier soit prérempli avec une information venant du premier formulaire.
En examinant ce problème, on détermine deux prédicats importants : Quand et Quoi. Quoi détermine la ou les actions à entreprendre. Quand détermine le moment où elles sont déclenchées, l'événement qui les lance.
Examinons d'abord le QUOI
Ouvrir un formulaire donné (formLivres) en lui passant un élément du formulaire courant. Cette ouverture doit se faire en mode ajout.
Nous avons donc préparé un formulaire formLivres basé sur la table des livres.
Si nous travaillions de manière interactive avec Access, nous prendrions l'option 'OUVRIR' du formulaire, après avoir sélectionné son nom. Nous allons faire de même, mais en code. La ligne suivante :
Application.DoCmd.OpenForm
"formLivres"
,,,,acFormAdd,,me.
[N°Auteur]
retrace exactement cette demande : on y retrouve une première indication importante :
Application.DoCmd.OpenForm
que l'on pourrait traduire par : "Dans l'application Access en cours (Application), faire la commande (DoCmd) ouvrir le formulaire (OpenForm)"
Ouvrir le formulaire d'accord, mais lequel ? Comment ? En mode création ? En boite de dialogue ? En filtrant les données ? Beaucoup de questions dont on trouvera la réponse dans la suite de la ligne :
Copier la ligne dans un module, puis faire F1 après avoir sélectionné OpenForm. Voici un extrait de ce qu'on obtient.
L'aide Access a écrit :
expression.OpenForm(NomFormulaire, Afficher, NomFiltre, ConditionWhere, ModeDonnées, Modefenêtre, ArgOuverture)
Il s'agit de la syntaxe utilisée pour la méthode OpenForm.
La première chose attendue : le nom du formulaire. Comme c'est du texte qui est attendu, on le mettra entre guillemets "".
Afficher correspond au mode d'affichage : en mode création, en mode formulaire... par défaut, c'est-à-dire si on ne met rien, ce sera en mode formulaire.
NomFiltre et ConditionWhere correspondent à des manières différentes de filtrer, de n'afficher qu'une certaine quantité d'enregistrements.
ModeDonnées permet notamment en mettant acFormAdd de dire que l'on ne souhaite qu'ajouter de nouvelles données. ModeFenêtre permet par exemple de faire une boite de dialogue.
Enfin ArgOuverture (OpenArgs) permet de définir une chaîne de caractères que recevra le formulaire qui s'ouvre. C'est la raison pour laquelle on y met ME.[N°Auteur], ce qui correspond à dire : la valeur du contrôle [N°Auteur] qui est en Moi(sous-entendu le formulaire dans lequel se trouve ce code).
Voyons maintenant le QUAND
Il s'agit de cliquer sur un bouton...
Donc, cette action décrite plus haut se fera sur le clic du bouton.
Chaque objet des formulaires contient des événements (actions de l'utilisateur ou du système) que nous pouvons intercepter pour y mettre une série d'actions à entreprendre. Lorsque nous programmons en VBA ces événements, nous créons ce que nous appelons des procédures événementielles.
Dans ce cas, l'événement sur clic d'un bouton. Un double-clic dans la zone blanche de droite fera apparaître [Procédure événementielle]. Cliquer maintenant sur les trois points à droite, et on se retrouve dans un module (celui du formulaire, c'est inscrit dans la barre de titre du module) dans une sub (procédure) déclarée Private( car limitée au formulaire) qui a un nom composé :
Private
sub
cmdLivres_Click
(
)
End
Sub
Le bouton s'appelle cmdLivres. La première partie du nom fait référence au nom de l'objet, la deuxième à l'événement concerné. Pour préciser que c'est à ce moment-là que nous voulons faire l'action examinée plus haut, il va falloir mettre l'action dans la procédure, ce qui donne le résultat suivant :
Private
sub
cmdLivres_Click
(
)
Application.DoCmd.OpenForm
"formLivres"
,,,,acFormAdd,,me.
[N°Auteur]
End
Sub
La première partie du travail est terminée.
Maintenant que nous avons réussi à ouvrir un formulaire en lui passant des informations, il va falloir que ce dernier (formLivres) exploite ces informations. Alors ? Il va faire QUOI et QUAND ?
QUOI
Il va vérifier s'il a reçu un Openarg. Si c'est le cas, il mettra la valeur reçue dans son [N°Auteur], sinon, il n'y a lieu de rien faire.
Cela se traduit comme suit :
If
IsNull
(
Me.OpenArgs
) Then
' Rien à faire
Else
Me.
[N°Auteur]=
Clng
(
Me.OpenArgs
)
End
if
Si en moi (Me) les OpenArgs ne sont pas définis (IsNull()), alors
puisqu'il n'y a rien à faire, nous ne préciserons aucune ligne particulière en dessous, mais juste un petit commentaire. On le fait toujours précéder d'une apostrophe " ' ". Sinon (Else) mettre la valeur de l'Openarg convertie en entier long (Clng(Me.OpenArg)) dans le contrôle [N°Auteur] qui est en Moi.
Fin des tests (End If).
Reste à savoir quand cette vérification doit se faire !
À l'ouverture du formulaire semble être une bonne solution.
QUAND
Dans les propriétés du formulaire formlivres, on regarde l'onglet des événements, et on trouve Sur ouverture. On accède à la procédure événementielle de la même manière que pour le bouton et on obtient :
Private
Sub
Form_Open
(
Cancel As
Integer
)
End
Sub
Pour que la série d'actions décrites ci-dessus s'accomplissent, il n'y a plus qu'à les mettre dans cette procédure d'événement. Le résultat est donc :
Private
Sub
Form_Open
(
Cancel As
Integer
)
If
IsNull
(
Me.OpenArgs
) Then
' Rien à faire
Else
Me.
[N°Auteur]=
Clng
(
Me.OpenArgs
)
End
if
End
Sub
En résumé, deux procédures événementielles. Une déclenchée en cliquant sur un bouton. Une qui se déclenche à chaque ouverture du formulaire Livres. Dans chaque procédure, les actions que l'on veut voir s'accomplir à ce moment précis.
Il faut définir la propriété Value de l'onglet. Value doit correspondre à la propriété PageIndex (IndexPage) de la page à sélectionner. Exemple :
Me!NomOnglet.Value
=
0
MonOnglet.Pages
(
0
).Picture
=
"c:\temp\bmpaide.bmp"
Pour effacer l'image :
MonOnglet.Pages
(
0
).Picture
=
""
Dim
fldDate As
DAO.Field
Set
fldDate =
CurrentDb.TableDefs
!NomTable.Fields
(
"MonChampDate"
)
fldDate.DefaultValue
=
"Now()"
Set
fldDate =
Nothing
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Dans les propriétés du contrôle, Solution 1 : Arrêt tabulation=non Solution 2 : activé = non
Lorsqu'un formulaire dépendant subit des modifications sur un de ses champs,
son événement Si Modification (Dirty) est déclenché.
D'autre part, si vous ne souhaitez pas utiliser cet événement, il existe aussi la propriété Dirty du
formulaire dont la valeur est égale à True lorsque le contenu du formulaire a été modifié.
Nous voulons par exemple un champ dans lequel l'utilisateur doit rentrer obligatoirement de 1 à 3 chiffres suivis de 0 à 5 lettres...
Il faut définir la propriété Masque de saisie (InputMask) du contrôle dans le formulaire ou du champ dans la table : 0aa?????
Pour connaître tous les caractères spéciaux à utiliser pour créer des masques de saisie personnalisés
>> vous positionnez le curseur de la souris sur une propriété Masque de saisie et vous appuyez sur F1. Access va vous donner tous les caractères spéciaux des masques !
_ Contrôle lié :
Il suffit de définir la propriété "Taille du champ" directement dans la table.
_ Contrôle indépendant :
Il est possible d'utiliser la propriété Masque de saisie, dans les propriétés de la zone de texte il faut entrer un masque de saisie propriétés/données/masque de
saisie
exemple :
###### permet de taper seulement six chiffres.
Il est aussi possible d'utiliser la propriété "Valide si". Par exemple, "NbCar([NomControle])<=5" empêchera d'entrer plus de 5 caractères. Pour personnaliser le message d'erreur, entrer du texte dans la propriété "Message si erreur".
Private
Sub
Form_Current
(
)
On
Error
GoTo
GestErr
If
Me.CurrentRecord
>
1
Then
Me!BoutonPrécédent.Enabled
=
True
Else
Me!BoutonPrécédent.Enabled
=
False
End
If
Exit
Sub
GestErr
:
Select
Case
Err
Case
2164
Me!AutreContrôleActifDeTonChoix.SetFocus
Resume
Case
Else
MsgBox
Err
.Description
, , "Erreur n°"
&
Err
.Number
Exit
Sub
End
Select
End
Sub
On peut imaginer une évolution du code pour l'adapter également au bouton suivant dans le cas où nous sommes sur le dernier enregistrement.
Vous avez un champ par exemple Nom de famille, et vous voulez que quel que soit ce que tape l'utilisateur, le résultat soit de la forme "Martin" même s'il a tapé "mARtIn".
Private
Sub
txtMemo_KeyPress
(
KeyAscii As
Integer
)
If
KeyAscii >
64
Then
'on vérifie si on se trouve au le premier caractère
If
txtMemo.Selstart
=
0
Then
KeyAscii =
Asc
(
UCase
(
Chr
(
KeyAscii)))
Else
KeyAscii =
Asc
(
LCase
(
Chr
(
KeyAscii)))
End
If
End
If
End
Sub
Me.Controls
(
MaVar).value
=
"Mon texte"
De même, pour parcourir une collection de 180 objets dont les noms sont Ctrl1, Ctrl2... :
dim
Ctl as
control
For
i =
1
To
180
set
ctl=
Me.controls
(
"Ctrl"
&
i)
ctl.value
=
"mon texte"
Next
i
Ce code imprime le nom de chaque contrôle de Form1 dans la fenêtre de débogage :
Dim
Ctrl As
Control
For
Each
Ctrl in
Form1.Controls
Debug.Print
Ctrl.Name
Next
Lien : FAQ VB
Pour utiliser ceci vous avez besoin des valeurs ASCII des touches que vous voulez "verrouiller".
Code à mettre sur l'événement OnKeyPress du contrôle concerné :
If
KeyAscii =
32
Or
KeyAscii =
34
Then
MsgBox
"Ce caractère est interdit"
, vbInformation
KeyAscii =
0
End
If
Lien : Comment limiter le nombre de caractères saisis dans une zone de texte indépendante ?
Il faut convertir la valeur en numérique de type Double et ça marche :
Dim
MaDateParDefaut as
date
MaDateParDefaut =
#09
/
02
/
2005
#
txtMaDate.defaultValue
=
cdbl
(
MaDateParDefaut)
La correction automatique d'Access peut être gênante, par exemple lorsque l'on souhaite saisir un mot de passe.
En effet, si vous saisissez par exemple un mot comme "chateau", Access va le corriger en "château". Vous n'allez rien remarquer puisque les caractères saisis sont masqués par des "*". Mais le mot de passe saisi ne sera pas reconnu...
Pour régler ce problème il faut impérativement passer par un formulaire pour entrer les données.
En effet, il est possible de désactiver la correction automatique pour un contrôle en utilisant sa propriété AutoCorrectionPermise (AllowAutoCorrect).
Mais cela n'est pas possible pour une table.
Conseil : pensez à désactiver la touche F7 afin que l'utilisateur n'appelle pas lui-même le correcteur d'Access :
Private
Sub
MonContrôle_KeyDown
(
KeyCode As
Integer
, Shift As
Integer
)
If
KeyCode =
vbKeyF7 Then
KeyCode =
0
End
Sub
Lien : Comment masquer ce qui est tapé dans une zone de texte (pour un mot de passe) ?
Nous travaillons ici sur un contrôle nommé ListeDeroulante.
Private
Sub
ListeDeroulante_KeyPress
(
KeyAscii As
Integer
)
If
KeyAscii >
31
Then
KeyAscii =
0
Beep
End
If
End
Sub
Ce code ne bloquera pas la souris, mais aucune touche ne passera, sauf les touches de contrôle (Tab, Enter, Backspace...) dont les codes sont inférieurs à 32 (= espace, le 1er caractère).
Il suffit d'utiliser :
Screen.Activecontrol
La zone de texte avec laquelle nous travaillons se nomme zdtNombre.
Il suffit de mettre le code suivant :
Private
Sub
zdtNombre_KeyDown
(
KeyCode As
Integer
, Shift As
Integer
)
If
(
KeyCode =
190
) Then
KeyCode =
188
End
If
End
Sub
Ainsi, lorsque l'utilisateur appuiera sur la touche "." du clavier, cela insérera tout de même une virgule ",".
Parce que les dates sont stockées sous la forme d'un nombre réel double.
Or dans une requête, ce nombre peut être formaté pour n'en afficher que la partie décimale sous forme d'heure.
Mais dans une étiquette, il n'y a pas de propriété format.
La solution est d'utiliser la fonction Format() :
MonLabel.caption
=
Format
(
DSum
(
"durée"
, "reqt"
, strfiltre),"hh:mm"
)
Tout d'abord, il faut ouvrir le formulaire en mode création.
Ensuite pour créer un contrôle par le code il faut utiliser la méthode CreateControl de l'objet Application.
Pour créer une procédure événementielle, il faut utiliser la méthode CreateEventProc de l'objet Module.
Dim
ctl As
Control
'Crée un contrôle "Groupe d'options" :
Set
ctl =
CreateControl
(
"NomFormulaire"
, acOptionGroup, , NomPag, , 1200
, 3800
, 6300
, 2700
)
With
ctl
' Définit un nom pour le contrôle
.Name
=
"Options"
' Déclare l'événement "Après mise à jour" du contrôle
.AfterUpdate
=
"[Event Procedure]"
End
With
' Normalement il ne nous reste plus qu'à écrire la procédure
' événementielle avec Module.CreateEventProc
' Mais étant donné que nous avons créé un groupe d'options
' il faut maintenant créer à l'intérieur,
' un contrôle pour chaque option (nous allons pour cela nous servir
' de l'argument "Parent" de la méthode CreateControl).
' Créons par exemple un bouton d'option :
Set
ctl =
CreateControl
(
"NomFormulaire"
, acOptionButton, , ctl.Name
, , 1500
, 4000
)
With
ctl
.Name
=
"option1"
.OptionValue
=
1
End
With
' Et maintenant, création du code à exécuter sur AfterUpdate de Options :
Dim
mdl As
Module
Dim
lng As
Long
'Sert à récupérer le numéro de la ligne d'insertion de la procédure
Set
mdl =
Forms![NomFormulaire].Module
lng =
mdl.CreateEventProc
(
"AfterUpdate"
, "Options"
)
mdl.InsertLines
lng +
1
, _
vbTab
&
_
"If(option1.value = 2) then MsgBox "
&
Chr
(
34
) &
"Vous avez choisi 1."
&
Chr
(
34
)
' On libère la mémoire allouée aux variables.
Set
ctl =
Nothing
Set
mdl =
Nothing
Par exemple pour une zone de liste vous utilisez :
Me.MaListe.ShortcutMenuBar
=
""
Je me permets un petit ajout pour associer du code VBA au contrôle.
En effet, la méthode CreateEventProc n'est pas forcément des plus simples à utiliser.
On peut donc définir au préalable une fonction, et l'associer à l'événement que l'on veut. Attention, la fonction peut-être définie dans n'importe quel module, mais doit être Public.
Exemple :
Public
Function
maFonction (
)
MsgBox
"Message déclenché par l'événement BeforeUpdate"
End
Function
Pour associer ce code à mon contrôle, il faut soit que le formulaire soit ouvert en mode création et insérer le code qui suit, soit mettre ce même code sur l'événement OnLoad() du formulaire :
monControl.BeforeUpdate
=
"=maFonction()"
Le tour est joué.
ATTENTION : vous remarquerez que cette fonction ne retourne aucune valeur, ce qui en fait une procédure, cependant, si vous la déclarez en tant que telle (comme Sub), cela ne fonctionne pas...
Lien : Est-il possible de créer dynamiquement des contrôles ?
Vous pouvez utiliser l'attribut SelStart du contrôle pour obtenir (ou même définir) cette information.
Dans l'exemple suivant nous voulons connaître la position du curseur dans une zone de texte nommée MaZdt :
MsgBox
MaZdt.SelStart
Vous pouvez vous inspirer de cet exemple.
Dans l'en-tête du module du formulaire, déclarez :
Private
Declare
Function
apiSetCursorPos Lib
"user32"
Alias "SetCursorPos"
(
_
ByVal
X As
Long
, ByVal
Y As
Long
) As
Long
Private
Sub
MoveMyMouseToControl
(
pCtrl As
String
)
Dim
lx As
Long
, ly As
Long
, lw As
Long
, lh As
Long
Call
Me.Controls
(
pCtrl).accLocation
(
lx, ly, lw, lh)
apiSetCursorPos lx +
lw /
2
, _
ly +
lh /
2
End
Sub
Utilisation :
MoveMyMouseToControl "txtNumClient"
La souris sera déplacée au milieu du contrôle txtNumClient.
Il s'agit d'une fonction non documentée. Si elle ne fonctionne pas (suivant votre version) vous pouvez utiliser :
Option
Explicit
Private
Type
RECT
Left
As
Long
Top As
Long
Right
As
Long
Bottom As
Long
End
Type
' Attribue la position de la souris
Private
Declare
Function
apiSetCursorPos Lib
"user32"
Alias "SetCursorPos"
(
_
ByVal
X As
Long
, ByVal
Y As
Long
) As
Long
' Retourne le rectangle d'un objet windows
Private
Declare
Function
GetWindowRect Lib
"user32"
_
(
ByVal
hwnd As
Long
, lpRect As
RECT) As
Long
Private
Declare
Function
apiGetFocus Lib
"user32"
_
Alias "GetFocus"
(
) As
Long
Private
Sub
MoveMyMouseToControl
(
ByVal
strCtl As
String
)
Dim
ctl As
Control
Dim
hCtl As
Long
Dim
myRect As
RECT
For
Each
ctl In
Me.Controls
If
ctl.name
=
strCtl Then
' Nous calculons le rectangle en pixels
' dans lequel s'inscrit le contrôle
' nous calculons les coordonnées du centre du
' rectangle afin d'y placer la souris
ctl.SetFocus
hCtl =
apiGetFocus
GetWindowRect hCtl, myRect
apiSetCursorPos myRect.Left
+
(
myRect.Right
-
myRect.Left
) /
2
, _
myRect.Top
+
(
myRect.Bottom
-
myRect.Top
) /
2
End
If
Next
ctl
Set
ctl =
Nothing
End
Sub
Voici un code permettant de donner le focus à un contrôle d'un sous-formulaire après (par exemple) avoir quitté une boîte de dialogue :
Me.NomSsForm.SetFocus
Me.
[NomSsForm].Form
![NomControle].SetFocus
Lien : Les syntaxes d'appel : Interaction des formulaires et états
Pour afficher une info-bulle lors d'un survol d'un contrôle, il suffit d'aller dans les propriétés de ce contrôle :
- onglet "Autres" sur la ligne
- "Texte d'Info-bulle" mettre le texte voulu.
Le code suivant permet de changer la forme du curseur lors du survol d'un contrôle.
Placez la fonction suivante dans un module :
Private
Const
IDC_HAND =
32649
Private
Declare
Function
LoadCursor Lib
"user32"
Alias "LoadCursorA"
(
ByVal
hInstance As
Long
, ByVal
lpCursorName As
Long
) As
Long
Private
Declare
Function
SetCursor Lib
"user32"
(
ByVal
hCursor As
Long
) As
Long
Function
ChangeMouseToHand
(
)
Dim
hCur As
Long
hCur =
LoadCursor
(
0
, IDC_HAND)
If
(
hCur >
0
) Then
SetCursor hCur
End
If
End
Function
Pour afficher la main lors du survol d'un contrôle, il suffit d'appeler cette fonction.
Pour exemple : votre contrôle s'appelle ctrMonControl,
dans l'événement Sur souris déplacée de ce contrôle appelez la fonction.
Private
Sub
ctrMonControl_MouseMove
(
Button As
Integer
, Shift As
Integer
, X As
Single
, Y As
Single
)
' Appel Fonction pour changer le curseur
ChangeMouseToHand
End
Sub
Pour réinitialiser le curseur afin de retrouver le curseur par défaut, mettez le code ci-dessous sur l'événement Sur souris déplacée du formulaire :
Private
Sub
Form_MouseMove
(
Button As
Integer
, Shift As
Integer
, X As
Single
, Y As
Single
)
' Initialisation du curseur
Screen.MousePointer
=
0
End
Sub