窗体UserForm——代码插入不定数量带事件的控件

2020-07-28 11:32:48 浏览数 (1)

在前面的例子里,我们使用代码插入了不定数量的选项按钮,但是为了激活工作表,还手动插入了一个命令按钮,通过遍历控件的方式,找到要激活的工作表。如果能够不需要命令按钮,只要点击选项按钮就激活工作表,那就更简洁了。

要实现点击选项按钮就激活工作表,显然需要插入的选项按钮具有某个事件,在使用代码插入控件的时候,是可以同时让控件具有事件的:

代码语言:javascript复制
Private WithEvents ob As MSForms.OptionButton

在窗体最上面这样写语句的话,就相当于手动插入了一个名称是ob的选项按钮,这样在代码编辑器下拉框里,就能选择ob,然后选择对应的事件。

但是在UserForm_Initialize事件里添加控件,如果使用窗体的全局变量ob的话,ob只能指向最后一个控件,因为它仅仅是一个变量,不会同时指向多个控件。

而窗体的全局变量声明带WithEvents的时候又不能声明为数组控件,所以在窗体里没法插入不定数量,却又带有事件的控件。

这个时候我们就希望如果能使用代码添加事件就好了,可是VBA没有设置这样的接口。

VB.NET这样的语言是有AddHandler 这样的方法去使用代码添加事件的。

那么在VBA里还有没有办法呢?

其实这个功能的实现只要有一种对象,能够让我们添加控件,同时这个对象内部又能让我们编辑控件事件的代码。这种对象和以前说到过的类是不是很像?类就是一种对象,而且这种对象就是可以让使用者来自定义的。

是的,只要结合类,就能够完成这么一个功能,新建一个类模块,命名为COB,编辑代码:

代码语言:javascript复制
'定义私有变量OptionButton
Private WithEvents ob As MSForms.OptionButton

'设置属性OptionButton
Property Set OptionButton(v As MSForms.OptionButton)
    Set ob = v
End Property

'OptionButton的Change事件
Private Sub ob_Change()
    If ob.Value Then
        Worksheets(ob.Caption).Activate
    End If
End Sub

这样,这个类就具有了MSForms.OptionButton的属性,而且内部也实现了Change事件,只要控件的Value改变了,就会运行代码。

说明(重要):

这里使用了Private来声明私有变量,故意不使用Public的目的是:

如果使用Public,是可以省略Property属性的,看起来是更方便了。但是作为写程序,一定要非常的严谨,因为这个属性在这里只需要设置,而不希望让外部读取,如果使用Public,外部是可以设置、也可以读取。

Public这种处理方式可能会造成一些问题,比如:设计了一个类,有一个属性Num,这个属性设计类的时候是希望它不能被设置小于10的数字,如果使用Public声明变量的形式,那么这个属性将被外部不可控制的设置任意值

而如果使用Property属性的方法,在Property Let里,就可以去检测传递的参数是否符合要求,不符合要求的情况下就提前退出Property,就能够避免设置非法的值。

在窗体中编辑代码:

代码语言:javascript复制
Option Explicit
'声明COB数组,记录COB对象
Private cobs() As COB

Private Sub UserForm_Initialize()
    '定义MSForms.OptionButton变量
    Dim ob As MSForms.OptionButton
    Dim i As Long
    Dim itop As Integer

    itop = 10

    ReDim cobs(Worksheets.Count - 1) As COB
    For i = 1 To Worksheets.Count
        '添加选项按钮
        Set ob = Me.Controls.Add("Forms.OptionButton.1")
        '以工作表名称设置选项按钮内容
        ob.Caption = Worksheets(i).Name
        '设置选项按钮的位置
        ob.Left = 5
        ob.Top = itop
        '记录下一个选项按钮应该出现的位置
        itop = itop   ob.Height   10

        '实例化COB
        Set cobs(i - 1) = New COB
        '设置COB的OptionButton属性
        Set cobs(i - 1).OptionButton = ob
    Next

    '设置窗体的高度,防止工作表太多看不到
    Me.Height = itop   20
End Sub

这样就能够实现直接点击选项按钮,激活对应的工作表。

0 人点赞