Ash*_*hok 7 excel vba excel-2007 excel-vba userform
我有一个包含大量文本框的用户表单.当这些文本框的值发生变化时,我需要通过调用子程序AutoCalc()来重新计算基于文本框值的最终结果值.
我有大约25个盒子,我不想单独向调用所述子例程的每个文本框添加一个Change()事件.每当某些值发生变化时,调用AutoCalc()的最快捷有效的方法是什么?
Ale*_*x P 14
这可以通过使用类模块来实现.在下面的示例中,我将假设您已经拥有一个带有一些文本框的用户窗体.
首先,在VBA项目中创建一个类模块(让我们调用它clsTextBox
- 确保更改类模块的'Name'属性!)
Private WithEvents MyTextBox As MSForms.TextBox
Public Property Set Control(tb As MSForms.TextBox)
Set MyTextBox = tb
End Property
Private Sub MyTextBox_Change()
AutoCalc() //call your AutoCalc sub / function whenever textbox changes
End Sub
Run Code Online (Sandbox Code Playgroud)
现在,在userform中,添加以下代码:
Dim tbCollection As Collection
Private Sub UserForm_Initialize()
Dim ctrl As MSForms.Control
Dim obj As clsTextBox
Set tbCollection = New Collection
For Each ctrl In Me.Controls
If TypeOf ctrl Is MSForms.TextBox Then
Set obj = New clsTextBox
Set obj.Control = ctrl
tbCollection.Add obj
End If
Next ctrl
Set obj = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
如上面的答案所示,课堂使用是一种以简洁优雅的方式处理许多控件的好策略,但是:
1)我发现使用1行创建25个事件没有问题,调用一个常见的userform私有例程,除非控件的数量是动态的.这是一个KISS哲学.
2)一般来说,我认为Change事件非常令人不安,因为他完成了每个数字输入的所有重新计算.使用Exit事件或Before Update事件更加明智和适度,因为它仅在决定值时才进行重新计算.例如,谷歌即时骚扰我试图返回响应,消耗资源,而无需用户定义问题.
3)存在验证问题.我同意您可以通过Change事件避免错误的键,但是如果您需要验证数据,则无法知道用户是否将继续键入或者数据是否已准备好进行验证.
4)您应该记住,更改或退出事件不会强制用户传入文本字段,因此在尝试退出表单而不取消时需要重新验证并重新计算系统.
以下代码对于静态表单很简单但有效.
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call AutoCalc(Cancel)
End Sub
Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call AutoCalc(Cancel)
End Sub
.....
Private Sub TextBox25_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call AutoCalc(Cancel)
End Sub
Private Function Valid
.....
End Function
Private Sub AutoCalc(Canc As Variant)
If Not Valid() Then Canc=True
' Calculation
End Sub
Run Code Online (Sandbox Code Playgroud)
您沉迷于节省时间,您可以创建一个通用的VBA例程,以便以适合掩码的形式生成与控件相关的事件的代码.此代码可以在草稿表中(更安全,直接生成代码,在某些Excel版本中有错误),而不是复制并粘贴到表单模块.
Sub GenerateEvent(Form As String, Mask As String, _
Evento As String, Code As String)
' Form - Form name in active workbook
' Mark - String piece inside control name
' Evento - Event name to form procedure name
' Code - Code line inside event
Dim F As Object
Dim I As Integer
Dim L As Long
Dim R As Range
Dim Off As Long
Set F = ThisWorkbook.VBProject.VBComponents(Form)
Set R = ActiveCell ' Destination code
Off = 0
For I = 0 To F.Designer.Controls.Count - 1
If F.Designer.Controls(I).Name Like "*" & Mask & "*" Then
R.Offset(Off, 0) = "Private Sub " & _
F.Designer.Controls(I).Name & "_" & Evento & "()"
R.Offset(Off + 1, 0) = " " & Code
R.Offset(Off + 2, 0) = "End Sub"
Off = Off + 4
End If
Next I
End Sub
Sub Test()
Call GenerateEvent("FServCons", "tDt", "Exit", _
"Call AtuaCalc(Cancel)")
End Sub
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
53116 次 |
最近记录: |