目录
什么是VBA?
首先,第一个问题,什么是 VBA?
Visual Basic for Applications(VBA)是 VisualBasic 的一种宏语言,是微软开发出来在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展 Windows 的应用程序功能,特别是Microsoft Office软件。
以上是 VBA 的百科定义,说简单点,VBA 是运行在 Microsoft Office 软件之上,可以用来编写非软件自带的功能的编程语言。Office 软件提供丰富的功能接口,VBA 可以调用它们,实现自定义的需求。基本上,能用鼠标和键盘能做的事情,VBA 也能做。
正如前文所述,VBA 可以运行在 Office 软件上,包括 Excel、Word、PPT、Outlook 等。VBA 语言在 Office 软件中是通用的,基本语法和用法都相同。但是每一个软件具有自己独有的对象,例如 Excel 有单元格对象,Word 有段落对象,PPT 有幻灯片对象。
回到 Excel VBA,用它可以编写自定义函数,插入任意图表、批量处理大量数据单元格,编写插件自动化工作。甚至可以编写基于 Excel 的复杂的管理系统,其功能可以媲美桌面软件。
VBA 与宏有什么区别?
「宏」。简单的说,宏是一段可以运行的 VBA 代码片段,也可以说是一个简称,并没有特别的不同之处。所以学习 VBA 时,不用纠结于两者到底有什么区别,只需要记住一点,宏是使用 VBA 编写的一段代码片段。
学习 Excel VBA 有什么用处?
VBA 几乎可以实现任何功能,从简单的数据处理,到批量数据分析,再到与 Office 其他软件交互,甚至与操作系统交互实现复杂的功能,VBA 几乎都可以胜任。以下是 Excel VBA 几个典型的用途。
- 节省时间:只需一次点击就可以重复执行任意数量的操作。例如,现在要新建 20 个工作表,手动操作可能需要一分钟的时间。使用 VBA 只需一秒即可。
- 自动化任务:只需一次点击就可以按预先设置好的步骤,自动完成操作。例如,插入一个图表并设调整格式,根据其复杂程度,可能需要多达几分钟时间。而使用VBA编写调整步骤,一次点击,几秒内即可完成所有的操作。
- 减少错误:相比于手动操作出现的错误,只要正确编写 VBA 代码,执行过程中就不会出现错误。例如,从一区域中筛选指定数据,并复制到另外一个位置,手动操作可能会出现漏选的可能。但是使用 VBA,极短的时间内正确无误的完成操作。
- 与其他软件交互:使用 VBA,可以在 Excel 里创建、更新 Word、PPT 等文件。还可以与系统交互,做到复制、移动、重命名其他文件等操作,无需打开其他文件。
Excel VBA 基本原理
Excel 是一个对象,这个对象包含很多属性和子对象,而 VBA 是可以操作这些对象的工具,实现各种各样的效果。例如,Excel 包括 Range 对象,即单元格对象,使用 VBA 可以改变单元格对象的填充颜色属性。用代码表示如下。
'A1 单元格的填充颜色设置为颜色号为 49407 的颜色
Range("A1").Interior.Color = 49407
在这里使用代码简单的演示一下 Excel 中的对象和 VBA 的关系。
- Range(“A1”)、Interior、Color 等是 Excel 具备的对象和属性;
- 对象和属性的操作,是通过 VBA 语言实现的,即上面是一行 VBA 代码。中间的等号(=)是 VBA 语言的赋值符号,也是能改变单元格填充颜色的关键所在。
Excel Vba 语言中的基本概念
1、注释
注释是代码中不会被执行的一段代码。注释是几乎所有编程语言具备的功能,VBA 也不例外。
VBA 中的注释以英文单引号 (‘) 开头,后面接注释的内容。从单引号开始的部分不会被执行。
'我是一行注释
注释,正如字面意思,用来对代码进行解释。在写代码过程中,对代码进行注释是好的习惯,有助于自己或别人,更好的理解已经存在的一段代码。
2、变量
变量是存储数据的一种表达方式。在程序开始,可以声明一个变量,指定变量的类型(数字、文本、逻辑值等),并给变量赋值。在程序其他地方,就可以用该变量,使其存储的值参与运算。
以下方代码为例,
'声明一个文本类型的变量
Dim s As String
'给 s 变量赋值,即 "Hello World"
s = "Hello World"
'在 A1 单元格写入 s 变量存储的数据
Range("A1").Value = s
可以看到,s 变量存储 “Hello World”文本,该文本在程序中就可以用s 变量表示
3、程序结构
程序结构表示程序的运行方式。VBA 正是因为存在多种代码结构,才能实现各类复杂的数据计算。常用的代码结构以下三种:
- 顺序结构
- 条件结构
- 循环结构
顺序结构,顾名思义,程序按照顺序执行。在 VBA 中就是从上到下,一行一行地执行。
条件结构,代码中的指定部分,按照某个条件,选择性地执行。即,条件为真时,执行指定代码;否则跳过该部分代码,不执行。
循环结构,代码中的指定部分,按指定次数,循环执行。这是为什么 VBA 的效率高的一个原因,因为它能将相同的操作,自动按任意数量重复执行。
4、过程或函数
包含多行代码,是组织代码的两种方式。一般情况下,一个过程或函数只包含实现一个功能的相关代码。如果一个过程或函数实现多个功能,建议将代码分成多个过程或函数。
过程和函数都可以执行一段代码,主要区别是,执行完代码后,函数能返回一个值,而过程不能返回
5、数组
数组表示一组同类型的数据的集合,是 VBA 中最重要的概念之一。以下面的代码为例:
'创建数组
Dim s(1 to 4) As String
'给数组的元素赋值
s(1) = "Excel"
s(2) = "Word"
s(3) = "PowerPoint"
s(4) = "Outlook"
上述代码创建了一个长度为4个、类型为文本的一个数组。对数组,使用编号给相应位置进行赋值。
在 VBA 的实际应用中,经常需要将单元格的数据转换为数组进行处理
6、对象
对象是一个物,它可以是一个事、一个物体、一个概念、一个名词。对象包含描述静态信息的属性和对对象可以操作的方法。
以生活中的对象为例子,汽车是一个对象。汽车的车牌号、油量、里程等是汽车的属性;开车、加油、换车牌等是汽车的方法。
在 VBA 中也是类似。工作表(Worksheet)是一个对象,它具有名称、标签颜色等属性,有添加、删除等方法
常用 Excel 对象
- Application 对象,表示 Excel 应用程序。
- Workbook 对象,表示工作簿对象。
- Worksheet 对象,表示工作表对象
- Range 对象,表示单元格区域对象。
7、模块
模块是包含一个或多个过程或函数的内部组件。一个工作簿内包含的模块数量没有限制,一个模块内包含的过程或函数数量也没有限制。模块用来作为保存过程或函数的容器,这些过程和函数通常应用于整个工作簿。
通过把多个过程和函数,合理的放置在不同的模块,可以使整个 VBA 代码逻辑更清晰、更易于阅读和理解。
8、用户窗体
用户窗体是 VBA 代码与使用者交互的用户界面。Excel VBA 提供很多基本的窗体控件,可以制作复杂的用户界面。最典型的,Excel 中设置单元格格式的窗口界面,就是一个用户窗体。
最基本的窗体控件包括:
- 文本控件
- 按钮控件
- 列表控件
- 输入控件
编写第一个VBA宏
步骤 1 创建启用宏的工作簿
首先新建一个工作簿,并将工作簿保存为「启用宏的工作簿」类型,文件名后缀为xlsm
步骤 2 打开 VBA 编辑器
通过功能区「开发工具 → 代码→Visual Basic」或快捷键 Alt + F11 打开 VBA 编辑器
步骤 3 插入一个新模块
Excel 工作簿中的 VBA 代码通常保存在工作表对象或模块中。本例中,我们用模块保存 VBA 代码。
首先选中左侧工程列表中的工作簿,后右键,在弹出的选项列表中,选择「插入」。二级菜单中,选择「模块」,完成插入新模块
步骤 4 打开模块
双击上一步插入的模块1,在右侧代码窗口区域里,将打开模块1的代码编辑器。在右侧代码窗口中当前打开的代码编辑器所对应的模块,在编辑器标题末尾可以看到
步骤 5 创建一个宏(VBA 过程)
在代码编辑窗口中,输入以下代码:
Sub MyCode()
End Sub
这段代码是一个空的 VBA 过程,只有开始和结束。过程的其他代码,都在这中间编写。
其中 Sub
是 Subroutine 的缩写,直译过来是子程序。在 VBA 中表示一个过程,也是代表一个过程的开始。下一行 End Sub
表示过程的结束。
步骤 6 编写 VBA 过程实体部分
过程的实体部分指的是,真正会被执行的部分。上一步创建的是一个空的 VBA 过程,里面不包含实体代码。虽然可以正常运行,但是不会有结果输出。
这一步我们编写 VBA 过程的实体部分。将如下代码输入到过程的开始和结束处之间。
MsgBox "Hello World"
步骤 7 运行代码
将光标放置在代码的任何一处,点击工具栏上的运行「▶ 」按钮,或按 F5,运行代码
VBA 变量
什么是 VBA 变量
VBA 变量是一个存储数据的 VBA 代码结构。变量存储的数据,可在程序运行过程中改变。又能代表它存储的数据,在程序中参与各类计算。
变量可以简单理解为 Excel 中的单元格引用地址,例如 A1。在公式中,A1 代表 A1 单元格内的数据,参与计算。
变量有两个重要的概念,变量名和变量类型。
- 变量名:代表变量的名称
- 变量类型:变量存储的数据的类型,例如数字、文本、逻辑值等。
声明变量
如果想在代码中使用变量,需要先声明,即给出变量名和变量类型。
声明变量使用以下语法:
Dim [变量名] As [数据类型]
Dim
和As
是 VBA 中声明变量需要使用的关键词。Dim
表示声明语句的开始,As
表示在它之后指定数据类型。
[变量名]
和[数据]
是,声明代码中可变部分,需要用户输入。
- [变量名] 就是该变量的名称
- [数据类型] 是该变量的数据类型
举例说明
Dim name As String
Dim age As Integer
可以看到,name
和age
是变量的名称,String
是文本类型数据,代表员工姓名;Integer
是整数数据类型,代表员工年龄。
命名变量
VBA 中规定,变量命名需要符合以下条件,否则程序出错。
- 首字母必须以字母开头。
- 不能包含空格、.(英文句号)、!(感叹号)、@、&、$、# 等字符。
- 长度不能超过 255 个字符。
- 不能使用 VBA 中保存的关键词作为变量名。
以上是变量名必须符合的规则。符合规则的前提下,虽然可以随便命名,但在实际开发过程,建议按驼峰法命名。
驼峰法是一种很多编程语言通用的命名规则,优点是可读性高、易于理解。
骆驼式命名法就是当变量名或函数名是由一个或多个单词连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始;从第二个单词开始以后的每个单词的首字母都采用大写字母。
例如:myFirstName、myLastName,这样的变量名看上去就像骆驼峰一样此起彼伏,故得名。
变量类型
即变量存储数据的数据类型。正确指定数据类型,可以使程序编写和运行效率更高,并且易于理解。
VBA 中的数据类型主要分为三大类,一个是数字类型,一个是非数字类型,一个是通用类型。
数字类型
数字类型的变量顾名思义,均是以数字变量。不同类型其数据范围有区别。
类型 | 说明 | 数据范围 |
---|---|---|
Byte | 字节 | 0 至 255 |
Integer | 整数 | -32,768 至 32,767 |
Long | 长整数 | -2,147,483,648 至 2,147,483,648 |
Single | 单精度浮点数 | 在表示负数时: -3.402823E38 ~ -1.401298E-45 在表示正数时: 1.401298E-45 ~ 3.402823E38 |
Double | 双精度浮点数 | 在表示负数时: -1.79769313486231E308 ~ -4.94065645841247E-324 在表示正数时: 4.94065645841247E-324 ~ 1.79769313486231E308 |
Currency | 货币 | -922,337,203,685,477.5808 至 922,337,203,685,477.5807 |
Decimal | 定点数 | 未放置定点数: +/- 79,228,162,514,264,337,593,543,950,335 放置定点数: +/- 7.9228162514264337593543950335 |
非数字类型
非数字变量通常不能直接参与算术运算。
类型 | 说明 | 数据范围 |
---|---|---|
String | 文本类型 | 0 至 20亿字符 |
Boolean | 逻辑值 | True 或 False |
Date | 日期和时间 | 时间:00:00:00 至 23:59:59 日期: 100-1-1 至 9999-12-31 |
Object | 对象 | VBA 和 Excel 对象 |
通用类型
通用数据类型,指的是可存储任何类型的数据。在程序运行过程,VBA 可以自动识别数据类型,参与计算。
类型 | 说明 | 数据范围 |
---|---|---|
Variant | 任意类型 | 不限 |
Variant 类型虽然灵活,但是它会占用更多内存空间,执行效率也会受影响。因此建议,在明确知道数据是何种类型时,指定数据类型;如果数据类型是可变的或不明确,使用 Variant 类型。
给变量赋值
给变量赋值很简单,使用以下语法:
[变量名] = [数据]
赋值语法核心就是 =
(等号),变量在左侧,数据在右侧。可以理解为变量等于赋值的数据。
一个值得注意的点是,[数据]的形式。
- 数据可以是直接书写的内容,例如 2、”学校”、True等。
- 也可以是另外一个变量
给变量赋值完成后,在后续的程序中,就可以使用变量参与各类计算。
具体的例子如下。
Dim name As String
name = "张三"
Range("A1") = name
以上代码,先声明了 name
变量,数据类型为文本。然后给它赋值了张三
文本。最后将name
变量的数据,写入到工作表 A1 单元格
VBA 常量
声明常量
声明常量与声明变量类似,需要指明名称和数据类型。不同点在于,常量的值在声明时就需要指定。
声明常量的语法如下:
Const [常量名] As [数据类型] = [值]
其中,Const
是英文单词 Constant 的缩写,表示常量。
命名常量
与变量相同,常量命名需要符合以下条件,否则程序出错。
- 首字母必须以字母开头。
- 不能包含空格、.(英文句号)、!(感叹号)、@、&、$、# 等字符。
- 长度不能超过 255 个字符。
- 不能使用 VBA 中保存的关键词作为常量名。
常量类型
常量类型与变量类型相同,参考变量类型。
示例
将 π 的值作为一个常量声明,在后续的过程中,直接使用 Pi
作为 π 的值参与计算。
Sub MyCode()
'声明 π 常量
Const Pi As Double = 3.14159
'声明半径 r 和周长 C 变量
Dim r As Double
Dim C As Double
'从单元格 A1 读取半径值
r = Range("A1").Value
'计算周长
C = 2 * Pi * r
MsgBox "周长为:" & C
End Sub
VBA 运算符
赋值运算符
赋值运算符 ( = )。赋值语法核心就是 =
(等号),变量在左侧,数据在右侧。可以理解为变量等于赋值的数据。
运算符 | 说明 | 示例 |
---|---|---|
= | 给变量赋值 | name = “Zhang San” |
算术运算符
算数运算符是我们常用的数学运算符,包括加减乘除等。VBA 中完整的算术运算符如下。
假设 a = 10
,b = 3
,->
表示结果。
运算符 | 说明 | 示例 |
---|---|---|
+ | 两数相加 | a + b -> 13 |
– | 两数相减 | a – b -> 7 |
* | 两数相乘 | a * b -> 30 |
/ | 两数相除 | a / b -> 3.33… |
\ | 两数相除,取整数部分 | a \ b -> 3 |
Mod | 两数相除,取余数 | a Mod b -> 1 |
^ | 幂运算 | a ^ b -> 1000 |
-(取负) | 对数字取负 | -a -> -10 |
比较运算符
比较运算符,比较提供的两个变量,如果符合比较条件,返回 True,否则,返回 False。
假设 a = 10
,b = 3
,->
表示结果。
运算符 | 说明 | 示例 |
---|---|---|
= | 比较两个值是否相等 | a = b -> False |
> | 大于 | a > b -> True |
>= | 大于等于 | a >= b -> True |
< | 小于 | a < b -> False |
<= | 小于等于 | a <= b -> False |
<> | 不等于 | a <> b -> True |
逻辑运算符
逻辑运算符对逻辑值,即 True 和 False,进行逻辑运算,返回运算结果,运算结果也是逻辑值。
假设 a = True
,b = False
,->
表示结果。
运算符 | 说明 | 示例 |
---|---|---|
And | 逻辑与,两个表达式都是真,返回 True。 | a And b -> False |
Or | 逻辑或,两个表达式至少有一个为真,返回 True。 | a Or b -> True |
Not | 逻辑否,对逻辑表达式取否 | Not a -> False |
Xor | 逻辑异或,如果两个表达式不相同,返回 True | a Xor b -> True |
连接操作符
VBA 中的连接运算符用于连接 2 个或多个文本。其用法与 Excel 公式中的 & 符号相同。
运算符 | 说明 | 示例 |
---|---|---|
& | 连接两个文本 | “Zhang” & ” ” & “San” -> “Zhang San” |
其他操作符
运算符 | 说明 |
---|---|
_ (下划线) | 将一行代码分解成两行 |
: ( 英文冒号) | 将两行代码放置在一行 |
VBA 数据类型
文本类型
文本类型是最常用的数据类型。实际中,几乎所有的数据均是文本类型。
类型 | 说明 | 数据范围 |
---|---|---|
String | 文本类型 | 0 至 20亿字符 |
首先,声明一个文本类型变量,String
是类型标识符,语法如下:
Dim name As String
VBA 中,文本需使用英文双引号表示。
name = "Zhang San"
如果把数字两端加上双引号,它会变成文本类型,不再表示数字
name = "101"
可以使用单元格内的文本,给文本类型变量赋值。
name = Range("A1")
与 Excel 提供的文本函数一样,VBA 也提供多种文本函数,可直接在程序中使用,包括:
- Format:格式化数据,并以文本类型返回
- InStr:返回指定字符的位置
- InStrRev:反方向返回指定字符位置
- Left:返回左侧指定长度文本
- Len:返回文本长度
- LCase:大写字母转换成小写字母
- LTrim:清除开头的空格
- Mid:返回指定的开始和结束位置之间的文本
- Replace:替换文本中的指定字符
- Right:返回右侧指定长度文本
- RTrim:清除末尾处的空格
- Space:返回指定重复数的空格文本
- StrComp:返回比较两个文本的结果
- StrConv:将文本转换成指定格式
- String:返回指定重复数的文本
- StrReverse:逆转提供的字符串
- Trim:清除开头和结尾处的空格
- UCase:将小写字母转换成大写字母
数字类型
数字类型是第二个基础数据类型。在写 VBA 代码时,应根据具体的数字大小,选择合适的数字类型。
如果小数字使用大范围数字类型存储,会浪费计算机内存;如果大数字使用小范围的数字类型存储,VBA 会自动转换成对应小范围数字,导致数字丢失精度。
VBA 中的数字类型包括如下几种。
类型 | 说明 | 数据范围 |
---|---|---|
Byte | 字节 | 0 至 255 |
Integer | 整数 | -32,768 至 32,767 |
Long | 长整数 | -2,147,483,648 至 2,147,483,648 |
Single | 单精度浮点数 | 在表示负数时: -3.402823E38 ~ -1.401298E-45 在表示正数时: 1.401298E-45 ~ 3.402823E38 |
Double | 双精度浮点数 | 在表示负数时: -1.79769313486231E308 ~ -4.94065645841247E-324 在表示正数时: 4.94065645841247E-324 ~ 1.79769313486231E308 |
Currency | 货币 | -922,337,203,685,477.5808 至 922,337,203,685,477.5807 |
Decimal | 定点数 | 未放置定点数: +/- 79,228,162,514,264,337,593,543,950,335 放置定点数: +/- 7.9228162514264337593543950335 |
其中,Integer
、Long
、Double
是常用到的数字类型。
与文本相似,声明数字类型,使用如下语句:
Dim age As Integer
以上定义一个岁数
变量,使用基本的 Integer 整数类型即可。
数字类型变量可以像数字一样,参与各类算数运算:
age = 3
age * 2 + 10 ‘-> 16
逻辑类型
逻辑类型只有两个值,True 和 False,即真与假。
类型 | 说明 | 数据范围 |
---|---|---|
Boolean | 逻辑值 | True 或 False |
逻辑值虽然只有两个,但是在程序中有着广泛的应用。VBA 中判断语句中,经常能用到逻辑值。
首选,声明一个逻辑变量,使用如下语句:
Dim isPass As Boolean
给逻辑变量赋值时,可以直接使用逻辑值,也可以使用返回逻辑值的表达式。
isPass = False
isPass = 70 >= 60
日期和时间类型
VBA 中的日期和时间使用数字表示,整数部分代表日期,小数部分代表时间。
- 日期从 100-1-1 开始到 9999-12-31。
- 时间从 00:00:00 到 23:59:59。
声明日期类型变量,使用如下语句:
Dim birthday As Date
Dim time As Date
给日期变量赋值时,可以直接把日期放置在两个 # 之间赋值,也可以使用数字,还可以把日期作为文本赋值:
birthday = #2018-1-1#
birthday = 43101
birthday = "2018-1-1"
time = #12:00:00#
time = 0.5
time = "12:00:00"
Variant类型
Variant 类型是一种通用类型,可以表示任何一种类型的数据。它也是声明变量未指定数据类型时的默认类型。
虽然 Variant 类型方便,但是相应的,占用更大的内存空间,也会影响程序运行效率。因此建议,在明确知道数据时何种类型时,指定数据类型;如果数据类型是可变的或不明确,使用 Variant 类型。
VBA 程序结构
顺序结构
顺序结构,顾名思义就是按照一定的顺序依次执行。VBA 中的执行顺序就是,从左到右、从上到下的顺序。
判断结构
判断结构主要有以下几种选择结构的语法和使用方式:
If … Then 结构
If Then
结构是最基础的一个。它只有条件表达式真时,执行的代码。If Then
结构基本语法如下,其中 End If
是选择结构的结束标志。
If 条件表达式 Then
'表达式为真时,执行的代码
End If
以下示例,判断学生是否及格,及格条件是成绩 ≥60。如果及格,在C列对应单元格填写“及格”。具体代码如下:
Sub MyCode()
Dim i As Integer
For i = 2 To 10
If Cells(i, "B").Value >= 60 Then
Cells(i, "C") = "及格"
End If
Next i
End Sub
If … Else 结构
If Else
结构中,条件表达式在真时,执行Then
后的代码;条件表达式为假时,执行 Else
后的代码。基本语法如下:
If 条件表达式 Then
'真时执行的代码
Else
'假时执行的代码
End If
示例,判断学生是否及格,及格条件是成绩 ≥60。如果及格,在C列对应单元格填写“及格”。对不及格的学生,在C列填入不及格。代码如下:
Sub MyCode()
Dim i As Integer
For i = 2 To 10
If Cells(i, "B").Value >= 60 Then
Cells(i, "C") = "及格"
Else
Cells(i, "C") = "不及格"
End If
Next i
End Sub
If ElseIf Else 结构
If ElseIf Else
结构,对同一个变量进行多次判断,并且为每一个判断结果编写不同的代码块,达到执行式 n 选 1 的效果。
If ElseIf Else
结构的基本语法如下:
If 条件表达式1 Then
'表达式1真时,执行的代码
ElseIf 条件表达式2 Then
'表达式2真时,执行的代码
ElseIf 条件表达式3 Then
'表达式3真时,执行的代码
...
ElseIf 条件表达式n Then
'表达式n真时,执行的代码
Else
'以上表达式都不为真时,执行的代码
End If
以下示例,判断学生成绩评级的代码。思路是,拿学生成绩,分别于85、75、60分比较,在 D 列填写对应的评级。
Sub MyCode()
Dim i As Integer
For i = 2 To 10
If Cells(i, "B").Value >= 85 Then
Cells(i, "D") = "优"
ElseIf Cells(i, "B").Value >= 75 Then
Cells(i, "D") = "良"
ElseIf Cells(i, "B").Value >= 60 Then
Cells(i, "D") = "及格"
Else
Cells(i, "D") = "不及格"
End If
Next i
End Sub
Select Case 结构
Select Case
结构是对同一个变量进行多次判断的另一种方式。相对于If ElseIf Else
结构,它把条件表达式中的变量提取出来,使得代码结构更简洁,也更易于阅读。
Select Case
结构的基本语法如下:
Select Case 变量
Case 判断条件 1
'条件 1 真时,执行的代码
Case 判断条件 2
'条件 2 真时,执行的代码
Case 判断条件 3
'条件 3 真时,执行的代码
Case Else
'之前的所有条件都不为真时,执行的代码
End Select
前一个例子,使用Select Case
结构,代码如下:
Sub MyCode()
Dim i As Integer
For i = 2 To 10
Select Case Cells(i, "B").Value
Case Is >= 85
Cells(i, "D") = "优"
Case Is >= 75
Cells(i, "D") = "良"
Case Is >= 60
Cells(i, "D") = "及格"
Case Else
Cells(i, "D") = "不及格"
End Select
Next i
End Sub
循环结构
循环结构用于多次重复执行同一段代码。重复次数通过特定数字或特定条件控制。通过控制循环过程中特定变量,循环结构可执行复杂的重复任务。
For 循环
For … Next 循环
使用 For ... Next
循环可以按指定次数,循环执行一段代码。For 循环使用一个数字变量,从初始值开始,每循环一次,变量值增加或减小,直到变量的值等于指定的结束值时,循环结束。
For ... Next
循环语法如下:
For [变量] = [初始值] To [结束值] Step [步长]
'这里是循环执行的语句
Next
其中:
[变量]
是一个数字类型变量,可在循环执行的语句里使用。[初始值]
和[结束值]
是给定的值;[步长]
是每次循环时,变量的增量。如果为正值,变量增大;如果为负值,变量减小。
下面看一个实际的例子,求 1 至 10 数字的累积和。
Sub MyCode()
Dim i As Integer
Dim sum As Integer
For i = 1 To 10 Step 1
sum = sum + i
Next
End Sub
For Each 循环
For Each
循环用于逐一遍历一个数据集合中的所有元素。数据集合包括数组、Excel 对象集合、字典等。
For Each 循环不需要一个数字变量,但是需要与数据集合中的元素相同的数据类型变量。其基本语法如下:
For Each [元素] In [元素集合]
'循环执行的代码
Next [元素]
其中,
[元素]
是与集合中的元素相同类型的变量,该变量可在循环代码中使用。[元素集合]
是包括多个元素的集合。
下面看一个实际例子,循环打印出工作簿中所有工作表的名称。
Sub MyCode()
Dim sh As Worksheet
For Each sh In Worksheets
Debug.Print sh.Name
Next sh
End Sub
Exit For 语句
Exit For
语句用于跳出循环过程,一般在提前结束循环时使用,均适用于 For Next
循环和 For Each
循环。
看一个实际的例子,求 1 – 10 数字的和时,当和大于 30 就停止循环。
Sub MyCode()
Dim i As Integer
Dim sum As Integer
For i = 1 To 10
sum = sum + i
If sum > 30 Then
Exit For
End If
Next
End Sub
Do While 循环
Do While
循环用于满足指定条件时循环执行一段代码的情形。循环的指定条件在 While
关键词后书写。
Do While
循环也有两种形式:
- Do While … Loop 循环
- Do … Loop While 循环
Do While … Loop 循环
Do While … Loop 循环,根据 While 关键词后的条件表达式的值,真时执行,假时停止执行。基本语法如下:
Do While [条件表达式]
'循环执行的代码
Loop
其中,只要 [条件表达式]
为真,将一直循环执行。[条件表达式]
一旦为假,则停止循环,程序执行 Loop
关键词后的代码。
看一个实际的例子,还是求 1- 10 累积和。
Sub MyCode()
Dim i As Integer
Dim sum As Integer
i = 1
Do While i <= 10
sum = sum + i
i = i + 1
Loop
End Sub
i
变量的初始值是 1,根据 While
后的条件,只要 i
变量小于等于 10,后续的代码就可以一直循环执行。
Do … Loop While 循环
Do ... Loop While
循环至少循环执行代码一次后,再判断条件表达式的值。基本语法如下:
Do
'循环执行的代码
Loop While [条件表达式]
其中,While 和条件表达式写在 Loop 关键词后。
Exit Do 语句
与 Exit For
语句类似,Exit Do
语句用于跳出 Do While
循环。
Do Until 循环
Do Until
循环与 Do While
循环类似。不同点在于,Do While
在条件表达式为真时,继续执行循环;而 Do Until
在条件表达式为真时,停止执行循环。
Do Until 循环也有两种形式:
- Do Until … Loop 循环
- Do … Loop Until 循环
Do Until … Loop 循环
循环开始前判断 Until
后条件表达式的值,如果是真,停止循环;如果是假,继续执行循环。基本语法如下:
Do Until [条件表达式]
'循环执行的代码
Loop
Do … Loop Until 循环
先运行一次,再判断 Until
后条件表达式的值,如果是真,停止循环;如果是假,继续执行循环。基本语法如下:
Do
'循环执行的代码
Loop Until [条件表达式]
VBA With 结构
With
结构由 With
和 End With
两个语句构成,对象的属性和方法都写在两者之间。基本语法如下:
With [对象]
.[属性] = [数据]
.[方法]
'其他属性和方法
End With
With
结构里,对象的属性和方法均由点 (.)
符号开始,后接对象的属性名和方法名。
现在看一个实际的例子,需要将工作簿中 Sheet1 工作表设置新名称,然后设置标签颜色为黑色,最后隐藏工作表。
如果不用 With 结构,代码如下:
Sub MyCode()
Worksheets("Sheet1").Name = "新名称"
Worksheets("新名称").Tab.ThemeColor = xlThemeColorLight1
Worksheets("新名称").Visible = xlSheetHidden
End Sub
可以看到,每个语句都重复写 Worksheets("工作表名称")
部分。
使用 With 结构,可以避免重复写同一个对象名,代码如下:
Sub MyCode()
With Worksheets("Sheet1")
.Name = "新名称"
.Tab.ThemeColor = xlThemeColorLight1
.Visible = xlSheetHidden
End With
End Sub
VBA 过程和函数 (Sub | Function)
VBA过程入门及示例
VBA 过程以 Sub
语句开始,以 End Sub
语句结束,包含一个或多个语句,完成一个特定的目标。
无参数过程
无参数的 VBA 过程的基本语法如下:
Sub [过程名]()
语句1
语句2
...
语句n
End Sub
有参数过程
过程还可以接受一个或多个参数,参数可以是常量、变量、表达式,并且每个参数指定其名称。在过程的语句中,接受的参数,以名称指定方式被使用。
接受参数的过程基本语法如下:
Sub [过程名]([变量名1] As [数据类型1],...[变量名n] As [数据类型n])
语句1
语句2
...
语句n
End Sub
举例说明:
'声明一个过程
Sub SayHello(name As String)
Msgbox "Hello" & name
End Sub
'在另一个过程,调用上述过程,调用时,提供一个实际的 name 参数
Sub MyCode()
SayHello "World 2"
End Sub
调用子过程
在程序开发中,把代码拆分成多个子过程和函数,可以使项目更容易管理、测试和运行,VBA 中也不例外。
实际开发中,项目通常具备一个主入口过程,或称为父过程。父过程通过调用多个子过程和函数,完成一系列复杂的操作。其中子过程和函数一般只负责一个操作或动作。
下面看一个简单的例子。
'主入口
Sub Main()
Dim name As String
Dim title As String
name = "Zhang san"
title = "CEO"
WriteInfo name & "," & title
End Sub
'子过程,在工作表A1单元格填写信息
Sub WriteInfo(info As String)
Range("A1") = info
End Sub
调用子过程有两种方法,直接调用和使用 Call 关键词调用。
直接调用
直接调用,直接写过程名,即可调用过程。
Sub Main()
MySub
End Sub
Sub MySub()
'代码
End Sub
如果子过程需要输入参数,多个参数只需用逗号(,)分开即可。
Sub Main()
MySub 2019,"年"
End Sub
Sub MySub(val1 As Integer, val2 As String)
'代码
End Sub
使用关键词 Call 调用
使用 Call 关键词调用时,Call 后接过程名
Sub Main()
Call MySub
End Sub
Sub MySub()
'代码
End Sub
如果子过程需要输入参数,则需要将参数放在括号内。
Sub Main()
Call MySub(2019,"年")
End Sub
Sub MySub(val1 As Integer, val2 As String)
'代码
End Sub
提前退出过程
Exit Sub 语句
在一个过程,当程序运行到 End
语句时,立即结束当前运行的所有 VBA 过程。
例子中,Main
过程调用 MySub
子过程,遇到 Exit Sub
语句,立即退出子过程,回到父过程 Main
,继续运行余下的语句。
Sub Main()
Call MySub
Msgbox "父过程"
End Sub
Sub MySub()
Exit Sub
Msgbox "子过程"
End Sub
'运行 Main 过程,返回结果:
=> "父过程"
End 语句
在一个过程,当程序运行到 End
语句时,立即结束当前运行的所有 VBA 过程。
例子中,Main
过程调用 MySub
子过程,遇到 End
语句时,立即结束当前运行的所有过程,包括父过程 Main
。
Sub Main()
Call MySub
Msgbox "父过程"
End Sub
Sub MySub()
End
Msgbox "子过程"
End Sub
'运行 Main 过程,返回结果:
=> 无返回结果
VBA函数入门及示例
基础语法
无参数函数
Function [函数名]() As [返回值类型]
语句1
语句2
...
语句n
[函数名] = [返回值]
End Function
函数使用 Function
和 End Function
语句作为函数的开始和结束。
函数包含的语句中,相比过程,可以看到多一个 [函数名] = [返回值]
语句,这是函数的返回值语句。函数名后指定该函数返回值的类型,语法与声明变量类似。实际例子如下:
'声明函数,该函数随机返回 true 或 false。函数需指定返回值类型。
Function RandomLogic() As Boolean
RandomLogic = Rnd() > 0.5
End Function
该函数的名称是 RandomLogic
,返回值类型时 Boolean
类型,运行调用后,随机返回一个 true
或 false
值。实现方法是,使用 VBA 内置函数 Rnd(随机产生0-1的数字),随机数与0.5对比大小,产生 true 或 false 值,并把值赋值给函数名。
有参数函数
Function [函数名]([变量名1] As [数据类型1],...[变量名n] As [数据类型n]) As [返回值类型]
语句1
语句2
...
语句3
[函数名] = [返回值]
End Function
实际例子如下:
Function Add2Number(num1 As Double, num2 As Double) As Double
Add2Number = num1 + num2
End Function
调用函数
调用方式与子过程相同。
调用有返回值的函数时,一般有两种情形:
- 一是,使用一个变量存储函数返回的值
- 二是,函数返回的值参与其他计算
两种情形调用函数方式相同,无参数函数直接书写,有参数函数将参数放在括号内。
Sub Main()
'使用变量存储函数返回的值
Dim result1 As Double
result1 = Add(12, 345)
'函数返回值继续参与计算
Dim result2 As Double
result2 = RandNum + Add(12, 345)
End Sub
'函数:返回一个随机值
Function RandNum()
RandNum = Rnd * 100
End Function
'函数:返回两数的和
Function Add(num1 As Double, num2 As Double) As Double
Add = num1 + num2
End Function
提前退出函数
Exit Function 语句
在一个函数中,当程序运行到 Exit Function
语句时,立即结束当前函数,提前退出。
这里需要注意的是,Exit Function
语句只作用于当前过程,不影响调用它的父过程或函数。
End 语句
在一个函数,当程序运行到 End
语句时,立即结束当前运行的所有 VBA 过程和函数。
在实际开发中,应谨慎使用 End
结束语句。End
语句的效果类似于电脑的强制关机命令,立即结束所有程序,不会保存任何值,于 VBA 有以下效果:
- 程序中对象的各类事件不会被触发;
- 任何在运行的 VBA 程序都会停止;
- 对象引用都会失效;
- 任何打开的窗体都被关闭。