Excel实战技巧69: 运用类来简化验证用户输入的代码
- 2019 年 12 月 23 日
- 筆記
如下图1所示,在用户窗体中有10个文本框,只有当这些文本框都有输入时,“下一步”按钮才显示。

图1
这10个文本框的名称分别为TextBox1、TextBox2、TextBox3、…、TextBox10,“下一步”按钮的名称为btn_Next。
通常,可以使用下面的代码来实现图1所示的效果:
Private Sub TextBox1_Change()
Dim i As Integer
For i = 1 To 10
If Trim(Me("TextBox" & i).Text) = "" Then Exit For
Next
Me("btn_Next").Visible = i = 11
End Sub
Private Sub TextBox2_Change()
Dim i As Integer
For i = 1 To 10
If Trim(Me("TextBox"& i).Text) = "" Then Exit For
Next
Me("btn_Next").Visible = i = 11
End Sub
Private Sub TextBox3_Change()
Dim i As Integer
For i = 1 To 10
If Trim(Me("TextBox" & i).Text) = "" Then Exit For
Next
Me("btn_Next").Visible = i = 11
End Sub
‘下面是其它文本框的代码
‘除文本模式名称外,代码相同
…
由于每个文本框Change事件的代码相同,因此上述代码可以简化为:
Private Sub TextBox1_Change()
btn_Next_visible
End Sub
Private Sub TextBox2_Change()
btn_Next_visible
End Sub
Private Sub TextBox3_Change()
btn_Next_visible
End Sub
‘下面是其它文本框的代码
‘除文本模式名称外,代码相同
…
Private Sub btn_Next_visible()
Dim i As Integer
For i = 1 To 10
If Trim(Me("TextBox" & i).Text) = "" Then Exit For
Next
Me("btn_Next").Visible = i = 11
End Sub
但是,仍然要使用每个文本框的Change事件,代码冗长。
下面,我们使用类模块来简化代码。
在VBE中,插入一个类模块,并将其命名为“NextVisible”,输入下面的代码:
Public WithEvents cls_textbox As MSForms.TextBox
Private Sub cls_textbox_Change()
Dim i As Integer
For i = 1 To 10
If cls_textbox.Parent("TextBox" & i).Text = "" Then ExitFor
Next
cls_textbox.Parent("btn_Next").Visible = i = 11
End Sub
这个类模块中的Change事件代替了用户窗体中所有文本框的Change事件过程。
使用集合
接着,应该由类模块控制的用户窗体中的控件必须与该类模块建立连接,并且应该在UserForm_Initialize事件中创建连接。可以使用集合来存储这些连接。在用户窗体代码模块中,输入下面的代码:
Public ctl_col As New Collection
Private Sub UserForm_Initialize()
Dim ctl As Control
For Each ctl In Controls
ctl_col.Add NewNextVisible, ctl.Name
If TypeName(ctl) ="TextBox" Then Set ctl_col(ctl.Name).cls_textbox = ctl
Next ctl
End Sub
通过添加类模块的新实例到集合中,将用户窗体中的每个控件连接到该类模块,使用控件的名字作为集合元素的键值。
ctl_col.Add New NextVisible, ctl.Name
在类模块中,文本框的事件变量为cls_textbox,因此需要使用Set语句将用户窗体中的文本框连接到对象变量cls_textbox。
Set ctl_col(ctl.Name).cls_textbox = ctl
如果用户对用户窗体中的任何文本框作了修改,则在集合中的连接将触发类模块中相应的Change事件过程。
使用数组
也可以使用数组来实现。
在用户窗体代码模块中,输入下面的代码:
Public str
Private Sub UserForm_Initialize()
Dim i As Integer
ReDim str(Controls.Count)
For i = 0 To Controls.Count – 1
Set str(i) = New NextVisible
If TypeName(Controls(i)) = "TextBox" Then
Set str(i).cls_textbox = Controls(i)
End If
Next
End Sub
通过添加类模块的新实例到数组中,将用户窗体中的每个控件连接到该类模块。由于类模块是对象,因此需要使用Set语句添加该类模块的新实例到数组中:
Set str(i) = New NextVisible
检查用户窗体中控件的类型,以确保与类模块中相应的WithEvents变量连接。通过数组中的链接将控件连接到类模块中的相应WithEvents变量。在类模块中的事件变量是cls_textbox。由于cls_textbox是一个对象变量,需要使用Set语句将用户窗体中的文本框连接到类模块对象变量cls_textbox:
Set str(i).cls_textbox = Controls(i)
如果用户对用户窗体中的任何文本框作了修改,则在数组中的连接将触发类模块中相应的Change事件过程。