乔山办公网我们一直在努力
您的位置:乔山办公网 > excel表格制作 > Excel VBA与数据统计 第三章 变量-excel四舍五入

Excel VBA与数据统计 第三章 变量-excel四舍五入

作者:乔山办公网日期:

返回目录:excel表格制作

第三章 变量

第一节 计算机中对信息的保存形式

3.1.1进制

在小学阶段,我们就知道,在书写一个数字的时候,按照从高位到低位的原则书写,高位上的1代表相邻低位上的10. 我们不妨再回忆一下这一部分的内容,这将对于我们理解进制有着非常大的帮助:

例如156这个数字,我们读作”一百五十六”。而当我们写下这个数字的时候,为啥就默认它等于1个一百,5个十,以及6个1组成的呢?这是因为,一般情况下,我们采用10进制来记录一个数字,所谓10进制,就是”逢10进1”,如果我们进一步把这个156用10进制的方式拆开,就是1*102+5*101+6*100.这里可以看到,”个位”上的数字自动认为是100,”十位”上的数字自动认为是101,”百位”上的数字自动认为是102.

然而,在现实生活中,并不是所有的进制都是10进制,最典型的例子是时间,在时间的表示中,1天等于24小时,这个是24进制,也就是”逢24进1”;1小时等于60分钟,1分钟等于60秒,这里是60进制,即”逢60进1”;1年等于12个月,这是12进制……

那么现在有一个问题,2天13小时12分20秒等于多少秒,这个时间由如何表示?对于这个时间我们是否可以表示为2:13:12:20 ? 当然可以,这里每两个”小结”之间的进制不再是10进制了。那么,不同的进制有什么不一样呢?我们知道,在10进制中,所有的数字为0~9,共计9个数字,所有的数都是由这9个数组成。而在过去的年代,我们采用”十六两称”的时候,即一斤等于16两。如何表示1斤12两这样的数呢?此时,由于12两不等于1斤,也不到当时的一斤,所以我们这样表示当然是不对的,正确的表示方式是:C两。在16进制中,我们引入A、B、C、D、E、F这五个字母表示大于等于10,且没有达到16的5个数字,即A代表10,B代表11……,那么相对于10进制,16进制就需要有16个”数字”构成,分别是从0~F。在音乐中,这个进制为8,即逢8进1,(只有7个音符,第8个音符与第一个音符唱名相同)。在8进制中,10等于10进制中的8.因此,8进制数需要用0~7,共计8个”数字”构成。

从上面的论述可以看到,任何一个进制的数,其采用的数字的个数等于进制单位。如何表示不同进行的数字呢?一般情况下,10进制的数字按照原来的方式写即可,其他进制的数字,在书写的时候,数字两边加上小括号,并在右下角写上进制的方法,用于相互区分,例如,16进制中的数字12,表示为(12)16. 8进制中的数字27,表示为(27)8.二进制中的数字101,表示为(101)2.

3.1.2 进制直接的相互换算

(1)其他进制转换为10进制

其他进制转化为10进制的方法比较简单,只需要”安位置”计算即可。我们可以参考10进制的计算原则,例如137=1*102+3*101+7*100,计算一下16进制的12C:

(12C)16=1*162+2*161+12*160=300.

同样的原理,可可以计算一下8进制下的45. (45)8=4*8+5=37.

(2) 10进制数转换为其他进制

将10进制数转化为其他进制数的方法是:用10进制数除以需要转换成为的进制,余数作为”各位”,然后商再除以进制,余数作为”十位”,然后依次类推,直到是这个十进制数除以进制后商等于0,将最后的余数作为最高位。

例如:将10进制数的25转换为2进制数,则进行如下运算:

第一轮:25除以2,商为12,余数为1.于是,第一位是1,商不等于0,进行第二轮。

第二轮:12除以2,商为6,余数为0,于是,第二位是0,商不等于0,进行第三轮。

第三轮:6除以2,商为3,余数是0,于是,第三位是0,商不等于0,进行第四轮。

第四轮:3除以2,商为1,余数是1,于是,第四位是1,商不等于0,进行第五轮。

第五轮:1除以2,商为0,余数是1,于是,第五位是1,商等于0,结束

于是。25化为2进制数便是(11001)2. (即上面的余数按照从低位到高位的顺序写)。

3.1.3计算机对信息的保存形式

计算机中,所有的信息都是以2进制的方式进行保存的。为什么计算机采用2进制保存信息?简单来说,2进制保存信息时,所需要的原件种类最少,原件结构最为简单!不妨想象一下,假设计算机以10进制来保存信息,那么势必需要一种能够表示10个不同状态的原件。而在电子原件中,让一个原件可以有10种不同的状态,远远比让一个原件只有两种不同的状态复杂!

在日常生活中,最常见到的2进制是开关,开关对于电路来说最为简单,假设开的状态我们表示为1,而关的状态表示为0,那么,我们只需要4个开关,就可以表示16进制中从0~F,这16个不同的数。

