一:简介

VBA可以通过窗体和用户进行数据交互,然后控制Excel总的内容(如新增、删除、修改、查询)。

表单控件也称为窗体控件 Form Controls

Workbook以及不同组件都有很多事件。

  • 标签:它用于表现静态文本。
  • 分组框:它用于将其他控件进行组合。
  • 按钮:用于执行宏命令。
  • 复选框:它是一个选择控件,通过单击可以选择和取消选择,可以多项选择。
  • 选项按钮:通常几个选项按钮组合在一起使用,在一组中只能选择一个选项按钮。
  • 列表框:用于显示多个选项并从中选择。只能单选。
  • 组合框:用于显示多个选项并从中选择。可以选择其中的项目或者输入一个其它值。
  • 滚动条:不是你常见的来给很长的窗体添加滚动能力的控件,而是一种选择机制。例如:调节过渡色的滚动条控件。包括水平滚动条和垂直滚动条。
    微调控件:也是一种数值选择机制,通过单击控件的箭头来选择数值。例如改变 Windows 日期或时间就会使用到微调控件。

VBA 表单控件UserForm_Text


VBA 表单控件UserForm_vba_02


有时候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