打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
VBA入门笔记

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的界限将逐渐模糊……

VBA的基本数据类型

比较常用的数据类型主要有整型和浮点型,字符串

说明数据类型简化后的申明符号占用字节数
字节型Byte
1
整型Integer%2
长整型Long&4
单精度浮点型Single4
双精度浮点型Double#8
货币型Currency@8
字符型String$每字符占1字节
布尔型Boolean

日期型Date
8
变体型Variant
不确定
对象型Object
4

字符串

string型是指一切可以打印的字符与字符串
一个西文字符占用一个字节,一个中文占用2字节

  • 边长字符串

随着赋值的变化而改变长度的字符串变量

  • 定长字符串

字符变量在声明时候进行限制 例如: Dim str As String*10  (类型关键字*10 )表示长度为10字节的定长字符串。

Variant

可变(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对系统来说是同一个变量
变量声明的两种形式:

  1. 隐式声明

1Dim x%, y!, z$  '%=整形 ;!=单精度浮点型 ;#=双精度浮点型;$=字符型
  1. 显式声明

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 '声明一个单精度浮点数
数组

数组是非常重要的概念

一维数组
数组(Arrays)用相同名字引用一系列变量,并用数字(索引)来识别它们

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 3As 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 31 To 3As 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(33)
13Debug.Print items(22)
14Debug.Print items(11)
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 101 To 101 To 10As 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(111)
17Debug.Print items(135)
18Debug.Print items(953)
19Debug.Print '循环次数 = '; cnt
20End Sub


运算符以及表达式

算术运算符
运算符含义示例
+加法运算符
-减,取负
*乘法运算符
/除法运算符
\整除运算符10\3  = 3
MOD取模运算10 MOD 3 = 1
^乘方运算符22   等于  2^2 = 4
算数运算符优先级
优先级运算符说明
1()所有的表达式中括号中的内容优先级最高
2^指数运算
3-取负
4* /乘-除
5\整除
6Mod取模
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

Debug

参数输入 使用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语句

一般用于处理对象属性以及结构体成员的初始化

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

分支结构-IF语句

单一分支

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

分支结构 Select Case语句

相比其他语法VB语言的Select Case语句有两种用法

  1. 常量条件

 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
  1. 表达式条件

使用条件表达式时需要用到 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 Loop循环会根据条件来判断是否要进行循环

循环类型说明
Do While … Loop 循环当条件为真时,循环执行
Do … Loop While 循环当条件为真时,循环执行。无论条件真假,至少运行一次
Do Until … Loop 循环直到条件为真时,停止执行
Do … Loop Until 循环直到条件为真时,停止执行。无论条件真假,至少运行一次
  1. 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 
  1. 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 
  1. Do Until … Loop

当条件为false时执行循环 直至条件成为true,跳出循环

1Do Until [条件表达式]
2    '循环执行的代码
3Loop
  1. Do  … Loop Until

当条件为false时执行循环 直至条件成为true,无论条件真假,至少运行一次

1Do
2    '循环执行的代码
3Loop Until [条件表达式]
While/Wend语句

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

For 循环

填充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
For Each

读取一系列单元格 当读取到数值 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

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

VBA过程

sub直译过来就是过程,VB语言的过程在其他语言中被称为函数或者子程序
用户可以在主过程中调用子过程,例如 Call subA ,调用SubA的子过程,当SubA执行完毕控制流会回到调用位置继续向下执行后面的代码

在VB中,通用过程分为两类:Sub(子程序)过程和Function(函数)过程。
Sub过程和Function过程的相似之处是,它们都可以被调用,都是一个可以获取参数,执行一系列语句,并能够改变其参数值的独立过程。
它们的主要不同点是,Sub过程不返回值,因此Sub过程不能出现在表达式中,且不具有数据类型;而Function过程具有一定的数据类型,能够返回一个相应数据类型的值,可以像变量一样出现在表达式中

SUB过程

定义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(1032)
5    Call sub02(912)
6    Call sub03(1288)
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过程

function过程和sub最大的区别在于它可以给主调程序返回参数,这样它就可以出现在表达式中给变量赋返回值。
Function 的调用方式有3种 最后一种尽量不要用,尽可能显式的调用定义的函数提高代码的可读性

 1Sub ABC()
2Dim resualt As Integer
3
4    resualt = Max(1020'以表达式的方式调用
5    Debug.Print resualt
6
7    Call Max(10023)     '使用call关键字调用
8    Max 123789          '使用函数名直接调用  少用!!
9    ' Max 后面两次调用有返回值 只不过被丢弃了
10
11End Sub
12
13'输入两个参数 返回最大值   ps这个例子有Bug参考即可
14Public Function Max(x As Integer, y As IntegerAs 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(1030230'调用Max
5    Debug.Print resualt
6    resualt = Min(123123)  '调用Min
7    Debug.Print resualt
8
9    Call hello               '调用hello
10End Sub
11'--------------------------------------------
12'输入两个参数 返回最大值
13Public Function Max(x As Integer, y As IntegerAs 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 IntegerAs 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 IntegerByVal 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(23)    
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 IntegerAs 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 IntegerAs Long
26
27If x = 1 Then factorial_2 = 1Exit Function
28
29factorial_2 = x * factorial_2(x - 1)
30
31End Function
32
33'----------输出结果---------------
34'factorial_1 =  24 
35'factorial_2 =  479001600 

VBA-面向对象

类的定义

①创建一个类模块命名为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 SingleAs 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 SingleAs Single
14    myFunc = Sqr(a ^ 2  + b ^ 2)'Sqr()VB语言的开方函数
15End Function
16'-------输出---------
17'斜边C长度 =  5.830952
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
VBA语法概述
vba基础 个人学习详细笔记 知识点梳理
VBA的过程及参数详解
Excel中VBA编程学习笔记(一)
Excel VBA入门(四)流程控制2-循环控制
学习VBA for Access
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服