第一个开关第二个开关第三个开关第四个开关表示的数字

00000

00011

00102

00113

01004

01015

01106

01117

10008

10019

1010A

1011B

1100C

1101D

1110E

1111F

3.1.4 原码和补码

计算机中,最基本的储存单位是字节Byte,一个字节由8个上面说到的”元件”组成。一个字节可以表示的数字范围为0~255(在上面的例子中,4个开关最多表示16种不同的情况,即16个数字)以计算机中最常见的整型为例,一个整形数据是有2个Byte组成,读者可以思考一下其表示的数字范围是多少?

原码:在计算机中,一个数字转化为2进制后,就是这个数字在计算机中的”原码”。例如,数字5在计算机中的原码为:0000000000000101。

补码:在原码的基础上,将原码中的0转换为1,1转换为0,最后再加上1。例如,数字5在计算机中的补码为:1111111111111011。

在计算机中,正数以原码的形式表示,而负数以补码的形式表示,上面的例子中,5,在计算机中为0000000000000101,而-5为1111111111111011。

负数储存为补码的好处:当负数表示为补码以后,减法运算可以简化为加法运算!例如,5-5=0,在计算机中,其运算为5+(-5),即0000000000000101+1111111111111011。我们可以看到,因为2进制中为”逢2进1”因此,0+0=0,1+0=1,0+1=1,1+1=10,这个0000000000000101+1111111111111011运算后,等于10000000000000000.而计算机中,一个整形最多保存16位,所以,最前面的那个1将会被”丢失”掉,最后这16个位置上的数正好全部归零。

3.1.5 ASCII码表

以上我们探讨了计算机对于整数的保存和运算形式,接下来我们来探讨一下计算机对于字母和符号的保存。与数字的保存形式一致,计算机也是采用2进制的方式保存字母和符号,计算机中,将特定的符号按照ASCII字母表的方式同一个byte(0-255)中的数相互对应。所谓ASCALL表,其全称是American Standard Code For Information Interchange,即美国信息交换标准代码。

ASCII数值字符ASCII数值字符ASCII数值字符ASCII数值字符

0NUL32Space64@96·

1SOH33!65A97a

2STX34“66B98b

3ETX35#67C99c

4EOT36$68D100d

5ENQ37%69E101e

6ACK38&70F102f

7BEL39‘71G103g

8BS40(72H104h

9HT41)73I105i

10LF42*74J106j

11VT43+75K107k

12FF44,76L108l

13CR45-77M109m

14SO46.78N110n

15SI47/79O111o

16DLE48080P112p

17DC149181Q113q

18DC250282R114r

19DC351383S115s

20DC452484T116t

21NAK53585U117u

22SYN54686V118v

23TB55787W119w

24CAN56888X120x

25EM57989Y121y

26SUB58:90Z122z

27ESC59;91[123{

28FS60<92/124|

29GS61=93]125}

