VBA
- Excel的宏与VBA
- 宏的录制
- 宏的启动运行
- 快捷键运行宏:
- 使用Excel对象运行宏*
- VBA的数据类型
- 字符串(String)
- 整形(Integer)和长整形(Long)
- 单精度浮点型(Single)和双精度浮点型(Double)
- 货币型(Currency)
- 日期型(Date)
- 变体型(Variant)
- 布尔型(Boolean)
- 字节型(Byte)
- 对象型(Object)
- 枚举类型
- 自定义数据类型
- 变量
- 变量的隐式声明
- 变量的作用域
- 变量的生存周期
- 常量
- 直接常量
- 数值常量
- 字符常量
- 日期/时间常量
- 布尔常量
- 符号常量
- 系统常量***
- VBA的运算符
- 计算运算符
- 比较运算符
- 逻辑运算符
- 连接运算符:合并字符串
- 数组
- 声明数组
- 一维静态数组
- 二维静态数组
- 动态数组
- 注释语句
- 代码语句的续行符和拼接符
- VBA的交互对话框**
- InputBox函数
- MsgBox函数
- Print 方法
- 程序流的条件执行与中断
- Stop语句
- End语句
- 分支语句
- 循环结构
- For循环
- While循环
- 处理程序的错误
- GoTo语句
- On Error GoTo 语句用于捕获错误
- 错误处理程序的例子
- Resume语句
- 备注:鉴于VBA语言在语法语句上十分近似SQL语言。为了尽快地掌握这门面对对象编程的语言,这张笔记会少举例子,多写区别和对比,以便有编程基础的程序员们尽快掌握这门语言
Excel的宏与VBA
– 宏是一系列存储于Visual Basic模块中的命令与函数,它们记录了用户的一段操作,能够在需要时执行以重现用户的操作过程。宏相当于一段记录用户操作的录像,在任何需要的时候可以重现。因此,使用宏是避免大量重复操作,实现操作自动化的好方法。
– Excel具有录制宏的能力,录制完成的宏,将作为VBA程序代码,存储在模块的“代码”窗口(如下图所示)中
– VBA是针对Office软件的一种程序语言,其能够帮助用户从繁杂的重复工作中解脱出来。录制宏可以直接借助于界面操作完成大部分的代码编写,程序员只需要对宏代码进行修改和优化即可获得最终需要的代码。
宏的录制
1.点击上图中的录制宏按钮
2.对Excel表格中的某对象依次进行若干操作
3.点击下图中的停止录制按钮
- 注意事项:
-
- 每次录制宏时,使用的是绝对引用,宏中被操作的单元格始终是录制时所选择的单元格
-
- 每次录制宏时,都有可能产生一些冗余代码,降低宏的运行效率
-
- 录制宏不支持条件判断,也没有分支结构
宏的启动运行
快捷键运行宏:
- 在VBA编辑器中,代码不能更改宏的快捷键,要在Excel的对话框中可以实现,如下图所示
使用Excel对象运行宏*
-
可以使用图片、图形或文本框等对象来作为宏的开关
-
举例:在文本框(或其他对象)上右击,选择关联菜单中的“指定宏”命令,此时将打开“指定宏”对话框,在对话框中选择列表中的宏,点击“确定”,即可完成关联。
VBA的数据类型
字符串(String)
- 在Excel中,字符串用双引号所框
"这是一组使用双引号括起来的字符串"
这是空字符串:
""
整形(Integer)和长整形(Long)
- 整形:占据2字节,可以表示-32768~32767之间的数
- 长整型:占据4字节,可以表示-2147483648~2147483647
单精度浮点型(Single)和双精度浮点型(Double)
- 单精度浮点型:占据4个字节
- 双精度浮点型:占据8个字节
货币型(Currency)
- 占据8个字节的整形数值型
实际操作过程中, 由于某些企业对于货币计量的精度要求极高,存储金额所使用的数据类型可能依然是字符串型
日期型(Date)
- 占据8个字节的浮点数值形式
- 日期型数据在使用时必须使用#号所括起来
# January 1, 2023#
变体型(Variant)
- 变体型数据是一种特殊的数据类型,是一种可变的数据类型,可以存放任何类型的数据
布尔型(Boolean)
- 只有两个:TRUE和FALSE
- 当其他数据类型转化为布尔型时,0将传化为False,其他为True
- 当布尔型转化为其他数据类型时,False转化为0 ,True转化为-1
字节型(Byte)
- 占用1个字节,表示0~255之间的整数
对象型(Object)
- 占用4个字节,用来表示应用程序中的对象。在程序中,使用Set语句来将声明为对象型的变量赋值为任何对象的引用
枚举类型
枚举类型是VBA中的一种特殊数据类型,当一个变量只有几种可能的值时,可以将其定为枚举类型。枚举类型的数据时将变量的所有可能值一一列举出来,属于该枚举类型的变量只能取枚举中的某一个值。
- 枚举类型定义的代码示例:
Public Enum Week
星期日
星期一
星期二
星期三
星期四
星期五
星期六
End Enum
自定义数据类型
- 自定义数据类型实际上包含了一个或多个数据元素,换句话说,它就是一个多种数据类型的集合。
自定义数据的语法格式:
Type 数据类型名
数据类型元素名 As 数据类型
数据类型元素名 As 数据类型
数据类型元素名 As 数据类型
...
End Type
Type myType
myName As String
myID As Number
myBir As Date
End Type
' 在这串代码中,定义了名为myType的自定义数据类型,
' 该数据类型包含了3个数据元素,这三个数据类型的元素分别是String,Number 和Date
Number 是个什么样子的数据类型?刚才也没提到啊
变量
- 由于VBA是基于C语言所写的高级语言,所以VBA给变量等标识符起名字的规则与其他面对对象编程的语言相差无几。
Dim 变量名 [As 数据类型]
- 举例:声明多个变量
Dim IntA As Integer, stringB As string ,
变量的隐式声明
- 强制声明: 避免隐式声明
用一句前提命令Option Explicit
Option Explicit
...' 剩余代码
变量的作用域
- 过程级变量:又叫私有变量,声明变量的Dim语句放在Sub过程之内
- 模块级变量:声明变量的Dim语句放在Sub过程之外
- 工程级变量:又叫全局变量,声明需要关键字Public,如下代码所示:
Option Explicit
Public myString As String
变量的生存周期
-
动态变量:假设某变量是动态变量,当程序进入该变量所在的sub过程时,该变量就会被初始化并载入内存;当退出该过程时,该变量占用的内存会被释放,其值也会消失。
-
静态变量:假设某变量是静态变量,在程序进入该变量所在的sub过程时,该变量会和动态变量一样被初始化,当退出该过程时,该变量占用的内存不会被释放,其值会依然留存在内存中,当再次进入该过程时,变量值可以被重复利用。
-
无论动态变量还是静态变量,其生存期都会在Excel工作簿关闭后结束
' 静态变量的声明:
Static myString As String
常量
直接常量
数值常量
Square = 3.14
字符常量
字符常量需要使用双引号"作为定界符,在字符串中有双引号时,需要用到转义字符:双引号"的转义字符是一个双引号"自己
"我说:""VBA实际上真的很简单!"""
在这里,最后用了三个引号,其中前两个引号将输出一个引号“"”,最后一个引号是这个字符串的右定界符
日期/时间常量
这也是在VBA中很常见的一类常量:用来表示某一天或者某一个时间。与字符常量不同,其需要使用“#”作为定界符
布尔常量
符号常量
- 对于需要在程序中反复使用的常量,可以为其命名,用一个标识符表示它。符号常量的定义方式如下:
[Public|Private] Const 常量名 [As 数据类型] = 常数表达式
其中,Public声明的是公有常量,Private声明的是私有常量
系统常量***
-
Excel VBA 系统常量是系统内部提供的一系列具有各种不同用途的符号常数。如色彩常数中的vbRed表示红色,显然比用数值0xFF0000要更直观的多
-
在VBA中,系统常数名常采用大小写混合的格式,其前缀表示定义常数的对象库名,在Excel中,系统常量名通常采用大小写混合的格式,其前缀表示定义常数的对象库名。
-
在Excel中,系统常量名通常是由小写的xl作为前缀。如设置工作簿显示状态属性的常量xlSheetVisible。VBA系统内部的符号常量通常是由小写vb作为前缀,如定义颜色的常量vbBlack和定义日期的常量vbSaturday等。
Excel VBA 系统常量的查阅:
Visual Basic 编辑器=> 对象浏览器=> 视图=> 搜索需要的系统常量
- 如下图所示:
VBA的运算符
计算运算符
- 斜杠/表示除法
- 反斜杠\表示整数除法
比较运算符
- "like"关键字是模式匹配的比较运算符,如下面表达式的运算结果为True
"EFGHIJK" like "*GH*"
其中,* 是通配符,在Excel中,* 表示一个或几个任意字符
逻辑运算符
- 与
- 或
- 非
- 异或:A Xor B
- 同或(等价): A Eqv B
- 蕴含: A Imp B
蕴含是指表达式A为True,表达式B为False时才会返回False,否则其他情况都返回True
** A Imp B 和 B Imp A是不同结果的两种表达式
连接运算符:合并字符串
“&”运算符用来强制将两个表达式作为字符串连接起来,如:
"I love" & "VBA"
数组
声明数组
一维静态数组
- 数组的声明,与变量相同,同样使用Dim、Static、Private或Public语句来实现。
Dim 数组名(上界) As 数据类型
Dim myStrings(15) As String
这里,声明了一个名为myStrings的一维数组,数组中的元素从myStrings(0)开始,一直到myStrings(15),一共包含16个元素
Dim 数组名(下界 to 上界) As 数据类型
Dim myArray(-2 to 8) As String
这里,声明了一个名为myArray的一维数组,数组中的元素从myArray(-2)开始,一直到myStrings(8),一共包含11个元素
二维静态数组
Dim 数组名(第一维上界,第二维上界) As 数据类型
Dim 数组名(第一维下界 to 第一维上界,第二维下界 to 第二维上界) As 数据类型
动态数组
主要分为两步:
1.使用Dim、Static、Private或Public语句来声明一个数组,此时括号内不写上下限,如:
Dim myArray() As Integer
2.在创建数组之后,使用ReDim语句再次对数组进行声明,为数组重新分配内存空间:
ReDim [Preserve] myArray(UBound(myArray)+10)
注意:这里UBound函数用来获取函数的最大下标,如果需要获取最小下标,使用LBound函数
注释语句
VBA提供了两种为代码添加单行注释的方法,如下例所示:
Rem 后面这些文字都是注释
' 后面这些文字都是注释
代码语句的续行符和拼接符
- 续行符 : “ _”(一个空格一个下划线)
- 分隔同行的两个不同语句的分隔符: “:”(一个冒号)
VBA的交互对话框**
InputBox函数
- InputBox函数本质上是一个赋值语句,语法如下:
返回值 = InputBox(Prompt[,Title] [,Default] [,Xpos,Ypos] [,Helpfile,Context])
Prompt : 该参数用于设置对话框中显示的提示信息,最大长度为1024个字符。如果需要在对话框内显示多行字符,可以在文字之间只用回车符 vbCrLf来换行
Title : 该参数用于设置对话框标题栏中显示的字符,其值为字符串型数据。
Default : 默认值
Xpos和Ypos : 这两个参数分别用于设置对话框在屏幕上的位置。
Helpfile: 该参数用于设置对话框的帮助文件
Context: 该参数用于设置对话框的帮助主题编号
MsgBox函数
MsgBox函数有两种使用方法:
1.不返回值的函数调用:只显示某些提示信息。例如:
MsgBox Prompt [,Buttons] [,Title] [,Helpfile,Context]
2.获取返回值的函数,需要将用户点击了哪个按钮告知程序,则可以使用下面的语法格式:
返回值 = MsgBox(Prompt [,Button] [,Title] [,Helpfile] [,Context])
其中,Buttons参数决定了按钮的样式,由VBA常数来设置,这些常数的意义如下表所示
常数 | 值 | 描述 |
---|---|---|
vbOKOnly | 0 | 显示 OK 按钮。 |
vbOKCancel | 1 | 显示 OK 及 Cancel 按钮。 |
vbAbortRetryIgnore | 2 | 显示 Abort、Retry 及 Ignore 按钮。 |
vbYesNoCancel | 3 | 显示 Yes、No 及 Cancel 按钮。 |
vbYesNo | 4 | 显示 Yes 及 No 按钮。 |
vbRetryCancel | 5 | 显示 Retry 及 Cancel 按钮。 |
vbCritical | 16 | 显示 Critical Message 图标。 |
vbQuestion | 32 | 显示 Warning Query 图标。 |
vbExclamation | 48 | 显示 Warning Message 图标。 |
vbInformation | 64 | 显示 Information Message 图标。 |
vbDefaultButton1 | 0 | 第一个按钮是缺省值。 |
vbDefaultButton2 | 256 | 第二个按钮是缺省值。 |
vbDefaultButton3 | 512 | 第三个按钮是缺省值。 |
vbDefaultButton4 | 768 | 第四个按钮是缺省值。 |
vbApplicationModal | 0 | 应用程序强制返回;应用程序一直被挂起,直到用户对消息框作出响应才继续工作。 |
vbSystemModal | 4096 | 系统强制返回;全部应用程序都被挂起,直到用户对消息框作出响应才继续工作。 |
vbMsgBoxHelpButton | 16384 | 将Help按钮添加到消息框 |
vbMsgBoxSetForeground | 65536 | 指定消息框窗口作为前景窗口 |
vbMsgBoxRight | 524288 | 文本为右对齐 |
vbMsgBoxRtlReading | 1048576 | 指定文本应为在希伯来和阿拉伯语系统中的从右到左显示 |
- VBA 返回值参数查阅表:
常数 | 值 | 描述 |
---|---|---|
vbOK | 1 | OK |
vbCancel | 2 | Cancel |
vbAbort | 3 | Abort |
vbRetry | 4 | Retry |
vbIgnore | 5 | Ignore |
vbYes | 6 | Yes |
vbNo | 7 | No |
- MsgBox函数应用实例:
MsgBox "这是一个信息提示框",vbYesNoCancel + vbMsgBoxHelpButton + vbExclamation + vbDefaultButton2
Print 方法
Debug.Print 显示内容
会在Visual Basic编译器的“立即窗口”中直接显示其内容
程序流的条件执行与中断
Stop语句
- 在程序中使用Stop语句可以使程序在该语句处暂停运行,该语句的作用相当于在该处设置断点。当程序运行到该语句处时,程序将被暂时挂起停止执行,但此时不会造成文件的关闭或变量清楚等情况的发生。暂停的程序可以继续执行,程序将从Stop语句的下一条语句开始执行。
- Stop语句能够将程序暂时挂起,但在继续运行时需要用户来操作,因此Stop语句常用于程序调试。
实例:使用Stop语句实现逐行显示:
Sub 使用Stop方法()
Dim a As String
a = InputBox("请输入字符","输入字符")
Debug.Print Tab(3);a
Stop
Debug.Print Tab(2);a;Tab(4);a
Stop
Debug.Print Tab(1);a;Tab(3);a;Tab(5);a
End Sub
继续点击运行按钮两次:
End语句
- 对于VBA来说,停止程序的运行意味着程序的运行被终止并返回VBA编译器,此时将卸载所有被程序打开的窗体。在没有其他程序引用当前程序公共类模块的对象,同时也没有代码被执行时,变量被占用的内存将被清空。在VBA中,停止程序运行可以使用End语句来实现。
对于之前本博客所举之案例,大部分Sub过程都只有一个End语句作为结束。特别地,如果代码中存在分支语句时,我们也许会给每一个分支语句的末尾写一个End语句作为结束,这样就有了不止一个End语句。
分支语句
- 对于多数主流计算机高级语言如C语言,Java语言等都支持程序的分支结构和循环结构,所以这里主要列举关键字,不再强调举例
If 条件表达式1 Then
语句块1
ElseIf 条件表达式2 Then
语句块2
.......
Else
语句块 n
End If
- 类似于SQL中的 “case when”语句,VBA中也有一个“select case”语句;
Select Case 条件表达式
Case 条件表达式1
语句序列1
Case 条件表达式2
语句序列2
.......
Case Else
语句序列n
End Select
循环结构
For循环
循环结构的基本语法代码如下
For 循环变量 = 初始值 To 终值 [步长]
循环语句块
Next [循环变量]
循环变量:该变量为必选参数,用于设置虚幻次数的计数变量名。
初始值:此参数为必选参数,用于设置循环变量的初始值。
终值:该参数为必选参数,用于设置循环变量的终止值。
步长:该参数为可选参数,用于设置循环变量在每次循环后变化的数值
示例:使用For循环计算累加值
Sub 计算指定范围内的累加和()
Dim a,b
Dim i As Integer,sum As Double
' 声明变量,i 为循环变量,sum为每次循环变量获得的和
a = InputBox("请输入初始值","计算数字的累加和","0")
' 获取用户输入的初始值和终止值
b = InputBox("请输入终止值","计算数字的累加和","0")
sum = 0
For i = a To b
sum = sum + i
Next
MsgBox "从" & a &"到" & b &"的和为" & sum, , "计算数字的累加和"
' 显示计算结果
End Sub
While循环
- While循环一共有四种:
Do While 条件表达式
循环语句块
Loop
' 进行条件判断,当条件表达式为真时,执行循环语句块;否则跳过循环体。执行完循环语句块时,再次进行条件判断
Do Until 条件表达式
循环语句块
Loop
' 进行条件判断,当条件表达式为假时,执行循环语句块;否则跳过循环体。执行完循环语句块时,再次进行条件判断
Do
循环语句块
Loop While 条件表达式
' 执行循环语句块,进行条件判断,当条件表达式为真时,再次执行循环语句块;
' 否则跳过循环体。执行完循环语句块时,再次进行条件判断
Do
循环语句块
Loop Until 条件表达式
' 执行循环语句块,进行条件判断,当条件表达式为假时,再次执行循环语句块;
' 否则跳过循环体。执行完循环语句块时,再次进行条件判断
处理程序的错误
在VBA中,处理程序的错误需要经过1.捕获错误2.错误处理程序的编写3.错误处理程序的退出
GoTo语句
- GoTo语句不是VBA中的错误捕捉语句,但要理解VBA的错误捕捉语句,GoTo语句必知必会。
学过汇编语言的小伙伴肯定对这样的指令跳转语句不陌生。 - 该语句的缺点:增加程序阅读和调试的难度,在大型程序中频繁使用该语句将可能导致程序的崩溃。除非必要,尽量少使用GoTo语句
GoTo语句的语法规则如下:
GoTo 行号|行标签
Sub 使用GoTo语句()
...
inputAgain:
...
Goto inputAgain
...
End Sub ' 这里的inputAgain 就是行标签
On Error GoTo 语句用于捕获错误
On Error GoTo 行标签
- 这里,On Error 语句捕获到程序的错误,程序将执行后面的GoTo语句,行标签处应当是错误处理程序的入口。
- 这里行标签指定的行必须与On Error语句处在同一个过程之中,否则会产生编译事件错误
错误处理程序的例子
Sub 对输入数字开方()
Dim a As Double , b As Double ' 声明变量
On Error GoTo error1 ' 捕获可能的输入错误并跳转
a = InputBox("请在此输入底数","简易开方计算器") ' 获取输入的底数
a = InputBox("请在此输入根指数","简易开方计算器") ' 获取输入的指数
On Error GoTo error2 ' 捕获计算中可能出现的错误并跳转
MsgBox "对数字" & a & "开" & b & "次方" & " 的 _
结果为:" & (a ^ (1 / b) ) , vbOKOnly ,"简易开方计算器" ' 显示计算结果
Exit Sub ' 结束过程
error1:
MsgBox "输入错误,程序只能对数字进行运算。",vbOKOnly,"错误提示" ' 显示输入错误提示
Exit Sub ' 结束过程
error2: ' 第二个行标签
If (b Mod 2 = 0) Then
MsgBox "无法对数字" & a & "开" & b & "次方", vbOKOnly ,"错误提示" ' b 为偶数时,给出错误提示
Else
a = -a ' b为奇数时,将a取相反数
MsgBox "对数字" & -a & "开" & b & "次方" & "的 _
结果为" & (-a ^ (1 / b) ) , vbOKOnly ,"简易开方计算器" ' 显示计算结果
End If
End Sub
Error2 后面的是第二段处理程序,用于处理幂运算中可能出现的错误,由上面的分析可以知道,程序出错的原因是底数a为负数,而作为指数的 1/b 不是整数。此时,如果b的值是偶数,则将会出现对负数a开偶数次方,这显然错误。要判断b是否为偶数,使用If语句判断b/2 余数是否为0 来判断是否为偶数。偶数则没有计算结果
Resume语句
在错误处理程序执行完成后,有时需要退出错误处理程序并返回到程序的适当位置继续执行。VBA的Resume语句就是具有这种功能的返回语句。Resume语句一般有下面三种用法:
- Resume 或 Resume 0 :程序返回到出错语句处继续执行原来的程序
- Resume Next :该语句使程序返回到出错处的下一个语句继续执行
- Resume 行标签: 该语句使程序返回到行标签所在行继续执行