窗体UserForm——代码插入不定数量带事件的控件
在前面的例子里,我们使用代码插入了不定数量的选项按钮,但是为了激活工作表,还手动插入了一个命令按钮,通过遍历控件的方式,找到要激活的工作表。如果能够不需要命令按钮,只要点击选项按钮就激活工作表,那就更简洁了。
要实现点击选项按钮就激活工作表,显然需要插入的选项按钮具有某个事件,在使用代码插入控件的时候,是可以同时让控件具有事件的:
Private WithEvents ob As MSForms.OptionButton
在窗体最上面这样写语句的话,就相当于手动插入了一个名称是ob的选项按钮,这样在代码编辑器下拉框里,就能选择ob,然后选择对应的事件。
但是在UserForm_Initialize事件里添加控件,如果使用窗体的全局变量ob的话,ob只能指向最后一个控件,因为它仅仅是一个变量,不会同时指向多个控件。
而窗体的全局变量声明带WithEvents的时候又不能声明为数组控件,所以在窗体里没法插入不定数量,却又带有事件的控件。
这个时候我们就希望如果能使用代码添加事件就好了,可是VBA没有设置这样的接口。
VB.NET这样的语言是有AddHandler 这样的方法去使用代码添加事件的。
那么在VBA里还有没有办法呢?
其实这个功能的实现只要有一种对象,能够让我们添加控件,同时这个对象内部又能让我们编辑控件事件的代码。这种对象和以前说到过的类是不是很像?类就是一种对象,而且这种对象就是可以让使用者来自定义的。
是的,只要结合类,就能够完成这么一个功能,新建一个类模块,命名为COB,编辑代码:
'定义私有变量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,就能够避免设置非法的值。
在窗体中编辑代码:
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
这样就能够实现直接点击选项按钮,激活对应的工作表。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Shiro学习笔记 三(认证授权)
- Shiro学习笔记四(Shiro集成WEB)
- Shiro学习笔记五(Shiro标签,及通配符)
- Shiro学习笔记六(自定义Reaml-使用数据库设置 user roles permissions)
- Luncene学习 第一天 《入门程序》
- Luncene学习二《搜索索引》
- JavaWeb--简单分页技术
- 使用Python制作第一个爬虫程序
- 使用BeautifulSoup 爬取一个页面上的所有的超链接
- 使用PlaceHolder,测试碰见的问题
- 隐藏MySQL InnoDB Cluster / ReplicaSet实例
- MySQL8.0.21——错误日志中的组复制系统消息
- 【一】、搭建Hadoop环境----本地、伪分布式
- 在组复制中指定恢复IP地址
- START GROUP_REPLICATION可以将恢复凭据作为参数