30RS62>94^126`

31US63?95_127DEL

第二节 VBA数据类型

3.2.1 数据类型和VBA的数据类型

数据在计算机中的储存方式成为数据类型,在上面一节中,曾经中提到,在计算机中,一个整形数据的储存形式,是2个字节范围。数据只有以一定的数据类型储存起来才具有意义。VBA中支持的数据类型以及该种数据类型表示的数据范围如下。

数据类型储存空间能够表示的范围

Byte1个字节0~255

Boolean2个字节True或者False

Integer2个字节-32768~32767

Long4个字节-2147483648~2147483647

Single4个字节-3.4E38~-1.4E-45,1.4E-45~3.4E38

Double8个字节-1.79E308~-4.8E-324,4.8E-324~1.79E308

Currency8个字节-9.22E18~9.22E18

Decimal14个字节±7.9E20范围内整数,28位小数:±7.9,最小非零1E-25

Date8个字节100年1月1日~9999年12月31日

String(变长)10个字节+0~2E9字符

String(定长)字符串长度1~6E4字符

Variant(数字)16个字节任何数字,最大可以到Double范围

Variant(字符)22个字节+与String(变长)相同

Type(用户自定义)Type中字节+等于Type中所有基础数据类型表示范围

对象型与对象有关等于对象最大表示范围

3.2.2 VBA数据类型

1用于储存逻辑型数据和整数型数据的类型

有Byte型、Boolean型、Integer型、Long型。Byte型,用于储存一个介于0~255之间的整数。Boolean型,用于储存逻辑数值,仅仅可以储存两个”逻辑数值”,即”True”或者”False”。Integer型和Long型,分别用于储存整形数据,Integer型的储存空间为2个字符,Long的储存空间为8个字符。

一个Integer型的数据,可以储存的最大数据是32767,如果让一个32767的整形数据再加上1,将会发生著名的”溢出错误”,即加完之后等于-32768。为什么会发生如此的情况呢?

在计算机中,最高位上的数表示这个数据的”符号”,最高位上等于0时,表示这个数是正数,按照”原码”的原则储存的;最高位是1时,表示这个数是负数,按照”补码”的原则储存的。(详见3.1.4原码和补码),所以,在计算机中进行32767+1运算时会发生如下的情况:32767=(0111111111111111)2,32767+1=(0111111111111111)2+(1)2=(1000000000000000)2,而这个数,正好是32768的补码,所以,等于-32768。

2 用于储存小数的数据类型

有Single型、Double型、Currency型、Decimal型,其中,Single型为4个字节,Double型为8个字节,Currency型为”货币类型”,可以储存没有小数的数据(整数),也可以储存有小数的数据,并且根据小数点的位置,其表示范围是可以变化的,Decimal型也具有这种储存方式,其精确程度在所有数据型类型中最高。

这里要说明的是,这些类型除了同样会有”溢出错误”以外,对于一个小数,计算机并不能完全储存小数点后的无限多的位置,所以,在计算机中,保存的小数位有限的情况下,后面的小数位将自动被”四舍五入”忽略。其中一个例子是,一个Single型的数据,等于1/3,然后让这个Single型数据再乘以3,结果将会是0.9999999999……。

3 用于保存日期的数据类型

在VBA中,有一个用于保存日期的数据类型,即Data型,Data型的数据可以直接想减,得到的数字为两个日期直接相隔的天数。

4 用于保存字符串的数据类型

String(变长)型:当字符串的长度不确定时,用String(变长)型来储存,用这种类型来保存字符串时,会自动在字符串前端加上字符串的长度,此时,占有的储存空间大小为10个字符+字符串长度。

String(定长)型:当字符串长度确定时,用String(定长)型来存储,这种类型保存字符串,保存长度等于字符串长度。

注意的一点是,当字符串中有汉字时,一个汉字或者一个汉字符号等于两个字符!(详见国标2312,GB2312)

5 变体型

当储存类型暂时不能确定时,VBA给用户提供了一种可以”通用”的类型,即Variant,使用这种类型数据时,用户不必担心所需要储存的数据是那种类型,而是编译器会自动根据实际数据的类型进行转换,然后再储存。

6 Type型

VBA允许用户自定义数据类型,自定义的数据类型由上述基础的数据类型构成,这种数据类型叫做结构体,我们将在数值与结构体一章中详细讲解。

用户自定义的结构体的储存空间大小,等于结构体中所有成员的储存空间大小之和。

7 对象类型

实际上,可以把对象类型看成一个结构体类型,不同的是,这种结构体是系统自带的,即VBA内部所支持的一个”类”。

第三节 变量和运算

3.3.1 变量

变量就是计算机中被命名的一个储存位置。不妨把变量想象成一个容器,在这个容器中,储存的是程序运算过程中可以改变的”数据”或者”对象”。也可以把变量想象成中学课本中的”未知数”,这些”未知数”可以改变,也可以参与求解运算。

3.3.2 变量的声明

在使用一个变量前,需要在计算机中进行声明该变量,即向系统说明,现在有这么一个变量。VBA声明变量的命令是: Dim 变量名 As 类型、Public 变量名 As 类型、Private 变量名 As 类型、Static 变量名As 类型。这里,只讲解第一种声明形式,剩下的声明形式在变量使用范围中讲解。

在命令”Dim 变量名 As 变量类型”中,变量名可以用英文字母、数字、下划线以及其组合,类型可以用上述类型中的任何一个类型。

例如:

Dim A As Integer

这一条命令即声明一个名字叫做”A”的整形变量。

Dim B As String(5)

这一条命令声明了一个名字叫做”B”的字符串变量,这个B的长度为5个字符。

Dim C As String

这一条命令声明了一个名字叫做’C”的字符串变量。C长度不确定。

Dim A As Integer, B As String

这一条命令一次性声明了两个变量,第一个是名字为A的整形变量,第二个是名字为B的字符串型变量。

对于数字和字符串的规定:VBA中规定,所有双引号中的内容,均被当作字符串进制处理,而没有双引号的内容当作数字、变量或者函数、过程处理。对于变量名称大小写的规定:VBA中,变量名称不区分大小写,即在VBA中,整形变量A和a,VBA认为是一个变量,VBE在第二次遇到相同的变量时,会自动把变量名称修改为与第一次的名称形式相同。

对于隐式声明和显示声明的规定:在VBA中,可以不用声明一个变量而直接使用,这时,编译器自动将第一次使用的该变量(隐式地)声明为变体型。变体型数据将会造成程序运行速度减慢,为了杜绝这一现象,可以让VBA强制采用显示声明的办法,即在程序开头的位置加上Option Explicit。加上该命令后,必须先显示声明变量才可以使用该变量。

3.3.3 变量的运算

既然变量是一个”数据”那么,就有同数据一样的参与运算的功能,那么,对变量进行的任何操作都可以称为变量的”运算”,我们可以根据在变量中储存的东西是数据或者对象,将变量分为数值变量和对象变量。下面将讲解变量的运算。

1. 赋值运算

变量最基础的运算便是”赋值运算”,也就是把一个数或者对象通过”赋值”的方法”复制”到变量中。在VBA中,赋值运算的方法有两种:Let 变量=表达式 或者Set 变量=表达式。Let用于数值变量的赋值,Set用于对对象变量的赋值。在”Let 变量=表达式”中,Let可以省略 所以,对于数值变量的赋值就简化成了”变量=表达式”

在上面这个式子中,变量一定要位于”=“符号的左边,而”=“符号的右边可以是任意的数学运算、判断运算或者字符串运算等。这个”=“不再是数学中的”等于”的意思,而是将右边的数字、字符或者逻辑值进行运算,然后把右边的结果复制给左边的变量。例如

a=a+1

这一个命令是,把原来变量a的数值加上1,然后再赋值给变量a,命令结束后,a的数值在原先基础上加了1.

2. 数学运算

VBA中支持许多数学运算,相关的数学运算有:

(1)四则运算:加法”+”,减法”-”,乘法”*”,除法”/”,整除”\\”,取余数”Mod”运算。例如:”5+2”,”7-4”,”4/3” ,”3\\2”,”17 Mod 3” 等。下面我们着重讲解除法和整除运算。

除法运算,即计算两个数的除后的结果,这里,如果运算后赋值给一个Single或者Double型将不会产生任何问题,但是,如果赋值给一个Integer或者Long型,将会产生一个小问题,请尝试一下下面的程序:

Sub Test()

Dim A As Integer, B As Single

A=1/2

B=1/2

MsgBox(“A=“& A &” B=“ & B)

End Sub

将显示”A=1 B=.5。这里,B=.5的输出我们暂且不去管它,这个输出等价于B=0.5,也就是说,B的运算时完全正确的,但是A为什么处于2以后任然等于1呢?

这是因为,我们在把例如0.5这样的小时赋值给一个整数时,VBA系统自动给我们”四舍五入”了!

整除运算,在进行整除运算时,计算机自动给出除后的整数部分,而忽略小数部分,还是上面的程序,现在修改一下:

Sub Test2()

Dim A As Integer, B As Single

A=1\\2

B=1\\2

MsgBox(“A=“ & A & “ B=“ & B)

End Sub

再次运行,发现此时结果是”A=0 B=0”这是因为,在进行整除运算时,计算机只取计算结果的整数部分,所以把一个整数赋值给一个小数或者整数,结果还是这个整数!

求余数运算,Mod运算符可以求除法运算中的”余数”,这个运算可以判断一个数是否为偶数(奇数)(偶数对2的余数等于0)。表达式 a Mod b表示求a对b的余数。

Sub Test3()

Dim A As Integer

A=17 Mod 3

MsgBox(a)

End Sub

程序将输出17对3的余数,即2.

(2)取整运算:取整运算的结果是把一个小数取成整数。取整运算有两种,即Int() 和Fix()。这两者是有区别的,Int()运算是求不大于这个小数的整数,当小数大于0时,将返回小数的整数部分,当小数小于0时,将返回这个小数的整数部分减去1,而Fix()作用是返回小数的整数部分,无论小数大于0或者小于0,例如:Int(8.7)等于8,Fix(3.6)=3,而Int(-7.2)=-8,Fix(-7.2)=-7

(3)函数运算:VBA支持的函数运算有:幂运算”^”,表示求幂,例如3^2表示求3的2次方幂。Exp()表示求底数为e的幂。对数运算:Log() 表示求以e为底的对数。三角函数:Sin()、Cos()、Tan()表示求弧度情况下的正弦、余弦、正切(注意括号内的数的单位为弧度)。随机函数:Rnd(),表示生成一个0~1之间的随机数。

3.逻辑运算

所谓逻辑运算,就是得到逻辑值True(真)或者逻辑值False(假)的运算,逻辑运算中,有逻辑值运算和逻辑值之间的运算。逻辑值运算就是得到一个命题为真或者为假的运算

VBA的逻辑值运算有:”>“,”<“,”<>“,”>=“,”<=“以及”=“

(1)大于运算 “>“ 判断左边是否大于右边,例如3>5,结果为False请尝试以下程序:

Sub Logisic()

Dim a As Boolean

a=3>5

Msgbox(a)

End Sub

正如所预料,得到结果”False”

(2)小于运算”<“判断左边的是否小于右边。

(3)不等于运算”<>“ 判断左右两边是否不等。

(4)等于运算”=“ 判断左右两边的是否相等。

(5)大于等于运算”>=“判断左边是否大于或等于右边。

(6)小于等于运算”<=“判断左边是否小于或等于右边。

VBA中的逻辑数值之间的运算有:And、Or、Not、Eqv、Imp、Xor。

(1) And运算:计算两个逻辑数值的”逻辑且”,只有当And两边的两个逻辑数均为Ture时,计算结果才为Ture。

(2) Or运算:计算两个逻辑数值的”逻辑或”,当参与Or运算的两个逻辑值其中一个为True时,结果为Ture,只有两个逻辑值均为”False”时,结果才为”False”

(3) Not运算:计算单一逻辑数值的”逻辑非”,当参与运算的逻辑值为Ture时,计算结果为False;当参与运算的逻辑值为False时,运算结果为True。

(4) Eqv运算:计算两个逻辑数值的”逻辑等价”,当参与Eqv运算的两个逻辑值的数值一致时,即两边都为True或者都为False,结果为True;否则结果为False

(5) Imp运算:计算两个逻辑数值的”逻辑蕴含”,当参与Imp运算的第一个逻辑数值为Ture,且第二个逻辑数值为False时,运算结果为False,其他情况下运算结果均为True。

(6) Xor运算:计算两个逻辑数值的”异或”结果,即当两个逻辑值中其中一个是True,一个是False时,运算结果为True,其他情况下,运算结果为False.

4. 字符串运算

(1) 判断字符串大小运算,字符串大小比较的运算符,同逻辑比较运算符。在比较两个字符串时,先比较字符串首字母ASCII码的大小,如果一致,则进行比较第二个字符的ASCII……,如果全部一致,则两个字符串大小一致。

(2) 求字符串长度函数Len(),函数Len() 将返回一个整数,这个整数等于字符串的长度,请尝试如下程序:

Sub StrLen()

Dim A As String, N As Integer

A=“I Love China”

N=Len(A)

MsgBox(N)

End Sub

运行结果显示,N的数值为12,(空格也算字符!)

(3) 左侧取字符函数Left(). 函数Left()返回从左侧取字符串的结果,函数的用法是:Left(字符串,N)表示从字符串的左侧取长度为N个字符后的结果。请尝试一下下面的程序。

Sub L()

Dim A As String, B As String

A=“Microsoft Cooperation”

B=Left(A,5)

MsgBox(B)

End Sub

运行结果,从字符串”Microsoft Cooperation”中,从左侧取5个字符,等于Micro。

(4) 右侧去字符函数Right(). 函数Right()的用法和Left()一致,不同的是,这个结果为从右侧取字符。

(5) 从中间取字符函数 Mid().Mid()的用法是: Mid(字符串,开始位置,N),表示从字符串中开始位置(第多少个字符开始)取N个字符,请尝试下列程序

Sub M()

Dim A As String, B As String

A=“I Came From China”

B=Mid(A,3,4)

MsgBox(B)

End Sub

运行结果:在字符串”I Came From China”中,从第3个字符开始取4个字符,得到”Came”。

(6) 获取字符串2在字符串1中的起始位置。Instr()函数可以返回字符串1在字符串2中的位置。用法是Instr(开始位置,字符串1,字符串2),表示从字符串1的开始位置查找字符串2.请尝试以下程序,若字符串2中没有找到字符串1,则返回开始位置的数值减去1.

Sub I()

Dim A As String, B As String

A=“Microsoft Visual Basic For Applications”

B=“For”

MsgBox(Instr(1,A,B))

End Sub

运行结果。返回字符串”For”在字符串”Microsoft Visual Basic For Applications”中的位置,24.

这里需要说明的是,如果字符串2中包含两个或者两个以上的字符串1,函数只会给出字符串1第一次在字符串2中出现的位置。例如

Sub I2()

Dim A As String, B As String

A=“Microsoft Visual Basic For Applications Is Suit For Beginners”

B=“For”

MsgBox(Instr(1,A,B))

End Sub

结果还是输出24.

(7) 反向获取字符串2在字符串1中的起始位置,InStrRev()函数,可以获得字符串1在字符串2中的位置,用法为InStrRev(字符串1,字符串2,起始位置),与上面函数不同的是,这个函数将在其实位置处从后向前查找,查找到的位置还是按照从前往后计算的!

(8) 将字符串中的英文字符换成大写UCase()函数。UCase(字符串) 作用是,将字符串中的英文字符写成大写。在转换后,数字或者其他符号并不会改变。

(9) 将字符串中的英文字符换成小写LCase() 函数。LCase(字符串) 作用是,将字符串中的英文字符写成小写。

(10) 获取字符的ASCII码:Asc()函数。ASCII(字符)作用是,获取字符的ASCII码。

(11) 按照ASCII码获取字符:Chr()函数。Chr(ASCIICode)作用是,根据ASCIICode(数字)获得ASCII码对照表中数字相对应的字符。

(12) 重复输入String()函数,String(N,字符)将获得字符重复N遍的字符串。

(13) 空格函数Space()。Space(N)将返回N个空格。

(14) 分割字符串函数Split()。Split()的用法是:Split(字符串,分割字符),它的意思是,在字符串中,按照分割字符分割字符串,分割后的结果,是一个字符串数组。请尝试下列程序(关于数组的相关内容,请阅读第4章)

Sub S()

Dim A As String, B() As String, I As Variant

A=“Red,Yellow,Blue,Black,Orange,Pink”

B=Split(A,”,”)

For Each I In B

MsgBox(I)

Next I

End Sub

这一段程序的作用是,先声明一个字符串变量A,这个字符串变量A中储存了各种颜色,即”Red”、”Yellow”、”Blue”、”Black”、”Orange”、”Pink”。每种颜色之间以逗号”,”连接。然后再定义一个数组B,用Split函数分割数组A,分割的依据是逗号”,”。分割完了之后,B这个数组中,有6个元素,这6个元素分别等于上面的”颜色”,然后再用一个I变量把B中的元素一个一个显示出来。所以结果是,第一次信息框显示”Red”,点击”确定”后,第二次显示”Yellow”……,一直到显示”Pink”。

(15) 字符串连接函数Join()。Join()函数正好和Split函数相反,即将一个数组合并为一个字符串。使用方法是,Join(数组,分隔符号),表示用分隔符号连接数组。请尝试下列程序:

Sub J()

Dim A(2) As String, B As String

A(0) = "Red"

A(1) = "Green"

A(2) = "Blue"

B = Join(A, "+")

MsgBox (B)

End Sub

这一程序作用是,先定义了一个数组A,数组A中的三个元素分别赋值为”Red”,”Green”和”Blue”,然后用加号”+”将3个元素连接起来,连接后的字符串为”Red+Green+Blue”。

(16) 字符串连接符号 “&”。”&”符号用于对两个字符串的”连接”。例如:”12” & “34” 连接后结果为”1234”,”Hello” & “World”连接后结果为”HelloWorld”,记住,”&”符号只是简单是”连接”,并不能在连接的两个字符之间加入空格或者其他特殊字符,需要加入这些字符时,可以采用 “&”字符的方式,例如,想连接”Hello”和”World”,中间加入Tab(制表符)时,可以写成”Hello” & Chr(9) & “World”. (制表符的ASCII码为9)。”&”也可以用于字符串和数字的连接,连接效果是,先把数字转化成字符串,再连接,因此,”12” & “34” 与 “12” & 34效果是一样的,均为”1234”。

(17) 字符串连接字符 “+”,”+”也可以用作字符串连接符,与”&”不同的是,”+”的行为比较”诡异”,其连接效果往往不是我们所需要的效果。连接规律为:当连接的两侧均为字符串时,连接效果与”&” 相同,即 “12” & “34” 与”12” + “34” 效果一致,均为”1234”。当连接的一侧为数字字符,另一侧为数字时,会进行数字的加法运算,然后再转换为字符,例如”12” + 34,结果为”46”。而当连接的两侧一侧为字符(含有字母)一侧为数字时,则不可以连接。

3.3.4 变量类型的转换

正如我们之前所见,变量在进行运算时,VBA可以自动将变量进行转换。但是有些转换就不可以自动实现了。VBA中,提供了各种转换类型的函数。我们可以用这些函数进行数据转换,然后再运用于各种运算。

(1)转换成整形变量CInt()。CInt()的作用是,将一个字符或者小数转换成整数,转换过程中,所需要转换的内容为字符时,这个字符中的所有字符必须全部是数字,例如CInt(“2.6”)可以转换成功,如果含有其他字符,例如CInt(“My1”)则会显示类型不匹配。CInt()转换时,无论正数或者负数,均采用”五舍六入”原则,即只有小数部分大于0.5时,才会”入”。例如CInt(2.5),结果是2,CInt(2.51)结果是3,CInt(-2.5)结果是-2,CInt(-2.51)结果是-3。

(2)转换成数值型变量Val()。Val()函数的作用是,将一个字符串转换成数值,转换的数值,当第一个字符是数字的时候,等于第一个数字,当第一个字符不是数字的时候,结果等于0,例如Val(“My21thBook2”)结果为0,而Val(“21th2”)结果为21。

(3)转化成字符串型变量Str()和CStr(),Str()的作用是,将一个数字转换成字符串,转换规律是,如果原先数字大于0,则会在字符串最前端多出一个空格,如果原先数字小于0,则最前面是表示复数的符号,即”-“。CStr()作用也是数字转换成字符,不同的是,如果原先数字大于0,则转换后的字符前面不会多出一个空格。

3.3.5 变量的命名法则

当一个程序比较复杂,使用的变量比较多的时候,有必要引用变量的命名法则。变量的命名法则并不是VBA强行规定的,只是为了程序编译人员方便而人为规定的,可以想象,如果一个程序有1000行命令,涉及到100个变量,如果这些变量随机地按照a1、a2、a3……这样命名,那么用不了多久,程序的编写人员自己都会忘记当初这些变量每一个是什么作用,是什么类型了。

(1)变量命名的总原则:”见字知意”,即看到变量名称就知道这个变量在程序中的作用。例如,定义一个向用户显示信息的字符串变量为Dim MyMsg As String。由于MyMsg这个名字,由My(我的)加上Msg(信息=Massage)所以以后看到MyMsg就知道这个变量当初的用途是向用户显示信息,或者需要向用户显示信息时候,就用这个MyMsg变量。

(2)变量名称尽可能地短,毕竟,不会有人用像例如Get_The_Information_Of_

FileName_As_My_Massage这么长的变量名称(打字都得大半天)。

(3)大小写混合,可以感受一下下面四个变量名: MyName, myname, MYNAME, Myname, myName。尽管VBA中变量名和函数名不区分大小写(后面章节中会说到函数名),但是,在这几种表达方式中,最为舒服的表达方式为MyName。

(4)用变量类型的前3个字母表示这个变量的类型,例如,定义一个字符串的变量,用StrL这个名字比用A这样的名字更能显示这个变量的类型。

(5)使用公认的变量名称,例如,i、j、k一般用于循环变量名,i,j还用于表示行和列的行数、列数,M、N一般用于表示一个二维数组的大小(M为列,N为行),File一般用于文件操作时的文件名称、Path一般用于文件操作时的路径名称,等。

第四节 变量的使用范围

3.4.1 内部变量、私有变量、公共变量、静态变量

(1) 内部变量

正如之前的例子用Dim在Sub内部可以定义变量,但是,这种用Dim在一个过程(Sub)内部定义的变量,在过程的外部却访问不到,不同的过程中,同样的变量名的变量也是不同的两个变量。例如,下面一段程序。

Sub Test1()

Dim MyAge As Integer

MyAge=27

Msgbox(MyAge)

End Sub

Sub Test2()

MyAge=MyAge+1

MsgBox(MyAge)

End Sub

分别运行这两个过程,可以看到,第一个过程结果是27,第二个过程结果是1.因为在Test2过程中的MyAge与Test1中的MyAge是不同的变量。在Test1中声明的MyAge变量,赋值为27。但是在Test2中,并不能访问Test1中的变量而是又重新定义了一个变量MyAge,因为没有给MyAge赋值,所以这个变量的值自动为0,把此时再把这个变量进行加一运算,结果是1.

像这种在过程或者函数内部,随着函数或者过程的消失而消失的变量叫做内部变量,由于内部变量总是随着过程或者函数的结束而消失,所以,在不同的函数或者过程内部可以有相同名称的内部变量。

如果我们想在过程Test2中访问过程Test1中的MyAge变量怎么办?我们可以把过程Test2加上一个参数,并且让这个参数等于过程Test1中的MyAge,然后用过程Test1来调用过程Test2,如下所述。

Sub Test1()

Dim MyAge As Integer

MyAge=27

MsgBox(MyAge)

Call Test2(MyAge)

End Sub

Sub Test2(MyAge As Integer)

MyAge=MyAge+1

MsgBox(MyAge)

End Sub

这里,过程Test1中的MyAge变量通过参数的形式传递给过程Test2,需要注意的是,过程Test2的参数可以用任意的名称,例如写成下列形式:

Sub Test2(Age As Integer)

Age=Age+1

MsgBox(Age)

End Sub

运行结果是一样的。这里有两点值得我们注意,第一,在Test1中,运用Test2过程的时候,前面加了一个关键字:”Call” 这个关键字的作用是,在Test1执行的过程中,执行到这一条语句时,转到Call后面的过程或者函数起始位置开始执行命令。第二,Test2通过参数传递的方式,从Test1中传递了参数MyAge,执行完毕后,Test1中的这个变量MyAge的数值也会发生改变,这一条读者先行记住即可,我们将在代码实战部分讲解参数的传递。

(2)私有变量

可以在一个模块开始的时候定义这个模块所使用的”私有变量”,定义私有变量的方法为Private 变量名 As 类型,定义在一个模块中的私有变量,在这个模块中随处可以访问,只有当模块结束的时候,这个变量才会消失。例如,在同一个用户模块中编入下列程序:

Private MyAge As Integer

Sub T1()

MyAge = 27

MsgBox (MyAge)

End Sub

Sub T2()

MyAge = MyAge + 1

MsgBox (MyAge)

End Sub

在这个模块中,T1过程和T2过程均可以访问变量MyAge,所以运行结果,如果先运行第一个,再运行第二个,第一次结果为27,第二次结果为1.如果直接执行第二个过程,则运行结果为1。(第一个过程相等于给MyAge变量赋值为1,而第二个过程是把MyAge的数值加上1)

私有变量只能在模块内部处处可见,而在模块外部却不可以调用,因此,不同的模块可以有相同名称的私有变量。

(3)公共变量

可以在模块开始的时候声明一个公共变量,声明公共变量的方法是: Public 变量名 As 类型。定义的公共变量,在这个工程中随处可见,不同的模块之间也可以调用。例如,首先插入一个模块,写入:Public MyAge As Integer,然后再插入一个模块写入以下两个过程。

Sub T1()

MyAge=27

MsgBox(MyAge)

End Sub

Sub T2()

MyAge=MyAge+1

MsgBox(MyAge)

End Sub

可以看到,尽管在这个模块中并没有定义私有变量MyAge,但是因为在之前的模块中,已经把MyAge定义成为了公共变量,所以,T1和T2仍然能够正常调用。

(4)静态变量

静态变量是介于内部变量和私有变量之间的一种变量,这种变量只有函数或者过程本身可以调用,其他函数或者过程不可以调用,但是,每调用一次后,静态变量的数值将会得到保存。举个例子说明一下,首先我们来看一下下列程序段。

Sub S()

Dim a As Integer

a=a+1

MsgBox(a)

End Sub

这样一段程序段,无论执行所少次,a的数值始终等于1,这是因为这个过程中的这个变量a随着过程的结束就会消失了,下一次再执行的时候,再重新声明变量a,在变量a没有赋值的时候,VBA自动给这个变量a赋值为0,所以a加上1,始终等于1。

但是,我们只需要把上面过程中的Dim 改成Static,情况就会发生改变了!像下面的这一段程度:

Sub S()

Static a As Integer

a=a+1

MsgBox(a)

End Sub

这样一段程序,随着执行次数的增加,a的数值会一直增加,每一次增加1,只要不关闭这个Excel工作表,a的数就会增加!这是因为,这个过程中,声明了一个静态的变量a,这个a的数值并不会因为过程的结束而消失,下一次再运行的时候,a的数值会保留上一次的运行结果。

第五节 常量

3.5.1 定义常量的意义

计算机中有变量,就有常量。所谓常量就是不能更改的量,例如数字123,字符串”My Work” 等,显然,我们可以用常量给变量赋值,例如Dim a As Integer a=1,但是却不可以给一个常量“赋值”,显然,数字3不可以“赋值”成数字5.即除了赋值运算,常量可以参与前面提到的所有运算。

为什么要定义常量呢,我们来看一下一个例子,假如我们现在要计算一个圆形的表面积、一个圆柱体的体积、和一个球的体积。这时候就需要用到圆周率这样一个常数π,而这个常数π等于3.1415926(假设我们只取小数点后7位数),那么,这个程序就需要这样写。

Sub CalC()

Dim R1 As Double, R2 As Double, H As Double, R3 As Double

Dim S1 As Double, V1 As Double, V2 As Double

R1=Inputbox(“输入圆的半径”)

S1=3.1415926*R1*R1

MsgBox(“圆形的面积为” & S1)

R2=Inputbox(“输入圆柱的半径”)

H=Inputbox(“输入圆柱的高”)

V1=3.1415926*R2*R2*H

MsgBox(“圆柱体积为” & V1)

R3=Inputbox(“输入球的直径”)

V2=4/3*3.1415926*R3*R3*R3

MsgBox(“球的体积为” & V2)

End Sub

这个程序中,Inputbox()的作用是,用一个对话框提示用户输入数据,在计算圆形的面积的时候需要用户输入圆形的半径,在计算圆柱体体积的时候,需要用户输入圆柱的半径和高,而需要计算球体体积的时候,需要用户输入球体的半径。MsgBox()这个在我们之前许多程序中已经见到了,它的作用,是向用户输出程序的结果和相关信息。关于Inputbox和MsgBox的作用,我们将在后续章节中详细讲解。

从这个程序中,我们可以看到,3.1415926这个数字被一个程序用了很多次。像这种常量,因为我们需要不断地引用,所以如果按照每一次重新输入的做法,一是比较麻烦,二是有可能在某一次输入的时候输入错误。这时,就可以定义一个常量。定义常量的命令是: Const 常量名 = 常量。

3.5.2 常量的定义和使用

还是用上面这个例子,如果我们定义了一个常量PI=3.1415926那么,上面这一段程序可以写成:

Sub CalC()

Dim R1 As Double, R2 As Double, H As Double, R3 As Double

Dim S1 As Double, V1 As Double, V2 As Double

Const PI=3.1415926

R1=Inputbox(“输入圆的半径”)

S1=PI*R1*R1

MsgBox(“圆形的面积为” & S1)

R2=Inputbox(“输入圆柱的半径”)

H=Inputbox(“输入圆柱的高”)

V1=PI*R2*R2*H

MsgBox(“圆柱体积为” & V1)

R3=Inputbox(“输入球的直径”)

V2=4/3*PI*R3*R3*R3

MsgBox(“球的体积为” & V2)

End Sub

可以看出,我们这里用常量PI代替了3.1415926,在程序中,每一次需要使用数字3.1415926的时候,就用PI来代替。这样做有三个好处:第一,在语法上更加接近我们传统的数学公式,毕竟,PI*R1*R1比3.1415926*R1*R1“更像”圆面积公式。第二,减少输入,只需要在开始定义的时候把PI定义成3.1415926,后面就可以直接用PI来代替这个数字了。第三,减少输入的错误,假设程序有100行,3.1415926这个数字需要使用100次,那么,如果直接用数字,可能会在某一次输入的时候输入成3.14或者3.14159265358979这样的数(毕竟人的大脑容易产生遗忘)。

相关阅读

关键词不能为空
极力推荐

ppt怎么做_excel表格制作_office365_word文档_365办公网