Class Module: Tạo sự kiện Enter/ Exit cho TextBox như thế nào?

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,655
Được thích
16,712
Giới tính
Nam
Tôi có một UserForm với nhiều TextBox và tôi muốn dùng Class để tạo 2 sự kiện Enter và Exit cho chúng vì chúng có chung một thủ tục.

Tôi thử với Class (Public WithEvents TbxEnter As MSForms.TextBox), mặc dù chúng có nhiều sự kiện của một TextBox, nhưng không có 2 sự kiện nói trên.

Xin vui lòng cho tôi hỏi, có thể tạo được 2 sự kiện trên không? Và tạo như thế nào?

Xin được hướng dẫn và giúp tôi về vấn đề này.

Trân trọng cám ơn.
 
Có giải pháp cho sự kiện Enter rồi hehehe.

Trong Standard Module:

Các hàm API & khai báo:

Mã:
Option Explicit

Declare Function SetTimer Lib "user32" _
(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long


Declare Function killtimerAPI Lib "user32" Alias "KillTimer" _
(ByVal hwnd As Long, ByVal nIDEvent As Long) As Long


Public lngTimerID As Long
Public strPreviousTextBox As String

Thủ tục tạo sự kiện:
Mã:
Public Sub TimerProc()

    With UserForm1
        If TypeName(.ActiveControl) = "TextBox" Then
            If strPreviousTextBox <> .ActiveControl.Name Then
                killtimerAPI 0, lngTimerID
                Call TextBox_Enter_Event
                .ActiveControl.SetFocus
                lngTimerID = SetTimer(0, 0, 1, AddressOf TimerProc)
                strPreviousTextBox = .ActiveControl.Name
            End If
        Else
            strPreviousTextBox = ""
        End If
    End With
    
End Sub

Thủ tục kiểm tra sự kiện hoạt động:

Mã:
Sub TextBox_Enter_Event()
    Dim strMsg As String
    With UserForm1.ActiveControl
        strMsg = "* Name :  " & .Name & vbCrLf
        strMsg = strMsg & "* Text :  " & .Object.Text & vbCrLf
        strMsg = strMsg & "* Tab index :  " & .TabIndex
    End With
    MsgBox "You entered TextBox : " & vbCrLf & vbCrLf & strMsg
End Sub

Thủ tục trong UserForm Module:

Mã:
Private Sub UserForm_Activate()
    lngTimerID = SetTimer(0, 0, 1, AddressOf TimerProc)
End Sub


Private Sub UserForm_Terminate()
    killtimerAPI 0, lngTimerID
    strPreviousTextBox = ""
End Sub
 
Upvote 0
Cuối cùng, mình cũng tìm ra giải pháp mình đang cần:

Trong Class Module:

[GPECODE=vb]Option ExplicitPublic WithEvents FormCtrl As UsfFormCtrl




Private Sub FormCtrl_OnEnter(Ctrl As MSForms.Control)


FormCtrl.Label2 = "You Entered the Control : " & "(" & Ctrl.Name & ")"


End Sub


Private Sub FormCtrl_OnExit(Ctrl As MSForms.Control, Cancel As Boolean)


FormCtrl.Label1 = "You left the Control : " & "(" & Ctrl.Name & ")"

End Sub
[/GPECODE]

Trong UserForm Module:

[GPECODE=vb]Option Explicit

Public Event OnEnter(Ctrl As MSForms.Control)
Public Event OnExit(Ctrl As MSForms.Control, Cancel As Boolean)


Private oXitClass As CtlExitCls
Private bFormUnloaded As Boolean
Private bCancel As Boolean
Private oPrevActiveCtl As MSForms.Control
Private oCol As New Collection


Private Sub UserForm_Layout()


Call WatchEvents


End Sub


Private Sub UserForm_Terminate()


Call CleanUp


End Sub




Private Sub WatchEvents()


If Not oXitClass Is Nothing Then Exit Sub


Set oXitClass = New CtlExitCls
Set oXitClass.FormCtrl = Me

bFormUnloaded = False

Set oPrevActiveCtl = Me.ActiveControl
RaiseEvent OnEnter(Me.ActiveControl)

Do While bFormUnloaded = False
If Not oPrevActiveCtl Is Nothing Then
If Not oPrevActiveCtl Is Me.ActiveControl Then
RaiseEvent OnExit(oPrevActiveCtl, bCancel)
RaiseEvent OnEnter(Me.ActiveControl)
If bCancel Then
oPrevActiveCtl.SetFocus
Else
Me.ActiveControl.SetFocus
End If
End If
End If
Set oPrevActiveCtl = Me.ActiveControl
DoEvents
Loop


End Sub


Private Sub CleanUp()


bFormUnloaded = True
RaiseEvent OnExit(oPrevActiveCtl, bCancel)
Set oXitClass = Nothing
Set oCol = Nothing
Set oPrevActiveCtl = Nothing


End Sub
[/GPECODE]

Hy vọng những ai có nhu cầu chung như mình cùng tham khảo và thấy bài này hữu ích.
 

File đính kèm

  • EnterExitEvent.xlsm
    24.4 KB · Đọc: 39
Upvote 0
Bài này chúng ta sẽ thấy nó tổng quát hơn:

Trong Class Module (clsFormEvents):

[GPECODE=vb]Option Explicit
Private WithEvents mFrm As MSForms.UserForm

Public Event OnEnter(ctl As MSForms.Control)
Public Event OnExit(ctl As MSForms.Control, Cancel As Boolean)

Private moFormControlEvents As clsFormControlEvents
Private mblnFormUnloaded As Boolean
Private mblnCancel As Boolean
Private mctlPrevious As MSForms.Control

Public Property Set Form(frmNew As MSForms.UserForm)
Set mFrm = frmNew
End Property

Public Property Let Unload(blnUnload)
mblnFormUnloaded = blnUnload
End Property

Private Sub mFrm_Layout()
Call WatchEvents
End Sub

Private Sub WatchEvents()
Set moFormControlEvents = New clsFormControlEvents
Set moFormControlEvents.FormCtrl = Me

Set mctlPrevious = mFrm.ActiveControl
RaiseEvent OnEnter(mFrm.ActiveControl)

Do While mblnFormUnloaded = False
If Not mctlPrevious Is Nothing Then
If Not mctlPrevious Is mFrm.ActiveControl Then
RaiseEvent OnExit(mctlPrevious, mblnCancel)
RaiseEvent OnEnter(mFrm.ActiveControl)
If mblnCancel Then
mctlPrevious.SetFocus
Else
mFrm.ActiveControl.SetFocus
End If
End If
End If
Set mctlPrevious = mFrm.ActiveControl
DoEvents
Loop

End Sub
[/GPECODE]

Trong Class Module (clsFormControlEvents):

[GPECODE=vb]Option Explicit
Public WithEvents FormCtrl As clsFormEvents

Private Sub FormCtrl_OnEnter(Ctrl As MSForms.Control)
UserForms(0).Label2 = "You Entered the Control : " & "(" & Ctrl.Name & ")"
End Sub

Private Sub FormCtrl_OnExit(Ctrl As MSForms.Control, Cancel As Boolean)
UserForms(0).Label1 = "You left the Control : " & "(" & Ctrl.Name & ")"
End Sub
[/GPECODE]

Và trong UserForm Module:

[GPECODE=vb]Option Explicit

Private moFormEvents As clsFormEvents
Private mcolFormEvents As Collection

Private Sub UserForm_Initialize()
If mcolFormEvents Is Nothing Then
Set mcolFormEvents = New Collection
End If

Set moFormEvents = New clsFormEvents
moFormEvents.Unload = False
Set moFormEvents.Form = Me
mcolFormEvents.Add moFormEvents
End Sub

Private Sub CommandButton1_Click()
Unload Me
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
moFormEvents.Unload = True
Set moFormEvents = Nothing
Set mcolFormEvents = Nothing
End Sub
[/GPECODE]
 

File đính kèm

  • EnterExitEvent2.xlsm
    26.9 KB · Đọc: 32
Lần chỉnh sửa cuối:
Upvote 0
Sửa code tí:

Thay vì:

Mã:
PrivateSub WatchEvents()
[COLOR=#000000][FONT=Consolas]    Set moFormControlEvents = New clsFormControlEvents[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]    Set moFormControlEvents.FormCtrl = Me[/FONT][/COLOR]

[COLOR=#000000][FONT=Consolas]    Set mctlPrevious = mFrm.ActiveControl[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]    RaiseEvent OnEnter(mFrm.ActiveControl)[/FONT][/COLOR]

[COLOR=#000000][FONT=Consolas]    Do While mblnFormUnloaded = False[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]        If Not mctlPrevious Is Nothing Then[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]            If Not mctlPrevious Is mFrm.ActiveControl Then[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]                RaiseEvent OnExit(mctlPrevious, mblnCancel)[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]                [COLOR=#ff0000]RaiseEvent OnEnter(mFrm.ActiveControl)[/COLOR][/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]                If mblnCancel Then[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]                    mctlPrevious.SetFocus[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]                Else[/FONT][/COLOR]
[COLOR=#ff0000][FONT=Consolas]                    mFrm.ActiveControl.SetFocus[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]                End If[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]            End If[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]        End If[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]        Set mctlPrevious = mFrm.ActiveControl[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]        DoEvents[/FONT][/COLOR]
[COLOR=#000000][FONT=Consolas]    Loop[/FONT][/COLOR]

EndSub

Thì sửa như thế này sẽ hợp lý hơn:

Mã:
Private Sub WatchEvents()
    
    Set moFormControlEvents = New clsFormControlEvents
    Set moFormControlEvents.FormCtrl = Me
    
    Set mctlPrevious = mFrm.ActiveControl
    RaiseEvent OnEnter(mFrm.ActiveControl)
    
    Do While mblnFormUnloaded = False
        If Not mctlPrevious Is Nothing Then
            If Not mctlPrevious Is mFrm.ActiveControl Then
                RaiseEvent OnExit(mctlPrevious, mblnCancel)
                If mblnCancel Then
                    mctlPrevious.SetFocus
                Else
[COLOR=#ff0000]                   RaiseEvent OnEnter(mFrm.ActiveControl)[/COLOR]
                End If
            End If
        End If
        Set mctlPrevious = mFrm.ActiveControl
        DoEvents
    Loop


End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom