VBA始终是我绕不过的坎,因此利用了一些休息的时间着重的学习了语法。
学习以及运行环境在Office2019 Excel中进行。
VBA和VB语法大致相同底层应该是有差异的,学习VBA之后可以一边看着文档一边尝试VB窗体开发或者操作数据库,个人感受VBA入门比较简单,和其他语言一样,入门简单 精通难 对于我们这个群体而言也没有必要要求自己达到程序员水平;
坊间传言VBA要过时了,未来office中的脚本语言将会被python或者JavaScript替代,可能以后会,但是VBA庞大的用户群体使用习惯不是一朝一夕就能改变的,除过officen内置了VBA 还有WPS 大名鼎鼎的CAD 工控界上位机WINCC FT-View,所以VBA还暂时不会淘汰
不过!
Protal WinCC Unifled是西门子最新的SCADA软件,其脚本语言已变成了JavaScript,IT&OT的界限将逐渐模糊……
比较常用的数据类型主要有整型和浮点型,字符串
说明 | 数据类型 | 简化后的申明符号 | 占用字节数 |
---|---|---|---|
字节型 | Byte | 1 | |
整型 | Integer | % | 2 |
长整型 | Long | & | 4 |
单精度浮点型 | Single | ! | 4 |
双精度浮点型 | Double | # | 8 |
货币型 | Currency | @ | 8 |
字符型 | String | $ | 每字符占1字节 |
布尔型 | Boolean | ||
日期型 | Date | 8 | |
变体型 | Variant | 不确定 | |
对象型 | Object | 4 |
string型是指一切可以打印的字符与字符串
一个西文字符占用一个字节,一个中文占用2字节
边长字符串
随着赋值的变化而改变长度的字符串变量
定长字符串
字符变量在声明时候进行限制 例如: Dim str As String*10
(类型关键字*10 )表示长度为10字节的定长字符串。
可变(Variant)类型数据能够根据赋值对象的类型变化和转换角色。
不建议使用Variant型,容易产生混乱。
类似C语言的结构体(PLC中的UDT),可以自定义数据模板 使用案例如下
1'定义用户数据结构
2Public Type myType
3 member01 As Integer
4 member02 As String
5 member03 As Single
6 member04 As Boolean
7End Type
8
9
10Sub ok()
11
12Dim x As myType'声明用户自定义类型变量 x
13
14'使用该结构体的成员 此处的赋值可以使用with语句处理
15x.member01 = 1234
16x.member02 = 'hello world'
17x.member03 = 3.141593
18x.member04 = True
19
20'输出成员中的值
21MsgBox (x.member01 & x.member02 & x.member03 & x.member04)
22
23End Sub
输出结果如下:
声明枚举时从代码的开头处声明 前面加上Public关键字
枚举成员默认从0开始向后排序,用户可以指定枚举成员的初始值
1Public Enum color
2 red '可以给第一个赋一个初始值 后面成员会自动递增
3 orange
4 yello
5 green
6 blue
7 indigo
8 purple
9End Enum
10
11Sub AAA()
12Dim x As Integer, y As Integer
13x = color.green
14y = color.purple
15
16MsgBox (x & y)'输出 3 6
17End Sub
下例中用Pi
来替代3.141593的值,系统会根据表达式的值决定Pi
的数据类型。
1Const Pi = 3.141593
2Range('C1').Value = Pi
const语句的范围有以下规则:
const a = 100 用于过程
Private const a = 100 私有
Public const a = 100 全局可用
小心:在VB中变量的大小写是不区分的,A1 和 a1对系统来说是同一个变量
变量声明的两种形式:
隐式声明
1Dim x%, y!, z$ '%=整形 ;!=单精度浮点型 ;#=双精度浮点型;$=字符型
显式声明
1Dim x As integer,y As integer 'AS 后面指明数据类型,多个变量之间使用','隔离
小心:不可以将Dim x As integer,y As integer
写成Dim x , y As integer
这个条语句最终会将变量x
视为Variant型数据。
用DIM关键字开头的语句指明该语句是用来声明变量,关键字As后指明变量的数据类型;
1Dim val As Integer'声明一个整型变量
2dim str as string'声明一个字符变量
3dim f1 as Single '声明一个单精度浮点数
数组是非常重要的概念
Dim ArrayName(varNumber) As DataType
下例中使用循环来进行初始化数组 要注意的是声明的数组数量是11个 这一点与其他语言有差异
1Dim i As Integer
2Const lenth = 10
3
4Dim ary(lenth) As Integer
5For i = 1 To lenth
6 ary(i) = i
7 Range('E' & i).Value = ary(i)
8Next i
数组另外一种初始化是直接给成员赋值
1Dim i As Integer
2Const lenth = 10
3
4Dim ary(lenth) As Integer
5
6ary(1) = 111
7ary(3) = 333
8ary(5) = 555
9ary(7) = 777
10
11For i = 1 To lenth
12 Range('E' & i).Value = ary(i)
13Next i
如果用户要自定数组的起始位置和结束位置参考下面的语句
格式 :Dim array(start To End) As DataType
1Sub AAA()
2
3Dim i As Integer
4
5Dim items(1 To 3) As String
6items(1) = 'MainProgram_Pak'
7items(2) = 'Are1_Dev0'
8items(3) = 'MainTask'
9
10For i = 1 To 3
11 Debug.Print items(i)
12Next i
13
14End Sub
15
16'------输出结果------
17'MainProgram_Pak
18'Are1_Dev0
19'MainTask
二维数组
二维数组的使用 通常用行列的概念理解起来会比较容易
1Sub AAA()
2
3Dim i As Integer, j As Integer '定义2个循环变量
4Dim items(1 To 3, 1 To 3) As String '定义一个二维数组
5
6For i = 1 To 3
7 For j = 1 To 3
8 items(i, j) = '我在' & i & '行' & j & '列' '数组初始化
9 Next j
10Next i
11'打印出数组中特定成员中的内容
12Debug.Print items(3, 3)
13Debug.Print items(2, 2)
14Debug.Print items(1, 1)
15
16End Sub
17'
18'----------输出结果---------
19'我在3行3列
20'我在2行2列
21'我在1行1列
三维数组
三维数组 用X Y Z空间坐标系理解起来比较容易 ,
第4行代码定义了一个10的3次方个元素
第7-14行代码对这个三维数组进行初始化
第16-18行代码输出特定元素中的值
第19行代码输出这个三层循环嵌套总循环次数
1Sub AAA()
2Dim cnt%
3Dim i As Integer, j As Integer, k As Integer '定义3个循环变量
4Dim items(1 To 10, 1 To 10, 1 To 10) As String '定义一个三维数组
5cnt = 0
6
7For i = 1 To 10
8 For j = 1 To 10
9 For k = 1 To 10
10 cnt = cnt + 1
11 items(i, j, k) = 'X轴=' & i & ' Y轴=' & j & ' Z轴=' & k
12 Next k
13 Next j
14Next i
15
16Debug.Print items(1, 1, 1)
17Debug.Print items(1, 3, 5)
18Debug.Print items(9, 5, 3)
19Debug.Print '循环次数 = '; cnt
20End Sub
运算符 | 含义 | 示例 |
---|---|---|
+ | 加法运算符 | |
- | 减,取负 | |
* | 乘法运算符 | |
/ | 除法运算符 | |
\ | 整除运算符 | 10\3 = 3 |
MOD | 取模运算 | 10 MOD 3 = 1 |
^ | 乘方运算符 | 22 等于 2^2 = 4 |
优先级 | 运算符 | 说明 |
---|---|---|
1 | () | 所有的表达式中括号中的内容优先级最高 |
2 | ^ | 指数运算 |
3 | - | 取负 |
4 | * / | 乘-除 |
5 | \ | 整除 |
6 | Mod | 取模 |
7 | + - | 加-减 |
关系运算符包括 =, >, <, <>, >=, <=
关系运算符的优先级别小于算数运算符
注意:在关系运算符两侧的变量数据类型必须一致 否则编译报错~
VB中常用的逻辑运算有4种
逻辑运算符 | 含义 | 示例 |
---|---|---|
NOT | 逻辑非 | NOT(X > Y) |
AND | 逻辑与 | x <10 AND Y >20 |
OR | 逻辑或 | If A and B then |
XOR | 逻辑异或 | Ch1 Xor Ch2 |
字符表达式只有一个运算符 ,即连接运算符 '&' 该运算符用于多个字符的拼接
1Const Pi = 3.141593
2Const str1 = 'hello'
3Range('E1').Value = Pi & str1 'EXCEL工作表E1单元格中将被写入内容 3.141593hello
&
运算符还能将非字符串转换成字符串之后才进行拼接
VBE会自动将程序代码中的关键字首字母转换成大写
一行中的多个语句使用:
隔开 (建议换行书写)
1Const Pi = 3.141593 : Const str1 = 'hello'
2Range('E1').Value = Pi & str1 & 'OK'
语句延续 一句写不完情况可以使用 _
续行符
1Const Pi = 3.141593
2Const str1 = 'hello' & _
3'world' & 'OK'
4Range('E1').Value = Pi & str1
参数输入 使用inputBox函数接收来自键盘的数值 配合Val函数,Val函数将字符数字转换成数值
1Dim number As Integer
2number = Val(InputBox('输入参数'))
调试VBA代码过程中可以使用MsgBox +'string'来判断代码阶段性执行结果
1MsgBox 'step = ' & index
另外VB语言中的print方法可以输出窗口,VBA中虽不能弹出窗口但是可以在立即窗口中输出运算结果
Debug.print 'xxx' ; number ; 'yyyy' '多个字段的输出内容使用分号隔开
1Sub AAA()
2Dim i As Integer
3Const lenth = 10
4Dim ary(lenth) As Integer
5
6ary(1) = 111
7ary(3) = 333
8ary(5) = 555
9ary(7) = 777
10
11For i = 1 To lenth
12 Debug.Print 'hello'; ary(i); 'xyxyxy'
13Next i
14
15End Sub
将右侧的结果赋值给左值
1y = x
2a = 1024
Rem注释
1Rem 在此之后的本本皆为注释语句
1x = Pi * D :Rem 在此之后皆为注释 在语句与Rem之间用 ':'隔离
单引号注释('
) 推荐使用单引号注释
1Range('E1').Value = Pi & str1 '我就是单引号注释
一般用于处理对象属性以及结构体成员的初始化
With […………] end With
1Option Explicit
2Public Type myType
3 member01 As Integer
4 member02 As String
5 member03 As Single
6 member04 As Boolean
7End Type
8
9Sub initUDT()
10 Dim x As myType
11 With x
12 .member01 = 1234
13 .member02 = 'hello'
14 .member03 = 3.14
15 .member04 = False
16 End With
17
18 Debug.Print x.member01; x.member02
19
20End Sub
21
22'------输出------
23'1234 hello
单一分支
1Dim a, b, c As Integer
2
3Sub test()
4
5a = 3
6If a > 2 Then
7 Range('B' & a).Value = 123
8End If
9
10End Sub
双分支结构
比较C1 B1两个单元格的数值大小
1If Range('B1').Value > Range('C1').Value Then
2
3 Range('D1').Value = Range('B1').Value - Range('C1').Value
4Else
5
6 Range('D1').Value = Range('C1').Value - Range('B1').Value
7End If
多分支结构
成绩判断VBA代码示例
1Sub test()
2
3Dim index, line As Integer
4Dim a, b, c, d As String
5Dim column As String
6
7 column = 'B' '该参数决定了处理那一列数据
8 line = 10 '该参数决定了要处理多少行数据
9 '最终处理完的结果被写入C列的index行
10
11a = '卓越' '>95
12b = '优秀' '>80
13c = '及格' '>60
14d = '不及格' '<60
15
16For index = 1 To line
17
18 If Range(column & index).Value > 95 Then
19 Range('C' & index).Value = a
20
21 ElseIf Range(column & index).Value > 80 Then
22 Range('C' & index).Value = b
23
24 ElseIf Range(column & index).Value > 60 Then
25 Range('C' & index).Value = c
26
27 Else
28 Range('C' & index).Value = d
29
30 End If
31
32Next index
33
34End Sub
相比其他语法VB语言的Select Case语句有两种用法
常量条件
1Dim selecter As Integer
2
3selecter = 2
4Select Case selecter
5 Case 1
6 Range('D1').Value = 100
7 Case 2
8 Range('D1').Value = 200
9 Case 3
10 Range('D1').Value = 300
11 Case 4
12 Range('D1').Value = 400
13 Case Else
14 Range('D1').Value = 0
15End Select
表达式条件
使用条件表达式时需要用到 is
关键字,is
关键字代表了被测试变量本身,来测试与其他表达式之间的关系
注意:如果多个分支的条件都满足条件,则只对第一个匹配的Case值关联的代码产生作用。
1'液位转换示例
2'转换后的液位比例写入EXCEL的 D2 单元格
3Dim level As Integer
4
5level = 320
6Select Case level
7 Case Is > 1000
8 Range('D2').Value = 'level = full''
9 Case Is > 900
10 Range('D2').Value = 'level = 90%''901~1000
11 Case Is > 700
12 Range('D2').Value = 'level = 70%''701~900
13 Case Is > 500
14 Range('D2').Value = 'level = 50%''501~700
15 Case Is > 300
16 Range('D2').Value = 'level = 30%''301~500
17 Case Is > 100
18 Range('D2').Value = 'level = 10%''101~300
19 Case Else
20 Range('D2').Value = 'level = Low!''小于100 = low
21End Select
……
注意IF和ELSE的对应
注意Select Case 和 End Select的配对
为了代码的可读性 不同的嵌套层次需要使用缩进!
Do Loop循环会根据条件来判断是否要进行循环
循环类型 | 说明 |
---|---|
Do While … Loop 循环 | 当条件为真时,循环执行 |
Do … Loop While 循环 | 当条件为真时,循环执行。无论条件真假,至少运行一次 |
Do Until … Loop 循环 | 直到条件为真时,停止执行 |
Do … Loop Until 循环 | 直到条件为真时,停止执行。无论条件真假,至少运行一次 |
Do while … Loop
当条件为true时执行循环 条件为False时终止循环
1'求1~10范围整数之和
2Option Explicit
3
4Sub myCode()
5 Dim inc As Integer '用于增量
6 Dim sum As Integer '用于存范围数值之和
7 inc = 1
8
9 Do While inc <= 10
10 sum = sum + inc
11 inc = inc + 1
12 Loop
13
14 Debug.Print 'sum = '; sum
15End Sub
16
17'-------输出-----
18'sum = 55
Do … Loop while
当条件为true时执行循环 直至条件成为false,无论条件真假,至少运行一次
1Sub myCode()
2 Dim inc As Integer '用于增量
3 Dim sum As Integer '用于存范围数值之和
4 inc = 1
5
6 Do
7 sum = sum + inc
8 inc = inc + 1
9
10 Loop While inc <= 10
11
12 Debug.Print 'sum = '; sum
13End Sub
14
15'-------输出-----
16'sum = 55
至少循环一次的循环结构也可以用户来分割代码,将程序中相关的语句放在一起便于维护
1Option Explicit
2Sub myCode()
3 Dim a%, b%, c%
4
5 '用于打包相关的参数或者分割代码
6 Do
7 a = 123
8 b = 456
9 c = 789
10
11 Loop While False'等效语句 Loop While 0
12
13 Debug.Print a; b; c
14
15End Sub
16
17'------输出------
18' 123 456 789
Do Until … Loop
当条件为false时执行循环 直至条件成为true,跳出循环
1Do Until [条件表达式]
2 '循环执行的代码
3Loop
Do … Loop Until
当条件为false时执行循环 直至条件成为true,无论条件真假,至少运行一次
1Do
2 '循环执行的代码
3Loop Until [条件表达式]
While/Wend语句先判断条件,当条件为true时,执行循环体否则跳出循环,循环体中可以通过条件
在循环体中可以使用 goto+label 跳出循环
除过for循环 While/Wend应该是用的最为频繁的循环语句
1Option Explicit
2Sub myCode()
3 Dim i As Integer
4 Dim sum As Integer
5 i = 1
6
7 While i <= 10
8 sum = sum + i
9 i = i + 1
10 Wend
11
12 Debug.Print 'sum = '; sum
13
14End Sub
15'---------输出-----------
16sum = 55
While/Wend跳出循环
使用goto示例
1Option Explicit
2Sub myCode()
3 Dim i As Integer
4 Dim sum As Integer
5 i = 1
6
7 While i <= 10
8 sum = sum + i
9 i = i + 1
10
11 If i = 3 Then
12 GoTo label1
13 End If
14
15 Wend
16
17label1: Debug.Print 'sum = '; sum
18
19End Sub
20
21'---------输出-----------
22'sum = 3
填充B列 的1至10行
1Dim index As Integer
2For index = 1 To 10
3 Range('B' & index).Value = index + 10
4Next index
带有步长过的for循环示例
如果需要处理
1For index = 1 To 10 Step 2
2 Range('B' & index).Value = index + 10
3 Range('c' & index).Value = index + 123
4 Range('d' & index).Value = index + 238
5Next index
读取一系列单元格 当读取到数值 50 时退出循环
1Option Explicit
2'读取Excel一系列数据
3Sub myCode()
4
5 Dim rng As Range
6
7 For Each rng In Range('A1:A10')
8 Debug.Print rng.Value
9
10 If rng.Value = 50 Then Exit For
11 Next
12
13End Sub
Exit Do
用于跳出 Do while/Until循环语句
1Sub myCode()
2 Dim i As Integer
3 i = 1
4
5 Do While i < 10
6
7 i = i + 1
8
9 If i = 5 Then
10 Exit Do '当i = 5 跳出Do循环
11 End If
12 Loop
13
14 Debug.Print 'i = '; i
15End Sub
16
17'--------输出--------
18 ' 5
Exit For
用于跳出for循环
1Option Explicit
2Sub myCode()
3 Dim i As Integer
4
5 For i = 1 To 10 Step 1
6
7 If i = 5 Then
8 Exit For '判断条件满足跳出for循环
9 End If
10
11 Next i
12
13 Debug.Print 'i = '; i
14
15End Sub
16
17'--------输出--------
18 ' 5
sub直译过来就是过程,VB语言的过程在其他语言中被称为函数或者子程序
用户可以在主过程中调用子过程,例如 Call subA ,调用SubA的子过程,当SubA执行完毕控制流会回到调用位置继续向下执行后面的代码
定义Sub过程的语法格式
[Private | Public | Static] Sub subName (par_List)
无参数的子过程示例
1'定义3个符号常量
2Const msgB = 'sub01被调用'
3Const msgC = 'sub02被调用'
4Const msgD = 'sub03被调用'
5'---------------主调过程-----------------------
6'AAA()是主过程 调用了3个子过程
7Sub AAA()
8 Call sub01
9 Call sub02
10 Call sub03
11 Call sub01
12End Sub
13'----------------被调过程----------------------
14'以下是定义了三个子过程 --被调过程
15Public Sub sub01()
16 Debug.Print msgB
17End Sub
18Public Sub sub02()
19 Debug.Print msgC
20End Sub
21Public Sub sub03()
22 Debug.Print msgD
23End Sub
24
25'------输出--------
26' sub01被调用
27' sub02被调用
28' sub03被调用
29' sub01被调用
带有参数的sub过程
1'主调过程
2'-------------------------------------------
3Sub AAA()
4 Call sub01(10, 32)
5 Call sub02(9, 12)
6 Call sub03(128, 8)
7End Sub
8
9'-----被调过程------------------------------
10Public Sub sub01(x As Integer, y As Integer)
11 Debug.Print '两数之和 = '; x + y
12End Sub
13
14Public Sub sub02(x As Integer, y As Integer)
15 Debug.Print '两数之差 = '; x - y
16End Sub
17
18Public Sub sub03(x As Integer, y As Integer)
19 Debug.Print '两数之商 ='; x / y
20End Sub
21
22'--------输出结果-------
23' 两数之和 = 42
24' 两数之差 = -3
25' 两数之商 = 16
function过程和sub最大的区别在于它可以给主调程序返回参数,这样它就可以出现在表达式中给变量赋返回值。
Function 的调用方式有3种 最后一种尽量不要用,尽可能显式的调用定义的函数提高代码的可读性
1Sub ABC()
2Dim resualt As Integer
3
4 resualt = Max(10, 20) '以表达式的方式调用
5 Debug.Print resualt
6
7 Call Max(100, 23) '使用call关键字调用
8 Max 123, 789 '使用函数名直接调用 少用!!
9 ' Max 后面两次调用有返回值 只不过被丢弃了
10
11End Sub
12
13'输入两个参数 返回最大值 ps这个例子有Bug参考即可
14Public Function Max(x As Integer, y As Integer) As Integer '返回值为Integer
15If x > y Then
16 Max = x '返回值传递语句
17Else
18 Max = y '返回值传递语句
19End If
20End Function
案例2
1Sub ABC()
2Dim resualt As Integer
3
4 resualt = Max(1030, 230) '调用Max
5 Debug.Print resualt
6 resualt = Min(123, 123) '调用Min
7 Debug.Print resualt
8
9 Call hello '调用hello
10End Sub
11'--------------------------------------------
12'输入两个参数 返回最大值
13Public Function Max(x As Integer, y As Integer) As Integer '返回值为Integer
14If x > y Then
15 Max = x '返回值
16Else
17 Max = y '返回值
18End If
19End Function
20'--------------------------------------------
21'输入两个参数 返回最小值
22Public Function Min(x As Integer, y As Integer) As Integer
23If x < y Then
24Min = x
25Else
26Min = y
27End If
28End Function
29'--------------------------------------------
30'无参数的 无返回值的function 用来实现特定的动作
31Public Function hello()
32 Debug.Print 'hello world'
33End Function
34
35'-----输出-----
36'1030
37'123
38'hello world
VB中参数传递有两种形式
按地址传递(ByRef) 默认形式
按值传递(ByVal)
VB中默认的传参方式,即形参与实参使用同一个内存地址,类似C语言指针的意思 但更像PLC编程中的inout
类型的接口参数
大多数的编程语言中函数只能返回一个参数,但通用sub可以通过地址传递的方式实现有多个参数回传至主调过程弥补了函数只能返回一个参数的特性,当然C语言可以将结构体指针传给函数实现同样的目的
下例中变量a,b被作为参数传递进了子过程,由于形参和实参使用了同一段内存,在子过程执行时相当于直接操作了实参变量。
1Option Explicit
2
3Sub Abc()
4Dim a%, b% '声明2个整型变量
5
6Call Ref0(a, b) '调用Ref0() 将变量a和b做为参数
7
8Debug.Print a; b '当Ref()执行完毕 打印a和b的值
9End Sub
10'------------------------------------------------
11
12Sub Ref0(t As Integer, u As Integer) '定义子过程
13t = t + 5
14u = t + 10
15End Sub
16
17'------输出------
18' 5 15
按值传递时需要值用ByVal
显式的声明形式参数,当实参传入之后,便与被调sub中的形参无关,实际上传入的是实参的副本,这种形式适合参数的单向传递,参数作为条件的的场景。
1Option Explicit
2
3Sub Abc()
4
5Dim a%, b% '声明2个整型变量
6
7Call By_val(a, b) '调用By_val() 将变量a和b做为参数
8
9Debug.Print 'a = '; a; ' b = '; b '当Ref()执行完毕 打印a和b的值
10End Sub
11
12'-------------------------------------------------------------
13'参数一旦传入形参与实参之间再无瓜葛
14Sub By_val(ByVal t As Integer, ByVal u As Integer) '定义子过程
15t = t + 5
16u = t + 10
17Debug.Print 'by_Val内部执行结果 t= '; t; ' u='; u
18End Sub
19
20'------------------------------------------------------------
21'输出
22'by_Val内部执行结果 t= 5 u= 15
23'a = 0 b = 0
函数可以调用其他函数,可以嵌套调用,但是不可以在函数内部声明函数,函数不可以调用自己
1Option Explicit
2Sub Abc()
3 Dim a%, b%, n% '声明3个整型变量
4 a = 6
5 Debug.Print a; '的阶乘 = '; F_factorial(a)
6
7 b = 2: n = 3
8 Debug.Print b; '的'; n; '次方 = '; F_power(b, n)
9
10 '计算7的阶乘+3的阶乘 - 2的三次方
11 Debug.Print '(7! + 3!) - 2^3 ='; (F_factorial(7) + F_factorial(3)) - F_power(2, 3)
12End Sub
13
14'F_power输入一个正整数和指数返回计算结果---------------
15Function F_power(x%, n%) As Integer
16 F_power = x ^ n
17End Function
18
19'F_factorial输入一个正整数返回该数值的阶乘-------------
20Function F_factorial(num%) As Integer
21 Dim index As Integer
22 Dim result As Long
23 result = 1
24
25 For index = 1 To num
26 result = result * index
27 Next index
28 F_factorial = result
29End Function
30
31'----------输出-----------
32' 6 的阶乘 = 720
33' 2 的 3 次方 = 8
34'(7! + 3!) - 2^3 = 5038
全局对象需要用 Public 显式声明 可以实现跨模块操作
这个特性方便程序设计时将不同的功能定义在不同模块,主调函数按需跨模块调用
下面例子中在模块2中定义全局变量以及过程,然后在模块1中使用模块2的全局定义
跨模块使用变量,过程函数,以及字符常量
模块2中的代码:
1'这里的代码位于模块2
2Option Explicit
3
4Public str01 As String '声明一个名为 str01 的全局变量
5Public Const Pi = 3.141593 '声明一个名为 pi 的全局字符常量
6
7Public Sub init() '定义一个全局的 init()sub 用来初始化 Str01
8 str01 = '我是模块2的全局变量 Str01'
9End Sub
10
11Public Function F_module2()'定义一个名为 F_module2的function打印一句话
12 Debug.Print '我是模块2的函数 F_module2'
13End Function
模块1中的代码:
1'这里的代码位于模块1
2Option Explicit
3
4Sub Abc()
5 Call init '调用模块2中的init全局过程,给str01初始化
6 Debug.Print str01 '打印模块2中str01中的内容
7 Debug.Print Pi '打印模块2中字符常量 Pi中的内容
8 Call F_module2 '调用模块2中F_module2全局函数
9End Sub
10
11'-------------输出------------
12' 我是模块2的全局变量 Str01
13' 3.141593
14' 我是模块2的函数 F_module2
当过程(函数)直接或间接调用了自己时,则发生了递归。
比较经典的例子就是阶乘
1Option Explicit
2Sub myCode()
3 Dim a As Integer
4 Dim b As Integer
5
6 a = 4
7 b = 12
8
9 Debug.Print 'factorial_1 = '; factorial_1(a)
10
11 Debug.Print 'factorial_2 = '; factorial_2(b)
12
13End Sub
14
15'阶乘函数1-循环算法-------------------------
16Function factorial_1(x As Integer) As Integer
17Dim i As Integer
18factorial_1 = 1
19For i = 1 To x Step 1
20 factorial_1 = factorial_1 * i
21Next i
22End Function
23
24'阶乘函数2-递归算法-------------------------
25Function factorial_2(x As Integer) As Long
26
27If x = 1 Then factorial_2 = 1: Exit Function
28
29factorial_2 = x * factorial_2(x - 1)
30
31End Function
32
33'----------输出结果---------------
34'factorial_1 = 24
35'factorial_2 = 479001600
①创建一个类模块命名为base1
②在创建好的类模块中定义属性和方法(函数)
①像声明变量那样 New
一个对象
②类的实例化完成之后使用.
运算符 使用Base1的成员属性以及类方法
1'在刚才的实例(base1)中加入构造函数以及析构函数代码
2
3Private Sub Class_Initialize() '构造函数
4 Debug.Print '构造函数已执行'
5 v = 'created...'
6End Sub
7
8Private Sub Class_Terminate() '析构函数
9 Debug.Print '析构函数已执行'
10End Sub
再一次调用myCode( )
构造函数在创建对象时调用
析构函数在程序结束前调用
1'base1的完整代码-------------------------------------------
2Option Explicit
3'定义类的属性
4Public t As String
5Public u As String
6Public v As String
7
8Private Sub Class_Initialize()
9 '构造函数
10 Debug.Print '构造函数已执行'
11 v = 'created...'
12End Sub
13Private Sub Class_Terminate()
14 '析构函数
15 Debug.Print '析构函数已执行'
16End Sub
17
18'定义类的方法1
19Function func1() As Integer
20 Debug.Print '调用 func1()'
21End Function
22
23'定义类的方法2
24Function func2() As Integer
25 Debug.Print '调用 func2()'
26End Function
27
28
29'-----------------------------------------------------------
30'myCode()的完整代码
31Option Explicit
32
33Sub myCode()
34
35 Dim test As New base1 '创建一个类实例test
36
37 '类成员的赋值
38 test.t = 'hello'
39 Debug.Print test.t
40 Debug.Print test.v ' 构造函数对该成员进行初始化
41
42 '类方法的调用
43 test.func1
44 test.func2
45
46End Sub
如果某个对象执行完毕不再需要可以用下面的语句将其从内存中销毁,释放系统资源。
Set ClassName = Nothing
1Dim test As New base1 '创建一个类实例test
2
3Set test = Nothing '销毁一个实例
1、角度转换成弧度
⚪ 圆周长 = 2派r = 派d(d直径)
圆一周的弧长 = 2派r (周长 = 弧长)
弧度 = 弧长÷半径 = 2Πr ÷ r = 一个整圆弧度:2Π
先求出一度对应的弧度 然后再乘以x度 将计算好的弧度返回
1Option Explicit
2Sub myCode()
3 Dim a As Single
4 Dim b As Single
5
6 a = 30
7 b = 180
8
9 Debug.Print 'call a'; rad(a)
10 Debug.Print 'call b'; rad(b)
11
12End Sub
13
14Function rad(x As Single) As Single
15Const Pi = 3.141593
16 rad = (Pi / 180#) * x '2Pi/360 = pi/180
17End Function
2、计算直角三角形斜边
已知直角三角形的两条直边的长度,求斜边的长度
根据勾股定律 :C^2 = A^2 + B^2
1Option Explicit
2Sub myCode()
3 Dim a As Single
4 Dim b As Single
5
6 a = 3
7 b = 5
8
9 Debug.Print '斜边C长度 = '; myFunc(a, b)
10
11End Sub
12
13Function myFunc(a As Single, b As Single) As Single
14 myFunc = Sqr(a ^ 2 + b ^ 2)'Sqr()VB语言的开方函数
15End Function
16'-------输出---------
17'斜边C长度 = 5.830952
联系客服