FAQ VBA

FAQ VBAConsultez toutes les FAQ
Nombre d'auteurs : 10, nombre de questions : 133, dernière mise à jour : 15 juin 2021
Sommaire→Excel→Userforms, Code et Contrôles- 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 Sub2) 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 LongFonction 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 SubDans 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 SubLien : 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 SubLien : Comment supprimer un module de code dans un classeur externe ?



