从自定义类读取/返回变量值到用户名-VBA Excel

从自定义类读取/返回变量值到用户名-VBA Excel,excel,vba,class,variables,methods,Excel,Vba,Class,Variables,Methods,我有一个基于CommandButton类自定义创建的类btnClass Public WithEvents ButtonEvent As MsForms.CommandButton Private Sub ButtonEvent_Click() End sub 我有一个UserForm1,它有一个列表框、一个标签和数百个动态创建的CommandButtons。我给按钮分配了btnClass。单击按钮时,我希望单击事件具有以下结果: 如果选择的按钮数量selQty小于Label.Captio

我有一个基于CommandButton类自定义创建的类btnClass

Public WithEvents ButtonEvent As MsForms.CommandButton

Private Sub ButtonEvent_Click()

End sub
我有一个UserForm1,它有一个列表框、一个标签和数百个动态创建的CommandButtons。我给按钮分配了btnClass。单击按钮时,我希望单击事件具有以下结果:

如果选择的按钮数量selQty小于Label.Caption totalQty,并且此按钮以前未被选择,请向listBox添加值并更改背景色。 如果之前选择了此按钮,请更改颜色并将所选按钮数减少1。 我尝试创建公共变量,但无法得到想要的结果。这可行吗


注意:当激活UserForm1时,表示未选择任何按钮;单击按钮时,我会更改按钮的颜色并将其接受为选中状态。

以下是一些让您开始学习的内容

创建一个包装类,用于包装每个按钮并处理其单击事件。然后,当表单加载时,循环遍历控件并包装按钮

需要一个模块级集合来保存包装按钮包装类的引用

ButtonRapper类:

表单背后的代码:

Option Explicit

Private m_handlers As Collection

'Initialize
Private Sub UserForm_Initialize()

    Set m_handlers = New Collection

    Dim ctl As Control

    For Each ctl In Me.Controls
        If TypeName(ctl) = "CommandButton" Then
            With New ButtonWrapper
                m_handlers.Add .WrapCommandButton(ctl)
            End With
        End If
    Next ctl
End Sub

'Clean up
Private Sub UserForm_Terminate()
    Set m_handlers = Nothing
End Sub

希望这能有所帮助。

看起来你想做这样的事情

clsButtonClick:

Option Explicit

Public WithEvents ButtonEvent As MSForms.CommandButton

Private Sub ButtonEvent_Click()
    'pass the button to the procedure in the userform
    ButtonEvent.Parent.HandleClick ButtonEvent
End Sub
用户表单代码:

Option Explicit

Const CLR_SEL As Long = vbRed         'selected color
Const CLR_NOT_SEL As Long = vbGreen   'unselected color

Dim btnCol As Collection
Dim maxQty As Long   'max number selectable
Dim currQty As Long  'number currently selected

'perform some setup
Private Sub UserForm_Activate()
    Const NUM_BUTTONS As Long = 10
    Dim i As Long, btn As MSForms.CommandButton
    Dim o As clsButtonClick

    currQty = 0  'number selected
    maxQty = 5   'max selectable
    Set btnCol = New Collection
    'add some buttons
    For i = 1 To NUM_BUTTONS
        Set btn = Me.Controls.Add("Forms.CommandButton.1", "btn" & i, True)
        btn.BackColor = CLR_NOT_SEL
        btn.Height = 18
        btn.Left = 20
        btn.Top = 20 * i
        btn.Caption = "Button " & i
        Set o = New clsButtonClick
        Set o.ButtonEvent = btn
        btnCol.Add o
    Next i
End Sub

'handle a button click event (button is passed in)
Sub HandleClick(btn As MSForms.CommandButton)
    If btn.BackColor = CLR_SEL Then
        btn.BackColor = CLR_NOT_SEL
        currQty = currQty - 1
    Else
        If currQty = maxQty Then
            MsgBox "no more selections available"
        Else
            btn.BackColor = CLR_SEL
            currQty = currQty + 1
        End If
    End If
End Sub

您所选择的按钮数量是什么意思?很抱歉造成混淆。我的意思是当UserForm1被激活时,意味着没有选择任何按钮;当我点击按钮时,我改变了按钮的颜色并接受它为选中状态。总是帮助显示你尝试了什么…似乎这就是我想要做的。是否也可以在ButtonEvent\u Click中执行,而不调用ButtonEvent.Parent.HandleClick?当然,只需将HandleClick代码移动到类的ButtonEvent\u Click方法中。UserForm1上的maxQty、selQty和ListBox1的值如何?如何将这些值传入和传出ButtonEvent_Click?这是我的问题,您可能可以在类中使用这些值,但这将是一个糟糕的设计。该类不需要知道有关userform的详细信息。蒂姆的想法是更好的办法。
Option Explicit

Const CLR_SEL As Long = vbRed         'selected color
Const CLR_NOT_SEL As Long = vbGreen   'unselected color

Dim btnCol As Collection
Dim maxQty As Long   'max number selectable
Dim currQty As Long  'number currently selected

'perform some setup
Private Sub UserForm_Activate()
    Const NUM_BUTTONS As Long = 10
    Dim i As Long, btn As MSForms.CommandButton
    Dim o As clsButtonClick

    currQty = 0  'number selected
    maxQty = 5   'max selectable
    Set btnCol = New Collection
    'add some buttons
    For i = 1 To NUM_BUTTONS
        Set btn = Me.Controls.Add("Forms.CommandButton.1", "btn" & i, True)
        btn.BackColor = CLR_NOT_SEL
        btn.Height = 18
        btn.Left = 20
        btn.Top = 20 * i
        btn.Caption = "Button " & i
        Set o = New clsButtonClick
        Set o.ButtonEvent = btn
        btnCol.Add o
    Next i
End Sub

'handle a button click event (button is passed in)
Sub HandleClick(btn As MSForms.CommandButton)
    If btn.BackColor = CLR_SEL Then
        btn.BackColor = CLR_NOT_SEL
        currQty = currQty - 1
    Else
        If currQty = maxQty Then
            MsgBox "no more selections available"
        Else
            btn.BackColor = CLR_SEL
            currQty = currQty + 1
        End If
    End If
End Sub