VBA获取除CommandButton_Click()以外的按钮点击

时间:2013-12-11 13:14:03

标签: vba excel-vba excel

在VBA中进行编码,我有一个表单窗口,其中包含多个输入字段和按钮,以与每个输入字段一起使用。我想知道是否有更快的方法来编写以下

Private Sub deleteButton1_Click()
     MsgBox ("delete button")
End Sub

Private Sub deleteButton2_Click()
     MsgBox ("delete button")
End Sub

Private Sub deleteButton3_Click()
     MsgBox ("delete button")
End Sub

Private Sub deleteButton4_Click()
     MsgBox ("delete button")
End Sub

我正在寻找符合

的内容
for i = 1 to 100 
     Private Sub deleteButton+i+_Click()
         MsgBox ("delete button")
     End Sub
next i 

虽然我知道你不能在for循环中声明函数和subs。 谢谢..

1 个答案:

答案 0 :(得分:3)

虽然我同意Mehow的评论,但作为一个直接的答案,你会使用一个类来处理按钮引发的事件:

班级cBtnClick

Public WithEvents btn As msforms.CommandButton

Private Sub btn_Click()
    MsgBox "Delete Button"
End Sub

用户形式代码

Dim BtnCollection As Collection

Private Sub UserForm_Initialize()

    Dim ctl As Object
    Dim clsBtn As cBtnClick

    Set BtnCollection = New Collection

    For Each ctl In Me.Controls
        If TypeOf ctl Is msforms.CommandButton Then
            If UCase(ctl.Caption) = "DELETE" Then
                Set clsBtn = New cBtnClick
                Set clsBtn.btn = ctl
                BtnCollection.Add clsBtn
            End If
        End If
    Next ctl

End Sub

除此之外,我建议你看看代码的结构,你不应该真的需要17个删除按钮来做同样的事情,一个就足够了。如果每个按钮清除它的相应文本框,那么我会考虑动态添加控件并将文本框和按钮封装在单个类对象中。

从你的进一步评论中,看看这样的事情:

类cInputClear:

Private WithEvents p_tb As MSForms.TextBox
Private WithEvents p_btn As MSForms.CommandButton

Public Sub Add(Parent As Object, top As Long, left As Long, width As Long)
    Set p_tb = Parent.Controls.Add("Forms.Textbox.1")
    With p_tb
        .top = top
        .left = left
        .width = width
    End With

    Set p_btn = Parent.Controls.Add("Forms.CommandButton.1")
    With p_btn
        .top = top
        .left = left + width + 5 '5 for padding
        .Height = p_tb.Height
        .Caption = "Delete"
    End With

End Sub

Private Sub p_btn_Click()
    p_tb.value = ""
End Sub

Public Property Get TextBoxValue() As String
    TextBoxValue = p_tb.value
End Property

<强>用户窗体:

Private cCollection As Collection

Private Sub UserForm_initialize()

    Dim x As Long
    Dim octrl As cInputClear

    Set cCollection = New Collection
    For x = 1 To 5
        Set octrl = New cInputClear
        octrl.Add Me, 20 * x, 5, 60
        cCollection.Add octrl
    Next x

End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)

    Dim octrl As cInputClear
    For Each octrl In cCollection
        Debug.Print octrl.TextBoxValue
    Next octrl

End Sub

建议的方法,重新评论结构。我认为如果有任何帮助,我会像这样接近它 - 这假设你只想编辑描述而不是代码,但是你应该明白这个想法:

N.B - 您需要在用户表单上放置一个框架

类cData:

Public Code As String
Public Description As String

类cInputClear:

Option Explicit

Private WithEvents p_tb As MSForms.TextBox
Private WithEvents p_btn As MSForms.CommandButton
Private WithEvents p_lbl As MSForms.Label
Private p_LabelKey As String
Private p_Parent As Object

Public Sub Add(Parent As Object, ByVal LabelKey As String, ByVal TextBoxValue As String, top As Long, left As Long, width As Long)

    Set p_Parent = Parent

    Set p_lbl = Parent.Controls.Add("Forms.label.1")
    With p_lbl
        .top = top
        .left = left
        .Caption = LabelKey
    End With

    Set p_tb = Parent.Controls.Add("Forms.Textbox.1")
    With p_tb
        .top = top
        .left = left + p_lbl.width + 5
        .width = width
        .Value = TextBoxValue
    End With

    Set p_btn = Parent.Controls.Add("Forms.CommandButton.1")
    With p_btn
        .top = top
        .left = left + width + p_lbl.width + 5 '5 for padding
        .Height = p_tb.Height
        .Caption = "Delete"
    End With

    p_LabelKey = LabelKey

End Sub

Private Sub p_btn_Click()
    p_Parent.Parent.Delete Me.LabelKey
End Sub

Public Property Get TextBoxValue() As String
    TextBoxValue = p_tb.Value
End Property

Public Property Get LabelKey() As String
    LabelKey = p_LabelKey
End Property

Private Sub p_tb_Change()
    p_Parent.Parent.Update Me.LabelKey, Me.TextBoxValue
End Sub

UserForm代码:

Option Explicit

Private cCollection As Collection
Private MyCollection As Collection
Private EnableEvents As Boolean

Private Sub Frame1_Click()

End Sub

Private Sub UserForm_initialize()

    Dim x As Long
    Dim myData As cData


    '//////// Just build dummy data for an example
    Set MyCollection = New Collection

    For x = 1 To 5
        Set myData = New cData
        myData.Code = "ABC123" & x
        myData.Description = "Description Of Data"
        MyCollection.Add myData, myData.Code
    Next x

    '///////////////////////////////////////////////


    BindData

End Sub

Private Sub BindData()

    Dim x As Long
    Dim InvoiceItem As cData
    Dim oCtrl As cInputClear

    EnableEvents = False
    Set cCollection = New Collection

    x = 1
    For Each InvoiceItem In MyCollection
        Set oCtrl = New cInputClear

        oCtrl.Add Me.Frame1, _
                    InvoiceItem.Code, _
                    InvoiceItem.Description, _
                    top:=20 * x, _
                    left:=5, _
                    width:=150

        cCollection.Add oCtrl, oCtrl.LabelKey
        x = x + 1
    Next InvoiceItem

    EnableEvents = True

    Me.Frame1.ScrollBars = fmScrollBarsVertical
    Me.Frame1.ScrollHeight = x * 20


End Sub

Public Sub Update(Key As String, ByVal Value As String)
    If EnableEvents Then
        'Update the datasource
       MyCollection(Key).Description = Value
    End If
End Sub

Public Sub Delete(Key As String)

    MyCollection.Remove (Key) 'Update our datasource
    '// Remove all controls from the frame
    Me.Frame1.Controls.Clear
    BindData
End Sub