第二章 Visual Basic编程语言
复习要求
1.掌握基本数据类型。
2.熟练掌握常量与变量、常用内部函数、表达式与运算符、标识符命名规则、语句书写格式。
3.掌握格式输出函数、IIf函数。
4.熟练掌握赋值语句、Print语句、注释语句、结束语句、If语句、Select语句、For循环语句、While循环语句、Do循环语句。
5.理解数组的概念、熟练掌握数组的定义、数组的初始化、数组的清除、数组的访问。
6.掌握通用过程和事件过程、自定义函数的编写及调用、理解参数的传递方法。
7.理解VB程序错误种类,掌握VB程序错误处理方法。
复习内容
一、基本数据类型
(1)字符型(String):用于各种字符串的处理。
(2)数值型:用于处理不同类型的数值。
① 整型(Integer):用于处理-32768~32767之间的整数。
存储空间占2字节。
② 长整型(Long):用于处理-2147 483648~2147 483647之间的整数。
存储空间占4字节。
③ 单精度型(Single):用于处理不超过7位有效数字的实数。
存储空间占4字节。
④ 双精度型(Double):用于处理8~15位有效数字的实数。
存储空间占8字节。
⑤ 货币型(Currency):用于处理整数位不超过15位,4位小数的数值。
存储空间占8字节。
(3)字节型(Byte):无符号的整数,用于二进制数据处理。
存储空间占1字节。
(4)日期型(Date):用于日期和时间的处理。存储空间占8字节。
(5)布尔型(Boolean):用于真(True)和假(False)的处理。
存储空间占2字节。
(6)可变型(Variant):能够存储所有系统定义类型的数据。
数值型占16字节,字符型占22字节加上字符串长度。
(7)对象型(Object ):用于引用程序或某些应用程序中的对象。用 Set语句将对象赋值于对象变量。存储空间占4字节。
二、常量
在程序执行期间数值始终不变的量称为常量。在 Visual Basic 中,常量分为两种:一般常量和符号常量。
(一)一般常量
即包含在程序代码中的常量。按数据类型,一般常量分为以下几种。
(1)字符串常量:就是用双引号括起来的一串字符。这些字符可以是除双引号和回车键之外的任何字符。例如,字符串常量:"我爱我的祖国!","abcdefg1234567890"。
(2)数值常量:包括整数、定点数和浮点数。
整数有十进制数、十六进制数和八进制数三种形式。十六进制数以&H(或&h)开头,八进进制数以&O(或&o)开头。例如: 十进制数 255,在程序中可以表示为255、&Hff、&O377三种形式。
定点数是带有小数点的正数或负数。例如:3.141 592 6、-1.5、0.1、12.05等。
浮点数由尾数、指数符号和指数三部分组成。指数符号用 E表示。
(3)布尔型常量:只有两个值,即True、False。
(4)日期型常量:期型常量要用“#”符号括起来。例如,#1/31/2007#、#1/31/2007 11:49:50 PM#。
(二)符号常量
符号常量是在程序中用标识符表示的一些永远不变的常数或字符串。
符号常量分为两种:系统内部定义的符号常量和用户定义的符号常量。
(1)系统内部定义的符号常量。Visual Basic 6.0定义了许多符号常量,例如:vbRed (红色)、vbBlue (蓝色)、vbGreen(绿色)等,在程序设计中可以直接使用。
(2)用户定义的符号常量可以用 Const语句来声明,语法格式如下。
Const 常量名 [As 类型] = 常量表达式
一旦声明了常量,就不能在此后的语句中改变它的数值,这是一个安全特性,也是声明常量的一个好处。
三、标识符命名规则
Visual Basic中有许多需要命名的地方,如符号常量名、变量名等,在命名时需要遵循以下规则。
(1)标识符必须以字母开头。最大长度为255。
(2)标识符不能使用 Visual Basic的保留字(关键字)。不能包含在 Visual Basic中有特殊含义的字符,例如:句号、空格、类型说明符、运算符等。
(3)Visual Basic的标识符不区分大小写。
(4)标识符在标识符的同一范围内必须是唯一的。
在Visual Basic中,符号常量名、变量名、过程名、记录类型名、元素名等名称都必须遵循上述命名规则。
四、变量
(1)程序执行过程中其值可以变化的量称为变量。在程序运行中,系统为程序中的每一个变量分配一个存储单元,变量名实质上就是计算机内存单元的命名。
(2)变量名用于识别变量在内存中的位置,变量的类型指定其占用内存空间的大小。
注意:“变量名”的命名规则遵守标识符的命名规则。
“类型”用来声明“变量名”的数据类型或对象类型。
(3)Visual Basic中,可以用变量声明语句来声明变量的类型,语法格式如下:
<Dim|Private|Static|Public > <变量名> [As 类型] [,<变量名> [As 类型]]
使用声明语句声明一个变量后,Visual Basic自动将数值类型的变量赋初值为0,将字符或 Variant类型的变量赋初值为空串,将布尔型的变量值赋初值为 False,将日期型的变量赋初值为 00:00:00(如果系统为12小时制,会有所不同)。
Visual Basic中允许变量不经过声明就直接使用,这称为隐式声明,所有隐式声明的变量都是Variant的,并默认为局部变量。
五、常用内部函数
在程序中经常需要一些特定的运算或操作。Visual Basic 把这些运算或操作进行了封装,以函数的形式提供给用户。合理使用这些函数,可以简化程序的设计。这些函数主要是:数学函数、字符串函数、日期时间函数和转换函数。
(一)数学函数
(1)Abs(x) :求x的绝对值,结果类型与X类型相同。
例:Abs(-3.6)=3.6
(2)Asc(x):求字符串首字符的 ASCII码 ,结果为Integer型。
例: Asc("A")=65
(3)Atn(x):求反正切函数,结果为Double型。
例: 4*Atn(1)=3.1415926
(4)Cos(x):求余弦函数(x是弧度),结果为Double型。
例: Cos(60*3.1415926/180)=0.5
(5)Exp(x):求ex(e≈2.718 28),结果为Double型。
例: Exp(1)=2.71828
(6)Fix(x):去掉一个浮点数的小数部分,结果为Double型。
例: Fix(123.432)=123
(7)Int(x):取不大于x的最大整数,结果为Double型。
例: Int(5.2)=5
(8)Log(x):求以e为底的对数,结果为Double型。
例: Log(2.71828)=1
(9)Rnd(x):产生0~1间的随机数,结果为Single型。
(10)Sin(x):求正弦函数(x是弧度),结果为Double型。
例: Sin(30*3.1415926/180)=0.5
(11)Sqr(x):求x的算术平方根,结果为Double型。
例:Sqr(25)=5
(12)Tan(x):求正切函数(x是弧度),结果为 Double型。
例:Tan(45*3.1415926/180)=1
说明:
(1)三角函数的自变量 x是一个数值表达式。其中Sin、Cos和Tan的自变量是以弧度为单位的角度;Atn函数的自变量是正切值, 它返回正切值为 x的角度 (以弧度为单位)。
一般情况下,自变量以角度给出,可以用下面的公式转换为弧度。
1度=3.1415926/180(弧度)
(2)在使用随机函数 Rnd时,为了能产生不同的随机数序列,可以在使用随机函数之前加一条随机数生成器初始化语句,格式为:
Randomize [数值]
(3)为了生成某个范围内的随机整数,可以使用以下表达式:
Int((上限 - 下限 + 1) * Rnd() + 下限)
例如,在生成 1~100范围内的随机整数,可以使用以下表达式。
Int((100 - 1 + 1) * Rnd() + 1) 即Int(100 * Rnd() + 1)
(二)字符串函数
(1)LCase(String):把大写字母转换为小写字母 ,结果为String型。
例:LCase("AbC")="abc"
(2)Left(String, n):取左字符串函数,结果为String型。
例: Left("abcdef",3) = "abc"
(3)Len(x): 取字符长度函数,结果为Integer型 或 Variant型。
例: Len("abcdef") = 6
(4)Ltrim(x):去掉字符串左边的空格,结果为String型。
例:Ltrim(" A ")="A "
(5)Mid(String, m, n):取中段字符串函数,结果为 String型。
例: Mid("abcdef",3,2) = "cd"
(6)Right(String, n):取右字符串函数,结果为String型。
例: Right("abcdef",3) = "def"
(7)Rtrim(String):去掉字符串右边的空格,结果为 String型。
例: Rtrim(" A ")=" A"
(8)Space(n) :取空格函数,结果为String型。
例:Space(3) =" "
(9)UCase(String):把小写字母转换为大写字母,结果为 String型。
例:UCase("abc")="ABC"
(三)日期和时间函数
(1)Now:结果为Date型,返回系统日期和时间(yy-mm-dd hh:mm:nn)。
(2)Day:结果为Integer型,返回月中第几天(1~31)。
(3)Date:结果为Date型,返回当前日期(yy-mm-dd)。
(4)Weekday:结果为Integer型,返回星期几(1~7)。
(5)Month:结果为Integer型,返回一年中的某月(1~12)。
(6)Year:结果为Integer型,返回年份(yyyy)。
(7)Hour:结果为Integer型,返回小时(0~23)。
(8)Minute:结果为Integer型,返回分钟(0~59)。
(9)Second:结果为Integer型,返回秒(0~59)。
(10)Timer:结果为Integer型,返回从午夜算起已过的秒数。
(11)Time:结果为Date型,返回当前时间(hh:mm:nn)。
(四)格式输出函数
Format(表达式[,格式字符串])
说明:
(1)表达式是要格式化的数值、日期或字符串表达式。
(2)格式字符串是表示按指定的格式输出表达式的值。
(3)格式字符串有三类:数值格式、日期格式和字符串格式。
(4)格式字符串要放在引号内。
1.数值格式化常用格式字符
(1)0:实际数字小于符号位数,数字前后加0。
(2)#:实际数字小于符号位数,数字前后不加0。
(3).:加小数点。
(4),:千分位。
(5)%:数值乘以100,加百分号。
(6)$:在数字前加$。
(7)+:在数字前加+。
(8)-:在数字前加-。
(9)E+:用指数表示。
(10)E-:用指数表示。
2.日期时间表达式格式化常用格式化字符
(1)d:显示日期(1~31),个位前不加0。
(2)dd:显示日期(1~31),个位前加0。
(3).y:显示一年中的天(1~366)。
(4)yy:两位数字显示年份(00~99)。
(5)yyyy:四位数字显示年份(0100~9999)。
(6)h:显示小时(0~23),个位前不加0。
(7)hh:显示小时(0~23),个位前加0。
(8)m :显示月份(1~12),个位前不加0。
(9)mm:显示月份(1~12),个位前加0。
(10)s:显示秒(0~59),个位前不加0。
(11)ss:显示秒(0~59),个位前加0。
(五)常用的数据类型转换函数
在 Visual Basic 中,一些数据类型可以自动转换,但是多数类型不能自动转换,需要用类型转换函数进行转换。
(1)CBool(x):结果为Boolean型,参数是任何有效的字符串或数值表达式。
(2)CByte(x):结果为Byte型,参数是0~255。
(3)CCur(x):结果为Currency型,参数是-922 337 203 685 477.5808~922 337 203 685 477.5807。
(4)CDate(x):结果为Date型,参数是任何有效的日期表达式。
(5)CDbl(x):结果为Double型,参数范围如下。
负数为-1.79769313486232E308~-4.94065645841247E-324;
正数为4.94065645841247E-324~1.79769313486232E308。
(6)CInt(x):结果为Integer型,参数范围是-32 768~32 767,小数部分四舍五入。
(7)CLng(x):结果为Long型,参数范围是-2 147 483 648~2 147 483 647,小数部分四舍五入。
(8)CSng(x):结果为Single型,参数范围如下。
负数为-3.402823E38~-1.401298E-45;
正数为1.401298E-45~3.402823E38
(9)CStr(x):结果为String型,依据参数的情况返回字符串。
(10)CVar(x):结果为Variant型,若为数值,则范围与 Double相同;若不为数值,则范围与 String相同。
数据类型转换函数的自变量 x可以是字符串表达式或者数值表达式,传递给转换函数的表达式不能超过目标数据类型的范围,否则将发生错误。
六、运算符和表达式
在程序中对数据进行处理,其实就是对数据进行各种运算。运算符和数据组成各种各样的表达式,以完成各种不同的运算。在 Visual Basic 6.0中,主要有算术运算、字符串运算、关系运算和布尔运算。
(一)算术表达式
算术表达式由算术运算符、数值型量和圆括号组成,其运算结果为数值型。Visual Basic 6.0提供了8个算术运算符,如表2-1所示。
表2-1 算术运算符及优先级
(二)字符表达式
在 Visual Basic中有一个专门的字符串连接运算符“&”,用于连接两个或更多个字符串并构成字符串表达式。 算术运算符“+”也可以作为字符串连接运算符使用。Visual Basic在运算时会自动进行类型匹配转换,为了防止转换不符合要求,一般情况下,提倡使用运算符“&”来进行字符串连接运算。
例如,字符串表达式"xyz" & "123" & "abc" & "45" 的运算结果为 "xyz123abc45"。
(三)关系表达式
关系运算符用来对两个表达式的值进行比较,比较的结果是一个逻辑值,即真(True)或假(False),如表2-2所示。
表2-2 关系运算符
此外Is运算符还在 Select Case语句中使用。
关系表达式由关系运算符、数值表达式、字符串表达式组成,但关系运算符两侧的数据类型必须完全一致。Visual Basic 把非0值都认为是 True,但一般以-1来表示 True,以 0来表示 False。两个表达式是 Byte、Boolean、Integer、Long、Single、Double、Date、Currency时,可以进行数值比较。当一个表达式是数值型另一个是 Variant型时,则进行数值比较。字符串数据按其 ASCII码值进行比较。字符串比较时,首先比较两个字符串的第一个字符,其中ASCII码值较大的所在的字符串大。如果第一个字符相同,则比较第二个字符,依次类推。
关系表达式都是单独使用的,不存在优先级问题。
(四)布尔表达式
布尔运算符用来对各种布尔型数据进行布尔运算,如表2-3所示。
表2-3 算术运算符及优先级
布尔表达式由关系表达式、布尔运算符、布尔型常量组成,语法格式如下:
<关系表达式> <布尔运算符> <关系表达式>
注意:布尔型表达式的运算结果仍然为布尔型数据。
(五)运算符优先级
一个表达式可能含有多种运算,系统会按预先确定的顺序进行计算,此顺序称为运算符的优先顺序。从高到低顺序为:算术运算符→字符串连接运算符→关系运算符→布尔运算符。
说明:级别相同的运算符,按照它们从左到右出现的顺序进行运算。括号内的运算总是优先于括号外的运算。
七、语句格式
在 Visual Basic中,编写程序代码时,需要注意以下规则:
(1)不区分大小写。Visual Basic对关键字有自动转换大小写功能。例如:在输入 Print语句时,不论输入“PRINT”还是“print”,Visual Basic都会转换为“Print”。
(2)标点符号都需要在英文状态下输入。
(3)语句以回车键结束。一般要求“一句一行”。也可以使用复合语句,即把多句写在一行上,但每句代码之间必须用冒号(:)连接。当一行代码很长时可以用“空格+下画线”来续行。
八、Print语句
程序运行的结果一般都需要用输出语句输出到屏幕上。
Print语句就是用来输出数据和文本的一个重要语句。格式如下:
[对象名称.]Print [表达式] [,|;] [表达式] [,|;] …
其中“对象名称”可以是窗体(Form)、图片框(PictureBox)、打印机(Printer)、调试窗口(Debug),如果省略“对象名称”,则在当前窗体上输出。
“表达式”可以是符合Visual Basic语法的表达式,若省略“表达式”,则输出一个空行。
可以用一个 Print语句输出多个表达式的值,表达式之间用分隔符隔开。若用逗号分隔,则按标准输出格式(分区输出格式)显示数据项,各表达式之间间隔14个字符的位置;若用分号输出,则表达式按紧凑输出格式输出数据项。
Print语句具有计算和输出双重功能,对于表达式,先计算后输出。在一般情况下每执行一次Print语句都会自动换行。若想在一行上显示,则可在print语句的末尾加上分号或逗号。
九、赋值语句
当需要把表达式的值保存到变量中时,可使用赋值语句把右边的表达式的值赋给左边的变量或某个带有属性的对象,语法格式如下:
[Let] 变量名 = 表达式
说明:
(1)变量和表达式的数据类型必须一致。若两者同为数值型但精度不一样,则系统会强制将表达式的值转换为变量所要求的精度。
(2)赋值号“=”表示将表达式的值赋值给变量,与数学上的等号意义不一样。Let表示赋值,通常省略。例如:x=8=9语句的含义是将关系表达式 8=9的结果赋给变量 x,因此x的值为0(False)。
(3)赋值语句兼有计算与赋值双重功能,它首先计算赋值号右边“源操作符”的值,然后把结果赋给赋值号左边的“目标操作符”。
(4)若把多个赋值语句放在同一行,各语句之间必须用冒号隔开。例如:a=3:b=4:c=5。
十、注释语句
注释语句是为了方便程序阅读,对程序进行说明的语句,对程序运行没有影响。在 Visual Basic中有两个注释语句:Rem和',语法格式如下:
Rem|' [注释文本]
注释语句可以独占一行,也可以放在其他语句行尾。使用 Rem关键字时,Rem关键字与注释文本之间要加一个空格;放在其他语句尾时,要用冒号(:)隔开。使用撇号(')关键字时,则不必加冒号。
十一、结束语句
在 Visual Basic中有两个结束语句,它们的语法如下:
End Unload <对象名称>
End语句的功能是结束正在运行的程序功能。
Unload语句的功能是从内存中卸载窗体或控件。
十二、选择结构
(一)If语句
Visual Basic 6.0的选择语句包括单行形式和块形式。
(1)单行形式的 If语句格式:
If 条件 Then [语句1][Else 语句2]
单行形式If语句的执行流程是,如果“条件”值为 True(真),则执行“语句 1”;否则执行“语句 2”。“Else语句 2”可以省略。
(2)块形式的If语句格式:
If <条件1> Then [语句块1] [ElseIf <条件2> Then [语句块2] . [ElseIf <条件3> Then [语句块3] …… [Else [语句块n]] End If
说明:
(1)块形式的If语句的执行流程是:如果“条件1”为True(真),则执行“语句块1”;否则,如果“条件2”为True(真),则执行“语句块2”;……;如果条件都为 False (假),则执行“语句块n”。
(2)在块结构的If语句中,If语句必须是第一行语句,If语句块必须以一个End If语句结束。
(3)Else和ElseIf子句都是可选的。这里的“语句块”可以是一个语句,也可以是多个语句。
IIf函数可以执行简单的判断操作,语法格式如下:
Result=IIf(条件,True部分,False部分)
变量 Result用于保存 IIf函数的返回值。“条件”是一个布尔表达式。当“条件”为True(真)时,IIf函数返回“True部分”,当条件为 False(假)时,返回“False部分”。
(二)Select语句
Select Case语句根据测试表达式的值,从多个语句块中选择一个符合条件的语句块执行。
语法格式如下:
Select Case <测试表达式> Case 表达式列表1 语句块1 [Case 表达式列表2 语句块2] …… [Case Else 语句块n] End Select
说明:
(1)其中测试表达式可以是数值或字符串表达式;每个“表达式列表”可以是一个表达式、一组用逗号分隔的枚举值(如1, 2, 3)、表达式1 to表达式2(如1 to 5)、Is关系运算符表达式(如Is < 3)。
(2)Select Case语句执行的流程是:对测试表达式进行测试并检查表达式列表 1,若为真,则执行语句块1并结束选择;若为假,继续检查下一个条件。如果都不为真,则执行语句块n。如果没有语句块 n,则什么也不做就结束选择。
十三、循环结构
(一)For 循环
For 循环用于重复执行一行或数行代码,语法格式如下:
For 循环变量=初值 To 终值 [ Step 步长 ] [ 循环体 ] [ Exit For ] [ 循环体 ] Next [ 循环变量 ]
说明:
(1)循环变量用于循环的计数,每重复一次循环之后,循环变量的值就会增加一个步长,在循环体中除非特殊情况,一般不要改变循环变量的值,否则会改变循环体的执行次数。
(2)步长是循环变量的增量,其值可以是正数或负数,如果没有设置 Step,则步长默认值为1。
(3)循环体在下列两种情况下将不会执行: 步长为正数时,循环变量的值大于终值;步长为负值时,循环变量的值小于终值。
(4)Exit For通常用在选择语句中,用于提前结束循环。
(二)While 循环
(1)While根据指定条件重复执行一行或多行代码。语法格式如下:
While <条件> [ 循环体 ] Wend
(2)While循环的执行流程是:当条件为 True时,执行循环体,当条件为 False时退出循环。很明显,当条件为 True进入循环后,如果条件没有变化,循环将一直进行下去。所以,循环内应该有一个改变循环条件的语句,让程序在适当的时候结束循环。
(三)Do循环语句
在 Visual Basic中,循环语句除了 For-Next语句、While语句外,Visual Basic还提供了 Do循环语句,Do循环语句有以下两种语法格式:
1.格式一
Do [While|Until<循环条件>] [ 语句块 ] [ Exit Do ] [ 语句块 ] Loop
2.格式二
Do [ 语句块 ] [ Exit Do ] [ 语句块 ] Loop [While|Until<循环条件>]
说明:
(1)格式一的执行流程: 先检查循环条件, 如果循环条件符合执行循环的要求 (选用While,循环条件为 True时;选用 Until,循环条件为 False时),则执行语句块,否则(选用 While,循环条件为 False时;选用 Until,循环条件为 True时)退出循环。
(2)格式二的执行流程:首先执行语句块,然后检查循环条件,如果循环条件符合执行循环的要求(选用 While,循环条件为 True时;选用 Until,循环条件为 False时),则 执行语句块,否则(选用While,循环条件为 False时;选用 Until,循环条件为 True时)退出循环。
(3)格式一中的语句块可能一次也不能执行,格式二中的语句块至少要执行一次。
(4)当格式一和格式二中的“While | Until <循环条件>”部分省略时,这个循环成为一个不能结束的循环,如果要结束循环,需要在循环体中适当的位置出现“Exit Do”,以便程序能在一定的条件下结束循环。
十四、数组
在 Visual Basic 中,把一组具有同一名字、不同下标的变量称为数组。在计算机中,数组占据一块连续的内存区域,数组名就是这个区域的名称, 区域的每个单元都有自己的地址,下标指出每个单元在该区域的位置。
(一)定长数组
定长数组是指元素个数保持不变的数组。
在 Visual Basic中可以用以下语句来声明数组:使用Dim可在窗体模块或标准模块中声明数组,也可以在过程中使用;使用 Private 可在窗体模块或标准模块中声明数组,也可用在过程中;使用 Static可在过程中声明静态数组;使用 Public可在标准模块中声明全局数组。
下面以 Dim语句为例说明数组声明的语法格式,当用其他语句声明数组时,其格式也是一样的。
用 Dim语句声明数组时,应遵循以下语法格式:
Dim 数组名([下标下界 To ]下标上界[,下标下界 To 下标上界 ]) [ As 数据类型]
说明:
(1)Dim语句必须放在使用数组之前,遵守先声明后使用的原则。
(2)格式中的数组名可以是任何合法的变量名。
(3)数据类型可以是 Integer、Long、Single、Double、Currency、String等基本类型,也可以是 Variant(变体)类型。若省略As子句,则定义的数组为 Variant(变体)类型。
(4)用 Dim语句定义数组时,数值数组中的全部元素初始化为0,字符串数组中的全部元素初始化为空字符串。
(5)下标下界和下标上界表示该维的最小和最大下标值,通过关键字 To连接起来,代表下标的取值范围。下标的范围可以是不超过 Long数据类型的范围(-2147483648~2147483647)。如果省略了“下标下界To”,数组默认下界为 0,如果希望下标从1开始,可以通过Option Base语句来设置,即Optiong Base 1,该语句必须出现在窗体层或模块层的说明部分。
(6)数组有一个下标变量,称为一维数组。有两个或多个下标变量,称为二维数组或多维数组。数组的维数最多可以有60维(60个下标变量)。在声明多维数组时要慎重,数组维数的增加将使内存占用急剧增加,导致内存分配不足产生溢出错误。
(7)不能使用 Dim语句对已经声明了的数组进行重新声明。
(8)在同一过程中,数组名不能与变量名同名。
(9)在声明数组时,每一维元素的个数必须是常数,不能是变量和表达式。
(10)数组的下界必须小于数组的上界。
通过 LBound和 UBound函数可以测试上界值和下界值,语法格式如下。
LBound(数组名[,维]) UBound(数组名[,维])
这两个函数分别返回一个数组中指定维的上界和下界。其中数组名是要测试的数组的名字,维是要测试的维度。LBound函数返回数组某一维的下界值,而 UBound函数返回数组某一维的上界值,这两个函数一起使用可以确定一个数组的大小。
(二)默认数组
一般情况下,声明数组应指明其类型,例如:
Static Vari(1 To 100) As Integer' 声明类型为整型有100个元素的数组Vari
不过,在 Visual Basic中,允许声明默认数组,即数据类型为 Variant的数组。例如:Static Vari(1 To 100) '声明数组是默认数组,其类型为Variant。
该声明等价为:
Static Vari(1 To 100 ) As Variant
在多数程序设计语言中,一个数组各个元素的数据类型都要求相同,即一个数组只能存放同一种类型的数据。对于默认数组来说,同一个数组可以存放各种不同类型的数据,因此,默认数组可以说是一种“混合型数组”。
(三)数组的初始化
数组初始化就是给数组的各个元素赋初值。Visual Basic还提供了 Array函数,用于对数组进行初始化,为数组元素赋值,语法格式如下:
数组名 = Array(数组元素值)
说明:
(1)使用Array函数给数组赋初始值时,数组变量只能是 Variant类型。Array只适用于一维数组,不能对二维或多维数组赋值。
(2)数组可以不声明直接使用,也可以只声明数组不声明类型或声明成 Variant类型。
(3)数组名是预先声明的数组名,在其后没有括号。数组元素值是要赋给数组各元素的值,各值之间以逗号分开。如果不提供数组元素值,则创建一个长度为 0的数组。
(4)在默认情况下,使用Array函数创建的数组的下界从0开始。如果希望下标从 1开始,则应使用语句Option Base 1。
(四)数组的清除
如果想释放动态数组的存储空间或清除定长数组的内容,可以用 Erase语句来实现,语法格式如下:
Erase 数组名[,数组名]……
(1)Erase语句用来重新初始化定长数组的元素,或者释放动态数组的储存空间。
(2)当把 Erase语句用于定长数组时,不释放数组的所有空间,只是清除数组的内容。
(3)如果这个数组是数值数组,则把数组中的所有元素置为 0;如果是字符串数组,则把数组中的所有元素置为空字符串,如果是 Variant数组,则将每个元素置为Empty;如果是对象数组,则将每个元素设为Nothing。
(4)当把 Erase语句用于动态数组时,将删除整个数组结构并释放该数组所占有的内存,下一次使用需要重新用 ReDim语句定义。
(五)动态数组
动态数组是指计算机在执行过程中才给数组开辟存储空间的数组,可以用 ReDim语句再次分配动态数组占据的存储空间,也可以用 Erase语句删除它,收回分配给所占存储空间。
动态数组可以用变量作为下标值,在程序运行过程中完成声明,动态数组可以在任何时候改变大小。
创建动态数组通常分为两步:
首先在窗体级别、标准模块或过程中,用 Dim语句(模块级数组)、Public语句(公用数组)、Private或 Static (局部数组)声明一个没有下标的数组(括号不能省略)。
然后在过程中用 ReDim语句定义带下标的数组。
ReDim语句用来声明或重新声明原来用 Private、Public 或 Dim语句声明过的已经用带空圆括号(没有维数下标)的动态数组的大小。语法格式如下:
ReDim [Preserve] 变量(下标,下标) As 数据类型名称
说明:
(1)可以用ReDim语句在过程内直接声明数组。 对于用ReDim声明的数组,如果用ReDim重新声明只能修改数组中元素的个数,不能修改数组的维数。
(2)用 Private、Public或Dim语句声明过的已经用带空圆括号(没有维数下标)的动态数组,在一个程序中,可以根据需要使用 ReDim语句修改数组的维数或元素的个数,但不能修改数据的类型。
(3)重新分配动态数组时数组中的内容将被清除,如果在 ReDim语句中使用了Preserve选择项,则保留数组内容。
(4)ReDim语句只能出现在事件过程或通用过程中,用它定义的数组是一个临时数组,即在执行数组所在的过程时为数组开辟一定的内存空间,当过程结束时,这部分内存立即被释放。
(六)访问数组的方法
建立一个数组之后,可以对数组或数组元素进行操作。数组的基本操作包括输入、输出及复制,这些操作都是对数组元素进行的。
1.数组的引用
引用数组元素方法是,在数组名后面的括号中指定下标。引用数组时应注意以下几点。
(1)引用数组元素是在数组名后的括号内指定下标。
(2)在引用数组元素时,数组名、类型和维数必须与声明数组时一致。
(3)如果建立的是二维或多维数组,则在引用时必须给出两个或多个下标。
(4)引用数组元素时,要注意下标值要在声明的范围之内。
(5)一般可以出现常数或变量的地方都可以引用数组元素。
2.访问数组的常用方法
对数组元素的输入、输出和复制,一般采用以下方法实现。
(1)当数组较小或者只需要对数组中的指定元素操作时,可以通过直接引用数组,实现对数组指定元素的操作。
(2)对于元素较多的一维数组,通常采用一重循环实现对数组各个元素的遍历。
(3)对于元素较多的二维数组,通常采用二重循环实现对数组各个元素的遍历。本任务中数组的赋值、计算、输出即采用了二重循环。
(4)对于多维数组,通常采用多重循环实现对数组各个元素的遍历。
十五、过程
为了简化程序设计,通常将程序分割成较小的逻辑部件,这些部件称为过程。在 Visual Basic中,过程分为 Sub过程(没有返回值)和Function过程(具有返回值)。所有的可执行代码都必须属于某个过程。Sub过程可以放在标准模块或窗体模块中。过程的定义是平行的。不能在过程中定义其他过程。
(一)事件过程
事件过程分为窗体事件过程和控件事件过程,两者都使用 Private进行声明。
(1)窗体事件过程:
Private Sub Form_事件名 [(参数列表)] 语句块 End Sub
(2)控件事件过程:
Private Sub 控件名_事件名 [(参数列表)] 语句块 End Sub
(3)建立事件过程可以有以下3种方法:
① 双击窗体或控件,即可打开代码编辑器窗口,并且会出现该窗体或控件的默认过程代码。例如双击窗体会出现 Form的默认过程代码。
② 单击工程资源管理器窗口的“查看代码”按钮,然后从“对象”列表框中选择一个对象,从“过程”列表框中选择一个过程。
③ 自己编写事件过程,在代码编辑器窗口中直接编写事件过程。在事件过程中,过程的范围、名称、参数在通常情况下不能修改。应使用其默认的范围、名称和参数。
(二)通用过程
为了完成某个特定任务,通常会编写一段相对独立的程序。为了方便这段程序的维护、使用,这段程序一般用通用过程进行组织,语法格式如下:
[Private | Public ] [Static] Sub 过程名 [(参数列表)] [语句块] [Exit Sub] [语句块] End Sub
说明:
(1)Sub过程如果没有显式指定 Public、Private关键字,则 Sub过程默认范围是Public。Public声明在所有模块中都可以使用的过程。Private用于声明只能在包含该声明的模块中使用的过程。使用 Static关键字表示在调用 Sub过程之间,保留 Sub过程内局部变量的值。
(2)语句块是完成特定任务编写的程序,可以没有一行,也可以有多行。
(3)Exit Sub语句可以使程序在一定条件下从一个 Sub过程中退出,接着从调用该过程语句的下一行继续执行。在 Sub过程的任何位置都可以有 Exit Sub语句。
(4)过程名遵循标识符命名约定。若要建立通用过程,可打开代码编辑器窗口,从“对象”列表框中选择“通用”选项,然后在代码编辑区的空白处输入“Sub <过程名>”,按“Enter”键后即会出现 End Sub语句。
(三)参数传递
声明过程时,参数列表应遵循以下语法格式:
[Optional] [ByVal | ByRef] [ParamArray] 变量名[( )] [As 数据类型名称]
其中Optiontal表示参数是可选的,ByVal表示该参数按值传递,ByRef表示该参数按地址传递,ParamArray表示可以提供任意数目的参数,变量名命名遵守标识符命名规则,“( )”表示变量是一个数组,As 子句用来说明变量的类型。多个参数时,参数之间用逗号进行分隔。
下面分别讨论参数关键字的用法:
(1)按值传递参数。按值传递参数时,传递的只是变量的副本。如果过程改变了这个值,则变动只影响副本而不会影响变量本身。用 ByVal关键字指出参数是按值来传递的。
(2)按地址传递参数。按地址传递参数时,传递的是变量的内存地址。过程通过变量的内存地址去访问实际变量的内容。将变量传递给过程时,通过过程可永远改变变量的值。按地址传递参数是 Visual Basic过程参数传递的默认方式。
(3)使用可选的参数。在过程的参数列表中加入Optional关键字,就可以指定过程的参数为可选的。如果指定了可选参数,则参数表中此参数后面的其他参数也必是可选的,并且要用 Optional关键字来声明。
(4)使用不定数量的参数。一般说来,过程调用中的参数个数应等于过程说明的参数个数。用 ParamArray关键字指明,过程将接受任意个数的参数。ParamArray只能用于参数列表中最后一个参数,并且不能与 ByVal、ByRef、Optional一起使用。
(四)Sub过程的调用
要执行一个过程,就必须调用过程。在 Visual Basic 中,事件过程一般由操作系统调用,如鼠标事件等。通用过程则由通用过程或事件过程调用,通用过程最终由事件过程调用执行。在 Visual Basic中,调用 Sub过程有以下两种方式。
(1)用 Call语句调用过程,语法格式如下:
Call 过程名 [(实际参数)]
用Call语句调用一个过程时,如果过程本身没有参数,则实际参数和括号可以省略;否则应给出相应的实际参数,并把参数放在括号中。
(2)把过程名作为一个语句使用,语法格式如下:
过程名 [实际参数]
与第一种过程调用方式相比,这里省掉了关键字 Call,实际参数也不能放在括号中。
(五)自定义函数
在 Visual Basic中,除了内部函数外,还允许用户自定义函数,语法格式如下:
[Private|Public][Static]Function <函数名> ([参数列表]) [As 数据类型] [语句块] [函数名=表达式] [Exit Function] [语句块] [函数名=表达式] End Function
说明:
(1)Public用于声明在所有模块中可以使用的 Function过程;Private用于声明只能在包含该声明的模块中使用的Function过程;使用 Static关键字表示在调用 Function过程之间,保留 Function过程内局部变量的值。如果未显式指定 Public、Private关键字,则Function过程默认范围是 Public。
(2)函数名遵守 Visual Basic标识符命名规则。
(3)若要提前退出Function过程,可在 Function过程内适当位置加入 Exit Function语句。
(4)Function过程具有返回值。As子句用于声明函数的返回值的数据类型,数据类型可以是 Integer、Long、Single、Double、Currency、Boolean或 String。如果省略 As 子句,则返回值的类型为 Variant。若要从 Function过程返回一个值, 可将这个值赋给函数名。这个赋值语句可以出现在过程的任意位置。如果省略了“函数名=表达式”,则该过程返回一个默认值(数值函数过程返回 0值,字符串函数过程返回空字符串)。通常情况下,在过程中为函数名赋值。
(5)声明 Function过程时,参数列表的用法和声明 Sub过程时相同。
Function过程的调用方法和内部函数调用方法相同,语法格式如下。
函数名([参数列表])
在语句中可把函数名作为表达式或表达式的一部分直接使用。也可以使用调用 Sub过程的语法来调用 Function过程,此时将丢弃 Function过程的返回值。
十六、VB程序错误
(一)错误类型
Visual Basic程序中的错误可分为编译错误、实时错误和逻辑错误三种类型。
编译错误也称为语法错误,这种错误是由于程序中的语句违反了 Visual Basic的语法规则而引起的。例如,拼错了关键字、遗漏了必需的标点符号、语句格式不正确、有 For而无Next语句、有If而无对应的 End If或者括号不匹配等。对于这类错误,在程序输入或编译时,Visual Basic编译器就能自动检查出来,弹出相应的编译错误提示框,指出出错位置(被高亮度显示),按照提示信息就可以纠正相应错误。
实时错误是指程序输入或编译时并未出现任何语法错误,但在程序运行过程中发生错误,导致应用程序中断。该类错误在设计阶段较难发现,通常在程序运行时发现,一般是由于在设计程序时考虑不全面、不周到而造成的。
逻辑错误是最难以处理的一种错误。程序可以正常执行,但得不到所希望的结果。这不是程序语句的错误,而是由于程序设计时本身存在的逻辑缺陷导致的。例如使用了不正确的变量类型、语句的次序不对、循环中起始值和终止值不正确、表达式书写不正确等。大多数逻辑错误不容易找出错误的原因,Visual Basic系统也不能发现这类错误。因此,对于逻辑错误一般要借助调试工具对程序分析、查找错误。
(二)错误处理
对于 Visual Basic 程序中潜在的错误可以采用两种方法进行解决:对于已发现的错误,可以利用调试工具对程序的运行进行跟踪,找出并改正导致错误的语句;对于不可避免的错误或者还没有发现的错误,可以设置错误捕获语句,对错误进行捕获和处理。
1.使用调试工具
该工具提供了设置断点、单步执行、显示变量内容等功能。这些调试功能将有助于程序中错误的查找,尤其是对逻辑错误的分析。
2.使用错误捕捉
在 Visual Basic中,使用On Error语句激活错误捕捉,并将错误处理程序指定为从行号位置开始的程序段,语法格式如下:
On Error Goto [行号]
以下给出常用的错误处理程序的结构。
Sub ErrorDemo() [没有错误的语句块] On Error Goto ErrorHandler ' 启用错误捕捉 [可能会有错误的语句块] Exit Sub ErrorHandler: ' 错误处理由此开始 [错误处理语句] End Sub
错误信息一般使用Err对象获得。Err对象最常用的属性是Number属性和Description属性。Number属性存储当前错误的编号,Description属性存储当前错误的描述。