Sự kiện Enter của frame trong Class Module không nhận

Liên hệ QC

Bluestar092011

Thành viên hoạt động
Tham gia
17/8/15
Bài viết
129
Được thích
147
Giới tính
Nam
Em mới tìm hiểu về Class Module và có tạo một cái Class để bắt sự kiện Enter của Frame, Nhưng sự kiện này không có tác dụng trong Class, mặc dù sự kiện Click, MouseMove và KeyUp vẫn diễn ra bình thường. Anh chị nào biết nguyên nhân và chỉ cách khắc phục mình cảm ơn nhiều.
 

File đính kèm

  • Class Control.xlsm
    20 KB · Đọc: 9
Em mới tìm hiểu về Class Module và có tạo một cái Class để bắt sự kiện Enter của Frame, Nhưng sự kiện này không có tác dụng trong Class, mặc dù sự kiện Click, MouseMove và KeyUp vẫn diễn ra bình thường. Anh chị nào biết nguyên nhân và chỉ cách khắc phục mình cảm ơn nhiều.
Hầu như các controls thuộc UserForm không có sự kiện Enter và Exit trong Class Module nhé bạn.
 
Upvote 0
Vậy mình có giải pháp nào thay thế không anh? Ý em là muốn nhận biết khi nó nhận Focus ấy.

Bạn thử phối hợp sự kiện Form_MouseMove + Frame_MouseMove xem thử có giúp ích gì không.
khi di chuột qua Frame thì biến lưu thông tin frame như bạn đang làm, khi di chuột ra khỏi frame , nằm trên Form thì sự kiện form mouse move bắt và ghi thông tin "đang ở form".
 
Upvote 0
Em mới tìm hiểu về Class Module và có tạo một cái Class để bắt sự kiện Enter của Frame, Nhưng sự kiện này không có tác dụng trong Class, mặc dù sự kiện Click, MouseMove và KeyUp vẫn diễn ra bình thường. Anh chị nào biết nguyên nhân và chỉ cách khắc phục mình cảm ơn nhiều.
Bạn thêm Frame3 và thử đoạn code này xem
PHP:
Dim f3

Private Sub Frame3_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Not f3 Then
        Debug.Print "vô 3"
        f3 = True
    End If
End Sub

Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If f3 Then
        f3 = False
        Debug.Print "Ra lúc" & Now
    End If
End Sub
 
Upvote 0
Bạn thử phối hợp sự kiện Form_MouseMove + Frame_MouseMove xem thử có giúp ích gì không.
khi di chuột qua Frame thì biến lưu thông tin frame như bạn đang làm, khi di chuột ra khỏi frame , nằm trên Form thì sự kiện form mouse move bắt và ghi thông tin "đang ở form".
Cái này mình nghĩ không hợp lý, ví dụ người ta không dùng chuột và chỉ dùng phím Tab để chuyển qua lại giữa các control (Textbox, Combobox, frame, Listbox...) thì nhận biết bằng cách nào?
Bạn thêm Frame3 và thử đoạn code này xem
PHP:
Dim f3

Private Sub Frame3_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Not f3 Then
        Debug.Print "vô 3"
        f3 = True
    End If
End Sub

Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If f3 Then
        f3 = False
        Debug.Print "Ra lúc" & Now
    End If
End Sub
Giống quan điểm trên.
 
Upvote 0
Cái này mình nghĩ không hợp lý, ví dụ người ta không dùng chuột và chỉ dùng phím Tab để chuyển qua lại giữa các control (Textbox, Combobox, frame, Listbox...) thì nhận biết bằng cách nào?

Giống quan điểm trên.
Ván đề của chú thực ra chỉ là clone cái sub MouseMove rồi thay chữ "_Enter" thôi mà.
 
Upvote 0
OK, tặng cho bạn các sự kiện Enter & Exit cho tất cả controls trên UserForm luôn, thử xem sự thay đổi trên caption của UserForm khi click hay tab vào Frame1 và Frame2 xem sao nhé!

Trong Classe Module 1:

Mã:
Option Explicit
Private WithEvents mUSF 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 mUSF = frmNew
End Property

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

Private Sub mUSF_Layout()
    Call WatchEvents
End Sub

Private Sub WatchEvents()
  
    Set moFormControlEvents = New clsFormControlEvents
    Set moFormControlEvents.FormCtrl = Me
  
    Set mctlPrevious = mUSF.ActiveControl
    RaiseEvent OnEnter(mUSF.ActiveControl)
  
    Do While mblnFormUnloaded = False
        If Not mctlPrevious Is Nothing Then
            If Not mctlPrevious Is mUSF.ActiveControl Then
                RaiseEvent OnExit(mctlPrevious, mblnCancel)
                RaiseEvent OnEnter(mUSF.ActiveControl)
                If mblnCancel Then
                    mctlPrevious.SetFocus
                Else
                    'mUSF.ActiveControl.SetFocus
                    RaiseEvent OnEnter(mUSF.ActiveControl)
                End If
            End If
        End If
        Set mctlPrevious = mUSF.ActiveControl
        DoEvents
    Loop

