- VBA 教程
- VBA - 首页
- VBA - 概述
- VBA - Excel 宏
- VBA - Excel 术语
- VBA - 宏注释
- VBA - 消息框
- VBA - 输入框
- VBA - 变量
- VBA - 常量
- VBA - 运算符
- VBA - 决策
- VBA - 循环
- VBA - 字符串
- VBA - 日期和时间
- VBA - 数组
- VBA - 函数
- VBA - 子过程
- VBA - 事件
- VBA - 错误处理
- VBA - Excel 对象
- VBA - 文本文件
- VBA - 图表编程
- VBA - 用户窗体
- VBA 有用资源
- VBA 快速指南
- VBA - 有用资源
- VBA - 讨论
VBA 快速指南
VBA - 概述
VBA 代表Visual Basic for Applications,是微软的一种事件驱动编程语言,现在主要用于微软办公应用程序,如 MS Excel、MS Word 和 MS Access。
它帮助技术人员构建自定义应用程序和解决方案,以增强这些应用程序的功能。此功能的优点是您无需在 PC 上安装 Visual Basic,但是,安装 Office 将隐式地帮助实现此目的。
您可以在所有 Office 版本中使用 VBA,从 MS-Office 97 到 MS-Office 2013,以及任何最新的可用版本。在 VBA 中,Excel VBA 最受欢迎。使用 VBA 的优势在于您可以使用线性规划在 MS Excel 中构建非常强大的工具。
VBA 的应用
您可能想知道为什么要在 Excel 中使用 VBA,因为 MS-Excel 本身提供了大量的内置函数。MS-Excel 只提供基本的内置函数,这些函数可能不足以执行复杂的计算。在这种情况下,VBA 成为最明显的解决方案。
例如,使用 Excel 的内置公式很难计算贷款的月还款额。相反,为这种计算编写 VBA 比较容易。
访问 VBA 编辑器
在 Excel 窗口中,按“ALT+F11”。将打开一个 VBA 窗口,如下面的屏幕截图所示。
VBA - Excel 宏
在本章中,您将学习如何逐步编写简单的宏。
步骤 1 - 首先,在 Excel 20XX 中启用“开发工具”菜单。为此,请单击“文件”→“选项”。
步骤 2 - 单击“自定义功能区”选项卡,然后选中“开发工具”。单击“确定”。
步骤 3 - “开发工具”功能区将出现在菜单栏中。
步骤 4 - 单击“Visual Basic”按钮以打开 VBA 编辑器。
步骤 5 - 通过添加按钮开始编写脚本。单击“插入”→选择按钮。
步骤 6 - 执行右键单击并选择“属性”。
步骤 7 - 编辑名称和标题,如下面的屏幕截图所示。
步骤 8 - 现在双击按钮,将显示子过程大纲,如下面的屏幕截图所示。
步骤 9 - 通过简单地添加消息开始编码。
Private Sub say_helloworld_Click() MsgBox "Hi" End Sub
步骤 10 - 单击按钮以执行子过程。子过程的输出显示在下面的屏幕截图中。确保您的设计模式已开启。如果未开启,只需单击即可开启。
注意 - 在后面的章节中,我们将演示如何使用简单的按钮,如步骤 1 到 10 所述。因此,彻底理解本章很重要。
VBA - Excel 术语
在本章中,您将熟悉常用的 Excel VBA 术语。这些术语将在后续模块中使用,因此了解每一个术语都很重要。
模块
模块是编写代码的区域。这是一个新的工作簿,因此没有任何模块。
要插入模块,请导航到“插入”→“模块”。插入模块后,将创建“模块 1”。
在模块中,我们可以编写 VBA 代码,代码写在过程中。过程/子过程是一系列 VBA 语句,指示要执行的操作。
过程
过程是一组整体执行的语句,指示 Excel 如何执行特定任务。执行的任务可以是非常简单的任务,也可以是非常复杂的任务。但是,最好将复杂的过程分解成较小的过程。
两种主要类型的过程是 Sub 和 Function。
函数
函数是一组可重用的代码,可以在程序中的任何位置调用。这消除了反复编写相同代码的需要。这有助于程序员将大型程序分解成许多小型且易于管理的函数。
除了内置函数外,VBA 还允许编写用户定义的函数,语句写在Function和End Function之间。
子过程
子过程的工作方式类似于函数。子过程不返回值,而函数可能返回也可能不返回值。子过程可以不用 Call 关键字调用。子过程始终包含在Sub和End Sub语句中。
VBA - 宏注释
注释用于记录程序逻辑和用户信息,其他程序员将来可以无缝地处理相同的代码。
它包括开发人员、修改人员等信息,还可以包括已合并的逻辑。解释器在执行时会忽略注释。
VBA 中的注释用两种方法表示。
任何以单引号 (') 开头的语句都被视为注释。以下是一个示例。
' This Script is invoked after successful login ' Written by : TutorialsPoint ' Return Value : True / False
任何以关键字“REM”开头的语句。以下是一个示例。
REM This Script is written to Validate the Entered Input REM Modified by : Tutorials point/user2
VBA - 消息框
MsgBox 函数显示一个消息框,并等待用户单击一个按钮,然后根据用户单击的按钮执行操作。
语法
MsgBox(prompt[,buttons][,title][,helpfile,context])
参数说明
Prompt - 必需参数。在对话框中显示为消息的字符串。提示的最大长度约为 1024 个字符。如果消息超过一行,则可以使用回车符 (Chr(13)) 或换行符 (Chr(10)) 在每一行之间分隔行。
Buttons - 可选参数。一个数值表达式,指定要显示的按钮类型、要使用的图标样式、默认按钮的标识以及消息框的模式。如果留空,按钮的默认值为 0。
Title - 可选参数。在对话框的标题栏中显示的字符串表达式。如果标题留空,则应用程序名称将放在标题栏中。
Helpfile - 可选参数。一个字符串表达式,标识用于为对话框提供上下文相关帮助的帮助文件。
Context - 可选参数。一个数值表达式,标识帮助作者分配给相应帮助主题的帮助上下文编号。如果提供了 context,则也必须提供 helpfile。
Buttons 参数可以采用以下任何值:
0 vbOKOnly - 只显示“确定”按钮。
1 vbOKCancel - 显示“确定”和“取消”按钮。
2 vbAbortRetryIgnore - 显示“中止”、“重试”和“忽略”按钮。
3 vbYesNoCancel - 显示“是”、“否”和“取消”按钮。
4 vbYesNo - 显示“是”和“否”按钮。
5 vbRetryCancel - 显示“重试”和“取消”按钮。
16 vbCritical - 显示严重错误消息图标。
32 vbQuestion - 显示警告查询图标。
48 vbExclamation - 显示警告消息图标。
64 vbInformation - 显示信息消息图标。
0 vbDefaultButton1 - 第一个按钮为默认按钮。
256 vbDefaultButton2 - 第二个按钮为默认按钮。
512 vbDefaultButton3 - 第三个按钮为默认按钮。
768 vbDefaultButton4 - 第四个按钮为默认按钮。
0 vbApplicationModal 应用程序模式 - 在用户响应消息框之前,当前应用程序将无法工作。
4096 vbSystemModal 系统模式 - 在用户响应消息框之前,所有应用程序都将无法工作。
上述值在逻辑上分为四组:第一组(0 到 5)指示要在消息框中显示的按钮。第二组(16、32、48、64)描述要显示的图标的样式,第三组(0、256、512、768)指示哪个按钮必须是默认按钮,第四组(0、4096)确定消息框的模式。
返回值
MsgBox 函数可以返回以下值之一,这些值可用于识别用户在消息框中单击的按钮。
- 1 - vbOK - 单击了“确定”
- 2 - vbCancel - 单击了“取消”
- 3 - vbAbort - 单击了“中止”
- 4 - vbRetry - 单击了“重试”
- 5 - vbIgnore - 单击了“忽略”
- 6 - vbYes - 单击了“是”
- 7 - vbNo - 单击了“否”
示例
Function MessageBox_Demo() 'Message Box with just prompt message MsgBox("Welcome") 'Message Box with title, yes no and cancel Butttons int a = MsgBox("Do you like blue color?",3,"Choose options") ' Assume that you press No Button msgbox ("The Value of a is " & a) End Function
输出
步骤 1 - 以上函数可以通过单击 VBA 窗口上的“运行”按钮或从 Excel 工作表调用函数来执行,如下面的屏幕截图所示。
步骤 2 - 显示一个简单的消息框,其中包含消息“欢迎”和“确定”按钮。
步骤 3 - 单击“确定”后,将显示另一个对话框,其中包含消息以及“是”、“否”和“取消”按钮。
步骤 4 - 单击“否”按钮后,该按钮的值 (7) 将存储为整数,并作为消息框显示给用户,如下面的屏幕截图所示。使用此值,可以了解用户单击了哪个按钮。
VBA - InputBox
InputBox 函数提示用户输入值。输入值后,如果用户单击“确定”按钮或按键盘上的 ENTER 键,InputBox 函数将返回文本框中的文本。如果用户单击“取消”按钮,则该函数将返回空字符串 (“”)。
语法
InputBox(prompt[,title][,default][,xpos][,ypos][,helpfile,context])
参数说明
Prompt - 必需参数。在对话框中显示为消息的字符串。提示的最大长度约为 1024 个字符。如果消息超过一行,则可以使用回车符 (Chr(13)) 或换行符 (Chr(10)) 在每一行之间分隔行。
Title - 可选参数。在对话框的标题栏中显示的字符串表达式。如果标题留空,则应用程序名称将放在标题栏中。
Default - 可选参数。文本框中的默认文本,用户希望显示。
XPos − 可选参数。X 轴的位置表示提示框距离屏幕左侧水平方向的距离。如果留空,则输入框水平居中。
YPos − 可选参数。Y 轴的位置表示提示框距离屏幕左侧垂直方向的距离。如果留空,则输入框垂直居中。
Helpfile − 可选参数。一个字符串表达式,用于标识用于为对话框提供上下文相关帮助的帮助文件。
context − 可选参数。一个数值表达式,标识帮助作者分配给相应帮助主题的帮助上下文编号。如果提供 context,则也必须提供 helpfile。
示例
让我们通过在运行时使用两个输入框(一个用于长度,一个用于宽度)从用户处获取值来计算矩形的面积。
Function findArea() Dim Length As Double Dim Width As Double Length = InputBox("Enter Length ", "Enter a Number") Width = InputBox("Enter Width", "Enter a Number") findArea = Length * Width End Function
输出
步骤 1 − 为执行此操作,请使用函数名称调用并按 Enter 键,如下面的屏幕截图所示。
步骤 2 − 执行后,将显示第一个输入框(长度)。在输入框中输入一个值。
步骤 3 − 输入第一个值后,将显示第二个输入框(宽度)。
步骤 4 − 输入第二个数字后,单击“确定”按钮。面积将显示在下面的屏幕截图中。
VBA - 变量
变量是用于保存值的命名内存位置,该值可以在脚本执行期间更改。以下是变量命名的基本规则。
必须使用字母作为第一个字符。
不能使用空格、句点 (.)、感叹号 (!) 或字符 @、&、$、# 作为名称的一部分。
名称长度不能超过 255 个字符。
不能使用 Visual Basic 保留关键字作为变量名。
语法
在 VBA 中,需要在使用变量之前声明它们。
Dim <<variable_name>> As <<variable_type>>
数据类型
VBA 有许多数据类型,可以分为两大类:数值数据类型和非数值数据类型。
数值数据类型
下表显示了数值数据类型和允许的值范围。
类型 | 值范围 |
---|---|
Byte | 0 到 255 |
Integer | -32,768 到 32,767 |
Long | -2,147,483,648 到 2,147,483,648 |
Single |
负值:-3.402823E+38 到 -1.401298E-45 正值:1.401298E-45 到 3.402823E+38 |
Double |
负值:-1.79769313486232e+308 到 -4.94065645841247E-324 正值:4.94065645841247E-324 到 1.79769313486232e+308 |
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 (28 位小数) |
非数值数据类型
下表显示了非数值数据类型和允许的值范围。
类型 | 值范围 |
---|---|
String(固定长度) | 1 到 65,400 个字符 |
String(可变长度) | 0 到 20 亿个字符 |
Date | 100 年 1 月 1 日到 9999 年 12 月 31 日 |
Boolean | True 或 False |
Object | 任何嵌入对象 |
Variant(数值) | 任何与 Double 类型一样大的值 |
Variant(文本) | 与可变长度字符串相同 |
示例
让我们创建一个按钮,并将其命名为“Variables_demo”以演示变量的使用。
Private Sub say_helloworld_Click() Dim password As String password = "Admin#1" Dim num As Integer num = 1234 Dim BirthDay As Date BirthDay = DateValue("30 / 10 / 2020") MsgBox "Passowrd is " & password & Chr(10) & "Value of num is " & num & Chr(10) & "Value of Birthday is " & BirthDay End Sub
输出
执行脚本后,输出将如下面的屏幕截图所示。
VBA - 常量
常量是用于保存值的命名内存位置,在脚本执行期间**不能**更改。如果用户尝试更改常量的值,则脚本执行将导致错误。常量的声明方式与变量的声明方式相同。
以下是常量命名的规则。(与变量命名规则相同)
必须使用字母作为第一个字符。
不能使用空格、句点 (.)、感叹号 (!) 或字符 @、&、$、# 作为名称的一部分。
名称长度不能超过 255 个字符。
不能使用 Visual Basic 保留关键字作为变量名。
语法
在 VBA 中,我们需要为已声明的常量赋值。如果我们尝试更改常量的值,则会抛出错误。
Const <<constant_name>> As <<constant_type>> = <<constant_value>>
示例
让我们创建一个名为“Constant_demo”的按钮来演示如何使用常量。
Private Sub Constant_demo_Click() Const MyInteger As Integer = 42 Const myDate As Date = #2/2/2020# Const myDay As String = "Sunday" MsgBox "Integer is " & MyInteger & Chr(10) & "myDate is " & myDate & Chr(10) & "myDay is " & myDay End Sub
输出
执行脚本后,输出将如下面的屏幕截图所示。
VBA - 运算符
运算符可以使用简单的表达式来定义 - 4 + 5 等于 9。这里,4 和 5 称为操作数,+ 称为运算符。VBA 支持以下类型的运算符:
- 算术运算符
- 比较运算符
- 逻辑(或关系)运算符
- 连接运算符
算术运算符
VBA 支持以下算术运算符。
假设变量 A 保存 5,变量 B 保存 10,则:
运算符 | 描述 | 示例 |
---|---|---|
+ | 将两个操作数相加 | A + B 将得到 15 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -5 |
* | 将两个操作数相乘 | A * B 将得到 50 |
/ | 将分子除以分母 | B / A 将得到 2 |
% | 取模运算符,返回整数除法的余数 | B % A 将得到 0 |
^ | 指数运算符 | B ^ A 将得到 100000 |
比较运算符
VBA 支持以下比较运算符。
假设变量 A 保存 10,变量 B 保存 20,则:
运算符 | 描述 | 示例 |
---|---|---|
= | 检查两个操作数的值是否相等。如果相等,则条件为真。 | (A = B) 为假。 |
<> | 检查两个操作数的值是否相等。如果不相等,则条件为真。 | (A <> B) 为真。 |
> | 检查左侧操作数的值是否大于右侧操作数的值。如果是,则条件为真。 | (A > B) 为假。 |
< | 检查左侧操作数的值是否小于右侧操作数的值。如果是,则条件为真。 | (A < B) 为真。 |
>= | 检查左侧操作数的值是否大于或等于右侧操作数的值。如果是,则条件为真。 | (A >= B) 为假。 |
<= | 检查左侧操作数的值是否小于或等于右侧操作数的值。如果是,则条件为真。 | (A <= B) 为真。 |
逻辑运算符
VBA 支持以下逻辑运算符。
假设变量 A 保存 10,变量 B 保存 0,则:
运算符 | 描述 | 示例 |
---|---|---|
AND | 称为逻辑 AND 运算符。如果两个条件都为真,则表达式为真。 | a<>0 AND b<>0 为假。 |
OR | 称为逻辑 OR 运算符。如果两个条件中的任何一个为真,则条件为真。 | a<>0 OR b<>0 为真。 |
NOT | 称为逻辑 NOT 运算符。用于反转其操作数的逻辑状态。如果一个条件为真,则逻辑 NOT 运算符将使其为假。 | NOT(a<>0 OR b<>0) 为假。 |
XOR | 称为逻辑异或。它是 NOT 和 OR 运算符的组合。如果只有一个表达式计算结果为真,则结果为真。 | (a<>0 XOR b<>0) 为真。 |
连接运算符
VBA 支持以下连接运算符。
假设变量 A 保存 5,变量 B 保存 10,则:
运算符 | 描述 | 示例 |
---|---|---|
+ | 将两个值作为变量相加。值是数值型。 | A + B 将得到 15 |
& | 连接两个值。 | A & B 将得到 510 |
假设变量 A = "Microsoft" 和变量 B = "VBScript",则:
运算符 | 描述 | 示例 |
---|---|---|
+ | 连接两个值。 | A + B 将得到 MicrosoftVBScript |
& | 连接两个值。 | A & B 将得到 MicrosoftVBScript |
注意 − 连接运算符可用于数字和字符串。输出取决于上下文,即变量保存的是数值还是字符串值。
VBA - 决策
决策允许程序员控制脚本或其一部分的执行流程。执行由一个或多个条件语句控制。
以下是大多数编程语言中典型的决策结构的一般形式。
VBA 提供以下类型的决策语句。单击以下链接以查看其详细信息。
序号 | 语句和描述 |
---|---|
1 |
if 语句
if 语句由一个布尔表达式和一个或多个语句组成。 |
2 |
if..else 语句
if else 语句由一个布尔表达式和一个或多个语句组成。如果条件为真,则执行If语句下的语句。如果条件为假,则执行脚本的Else部分。 |
3 |
if...elseif..else 语句
一个if语句,后跟一个或多个ElseIf语句,这些语句由布尔表达式组成,然后后跟一个可选的else语句,当所有条件都为假时执行该语句。 |
4 |
嵌套 if 语句
另一个if或elseif语句中的if或elseif语句。 |
5 |
switch 语句
switch语句允许测试变量与值列表的相等性。 |
VBA - 循环
可能需要多次执行代码块的情况。通常情况下,语句是按顺序执行的:函数中的第一个语句首先执行,然后是第二个语句,依此类推。
编程语言提供了各种控制结构,允许更复杂的执行路径。
循环语句允许我们多次执行语句或语句组。以下是 VBA 中循环语句的一般形式。
VBA 提供以下类型的循环来处理循环需求。单击以下链接以查看其详细信息。
序号 | 循环类型和描述 |
---|---|
1 |
for 循环
多次执行一系列语句,并缩写管理循环变量的代码。 |
2 |
for ..each 循环
如果组中至少有一个元素,则执行此循环,并为组中的每个元素重复执行。 |
3 |
while..wend 循环
在执行循环体之前测试条件。 |
4 |
do..while 循环
只要条件为真,就执行 do..While 语句。(即) 循环应重复执行,直到条件为假。 |
5 |
do..until 循环
只要条件为假,就执行 do..Until 语句。(即) 循环应重复执行,直到条件为真。 |
循环控制语句
循环控制语句会改变其正常的执行顺序。当执行离开作用域时,循环中所有剩余的语句都不会执行。
VBA 支持以下控制语句。单击以下链接以查看其详细信息。
序号 | 控制语句和描述 |
---|---|
1 |
Exit For 语句
终止For循环语句,并将执行转移到紧跟在循环后面的语句。 |
2 |
Exit Do 语句
终止Do While语句,并将执行转移到循环后紧跟的语句。 |
VBA - 字符串
字符串是由字符组成的序列,可以包含字母、数字、特殊字符或所有这些字符。如果一个变量用双引号 " " 括起来,则称其为字符串。
语法
variablename = "string"
示例
str1 = "string" ' Only Alphabets str2 = "132.45" ' Only Numbers str3 = "!@#$;*" ' Only Special Characters Str4 = "Asc23@#" ' Has all the above
字符串函数
VBA 提供了预定义的字符串函数,帮助开发人员更有效地处理字符串。以下是 VBA 支持的字符串方法。请点击每个方法以了解更多详情。
序号 | 函数名称及描述 |
---|---|
1 |
InStr
返回指定子字符串的第一次出现位置。搜索从左到右进行。 |
2 |
InstrRev
返回指定子字符串的第一次出现位置。搜索从右到左进行。 |
3 |
Lcase
返回指定字符串的小写形式。 |
4 |
Ucase
返回指定字符串的大写形式。 |
5 | Left
返回字符串左侧指定数量的字符。 |
6 | Right
返回字符串右侧指定数量的字符。 |
7 |
Mid
根据指定的参数返回字符串中指定数量的字符。 |
8 |
Ltrim
返回删除指定字符串左侧空格后的字符串。 |
9 |
Rtrim
返回删除指定字符串右侧空格后的字符串。 |
10 |
Trim
返回删除开头和结尾空格后的字符串值。 |
11 |
Len
返回给定字符串的长度。 |
12 |
Replace
用另一个字符串替换字符串后返回一个字符串。 |
13 |
Space
用指定数量的空格填充字符串。 |
14 |
StrComp
比较两个指定的字符串后返回一个整数值。 |
15 |
String
返回一个字符串,其中包含指定字符,重复指定次数。 |
16 |
StrReverse
反转给定字符串的字符序列后返回一个字符串。 |
VBA - 日期时间函数
VBScript 日期和时间函数帮助开发人员将日期和时间从一种格式转换为另一种格式,或者以适合特定条件的格式表达日期或时间值。
日期函数
序号 | 函数及描述 |
---|---|
1 |
Date
返回当前系统日期的函数。 |
2 |
CDate
将给定输入转换为日期的函数。 |
3 |
DateAdd
返回添加指定时间间隔后的日期的函数。 |
4 |
DateDiff
返回两个时间段之间差值的函数。 |
5 |
DatePart
返回给定输入日期值的指定部分的函数。 |
6 |
DateSerial
为给定的年份、月份和日期返回有效日期的函数。 |
7 |
FormatDateTime
根据提供的参数格式化日期的函数。 |
8 |
IsDate
返回布尔值,指示提供的参数是否为日期的函数。 |
9 |
Day
返回表示指定日期的天数的 1 到 31 之间的整数的函数。 |
10 |
Month
返回表示指定日期的月份的 1 到 12 之间的整数的函数。 |
11 |
Year
返回表示指定日期的年份的整数的函数。 |
12 |
MonthName
返回指定日期的特定月份名称的函数。 |
13 |
WeekDay
返回表示指定日期的星期几的整数 (1 到 7) 的函数。 |
14 |
WeekDayName
返回指定日期的星期几名称的函数。 |
时间函数
序号 | 函数及描述 |
---|---|
1 |
Now
返回当前系统日期和时间的函数。 |
2 |
Hour
返回表示给定时间的小时部分的 0 到 23 之间的整数的函数。 |
3 |
Minute
返回表示给定时间的分钟部分的 0 到 59 之间的整数的函数。 |
4 | Second
返回表示给定时间的秒部分的 0 到 59 之间的整数的函数。 |
5 | Time
返回当前系统时间的函数。 |
6 |
Timer
返回自凌晨 12:00 以来经过的秒数和毫秒数的函数。 |
7 |
TimeSerial
为指定的小时、分钟和秒返回时间的函数。 |
8 |
TimeValue
将输入字符串转换为时间格式的函数。 |
VBA - 数组
我们非常清楚,变量是用于存储值的容器。有时,开发人员需要一次在一个变量中保存多个值。当一系列值存储在一个变量中时,它被称为数组变量。
数组声明
数组的声明方式与变量的声明方式相同,只是数组变量的声明使用括号。在下面的示例中,数组的大小在括号中指定。
'Method 1 : Using Dim Dim arr1() 'Without Size 'Method 2 : Mentioning the Size Dim arr2(5) 'Declared with size of 5 'Method 3 : using 'Array' Parameter Dim arr3 arr3 = Array("apple","Orange","Grapes")
虽然数组大小指示为 5,但它可以容纳 6 个值,因为数组索引从零开始。
数组索引不能为负数。
VBScript 数组可以在数组中存储任何类型的变量。因此,一个数组可以在单个数组变量中存储整数、字符串或字符。
向数组赋值
通过为每个要赋值的值指定数组索引值来为数组赋值。它可以是字符串。
示例
添加一个按钮并添加以下函数。
Private Sub Constant_demo_Click() Dim arr(5) arr(0) = "1" 'Number as String arr(1) = "VBScript" 'String arr(2) = 100 'Number arr(3) = 2.45 'Decimal Number arr(4) = #10/07/2013# 'Date arr(5) = #12.45 PM# 'Time msgbox("Value stored in Array index 0 : " & arr(0)) msgbox("Value stored in Array index 1 : " & arr(1)) msgbox("Value stored in Array index 2 : " & arr(2)) msgbox("Value stored in Array index 3 : " & arr(3)) msgbox("Value stored in Array index 4 : " & arr(4)) msgbox("Value stored in Array index 5 : " & arr(5)) End Sub
执行上述函数时,会产生以下输出。
Value stored in Array index 0 : 1 Value stored in Array index 1 : VBScript Value stored in Array index 2 : 100 Value stored in Array index 3 : 2.45 Value stored in Array index 4 : 7/10/2013 Value stored in Array index 5 : 12:45:00 PM
多维数组
数组不仅限于一维,但最多可以有 60 维。二维数组是最常用的数组。
示例
在下面的示例中,声明了一个具有 3 行 4 列的多维数组。
Private Sub Constant_demo_Click() Dim arr(2,3) as Variant ' Which has 3 rows and 4 columns arr(0,0) = "Apple" arr(0,1) = "Orange" arr(0,2) = "Grapes" arr(0,3) = "pineapple" arr(1,0) = "cucumber" arr(1,1) = "beans" arr(1,2) = "carrot" arr(1,3) = "tomato" arr(2,0) = "potato" arr(2,1) = "sandwitch" arr(2,2) = "coffee" arr(2,3) = "nuts" msgbox("Value in Array index 0,1 : " & arr(0,1)) msgbox("Value in Array index 2,2 : " & arr(2,2)) End Sub
执行上述函数时,会产生以下输出。
Value stored in Array index : 0 , 1 : Orange Value stored in Array index : 2 , 2 : coffee
ReDim 语句
ReDim 语句用于声明动态数组变量并分配或重新分配存储空间。
语法
ReDim [Preserve] varname(subscripts) [, varname(subscripts)]
参数说明
Preserve - 一个可选参数,用于在更改最后一维的大小是保留现有数组中的数据。
Varname - 一个必需参数,表示变量的名称,应遵循标准变量命名约定。
Subscripts - 一个必需参数,指示数组的大小。
示例
在下面的示例中,重新定义了一个数组,然后在更改数组的现有大小时保留这些值。
注意 - 将数组大小调整为小于其原始大小后,已删除元素中的数据将丢失。
Private Sub Constant_demo_Click() Dim a() as variant i = 0 redim a(5) a(0) = "XYZ" a(1) = 41.25 a(2) = 22 REDIM PRESERVE a(7) For i = 3 to 7 a(i) = i Next 'to Fetch the output For i = 0 to ubound(a) Msgbox a(i) Next End Sub
执行上述函数时,会产生以下输出。
XYZ 41.25 22 3 4 5 6 7
数组方法
VBScript 中有各种内置函数,可以帮助开发人员有效地处理数组。下面列出了与数组一起使用的所有方法。请点击方法名称以了解详细信息。
序号 | 函数及描述 |
---|---|
1 |
LBound
返回与给定数组的最小下标对应的整数的函数。 |
2 |
UBound
返回与给定数组的最大下标对应的整数的函数。 |
3 |
Split
返回包含指定数量值的数组的函数。基于分隔符进行分割。 |
4 |
Join
返回包含数组中指定数量的子字符串的字符串的函数。这是 Split 方法的完全相反的函数。 |
5 |
Filter
返回一个基于零的数组,该数组包含基于特定筛选条件的字符串数组的子集。 |
6 |
IsArray
返回布尔值,指示输入变量是否为数组的函数。 |
7 |
Erase
回收数组变量已分配内存的函数。 |
VBA - 用户自定义函数
函数是一组可重用的代码,可以在程序中的任何位置调用。这消除了重复编写相同代码的需要。这使程序员能够将大型程序划分为许多小型且易于管理的函数。
除了内置函数外,VBA 还允许编写用户自定义函数。在本节中,您将学习如何在 VBA 中编写自己的函数。
函数定义
VBA 函数可以有一个可选的 return 语句。如果您想从函数返回一个值,则需要此语句。
例如,您可以将两个数字传递给函数,然后您可以期望函数在您的调用程序中返回它们的乘积。
注意 - 函数可以返回多个值,这些值以逗号分隔,作为分配给函数名本身的数组。
在使用函数之前,我们需要定义该函数。在 VBA 中定义函数最常见的方法是使用Function关键字,后跟唯一的函数名,它可以包含或不包含参数列表和带有End Function关键字的语句,该语句指示函数的结束。以下是基本语法。
语法
添加一个按钮并添加以下函数。
Function Functionname(parameter-list) statement 1 statement 2 statement 3 ....... statement n End Function
示例
添加以下返回面积的函数。请注意,可以使用函数名本身返回值/值。
Function findArea(Length As Double, Optional Width As Variant) If IsMissing(Width) Then findArea = Length * Length Else findArea = Length * Width End If End Function
调用函数
要调用函数,请使用函数名调用函数,如下面的屏幕截图所示。
如下所示的面积输出将显示给用户。
VBA - 子过程
Sub 过程类似于函数,但有一些区别。
Sub 过程不返回值,而函数可以返回值也可以不返回值。
Sub 过程可以不使用 call 关键字进行调用。
Sub 过程始终包含在 Sub 和 End Sub 语句中。
示例
Sub Area(x As Double, y As Double) MsgBox x * y End Sub
调用过程
要在脚本中的某个位置调用过程,您可以从函数进行调用。我们无法像函数那样使用相同的方式,因为 Sub 过程不会返回值。
Function findArea(Length As Double, Width As Variant) area Length, Width ' To Calculate Area 'area' sub proc is called End Function
现在您只能调用函数,而不能调用 Sub 过程,如下面的屏幕截图所示。
面积计算结果仅在消息框中显示。
结果单元格显示零,因为面积值没有从函数返回。简而言之,您无法从 Excel 工作表直接调用 Sub 过程。
VBA - 事件
VBA 是一种事件驱动的编程,当您手动更改单元格或单元格值范围时可以触发。更改事件可以使事情更容易,但是您可以很快结束一页的格式设置。事件有两种。
- 工作表事件
- 工作簿事件
工作表事件
当工作表发生更改时,会触发工作表事件。它是通过右键单击工作表标签并选择“查看代码”,然后粘贴代码来创建的。
用户可以选择这些工作表中的每一个,并从下拉菜单中选择“工作表”以获取所有受支持的工作表事件列表。
以下是用户可以添加的受支持的工作表事件。
Private Sub Worksheet_Activate() Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) Private Sub Worksheet_Calculate() Private Sub Worksheet_Change(ByVal Target As Range) Private Sub Worksheet_Deactivate() Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink) Private Sub Worksheet_SelectionChange(ByVal Target As Range)
示例
假设我们只需要在双击之前显示一条消息。
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) MsgBox "Before Double Click" End Sub
输出
双击任何单元格时,会向用户显示消息框,如下面的屏幕截图所示。
工作簿事件
当整个工作簿发生更改时,会触发工作簿事件。我们可以通过选择“ThisWorkbook”并从下拉菜单中选择“工作簿”来添加工作簿事件的代码,如下面的屏幕截图所示。立即向用户显示 Workbook_open 子过程,如下面的屏幕截图所示。
以下是用户可以添加的受支持的工作簿事件。
Private Sub Workbook_AddinUninstall() Private Sub Workbook_BeforeClose(Cancel As Boolean) Private Sub Workbook_BeforePrint(Cancel As Boolean) Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Private Sub Workbook_Deactivate() Private Sub Workbook_NewSheet(ByVal Sh As Object) Private Sub Workbook_Open() Private Sub Workbook_SheetActivate(ByVal Sh As Object) Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) Private Sub Workbook_SheetCalculate(ByVal Sh As Object) Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) Private Sub Workbook_SheetDeactivate(ByVal Sh As Object) Private Sub Workbook_SheetFollowHyperlink(ByVal Sh As Object, ByVal Target As Hyperlink) Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range) Private Sub Workbook_WindowActivate(ByVal Wn As Window) Private Sub Workbook_WindowDeactivate(ByVal Wn As Window) Private Sub Workbook_WindowResize(ByVal Wn As Window)
示例
假设我们只需要在创建新工作表时向用户显示一条消息,指示新工作表已成功创建。
Private Sub Workbook_NewSheet(ByVal Sh As Object) MsgBox "New Sheet Created Successfully" End Sub
输出
创建新的 Excel 工作表时,会向用户显示一条消息,如下面的屏幕截图所示。
VBA - 错误处理
编程中存在三种类型的错误:(a)语法错误,(b)运行时错误和(c)逻辑错误。
语法错误
语法错误,也称为解析错误,发生在VBScript的解释时间。例如,以下行会导致语法错误,因为它缺少一个右括号。
Function ErrorHanlding_Demo() dim x,y x = "Tutorialspoint" y = Ucase(x End Function
运行时错误
运行时错误,也称为异常,发生在解释之后,执行期间。
例如,以下行会导致运行时错误,因为这里的语法是正确的,但在运行时它试图调用fnmultiply,这是一个不存在的函数。
Function ErrorHanlding_Demo1() Dim x,y x = 10 y = 20 z = fnadd(x,y) a = fnmultiply(x,y) End Function Function fnadd(x,y) fnadd = x + y End Function
逻辑错误
逻辑错误可能是最难追踪的错误类型。这些错误不是语法错误或运行时错误的结果。相反,当你在驱动脚本的逻辑中犯错并且没有得到你期望的结果时,就会发生这些错误。
你无法捕获这些错误,因为这取决于你的业务需求,你想要在你的程序中使用什么样的逻辑。
例如,将一个数字除以零,或编写一个进入无限循环的脚本。
Err对象
假设如果我们有一个运行时错误,那么执行将停止并显示错误消息。作为开发者,如果我们想捕获错误,则使用Err对象。
示例
在下面的例子中,Err.Number给出错误号,Err.Description给出错误描述。
Err.Raise 6 ' Raise an overflow error. MsgBox "Error # " & CStr(Err.Number) & " " & Err.Description Err.Clear ' Clear the error.
错误处理
VBA启用错误处理例程,也可以用于禁用错误处理例程。如果没有On Error语句,发生的任何运行时错误都是致命的:会显示一条错误消息,并且执行会突然停止。
On Error { GoTo [ line | 0 | -1 ] | Resume Next }
序号 | 关键字及说明 |
---|---|
1 |
GoTo line 启用从required line参数中指定的行开始的错误处理例程。指定的行必须与On Error语句位于相同的过程中,否则将发生编译时错误。 |
2 |
GoTo 0 禁用当前过程中启用的错误处理程序并将其重置为Nothing。 |
3 |
GoTo -1 禁用当前过程中启用的异常并将其重置为Nothing。 |
4 |
Resume Next 指定当发生运行时错误时,控制权将转到发生错误的语句后面的语句,并从该点继续执行。 |
示例
Public Sub OnErrorDemo() On Error GoTo ErrorHandler ' Enable error-handling routine. Dim x, y, z As Integer x = 50 y = 0 z = x / y ' Divide by ZERO Error Raises ErrorHandler: ' Error-handling routine. Select Case Err.Number ' Evaluate error number. Case 10 ' Divide by zero error MsgBox ("You attempted to divide by zero!") Case Else MsgBox "UNKNOWN ERROR - Error# " & Err.Number & " : " & Err.Description End Select Resume Next End Sub
VBA - Excel 对象
使用VBA编程时,用户会处理一些重要的对象。
- 应用程序对象
- 工作簿对象
- 工作表对象
- 区域对象
应用程序对象
Application对象包含以下内容:
- 应用程序范围的设置和选项。
- 返回顶级对象的方法,例如ActiveCell、ActiveSheet等等。
示例
'Example 1 : Set xlapp = CreateObject("Excel.Sheet") xlapp.Application.Workbooks.Open "C:\test.xls" 'Example 2 : Application.Windows("test.xls").Activate 'Example 3: Application.ActiveCell.Font.Bold = True
工作簿对象
Workbook对象是Workbooks集合的成员,包含当前在Microsoft Excel中打开的所有Workbook对象。
示例
'Ex 1 : To close Workbooks Workbooks.Close 'Ex 2 : To Add an Empty Work Book Workbooks.Add 'Ex 3: To Open a Workbook Workbooks.Open FileName:="Test.xls", ReadOnly:=True 'Ex : 4 - To Activate WorkBooks Workbooks("Test.xls").Worksheets("Sheet1").Activate
工作表对象
Worksheet对象是Worksheets集合的成员,包含工作簿中的所有Worksheet对象。
示例
'Ex 1 : To make it Invisible Worksheets(1).Visible = False 'Ex 2 : To protect an WorkSheet Worksheets("Sheet1").Protect password:=strPassword, scenarios:=True
区域对象
Range对象表示一个单元格、一行、一列或包含一个或多个连续单元格块的单元格选择。
'Ex 1 : To Put a value in the cell A5 Worksheets("Sheet1").Range("A5").Value = "5235" 'Ex 2 : To put a value in range of Cells Worksheets("Sheet1").Range("A1:A4").Value = 5
VBA - 文本文件
您还可以使用VBA读取Excel文件并将单元格内容写入文本文件。VBA允许用户使用两种方法处理文本文件:
- 文件系统对象
- 使用Write命令
文件系统对象 (FSO)
顾名思义,FSO帮助开发人员处理驱动器、文件夹和文件。在本节中,我们将讨论如何使用FSO。
序号 | 对象类型及说明 |
---|---|
1 |
驱动器 (Drive) Drive是一个对象。包含允许您收集有关连接到系统的驱动器的信息的方法和属性。 |
2 |
驱动器集合 (Drives) Drives是一个集合。它提供连接到系统的驱动器的列表,无论是物理的还是逻辑的。 |
3 |
文件 (File) File是一个对象。它包含允许开发人员创建、删除或移动文件的方法和属性。 |
4 |
文件集合 (Files) Files是一个集合。它提供文件夹中包含的所有文件的列表。 |
5 |
文件夹 (Folder) Folder是一个对象。它提供允许开发人员创建、删除或移动文件夹的方法和属性。 |
6 |
文件夹集合 (Folders) Folders是一个集合。它提供文件夹中所有文件夹的列表。 |
7 |
文本流 (TextStream) TextStream是一个对象。它使开发人员能够读取和写入文本文件。 |
驱动器 (Drive)
Drive是一个对象,它提供对特定磁盘驱动器或网络共享的属性的访问。Drive对象支持以下属性:
- 可用空间 (AvailableSpace)
- 驱动器号 (DriveLetter)
- 驱动器类型 (DriveType)
- 文件系统 (FileSystem)
- 可用空间 (FreeSpace)
- 就绪状态 (IsReady)
- 路径 (Path)
- 根文件夹 (RootFolder)
- 序列号 (SerialNumber)
- 共享名 (ShareName)
- 总大小 (TotalSize)
- 卷标 (VolumeName)
示例
步骤1 - 在继续使用FSO进行脚本编写之前,我们应该启用Microsoft Scripting Runtime。为此,请导航到工具→引用,如下面的屏幕截图所示。
步骤2 - 添加“Microsoft Scripting RunTime”并单击“确定”。
步骤3 - 添加要写入文本文件的数据并添加一个命令按钮。
步骤4 - 现在是编写脚本的时候了。
Private Sub fn_write_to_text_Click() Dim FilePath As String Dim CellData As String Dim LastCol As Long Dim LastRow As Long Dim fso As FileSystemObject Set fso = New FileSystemObject Dim stream As TextStream LastCol = ActiveSheet.UsedRange.Columns.Count LastRow = ActiveSheet.UsedRange.Rows.Count ' Create a TextStream. Set stream = fso.OpenTextFile("D:\Try\Support.log", ForWriting, True) CellData = "" For i = 1 To LastRow For j = 1 To LastCol CellData = Trim(ActiveCell(i, j).Value) stream.WriteLine "The Value at location (" & i & "," & j & ")" & CellData Next j Next i stream.Close MsgBox ("Job Done") End Sub
输出
执行脚本时,请确保将光标放在工作表的第一个单元格中。“D:\Try”下创建Support.log文件,如下面的屏幕截图所示。
文件内容如下面的屏幕截图所示。
Write命令
与FSO不同,我们不需要添加任何引用,但是,我们将无法处理驱动器、文件和文件夹。我们只能将流添加到文本文件。
示例
Private Sub fn_write_to_text_Click() Dim FilePath As String Dim CellData As String Dim LastCol As Long Dim LastRow As Long LastCol = ActiveSheet.UsedRange.Columns.Count LastRow = ActiveSheet.UsedRange.Rows.Count FilePath = "D:\Try\write.txt" Open FilePath For Output As #2 CellData = "" For i = 1 To LastRow For j = 1 To LastCol CellData = "The Value at location (" & i & "," & j & ")" & Trim(ActiveCell(i, j).Value) Write #2, CellData Next j Next i Close #2 MsgBox ("Job Done") End Sub
输出
执行脚本后,“D:\Try”位置将创建“write.txt”文件,如下面的屏幕截图所示。
文件内容如下面的屏幕截图所示。
VBA - 图表编程
使用VBA,您可以根据特定条件生成图表。让我们通过一个例子来看一下。
步骤1 - 输入要生成图表的数据。
步骤2 - 创建3个按钮 - 一个生成条形图,另一个生成饼图,另一个生成柱状图。
步骤3 - 开发一个宏来生成每种类型的图表。
' Procedure to Generate Pie Chart Private Sub fn_generate_pie_graph_Click() Dim cht As ChartObject For Each cht In Worksheets(1).ChartObjects cht.Chart.Type = xlPie Next cht End Sub ' Procedure to Generate Bar Graph Private Sub fn_Generate_Bar_Graph_Click() Dim cht As ChartObject For Each cht In Worksheets(1).ChartObjects cht.Chart.Type = xlBar Next cht End Sub ' Procedure to Generate Column Graph Private Sub fn_generate_column_graph_Click() Dim cht As ChartObject For Each cht In Worksheets(1).ChartObjects cht.Chart.Type = xlColumn Next cht End Sub
步骤4 - 单击相应的按钮,将创建图表。在下面的输出中,单击“生成饼图”按钮。
VBA - 用户窗体
用户窗体是一个自定义的对话框,它使用户数据输入更可控,更容易使用。在本节中,您将学习如何设计一个简单的窗体并将数据添加到Excel中。
步骤1 - 按Alt+F11导航到VBA窗口,然后导航到“插入”菜单并选择“用户窗体”。选择后,将显示用户窗体,如下面的屏幕截图所示。
步骤2 - 使用给定的控件设计窗体。
步骤3 - 添加每个控件后,必须为控件命名。Caption对应于窗体上显示的内容,name对应于编写该元素的VBA代码时将出现的逻辑名称。
步骤4 - 以下是每个添加控件的名称。
控件 | 逻辑名称 | 标题 |
---|---|---|
窗体 | frmempform | 员工信息表 |
员工ID标签框 | empid | 员工ID |
名字标签框 | firstname | 名字 |
姓氏标签框 | lastname | 姓氏 |
出生日期标签框 | dob | 出生日期 |
邮箱标签框 | mailid | 邮箱 |
持护照标签框 | Passportholder | 持护照 |
员工ID文本框 | txtempid | 不适用 |
名字文本框 | txtfirstname | 不适用 |
姓氏文本框 | txtlastname | 不适用 |
邮箱文本框 | txtemailid | 不适用 |
日期组合框 | cmbdate | 不适用 |
月份组合框 | cmbmonth | 不适用 |
年份组合框 | cmbyear | 不适用 |
是单选按钮 | radioyes | 是 |
否单选按钮 | radiono | 否 |
提交按钮 | btnsubmit | 提交 |
取消按钮 | btncancel | 取消 |
步骤5 - 通过右键单击窗体并选择“查看代码”来添加窗体加载事件的代码。
步骤6 - 从对象下拉列表中选择“用户窗体”,然后选择“Initialize”方法,如下面的屏幕截图所示。
步骤7 - 加载窗体时,确保文本框已清除,下拉框已填充,并且单选按钮已重置。
Private Sub UserForm_Initialize() 'Empty Emp ID Text box and Set the Cursor txtempid.Value = "" txtempid.SetFocus 'Empty all other text box fields txtfirstname.Value = "" txtlastname.Value = "" txtemailid.Value = "" 'Clear All Date of Birth Related Fields cmbdate.Clear cmbmonth.Clear cmbyear.Clear 'Fill Date Drop Down box - Takes 1 to 31 With cmbdate .AddItem "1" .AddItem "2" .AddItem "3" .AddItem "4" .AddItem "5" .AddItem "6" .AddItem "7" .AddItem "8" .AddItem "9" .AddItem "10" .AddItem "11" .AddItem "12" .AddItem "13" .AddItem "14" .AddItem "15" .AddItem "16" .AddItem "17" .AddItem "18" .AddItem "19" .AddItem "20" .AddItem "21" .AddItem "22" .AddItem "23" .AddItem "24" .AddItem "25" .AddItem "26" .AddItem "27" .AddItem "28" .AddItem "29" .AddItem "30" .AddItem "31" End With 'Fill Month Drop Down box - Takes Jan to Dec With cmbmonth .AddItem "JAN" .AddItem "FEB" .AddItem "MAR" .AddItem "APR" .AddItem "MAY" .AddItem "JUN" .AddItem "JUL" .AddItem "AUG" .AddItem "SEP" .AddItem "OCT" .AddItem "NOV" .AddItem "DEC" End With 'Fill Year Drop Down box - Takes 1980 to 2014 With cmbyear .AddItem "1980" .AddItem "1981" .AddItem "1982" .AddItem "1983" .AddItem "1984" .AddItem "1985" .AddItem "1986" .AddItem "1987" .AddItem "1988" .AddItem "1989" .AddItem "1990" .AddItem "1991" .AddItem "1992" .AddItem "1993" .AddItem "1994" .AddItem "1995" .AddItem "1996" .AddItem "1997" .AddItem "1998" .AddItem "1999" .AddItem "2000" .AddItem "2001" .AddItem "2002" .AddItem "2003" .AddItem "2004" .AddItem "2005" .AddItem "2006" .AddItem "2007" .AddItem "2008" .AddItem "2009" .AddItem "2010" .AddItem "2011" .AddItem "2012" .AddItem "2013" .AddItem "2014" End With 'Reset Radio Button. Set it to False when form loads. radioyes.Value = False radiono.Value = False End Sub
步骤8 - 现在将代码添加到“提交”按钮。单击“提交”按钮后,用户应该能够将值添加到工作表中。
Private Sub btnsubmit_Click() Dim emptyRow As Long 'Make Sheet1 active Sheet1.Activate 'Determine emptyRow emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1 'Transfer information Cells(emptyRow, 1).Value = txtempid.Value Cells(emptyRow, 2).Value = txtfirstname.Value Cells(emptyRow, 3).Value = txtlastname.Value Cells(emptyRow, 4).Value = cmbdate.Value & "/" & cmbmonth.Value & "/" & cmbyear.Value Cells(emptyRow, 5).Value = txtemailid.Value If radioyes.Value = True Then Cells(emptyRow, 6).Value = "Yes" Else Cells(emptyRow, 6).Value = "No" End If End Sub
步骤9 - 当用户单击“取消”按钮时,添加一个方法来关闭窗体。
Private Sub btncancel_Click() Unload Me End Sub
步骤10 - 通过单击“运行”按钮来执行窗体。将值输入窗体并单击“提交”按钮。值将自动流入工作表,如下面的屏幕截图所示。