Trigger Enter field behaviour through class for a

2020-02-07 03:57发布

I raised a query on Friday (here is the query) which works perfectly as per David Zemens instructions and BrakNicku guidance. Problem I have is that: one of the events I want to use is Enter. Unfortunately, within the class, I don't get the option for this event. Does anyone one know if there is a way to perhaps add this to the class or trigger an Enter event for the control somehow?

I've tried using most of the events available within the class but none of them behave the way I need them to. Just to give a quick background: I use Enter event to set help text for the field in focus. So everytime user enters a field, I have a help textbox that gets populated with help text

Unfortunately, I am unable to share the workbook but happy to answer any questions

Thanks in advance

标签: excel vba
3条回答
狗以群分
2楼-- · 2020-02-07 04:36

So the approach I went with was: I already had Class Module that was trapping Change event (can be seen here). As i didnt have access to Enter event in my class, I used the KeyUp and MouseDown events in this class to set help for each control. This way user can get to a field by clicking on it or tabbing to it: help is displayed for the selected control

查看更多
我想做一个坏孩纸
3楼-- · 2020-02-07 04:39

Here another solution, (doesnot work on a MAC)

Open Notepad and copy code below and paste it in a new txt-file save it als CatchEvents.cls

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "CatchEvents"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Private Type GUID
      Data1 As Long
      Data2 As Integer
      Data3 As Integer
      Data4(0 To 7) As Byte
End Type

#If VBA7 And Win64 Then
      Private Declare PtrSafe Function ConnectToConnectionPoint Lib "shlwapi" Alias "#168" (ByVal punk As stdole.IUnknown, _
              ByRef riidEvent As GUID, ByVal fConnect As Long, ByVal punkTarget As stdole.IUnknown, ByRef pdwCookie As Long, _
              Optional ByVal ppcpOut As LongPtr) As Long
#Else
     Private Declare Function ConnectToConnectionPoint Lib "shlwapi" Alias "#168" (ByVal punk As stdole.IUnknown, ByRef riidEvent As GUID, _
              ByVal fConnect As Long, ByVal punkTarget As stdole.IUnknown, ByRef pdwCookie As Long, Optional ByVal ppcpOut As Long) As Long
#End If

Private EventGuide As GUID
Private Ck As Long
Private ctl As Object
'All Other Control-Events also possible
Public Sub MyEnter()
Attribute MyEnter.VB_UserMemId = -2147384830
  Select Case TypeName(ctl)
  Case "TextBox": MsgBox "Your code for " & ctl.Name & " here!"
  Case Else: MsgBox "You entered no TextBox but another control (" & ctl.Name & ")!"
  End Select
End Sub

Public Sub ConnectAllEvents(ByVal Connect As Boolean)
      With EventGuide
          .Data1 = &H20400
          .Data4(0) = &HC0
          .Data4(7) = &H46
      End With
      ConnectToConnectionPoint Me, EventGuide, Connect, ctl, Ck, 0&
End Sub

Public Property Let Item(Ctrl As Object)
      Set ctl = Ctrl
      Call ConnectAllEvents(True)
End Property

Public Sub Clear()
      If (Ck <> 0) Then Call ConnectAllEvents(False)
      Set ctl = Nothing
End Sub

In your VBA editor you import this File

In your Userform code you add:(when you have already an Initialize-event you combine those)

Private AllControls() As New CatchEvents 'on top

Private Sub UserForm_Initialize()
ReDim AllControls(Controls.Count - 1)
    For j = 0 To Controls.Count - 1
        AllControls(j).Item = Controls(j)
    Next
End Sub

Now every Enter-event of any control will be catched, so you have to act accordingly. Every event on a Userform can be catched this way.

查看更多
Summer. ? 凉城
4楼-- · 2020-02-07 04:47

Let's say your userform (Userform1) looks like this

enter image description here

I am going to demonstrate the Enter Event for 2 controls. TextBox and ComboBox.

Ensure that you place the CommandButton1 first on the userform. Or alternatively, set it's TabIndex to 0. This is so that the command button takes focus first when the userform loads and you can test the Entering of TextBox and ComboBox.

enter image description here

Paste this in a class module. My Class module name is Class1

Option Explicit

Public WithEvents Usrfrm As UserForm1
Const MyMsg As String = "Hiya there. Did you just try to sneak into the "

Private Sub Usrfrm_OnEnter(ctrl As msforms.Control)
    Select Case True
        Case TypeName(ctrl) Like "ComboBox"
            'Call Usrfrm.Combobox_List(ctrl)
            MsgBox MyMsg & "combobox?", vbCritical, "Aha!"
        Case TypeName(ctrl) Like "TextBox"
            MsgBox MyMsg & "textbox?", vbCritical, "Aha!"
    End Select
End Sub

Paste this in the userform code area

Option Explicit

Public Event OnEnter(ctrl As msforms.Control)
Private prevCtl As msforms.Control
Private mycls As Class1
Private IsfrmUnloaded As Boolean

Private Sub CommandButton1_Click()
    Unload Me
End Sub

Private Sub UserForm_Layout()
    Call spyWhatsGoingOn
End Sub

Private Sub spyWhatsGoingOn()
    Set mycls = New Class1
    Set mycls.Usrfrm = Me

    IsfrmUnloaded = False

    Set prevCtl = Me.ActiveControl

    RaiseEvent OnEnter(Me.ActiveControl)

    Do While IsfrmUnloaded = False
        If Not prevCtl Is Nothing Then
            If Not prevCtl Is Me.ActiveControl Then
                RaiseEvent OnEnter(Me.ActiveControl)
                Me.ActiveControl.SetFocus
            End If
        End If
        Set prevCtl = Me.ActiveControl
        DoEvents
    Loop
End Sub

Demo

enter image description here

查看更多
登录 后发表回答