End Sub

Trong Class Module 2:

Mã:
Option Explicit
Public WithEvents FormCtrl As clsFormEvents

Private Sub FormCtrl_OnEnter(Ctrl As MSForms.Control)
    With UserForms(0)
        .Label2 = "You Entered the Control :  " & "(" & Ctrl.Name & ")"
        If Ctrl.Name = "Frame1" Or Ctrl.Name = "Frame2" Then
            .Caption = "Ban dang Click vao " & Ctrl.Name
        Else
            .Caption = "Nghia dep trai"
        End If
    End With
End Sub

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

Trong UserForm:

Mã:
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

Hy vọng nó có thể sử dụng được trong trường hợp của bạn.
 

File đính kèm

  • EnterExitEvent2.xlsm
    27.6 KB · Đọc: 19
Lần chỉnh sửa cuối:
Upvote 0
Ván đề của chú thực ra chỉ là clone cái sub MouseMove rồi thay chữ "_Enter" thôi mà.
Ý mình là muốn phát hiện tab nhảy đến Frame đó bạn, còn cái vụ Clone gì đó mình chưa biết rồi (Do mình không chuyên về lập trình nên có thể nó là các từ chuyên ngành nào đó mình chưa tìm hiểu).
OK, tặng cho bạn các sự kiện Enter & Exit cho tất cả controls trên form luôn, thử xem sự thay đổi trên caption của UserForm khi click hay tab vào Fram1 và Frame2 xem sao nhé!

Trong Classe Module 1:

Mã:
Option Explicit
Private WithEvents mUSF 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 mUSF = frmNew
End Property

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

Private Sub mUSF_Layout()
    Call WatchEvents
End Sub

Private Sub WatchEvents()
  
    Set moFormControlEvents = New clsFormControlEvents
    Set moFormControlEvents.FormCtrl = Me
  
    Set mctlPrevious = mUSF.ActiveControl
    RaiseEvent OnEnter(mUSF.ActiveControl)
  
    Do While mblnFormUnloaded = False
        If Not mctlPrevious Is Nothing Then
            If Not mctlPrevious Is mUSF.ActiveControl Then
                RaiseEvent OnExit(mctlPrevious, mblnCancel)
                RaiseEvent OnEnter(mUSF.ActiveControl)
                If mblnCancel Then
                    mctlPrevious.SetFocus
                Else
                    'mUSF.ActiveControl.SetFocus
                    RaiseEvent OnEnter(mUSF.ActiveControl)
                End If
            End If
        End If
        Set mctlPrevious = mUSF.ActiveControl
        DoEvents
    Loop

End Sub

Trong Class Module 2:

Mã:
Option Explicit
Public WithEvents FormCtrl As clsFormEvents

Private Sub FormCtrl_OnEnter(Ctrl As MSForms.Control)
    With UserForms(0)
        .Label2 = "You Entered the Control :  " & "(" & Ctrl.Name & ")"
        If Ctrl.Name = "Frame1" Or Ctrl.Name = "Frame2" Then
            .Caption = "Ban dang Click vao " & Ctrl.Name
        Else
            .Caption = "Nghia dep trai"
        End If
    End With
End Sub

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

Trong UserForm:

Mã:
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

Hy vọng nó có thể sử dụng được trong trường hợp của bạn.
Đúng cái này rồi đó anh, nhưng anh có thể chú thích code cho em hiểu với được không? Nhìn code thấy mong lung quá, mà anh có tài liệu nào nói về cái vụ Class Module cho VBA cho em xin với, chủ yếu là mò và nhìn thấy code anh viết thì chẳng biết gì luôn, mới tìm hiểu mà anh chỉ kết hợp 2 cái Class lại thì có lẽ dễ tẩu quả lắm.
 
Upvote 0
Đúng cái này rồi đó anh, nhưng anh có thể chú thích code cho em hiểu với được không? Nhìn code thấy mong lung quá, mà anh có tài liệu nào nói về cái vụ Class Module cho VBA cho em xin với, chủ yếu là mò và nhìn thấy code anh viết thì chẳng biết gì luôn, mới tìm hiểu mà anh chỉ kết hợp 2 cái Class lại thì có lẽ dễ tẩu quả lắm.
Tôi nghĩ bạn nên nghiên cứu trước về nó tại đây:
 
Upvote 0
Web KT
Back
Top Bottom