1

I know this is a question that has been asked before and I have attempted multiple suggested solutions but either I dont quite understand how most of the solutions work or something else is happening.
The code builds a collections from dynamically created form objects to send to a class where they get attached to events to be executed or Atleast thats the plan. However it doesnt want to execute the event code for each of the objects unless go through it step by step after editing the code and then it will do it only once.

I did have a working version of the code but I wanted to optimize it for runtime and even though it generated the form and objects properly and added the objects to the collection the same way as the old code did it stopped working.
I then rewrote the code really simply to see what the problem was and I couldnt seem to figure it out.

Here is the simplified code

    Dim cEvents As Collection: Set cEvents = New Collection
    Dim CntrlH As caCntrlHndlr
    Dim OptBtn1 As MSForms.OptionButton
    Dim OptBtn2 As MSForms.OptionButton
    Dim ChkBx As MSForms.CheckBox
    Dim Nm As String
    Dim iMvT, iMvL, iOpt As Integer
    
        iOpt = 16
        iMvT = 12
        i = 0
For Each vKey In .Keys
                
                Set CntrlH = New caCntrlHndlr
                Set ChkBx = S5ca1.Frame1.Controls.Add("Forms.CheckBox.1", "Slct" & i, True)
                With ChkBx
                    .Caption = vKey
                    .Height = iOpt
                    .Width = Len(CStr(vKey)) * 20
                    .Left = 6
                    .Top = iMvT
                End With
                
                Set CntrlH.ChkBx = ChkBx
                
                Nm = "X"
                iMvL = 5
                Set OptBtn1 = S5ca1.Frame2.Controls.Add("Forms.OptionButton.1", Nm & i, True)
                With OptBtn1
                    .GroupName = Nm & i
                    .Caption = ""
                    .Height = iOpt
                    .Width = iOpt
                    .Left = 5
                    .Top = iMvT
                End With
                Set CntrlH.OptBtn1 = OptBtn1
                
                Set OptBtn2 = S5ca1.Frame2.Controls.Add("Forms.OptionButton.1", Nm & i, True)
                iMvL = 30
                With OptBtn2
                    .GroupName = Nm & i
                    .Caption = ""
                    .Height = iOpt
                    .Width = iOpt
                    .Left = 30
                    .Top = iMvT
                End With
                Set CntrlH.OptBtn2 = OptBtn2
            
                iMvT = iMvT + 20
                i = i + 1
                cEvents.Add CntrlH
                
                Next vKey
    
    S5ca1.Height = iMvT + 120
    S5ca1.Frame1.Height = iMvT + 10
    S5ca1.Frame2.Height = iMvT + 10

    S5ca1.OK.Top = S5ca1.Height - 54
    End With
End Sub

The above code is only a portion of it so dont worry about the end with at the very bottom that isnt the problem.

Class Code

Public WithEvents ChkBx As MSForms.CheckBox
Public WithEvents OptBtn1 As MSForms.OptionButton
Public WithEvents OptBtn2 As MSForms.OptionButton

Private Sub ChkBx_Click()
MsgBox "ChkBx"
End Sub
Private Sub OptBtn1_Click()
MsgBox "OptBtn1"
End Sub
Private Sub OptBtn2_Click()
MsgBox "OpBtn2"
End Sub

Attempted Solutions

I know for a fact that having multiple objects per item in the Collection probably isnt the problem. I have tried using an oject per item and that didnt seem to work and the working version of the script had the Collection setup. I have tried using the FrmObjct.OnClick="[Event Procedure]" Event to force an interaction and unless I am doing it wrong somehow, then that isnt working (Im pretty sure im applying that wrong).

Considering the nature of the problem its probably something really simple I missed but I cant seem to find what that is and my apologies if the solution is simple. Its my first time working with classes.

Thanks for the help already.

4

1 回答 1

2

You need to keep a reference to your cEvents collection outside of the method. Otherwise, your collection is destroyed after the method finishes executing.

private cEvents as Collection

Public Sub YourSubFromYourPost()
    set cEvents = new Collection

    '// the rest of your code here

End Sub
于 2021-03-30T14:18:08.263 回答