在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。 谢谢..
答案 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