一:简介
VBA可以通过窗体和用户进行数据交互,然后控制Excel总的内容(如新增、删除、修改、查询)。
表单控件也称为窗体控件 Form Controls
Workbook以及不同组件都有很多事件。
- 标签:它用于表现静态文本。
- 分组框:它用于将其他控件进行组合。
- 按钮:用于执行宏命令。
- 复选框:它是一个选择控件,通过单击可以选择和取消选择,可以多项选择。
- 选项按钮:通常几个选项按钮组合在一起使用,在一组中只能选择一个选项按钮。
- 列表框:用于显示多个选项并从中选择。只能单选。
- 组合框:用于显示多个选项并从中选择。可以选择其中的项目或者输入一个其它值。
- 滚动条:不是你常见的来给很长的窗体添加滚动能力的控件,而是一种选择机制。例如:调节过渡色的滚动条控件。包括水平滚动条和垂直滚动条。
微调控件:也是一种数值选择机制,通过单击控件的箭头来选择数值。例如改变 Windows 日期或时间就会使用到微调控件。
有时候excel文件一打开就会只显示窗体控件,不会显示Excel内容,此时输入和查询只能通过提供的窗体来操作。
用户窗体 UserForm
Private Sub UserForm_QueryClose(Cancel As Interger, CloseMode As Interger)
If MsgBox("是否关闭工作簿", vbYesNo) = vbYes Then
ThisWorkbook.Close
End If
End Sub
标签 Label
支持鼠标移入、移除、点击等事件,可以用于修改一些属性。
Private Sub Label1_Click()
' 点击跳转网页
ActiveWorkbook.FollowHyperlink "https://www.baidu.com"
End Sub
单选框 OptionButton
' 返回是否选中
OptionButton1.Value
OptionButton1.Caption
OptionButton1.Enable
' 清空
OptionButton1.Value = False
框架 Frame
框架内部的控件和框架外互不影响。
当有多个单标签时通过框架保证互相不影响,其实就是对单选按钮分组
' 获取框架里面的所有控件
For Each ss in Frame1.Controls
If ss.Value Then
zt.Offset(1, 2) = ss.Caption
End If
Next ss
复选框 CheckBox
CheckBox1.Value
For i = 1 To 4
If Controls("checkbox" & i).Value Then
t = t & "/" & Controls("checkbox" & i).Caption
End If
Next i
zt.Offset(1,3) = Mid(t, 2)
复合框(下拉列表)ComboBox
Private Sub UserForm_Initialize()
ComboBox1.List = arr
End Sub
Private Sub ComboBox1_Change()
Dim xy As Range
'Set result = Sheets("Sheet2").Columns(2).Find("xx",,,1)
Set xy = Sheet2.Range("a:a").Find(ComboBox1.Text,,,1)
If xy Is Nothing Then
MsgBox "未查到"
Else
xy.Row
End If
ComboBox2.AddItem "xxx"
' 直接接收是个二维数组,需要转置一下变成一维数组?
arr = Sheet2.Range(xy.Offset(0, 1), xy.Offset(0, 3333).End(xlToLeft))
arr = WorksheetFunction.Transpose(arr)
ComboBox2.List = arr
End Sub
' 清空控件内容
For Each control In UserForm1.Controls
If Mid(control.Name, 1, 4) = "TEXT" Then
kj.Text = ""
Else If Mid(control.Name, 1, 4) = "Comb" Then
kj.Text = ""
Else If Mid(control.Name, 1, 4) = "Opti" Then
kj.Value = False
Else If Mid(control.Name, 1, 4) = "Chec" Then
kj.Value = False
End If
Next kj
切换按钮 ToggleButton
ToggleButton1.Value
ToggleButton1.Caption
列表框 ListBox
可以显式单列,或者多行多列表格
ListBox1.AddItem "xxx"
arr = Range("a1").CurrentRegion
arr= WorksheetFunction.Transpose(arr)
列 = UBound(arr, 2)
' 设置列的宽度
For i = 1 To 列
w = w & "," & 50
Next i
w = Mid(w, 2, Len(w))
ListBox1.ColumnWiths = w
ListBox1.ColumnCount = 列
ListBox1.List = arr
图片 Image
Image1.Picture = LoadPicture("xx/yyy.png")
基础示例
' 关闭提示
Application.DisplayAlerts = True
Private Sub Workbook_Open()
' 关闭Excel页面主窗体,先显示UserForm1
Application.Visible = False
UserForm1.Show 0
' 定时器
Application.OnTime Now + TimeValue("00:00:03"), "close"
End Sub
' 初始化加载事件
Private Sub UserForm1_Initialize()
Caption = "xxx"
ComBox1.AddItem "a1"
ComBox1.AddItem "a2"
End Sub
Sub close()
Unload UserForm1
' Unload Me
Application.Visible = True
End Sub
反禁用宏示例
我们的Sheet可能有很多机密,想要查看需要弹框先输入用户名密码才可,而窗体程序需要Excel开启宏设置,如果用户关闭掉宏设置就绕过校验可以直接看到机密的内容。
解决方法:禁用时隐藏对应的Sheet并且不能取消隐藏(Sheet不能隐藏所有一个不剩,所以要预留一个空白工作簿),并且不能查看VBA源码(工具 - VBAProject属性 - 保护 - 设置密码即可)
' 全局变量写在Module中 通用 声明 中, 声明的全局变量可以在不同的UserForm中共享访问
Public value
ThisWorkbook
ThisWorkbook.Protect Password:="123456" ' 工作簿保护
ThisWorkbook.Unprotect Password:="123456" ' 取消工作簿保护
' 一般程序开始时关闭,程序运行后要重新打卡
' 关闭刷新(用于提高效率,开发时不要关闭可用于调试)
Application.ScreenUpdating = False
' 关闭中间弹出提示中断程序
Application.DisplayAlers = False
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim ws As Worksheet
Sheets("空白").Visible = xlSheetVisible
' 让其它Sheet隐藏,除了"空白"
For Each ws In Worksheets
If ws.Name <> "" Then
ws.Visible = xlSheetVeryHidden
End If
Next ws
ThisWorkbook.Save
End Sub
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In Worksheets
If ws.Name <> "" Then
ws.Visible = xlSheetVisible ' 可见
End If
Next ws
Sheets("空白").Visible = xlSheetVeryHidden ' 隐藏且无法取消隐藏
Application.EnableCancelKey = xlDisable ' 禁用Ctrl+Break
Application.Visible = False
UserForm1.Show
End Sub
Private Sub ExitBtn_Click()
' 关闭当前窗体
Unload Me
ThisWorkbook.Save
ThisWorkbook.Close
' 退出应用程序
Application.Quit
End Sub
注册示例
Sheet本身就是一张表,可以将注册的用户信息单独存放到一个Sheet中,并且将该Sheet隐藏起来。
Private Sub Label3_Clikc()
UserForm2.Show
End Sub
Private Sub CommandButton1_Click()
Dim zh As Range, zt As Range
If TextBox1 = "" Then MsgBox "未填入账号" : Exit Sub
If TextBox2 <> TextBox3 Then MsgBox "密码不一致" : Exit Sub
Set zh = Sheets("注册").Range("a:a").Find(TextBox1.Text,,,1)
If zh is Nothing Then
Set zt = Sheets("注册").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
zt = TextBox1.Text
zt.Offset(0, 1) = TextBox2.Text
zt.Offset(0, 2) = Now
MsgBox "注册成功"
Unload Me
Else
MsgBox "账号已经存请更换"
End If
End Sub
登录示例
Private Sub CommandButton2_Click()
' 清空
TextBox1.Text = ""
Dim zh As Range
If Len(TextBox1) = 0 Then MsgBox "请输入账号" : Exit Sub
Set zh = Sheets("注册").Range("a:a").Find(TextBox1.Text,,,1)
If Not zh Is Nothing Then
If TextBox2.Text <> zh.Offset(0, 1) Then
MsgBox "密码错误"
End If
Else
MsgBox "账号不存在"
End If
End Sub
' 监控键盘输入
Public Sub TextBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByValue)
If KeyCode = vbKeyHome Then
CommandButton2_Click
End If
End Sub