FAQ VBA
FAQ VBAConsultez toutes les FAQ
Nombre d'auteurs : 10, nombre de questions : 133, dernière mise à jour : 15 juin 2021
- Comment bloquer le code en utilisant une UserForm non modale ?
- Comment trouver le Handle d'une Userform ?
- Comment inhiber ou masquer le bouton "Fermer" d'une UserForm ?
- Comment supprimer la barre de titre d'une UserForm ?
- Comment supprimer un module de code dans un classeur externe ?
- Comment supprimer une macro par le code ?
Il suffit, aprés l'affichage de la Userform, d'effectuer une boucle tant que celle-ci est visible :
'-- Afficher la Form en non modale
UserForm1.Show
False
'-- Boucle d'attente
While
UserForm1.Visible
DoEvents
Wend
'-- Suite du code ...
' ...
De nombreuses fonctions de l'API Win32 agissant sur les fenêtres réclament en paramètre le handle (ou identificateur) de la dite fenêtre.
Malheureusement certains applicatifs tels Excel, Word... ne permettent pas de récupérer cette valeur.
la fonction FindWindowA, de l'API Win32, permet de connaître le handle d'une fenêtre à partir de son titre.
Private
Declare
Function
FindWindowA Lib
"user32"
_
(
ByVal
lpClassName As
String
, ByVal
lpWindowName As
String
) As
Long
Private
Sub
UserForm_Initialize
(
)
Dim
MeHwnd As
Long
MeHwnd =
FindWindowA
(
vbNullString
, Me.Caption
)
MsgBox
"le Handle de l'Userform "
&
Me.Caption
&
" est : 0x"
&
Hex
(
MeHwnd)
End
Sub
Vous pouvez avoir besoin d'empêcher la fermeture d'une userform par la croix système.
2 solutions vous sont proposées ci-dessous :
1) La plus simple : inhiber l'action de la croix de fermeture dans l'évènement QueryClose de la UserForm :
Private
Sub
UserForm_QueryClose
(
Cancel As
Integer
, CloseMode As
Integer
)
If
CloseMode =
vbFormControlMenu Then
Cancel =
True
End
Sub
2) La plus jolie : masquer le bouton de fermeture de la UserForm :
'-- Dans la partie Déclaration de la Form :
Private
Const
SC_CLOSE =
&
HF060&
Private
Const
MF_BYCOMMAND =
&
H0&
Private
Declare
Function
GetSystemMenu Lib
"user32"
_
(
ByVal
hwnd As
Long
, ByVal
bRevert As
Long
) As
Long
Private
Declare
Function
RemoveMenu Lib
"user32"
_
(
ByVal
hMenu As
Long
, ByVal
nPosition As
Long
, ByVal
wFlags As
Long
) As
Long
Private
Declare
Function
FindWindowA Lib
"user32"
_
(
ByVal
lpClassName As
String
, ByVal
lpWindowName As
String
) As
Long
'-- Dans l'évènement Initialise de la Form :
Private
Sub
UserForm_Initialize
(
)
Dim
hSysMenu As
Long
Dim
MeHwnd As
Long
MeHwnd =
FindWindowA
(
vbNullString
, Me.Caption
)
If
MeHwnd >
0
Then
hSysMenu =
GetSystemMenu
(
MeHwnd, False
)
RemoveMenu hSysMenu, SC_CLOSE, MF_BYCOMMAND
Else
MsgBox
"Handle de "
&
Me.Caption
&
" Introuvable"
, vbCritical
End
If
End
Sub
Il faut utiliser les fonctions de l'API Windows : SetWindowLong, SetWindowPos, GetWindowRect, GetWindowLong et hSysMenu
et, pour le cas d'Excel ou Word qui ne donne pas accès au handle de la fenêtre : FindWindowA...
Déclarations à placer dans un module standard :
Public
Type
RECT
Left
As
Long
Top As
Long
Right
As
Long
Bottom As
Long
End
Type
Const
GWL_STYLE =
(-
16
)
Const
WS_CAPTION =
&
HC00000
Const
SWP_FRAMECHANGED =
&
H20
Public
Declare
Function
FindWindowA Lib
"user32"
_
(
ByVal
lpClassName As
String
, ByVal
lpWindowName As
String
) As
Long
Public
Declare
Function
GetWindowRect Lib
"user32"
_
(
ByVal
hwnd As
Long
, lpRect As
RECT) As
Long
Public
Declare
Function
GetWindowLong Lib
"user32"
Alias _
"GetWindowLongA"
(
ByVal
hwnd As
Long
, ByVal
nIndex As
Long
) As
Long
Public
Declare
Function
SetWindowLong Lib
"user32"
Alias _
"SetWindowLongA"
(
ByVal
hwnd As
Long
, ByVal
nIndex As
Long
, _
ByVal
dwNewLong As
Long
) As
Long
Public
Declare
Function
SetWindowPos Lib
"user32"
_
(
ByVal
hwnd As
Long
, ByVal
hWndInsertAfter As
Long
, ByVal
x As
Long
, _
ByVal
y As
Long
, ByVal
cx As
Long
, ByVal
cy As
Long
, _
ByVal
wFlags As
Long
) As
Long
Fonction pour afficher ou masquer la barre de titre d'une UserForm (vous pouvez aussi la placer dans le module) :
Sub
AfficheTitleBarre
(
stCaption As
String
, pbVisible As
Boolean
)
Dim
vrWin As
RECT
Dim
style As
Long
Dim
lHwnd As
Long
'- Recherche du handle de la fenêtre par son Caption
lHwnd =
FindWindowA
(
vbNullString
, stCaption)
If
lHwnd =
0
Then
MsgBox
"Handle de "
&
stCaption &
" Introuvable"
, vbCritical
Exit
Sub
End
If
GetWindowRect lHwnd, vrWin
style =
GetWindowLong
(
lHwnd, GWL_STYLE)
If
pbVisible Then
SetWindowLong lHwnd, GWL_STYLE, style Or
WS_CAPTION
Else
SetWindowLong lHwnd, GWL_STYLE, style And
Not
WS_CAPTION
End
If
SetWindowPos lHwnd, 0
, vrWin.Left
, vrWin.Top
, vrWin.Right
-
vrWin.Left
, _
vrWin.Bottom
-
vrWin.Top
, SWP_FRAMECHANGED
End
Sub
Dans l'évènement Initialize de l'UserForm concernée :
Private
Sub
UserForm_Initialize
(
)
'On passe en arguments :
' - le titre de la fenêtre
' - False pour masquer la barre de titre
AfficheTitleBarre Me.Caption
, False
End
Sub
Lien : Afficher/Masquer la barre de titre d'une fenêtre (FAQ VBA/ Access)
Vous devez ajouter la référence "Microsoft visual Basic For Application Extensenbility x.x" à votre projet :
Sub
Macro1
(
ByVal
nom As
String
)
Dim
w As
Workbook
Dim
d As
VBComponent
Set
w =
Workbooks.Open
(
Filename:=
"Classeur1.xls"
)
For
Each
d In
w.VBProject.VBComponents
If
d.Type
=
vbext_ct_StdModule And
d.Name
=
nom Then
w.VBProject.VBComponents.Remove
w.VBProject.VBComponents
(
d.Name
)
End
If
Next
w.Close
True
Vous devez connaître le nom de la macro et le nom du module dans lequelle elle se trouve.
Vous devez ajouter la référence "Microsoft visual Basic For Application Extensenbility x.x" à votre projet :
'Supprimer la macro nommée "MaMacro" dans le "module3"
Sub
supprimerUneMacroPrecise
(
)
Dim
Debut As
Integer
, Lignes As
Integer
With
ThisWorkbook.VBProject.VBComponents
(
"Module3"
).CodeModule
Debut =
.ProcStartLine
(
"MaMacro"
, 0
)
Lignes =
.ProcCountLines
(
"MaMacro"
, 0
)
.DeleteLines
Debut, Lignes
End
With
End
Sub
Lien : Comment supprimer un module de code dans un classeur externe ?