Click Event in Class Module Not Firing

2019-01-26 23:05发布

I have a user form that displays line-by-line validation errors (in text box) that I want to supplement with user form labels that act as hyperlinks that users can click to go directly to the cell with issues.

I have code that builds labels on the fly and have added a click event through class modules but I cannot get it the click event in the class module to fire.

I did modify this code from working code that builds this type of label and click event on the fly, but that code loads labels at userform initiation and places each class object into a collection. I don't know if that is necessary to build into my solution, but I played with it and could not get it to work.

Here is my procedure to place label on the userform if needed. It runs inside another procedure if validation is needed. Userform is than shown, filled out with message (and this one label that gets created for now), if validation is needed.

Sub PlaceLinkLabel(SayWhat As String, WhichSheet As String, WhichRange As String)

    Dim lblNew As MSForms.Label
    Set lblNew = frmValidationMessage.Controls.Add(bstrProgID:="Forms.Label.1", Name:=SayWhat, Visible:=True)

    With lblNew
        With .Font
            .Size = 10
            .Name = "Comic Sans MS"
        End With

        .Caption = SayWhat
        .Top = 55
        .Height = 15
        .Left = 465
        .Width = 100
    End With

    Dim clsLabel As UserFormLabelLinks
    Set clsLabel = New UserFormLabelLinks
    Set clsLabel.lbl = lblNew

    With clsLabel
        .WhichRange = WhichRange
        .WhichSheet = WhichSheet
    End With

    'not sure if this is needed or not
    'Dim pLabels As Collection
    'Set pLabels = New Collection
    'pLabels.Add clsLabel

End Sub

Here is UserFormLabelLinks class module:

Option Explicit

Private WithEvents pLabel As MSForms.Label
Private sWhichRange As String
Private sWhichSheet As String

Public Property Set lbl(value As MSForms.Label)
    Set pLabel = value
End Property

Public Property Get WhichSheet() As String
    WhichSheet = sWhichSheet
End Property

Public Property Let WhichSheet(value As String)
    sWhichSheet = value
End Property

Public Property Get WhichRange() As String
    WhichRange = sWhichRange
End Property

Public Property Let WhichRange(value As String)
    sWhichRange = value
End Property


Private Sub pLabel_Click()

    MsgBox "hi" 'when i click label, this does not fire

    'Application.Goto ThisWorkbook.Worksheets(WhichSheet).Range(WhichRange), True
    'ActiveWorkbook.FollowHyperlink ("#" & WhichSheet & "!" & WhichRange)

End Sub

2条回答
走好不送
2楼-- · 2019-01-26 23:59

Another approach that worked:

Placing Private pLabels As Collection atop the module where PlaceLinkLabel is stored

and using

If pLabels Is Nothing Then Set pLabels = New Collection
pLabels.Add clsLabel

at the end of PlaceLinkLabel module

查看更多
可以哭但决不认输i
3楼-- · 2019-01-27 00:00

The MSForms.Label object is going out of scope as soon as PlaceLinkLabel exits, as does the UserFormLabelLinks object reference; thus you're creating a label, but it's a fire-and-forget thing that you can't programmatically access as soon as End Sub is reached, hence the events never fire.

You need a private field to hold on to the UserFormLabelLinks object reference (and thus keep the MSForms.Label reference around via the encapsulated pLabel field):

Option Explicit
Private clsLabel As UserFormLabelLinks

Then remove this line in the procedure:

Dim clsLabel As UserFormLabelLinks

In other words, promote that local variable to a field, to keep it around after the procedure has completed.

查看更多
登录 后发表回答