文档库 最新最全的文档下载
当前位置:文档库 › vb基础教程

vb基础教程

变量的范围确定了能够知晓该变量存在的那部分代码。在一个过程内部声明变量时,只有过程内部的代码才能访问或改变那个变量的值;它有一个范围,对该过程来说是局部的。但是,有时需要使用具有更大范围的变量,例如这样一个变量,其值对于同一模块内的所有过程都有效,甚至对于整个应用程序的所有过程都有效。visual basic 允许在声明变量时指定它的范围。

指定变量的有效范围

一个变量在划定范围时被看作是过程级(局部)变量,还是模块级变量,这取决于声明该变量时采用的方式。

范围专用公用

过程级变量对于这种过程是专用的,在该过程中出现了这些变量。不可使用。不能在一个过程中声明公用变量。

模块级变量对于这种过程是专用的,在该过程中出现了这些变量。变量可用于所有模块。

过程内部使用的变量

过程级变量只有在声明它们的过程中才能被识别。也称它们为局部变量。用dim 或者static 关键字来声明它们。例如:

dim inttemp as integer

—或者—

static intpermanent as integer

在整个应用程序运行时,用static 声明的局部变量中的值一直存在,而用dim 声明的变量只在过程执行期间才存在。

对任何临时计算来说,局部变量是最佳选择。例如,可以建立十来个不同的过程,每个过程都包含称作inttemp 的变量。只要每个inttemp 都声明为局部变量,那么每个过程只识别它自己的inttemp 版本。任何一个过程都能够改变它自己的局部的inttemp 变量的值,而不会影响别的过程中的inttemp 变量。

模块内部使用的变量

按照缺省规定,模块级变量对该模块的所有过程都可用,但对其它模块的代码不可用。可在模块顶部的声明段用private 关键字声明模块级变量,从而建立模块级变量。例如:private inttemp as integer

在模块级,private 和dim 之间没有什么区别,但private 更好些,因为很容易把它和public 区别开来,使代码更容易理解。

所有模块使用的变量

为了使模块级的变量在其它模块中也有效,用public 关键字声明变量。公用变量中的值可用于应用程序的所有过程。和所有模块级变量一样,也在模块顶部的声明段来声明公用变量。例如:

public inttemp as integer

注意不能在过程中声明公用变量,只能在模块的声明段中声明公用变量。

详细信息有关变量的其它信息,请参阅―高级变量主题‖。

使用多个同名的变量

如果不同模块中的公用变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们。例如,如果有一个在form1 和module1 中都声明了的公用integer 变量intx,则把它们作为module1.intx 和form1.intx 来引用便得到正确值。

为了看清这是如何工作的,在一个新工程中插入两个标准模块,并在窗体上画上三个命令按钮。

在第一个标准模块module1 之中声明一个变量intx。test 过程设置它的值:

public intx as integer ?声明module1 的intx。

sub test ()

‘设置module1 的intx 变量的值。

intx = 1

end sub

在第二个标准模块module2 中声明了第二个变量intx,它有相同的名字。又是名为test 的过程设置它的值:

public intx as integer ?声明了module2 的intx。

sub test ()

‘设置module2 的intx 变量的值。

intx = 2

end sub

在窗体模块中声明了第三个变量intx。名为test 的过程又一次设置它的值。

public intx as integer ?声明了该窗体的intx 变量。

sub test ()

‘ 设置form 中的intx 变量值。

intx = 3

end sub

在三个命令按钮的click 事件过程中,每一个都调用了相应的test 过程,并用msgbox 来显示这三个变量的值。

private sub command1_click ()

module1.test ? 调用module1 中的test。

msgbox module1.intx ‘ 显示module1 的intx。

end sub

private sub command2_click ()

module2.test ? 调用module2 中的test。

msgbox module2.intx ‘ 显示module2 的intx。

end sub

private sub command3_click ()

test ? 调用form1 中的test。

msgbox intx ‘ 显示form1 的intx。

end sub

运行应用程序,单击三个命令按钮中的每一个按钮。于是将看到三个公用变量被分别引用。注意在第三个命令按钮的click 事件过程中,在调用form1 的test 过程时不必指定

form1.test,在调用form1 的integer 变量的值时也不必指定form1.intx 。如果多个过程或变量同名,则visual basic 会取变化更受限制的值,在这个例子中,就是form1 变量。

公用变量与局部变量的比较

在不同的范围内也可有同名的变量。例如,可有名为temp 的公用变量,然后在过程中声明名为temp 的局部变量。在过程内通过引用名字temp 来访问局部变量;而在过程外则通过引用名字temp 来访问公用变量。通过用模块名限定模块级变量就可在过程内访问这样的变量。

public temp as integer

sub test ()

dim temp as integer

temp = 2 ? temp 的值为2。

msgbox form1.temp ‘ form1.temp 的值为1。

end sub

private sub form_load ()

temp = 1 ? 将form1.temp 的值设置成1。

end sub

private sub command1_click ()

test

end sub

一般说来,当变量名称相同而范围不同时,局限性大的变量总会用―阴影‖遮住局限性不太大的变量(即优先访问局限性大的变量)。所以,如果还有名为temp 的过程级变量,则它会用―阴影‖遮住模块内部的公用变量temp。

阴影窗体属性和控件

由于阴影效应,窗体属性、控件、常数和过程皆被视为窗体模块中的模块级变量。窗体属性或控件的名称与模块级变量、常数、自定义类型或过程的名称相同是不合法的,因为它们的范围相同。

在窗体模块内,和窗体中控件同名的局部变量将遮住同名控件。因此必须引用窗体名称或me 关键字来限定控件,才能设置或者得到该控件的值或它的属性值。例如:

private sub form_click ()

dim text 1 ,backcolor

‘假定该窗体有一个控件也叫做text1。

text1 = ―variable‖ ?变量用―阴影‖遮住控件。

me.text1 = ―control‖ ‘要得到控件,必须用?me‘限定。

text1.top = 0 ?导致出错!

me.text1.top = 0 ‘要得到控件,必须用?me‘限定。

backcolor = 0 ?变量用―阴影‖遮住属性。

me.backcolor = 0 ‘要得到窗体属性,必须用?me‘限定。

end sub

使用同名的变量和过程

专用模块级变量和公共模块级变量的名字也会和过程名冲突。模块中的变量不能和任何过程同名,也不能和模块中定义的类型同名。但可以和公用过程或其它模块中定义的类型或变量同名。在这种情况下,从别的模块访问这个变量时,就必须用模块名来限定。

虽然上面讨论阴影规则并不复杂,但是用阴影的方法可能会带来麻烦,而且会导致难以查找的错误。因此,对不同的变量使用不同的名称才是一种好的编程习惯。在窗体模块中应尽量使变量名和窗体中的控件名不一样。

除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于dim 声明的局部变量以及声明局部变量的过程,仅当过程在执行时这些局部变量才存在。通常,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。

但可将局部变量定义成静态的,从而保留变量的值。在过程内部用static 关键字声明一个或多个变量,其用法和dim 语句完全一样:

static depth

例如,下面的函数将存储在静态变量accumulate 中的以前的运营总值与一个新值相加,以计算运营总值。

function runningtotal (num)

static applessold

applessold = applessold + num

runningtotal = applessold

end function

如果用dim 而不用static 声明applessold,则以前的累计值不会通过调用函数保留下来,函数只会简单地返回调用它的那个相同值。

在模块的声明段声明applessold,并使它成为模块级变量,由此也会收到同样效果。但是,这种方法一旦改变变量的范围,过程就不再对变量排他性存取。由于其它过程也可以访问和改变变量的值,所以运营总值也许不可靠,代码将更难于维护。

声明所有的局部变量为静态变量

为了使过程中所有的局部变量为静态变量,可在过程头的起始处加上static 关键字。例如:static function runningtotal (num)

这就使过程中的所有局部变量都变为静态,无论它们是用static、dim 或private 声明的还是隐式声明的。可以将static 放在任何sub 或funtion 过程头的前面,包括事件过程和声明为private 的过程。

VB编程基础教程6–常数

收藏到QQ书签[ 程序乐园]

经常会发现代码包含一些常数值,它们一次又一次地反复出现。还可发现,代码要用到很难记住的数字—而那些数字没有明确意义。

在这些情况下,可用常数大幅度地改进代码的可读性和可维护性。常数是有意义的名字,取代永远不变的数值或字符串。尽管常数有点象变量,但不能象对变量那样修改常数,也不能对常数赋以新值。常数有两种来源:

内部的或系统定义的常数是应用程序和控件提供的。在―对象浏览器‖中的visual basic

( vb ) 、和visual basic for applications ( vba ) 对象库中列举了visual basic 的常数。其它提供对象库的应用程序,如microsoft excel 和microsoft project,也提供了常数列表,这些常数可与应用程序的对象、方法和属性一起使用。在每个activex 控件的对象库中也定义了常数关于使用―对象浏览器‖的详细信息,请参阅―用对象编程‖。

符号的或用户定义的常数是用const 语句来声明的。下节―创建属于自己的常数‖中将说明用户定义的常数。

在visual basic 中,常数名采用大小写混合的格式,其前缀表示定义常数的对象库名。来自visual basic 和visual basic for applications 对象库的常数以―vb‖ 开头—例如vbtilehorizontal。

设计前缀时应尽力防止发生意外冲突,不能出现常数名称相同但表示不同数值的情况。即使使用了前缀,两个对象库也仍可能包含表示不同值的相同常数。在这种情况下,引用哪个常数取决于哪个对象库具有更高的优先级。关于改变对象库优先级的信息,请参阅―引用对话框‖部分。

为了绝对确保不发生常数名字冲突,可用以下语法来限定对常数的引用:

[libname.][modulename.]constname

libname 通常是控件或库的类名。modulename 是定义常数的模块的名字。constname 是常数名。在对象库中定义了每个元素,并能在―对象浏览器‖中查看元素。

创建属于自己的常数

声明常数的语法是:

[public|private] const constantname[as type] = expression

参数constantname 是有效的符号名(其规则与建立变量名的规则一样),expression 由数值常数或字符串常数以及运算符组成;但在expression 中不能使用函数调用。

const 语句可以表示数量或date / time 量:

const conpi = 3.14159265358979

public const conmaxplanets as integer = 9

const conreleasedate = #1/1/95#

也可用const 语句定义字符串常数:

publ ic const conversion = ―07.10.a‖

const concodename = ―enigma‖

如果用逗号进行分隔,则在一行中可放置多个常数声明:

public const conpi = 3.14, conmaxplanets = 9, _

conworldpop = 6e+09

等号( = ) 右边的表达式往往是数字或文字串,但也可以是其结果为数或字符串的表达式(尽管表达式不能包含函数调用)。甚至可用先前定义过的常数定义新常数。

const conpi2 = conpi * 2

一旦已定义常数,就可将其放置在代码中,使代码更可读。例如:

static solarsystem (1 to conmaxplanets)

if numpeople > conworldpop then exit sub

设定用户自定义常数的范围

和变量声明一样,const 语句也有范围,也使用相同的规则:

为创建仅存在于过程中的常数,请在这个过程内部声明常数。

为创建一常数,它对模块中所有过程都有效,但对模块之外任何代码都无效,请在模块的声明段中声明常数。

为创建在整个应用程序中有效的常数,请在标准模块的声明段中进行声明,并在const 前面放置public 关键字。在窗体模块或类模块中不能声明public 常数。

详细信息关于范围的更详细信息,请参阅本章前面的―理解变量的范围‖一节。

避免循环引用

由于常数可以用其它常数定义,因此必须小心,在两个以上常数之间不要出现循环或循环引用。当程序中有两个以上的公用常数,而且每个公用常数都用另一个去定义时就会出现循环。例如:

?在module1 中:

public const cona = conb * 2 ‘在整个应用程序

?中有效。

‘在module 2:

public const conb = cona / 2 ?在整个应用程序

‘中有效。

如果出现循环,在试图运行此应用程序时,visual basic 就会产生错误信息。不解决循环引

用就不能运行程序。为避免出现循环,可将公共常数限制在单一模块内,或最多只存在于少数几个模块内。

VB编程基础教程7–数据类型

收藏到QQ书签[ 程序乐园]

变量是用来存储值的所在处;它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。在声明变量时也可指定它的数据类型。所有变量都具有数据类型,以决定能够存储哪种数据。

根据缺省规定,如果在声明中没有说明数据类型,则令变量的数据类型为variant。variant 数据类型很象一条变色龙—它可在不同场合代表不同数据类型。当指定变量为variant 变量时,不必在数据类型之间进行转换,visual basic 会自动完成各种必要的转换。

但是,如果知道变量确实总是存储特定类型的数据,并且还声明了这种特定类型的变量,则visual basic 会以更高的效率处理这个数据。例如,存储人名的变量最好表示成string 数据类型,因为名字总是由字符组成。

除变量外,数据类型也用于其它场合。在给属性赋值时,这个值就有数据类型;函数的参数也有数据类型。事实上,在visual basic 中,凡是与数据有关的东西就与数据类型有关。

也可声明任何基本类型的数组。

详细信息关于更详细信息,请参阅本章后面的―数组‖部分。在―性能和兼容性的设计‖中还将讨论通过选择数据类型来提高应用程序的性能。

声明带数据类型的变量

在使用非variant 变量之前,必须使用private、public、dim 或static 语句将变量声明为as type。例如,下列语句分别声明了integer、double、string 和currency 类型的变量:private i as integer

dim amt as double

static yourname as string

public billspaid as currency

一个声明语句可将多个声明组合起来,请看下列语句:

private i as integer,amt as double

private yourname as string,billspaid as currency

private test,amount,j as integer

注意如果不提供数据类型,则指定变量为缺省类型。在上例中,变量test 和amount 是variant 数据类型。如果由于其它编程语言的经验使人感到同一个声明语句中的所有变量都有相同的指定数据类型(此例中为integer),那么,此处的结果可能会令人感到新鲜。numeric 数据类型

visual basic 支持几种numeric 数据类型— integer(整型)、long(长整型)、single(单精度浮点型)、double(双精度浮点型)和currency(货币型)。与variant 类型相比,numeric 类型占用的存储空间通常要少。

如果知道变量总是存放整数(如12 )而不是带小数点的数字(如 3.57),就应当将它声明为integer 类型或long 类型。整数的运算速度较快,而且比其它数据类型占据的内存要少。在for…next 循环内作为计数器变量使用时,整数类型尤为有用。

详细信息关于控制结构的详细资料,请参阅本章后面的―控制结构概述‖。

如果变量包含小数,则可将它们声明为single、double 或currency 变量。currency 数据类型支持小数点右面 4 位和小数点左面15 位;它是一个精确的定点数据类型,适用于货币计算。浮点(single 和double)数比currency 的有效范围大得多,但有可能产生小的进位误差。

注意浮点数值可表示为mmmeeee 或mmmdeee ,其中mmm 是假数,而eee 是指数(以10 为底的幂)。single 数据类型的最大正数值为3.402823e+38,或3.4 乘以10 的38 次方;double 数据类型的最大正数值是1.79769313486232d+308 或1.8 乘以10 的308 次方。用d 将数值文字中的假数部分和指数部分隔开,就会导致将该值作为double 数据类型来处理。同样,用这种方式使用e,也会导致将该值作为single 数据类型来处理。

byte 数据类型

如果变量包含二进制数,则将它声明为byte 数据类型的数组。(本章后面的―数组‖中将讨论数组)。在转换格式期间用byte 变量存储二进制数据就可保留数据。当string 变量在ansi 和unicode 格式间进行转换时,变量中的任何二进制数据都会遭到破坏。在下列任何一种情况下,visual basic 都会自动在ansi 和unicode 之间进行转换:

读文件时

写文件时

调用dll 时

调用对象的方法和属性时

除一元减法外,所有可对整数进行操作的运算符均可操作byte 数据类型。因为byte 是从0 – 255 的无符号类型,所以不能表示负数。因此,在进行一元减法运算时,visual basic 首先将byte 转换为符号整数。

所有数值变量都可相互赋值,也可对variant 类型变量赋值。在将浮点数赋予整数之前,visual basic要将浮点数的小数部分四舍五入,而不是将小数部分去掉。

详细信息关于unicode 和ansi 转换的详细信息,请参阅―国际化‖。

string 数据类型

如果变量总是包含字符串而从不包含数值,就可将其声明为string 类型。

private s as string

然后可将字符串赋予这个变量,并用字符串函数对它进行操作。

s = ―database‖

s = left (s,4)

按照缺省规定,string 变量或参数是一个可变长度的字符串,随着对字符串赋予新数据,它的长度可增可减。也可以声明字符串具有固定长度。可用以下语法声明一个定长字符串:string * size

例如,为了声明一个长度为50 字符的字符串,可用下列语句:

dim empname as string * 50

如果赋予字符串的字符少于50 个,则用空格将empname 的不足部分填满。如果赋予字符串的长度太长,已不能成为定长字符串,则visual basic 会直接截去超出部分的字符。

因为定长字符串用空格填充尾部多余的空间,所以在处理定长字符串时可发现,删除空格的trim 和rtrim 函数是很有用的。

可将标准模块中的定长字符串声明为public 或private。在窗体和类模块中,必须将定长字

符串声明为private。

详细信息请参阅语言参考中的―ltrim、rtrim function 和trim 函数‖。

交换字符串和数字

如果字符串表示数值,则可将字符串赋予数值变量。也可将数值赋予字符串变量。例如,将命令按钮、文本框和列表框放置在窗体中。在命令按钮的click 事件中输入下列代码。运行应用程序并单击命令按钮。

private sub command1_click ()

dim intx as integer

dim stry as string

stry = ―100.23″

intx = stry ?将字符串传递给数值变量。

list1.additem cos (stry) ‘将字符串中数值的余弦值。

?添加到列表框中。

stry = cos (stry) ‘将余弦值传递给字符串变量。

text1.text = stry ?在文本框中显示字符串。

end sub

visual basic 会自动强制变量为适当的数据类型。在转换字符串和数值时要小心;如果传送字符串中的值不是数值,则在运行时会出错。

boolean 数据类型

若变量的值只是―true/false‖、―yes/no‖、―on/off‖信息,则可将它声明为boolean 类型。boolean 的缺省值为false。在下面的例子中,blnrunning 是boolean 变量,存储简单的yes/no 设置。

dim blnrunning as boolean

‘查看磁带是否在转。

if recorder.direction = 1 then

blnrunning = true

end if

date 数据类型

date 和time 值既可包含在特定的date 数据类型中,又可包含在variant 变量中。一般的date 特性适用于这两种类型。

详细信息请参阅《联机手册》的―高级变量主题‖中的―在variant 变量中存储date/time 值‖部分。

当其它数值数据类型转换为date 时,小数点左边的值表示date 信息,小数点右边的值则代表time。午夜为0,正午为0.5。负数表示公元1899 年12 月31 日之前的date。object 数据类型

object 变量作为32 位(4 个字节)地址来存储,该地址可引用应用程序中或某些其它应用程序中的对象。可以随后(用set 语句)指定一个被声明为object 的变量去引用应用程序所识别的任何实际对象。

dim objdb as object

set objdb = opendatabase (‖c:\vb5\biblio.mdb‖)

在声明对象变量时,请试用特定的类,而不用一般的object(例如用textbox 而不用control,或者象上面的例子那样,用database 取代object)。运行应用程序之前,visual basic 可以决定引用特定类型对象的属性和方法。因此,应用程序在运行时速度会更快。在―对象浏览器‖中列举了特定的类。

当使用其它应用程序的对象,并在―对象浏览器‖中的―类‖列表中列举对象时,不要用variant 或一般的object,而应声明对象。这样可确保visual basic 能够识别引用的特定类型对象,在运行时解决引用问题。

详细信息关于创建和指定对象以及对象变量的更详细信息,请参阅本章后面的―创建对象‖部分。

转换数据类型

visual basic 提供了几种转换函数,可用来将值转换成特定数据类型。例如,用ccur 函数将值转换成currency 类型:

payperweek = ccur (hours * hourlypay)

转换函数将表达式转换成

cbool boolean

cbyte byte

ccur currency

cdate date

cdbl double

cint integer

clng long

csng single

cstr string

cvar variant

cverr error

注意对目标数据类型,传递到转换函数的值必须是有效的,否则会发生错误。例如,如果想把long 型数转换成integer 型数,那么,long 型数必须在integer 数据类型的有效范围之内。

详细信息在联机帮助中查找指定的转换函数。

variant 数据类型

variant 变量能够存储所有系统定义类型的数据。如果把它们赋予variant 变量,则不必在这些数据的类型间进行转换;visual basic 会自动完成任何必要的转换。例如:

dim somevalue ?缺省为variant。

somevalue = ―17″ ‘somevalue包含―17″(双字符的串)。

somevalue = somevalue –15 ?现在,somevalue 包含数值2。

somevalue = ―u‖ & somevalue ‘现在,somevalue 包含―u2″ (双字符的串)。

不必过多关注variant 变量中数据的类型就可对variant 变量进行操作,但须避免落入陷阱。

如果对variant 变量进行数学运算或函数运算,则variant 必包含某个数。更详细的信息,请参阅《联机手册》中―高级变量主题‖中的―变量中存储的numeric 值‖部分。

如果正在连接两个字符串,则用‖ & ‖ 操作符而不用‖ + ‖ 操作符。更详细的信息,请参阅《联机手册》中―高级变量主题‖中的―variant 变量中存储的strings‖部分。

除了可以像其它标准数据类型一样操作外,variants 还包含三种特定值:empty,null 和error。

empty 值

有时需要知道是否已将一个值赋予所创建的变量。在赋值之前,variant 变量具有值empty。

值empty 是异于0、零长度字符串(‖") 或null 值的特定值。可用isempty 函数测试empty 值:

if isempty (z) then z = 0

当variant 变量包含empty 值时,可在表达式中使用它;将其作为0 或零长度字符串来处理,这要根据表达式来定。

只要将任何值(包括0、零长度字符串或null)赋予variant 变量,empty 值就会消失。而将关键字empty 赋予variant 变量,就可将variant 变量恢复为empty。

null 值

variant 数据类型还可包含一特定值:null。null通常用于数据库应用程序,表示未知数据或丢失的数据。由于在数据库中使用null 方法,null 具有某些唯一的特性:

对包含null 的表达式,计算结果总是null。于是说null 通过表达式―传播‖;如果表达式的部分之值为null,那么整个表达式的值也为null。

将null 值、含null 的variant 变量或计算结果为null 的表达式作为参数传递给大多数函数,将会使函数返回null。

null 值经由返回variant 数据类型的内在函数传播。

也可用null 关键字指定null 值。

z = null

也可用isnull 函数测试variant 变量是否包含null 值。

if isnull (x) and isnull (y) then

z = null

else

z = 0

end if

如果将null 值赋予variant 以外的任何其它类型变量,则将出现可以捕获的错误。而将null 值赋予variant 则不会发生错误,null 将通过包含variant 变量的表达式传播(尽管null 并不通过某些函数来传播)。可以从任何具有variant 返回值的函数过程返回null。

除非明确将null 赋予变量,否则变量不会设置成null 值,所以,如果不在应用程序中使用null,就不必书写测试null 和处理null 的程序。

详细信息关于如何在表达式中使用null 的详细信息,请参阅语言参考的―null‖部分。error 值

在variant 中,error 是特定值,指出已发生的过程中的错误状态。但是,与其它类型错误不同,这里并未发生正常的应用程序级的错误处理。因此,程序员或应用程序本身可根据error 值进行取舍。利用cverr 函数将实数转换成错误值就可建立error 值。

详细信息关于如何在表达式中使用error 值,请参阅语言参考中的―cverr 函数‖部分。关于错误处理的信息,请参阅―调试代码和处理错误‖。有关variant 数据类型的更详细信息,请参阅《联机手册》中的―高级变量主题‖。

上一篇:VB编程基础教程6–常数| 异次元软件世界

下一篇:VB编程基础教程8–高级变量主题| 异次元软件世界

(www740222的分类目录[我的图书馆])

VB编程基础教程8–高级变量主题

收藏到QQ书签[ 程序乐园]

数值在变量中的内部表示

variant 变量维护它们所存储的数值的内部表示。这个表示将决定visual basic 在执行比较操作和其它操作时如何处理这些值。将值赋予variant 变量时,visual basic 会用最紧凑的表示正确记录这个值。以后的操作可能使visual basic 改变这个用于特定变量的表示。(variant 变量不是无类型变量,而是能够随意改变类型的变量。)这些内部表示与本章前面在―数据类型‖中讨论的数据类型相一致。

注意variant 总保持16 位,无论其中存储了什么数据。对象、字符串和数组,在物理上并非存于variant 之中;在这些情况下,用四个字节的variant 来保持对象引用、或者字符串或数组的指针。而真正的数据存在其它地方。

很多时候,不必了解visual basic 为特殊变量使用哪一种变量类型;visual basic 会自动转换类型。若想了解visual basic 正在使用哪种变量类型,可使用vartype 函数。

例如,如果在variant 变量中存储二进制值,visual basic 就会用double 内部表示。如果知道应用程序并不需要double 值提供的高精度(以及由此而来的低速度),那么将此值转换成single 甚至转换成currency 就可以加快计算速度:

if vartype (x) = 5 then x = csng (x) ?转换成单精度。

对array 变量,vartype 的值等于数组元素与数据类型返回值之和。例如,这个数组包含double 值:

private sub form_click ()

dim dblsample (2) as double

msgbox vartype (dblsample)

end sub

visual basic 的今后版本可能会增加新的variant 表示,所以,任何根据vartype 函数的返回值做出判断的代码都应能适当地处理非当前定义的返回值。

详细信息关于vartype 函数的信息,请参阅语言参考中的―vartype 函数‖。关于数组的更详细信息,请参阅本章后面的―数组‖。关于转换数据类型的详细信息,请参阅本章前面的―数据类型‖。

variant 变量中存储的numeric 值

在variant 变量中存储整个数时,visual basic 使用最紧凑的表示。例如,若是存储不带小数点的微小的数值,variant 对该值使用integer 表示。如果此后赋予一个较大的数,则visual basic将使用long 值,如果这个数非常大或者有小数部分,则visual basic 将使用double 值。

有时想对一个数使用特定表示。例如,为了在以后的计算中避免舍入误差,可能希望variant 变量将数值作为currency 存储起来。visual basic 提供了几种转换函数,可以用它们将值转换成指定的类型(参阅本章前面的―转换数据类型‖)。例如,用ccur 函数可将值转换成currency 类型:

payperweek = ccur (hours * hourlypay)

如果variant 变量不含数或者不含可以解释为数的内容,则对variant 变量执行数学运算或函数计算就会出错。例如,不能对‘u2? 这个值进行任何算术运算,尽管它包含一个数值字符‘2?,但整个值并非合法的数。同样不能对值1040ez 进行任何计算,但是,可以对+10 或-1.7e6 进行计算,因为它们是有效的数。因此经常需要判定variant 变量是否包含可以当作数使用的值。isnumeric 函数可以完成这样的任务:

do

anynumber = inputbox (‖enter a number‖)

loop until isnumeric (anynumber)

msgbox ―the square root is: ‖ & sqr (anynumber)

当visual basic 将一个非数值的表示(如包含一个数的字符串)转换成数值时,它会使用地区设置(在windows 的―控制面板‖中规定)来解释千位分隔符、小数点符号和货币符号。于是,如果windows 的―控制面板‖中的国家/地区设置值被设置成美国、加拿大或澳大利亚,则这两个语句将返回true:

isnumeric (‖$100″)

isnumeric (‖1,560.50″)

而下面两个语句则返回false:

isnumeric (‖dm100″)

isnumeric (‖1.560,50″)

但是,如果在windows 的―控制面板‖中的国家/地区设置值被设置成德国,则情况正好相反:前两个语句返回false,而后两个语句返回true。

如果把包含数的variant 赋给字符串变量或属性,visual basic 自动把数的内部表示转换成字符串。如果想显式地将数转换成字符串,可以用cstr 函数。还可以用format 函数将数转换成字符串,字符串包含某种格式,如货币符,千位分隔符和小数点符号。format 函数按照windows―控制面板‖中的―地区设置‖对话框自动使用相应的符号。

详细信息请参阅的语言参考中的―format 函数‖ 以及关于转换函数的主题。关于编写分布在国外市场的应用程序的更详细信息,请参阅―国际化‖。

variant 变量中存储的字符串

一般说来,在variant 变量中存储和使用字符串不会出什么问题。但是如前所述,有时在使用两个variant 值时,‖ + ‖ 运算符的结果可能很含糊。如果两个variant 变量都包含数,则‖ + ‖ 运算符执行加法运算。如果两个variant 变量都包含字符串,则‖ + ‖ 运算符执行字符串连接。但是,如果一个值代表数,而另一个值代表字符串,则情况就很复杂了。visual basic 首先试图把字符串变成数。如果转换成功,那么‖ + ‖ 运算符把两者加在一起;如果不成功,则产生一个―类型不匹配‖错误。

为了确保执行的动作为字符串连接,不管变量中的表示如何,都用& 运算符。例如,以下代码:

sub form_click ()

dim x ,y

x = ―6″

y = ―7″

print x + y,x & y

x = 6

print x + y,x & y

end sub

在窗体上产生如下结果:

67 67

13 67

注意visual basic 在内部用unicode 存储字符串。关于unicode 的更详细的信息,请参阅―国际化‖。

variant 变量中存储的date/time 值

variant 变量还可以包含date/time 值。有几个函数返回date/time 值。例如,dateserial 返回

该年所剩的天数。

private sub form_click ()

dim rightnow ,daysleft ,hoursleft ,minutesleft

rightnow = now ‘now 返回当前的date 和time。

daysleft = int(dateserial(year(rightnow) _

+ 1, 1, 1) – rightnow)

hoursleft = 24 – hour (rightnow)

minutesleft = 60 – minute (rightnow)

print daysleft & ‖ days left in the year.‖

print hoursleft & ‖ hours left in the day.‖

print minutesleft & ‖ minutes left in the hour.‖

end sub

还可以对date/time 值进行运算。通过加减一个整数来增加或减少天数;通过加减一个分数来增加或减少时间。所以,加20 就是加20 天,而减掉1/24 就是减去一小时。

存储在variant 变量中的date 值的有效范围从公元0100 年 1 月1 日到公元9999 年

12 月31 日。计算date 时不考虑gregorian 历法采用之前的日期。所以如果计算gregorian 历法被采用那年(在英国及其殖民地为1752 年;其它国家/地区则或早一些或晚一些)之前的日期,结果可能会不正确。

在代码中可以采用date/time 文字,只要用一对‖ # ‖ 号将它们括起来,如同对字符串用一对双引号( ―‖ ) 括起来一样。例如,可以将包含date/time 值的variant 和一串表示date 的文字作比较:

if somedate > #3/6/93# then

下面的例子将包含date/time 值的variant 变量和一串表示date 和time 的文字相比较:

if somedate > #3/6/93 1:20pm# then

如果date/time 值不包括time,则visual basic 自动将该值的time部分设定为午夜(一天的开始)。如果date/time 值不包括date,则visual basic 自动将该值的date 部分设定为公元1899 年12 月30 日。

visual basic 接受许多种文字的date 和time 格式。下面的date/time 值全部有效:somedate = #3-6-93 13:20#

somedate = #march 27 ,1993 1:20am#

somedate = #apr-2-93#

somedate = #4 april 1993#

详细信息有关用国际格式处理date 的信息,请参阅―国际化‖。

用isnumeric 函数可测试一个variant 变量是否包含一个值,这个值可以看作有效的数值,同样,用isdate 函数可测试一个variant 变量是否包含一个值,这个值可以看作有效的date/time 值。然后可用cdate 函数将该值转换成date/time值。

例如,以下代码用isdate 测试文本框的text 属性。如果属性包含被看作有效date 的文本,则visual basic 将此文本转换成date 并计算到年底还有几天。

dim somedate ,daysleft

if isdate (text1.text) then

somedate = cdate (text1.text)

daysleft = dateserial(year(somedate) + _

1, 1, 1) – somedate

text2.text = daysleft & ‖ days left in the year.‖

else

msgbox text1.text & ‖ is not a valid date.‖

end if

详细信息关于各种date 和time 函数的信息,请参阅的语言参考中的―date function‖。variant 变量中存储的objects

可以将objects 存储在variant 变量中。当需要高效地处理包括objects 在内的各种数据类型时,这可能十分有用。例如,一个数组中的所有元素都必须具有相同的数据类型。将数组的数据类型设置成variant 就可将objects 连同其它数据类型一起存入同一个数组中。

上一篇:VB编程基础教程7–数据类型| 异次元软件世界

下一篇:VB编程基础教程9–数组| 异次元软件世界

(www740222的分类目录[我的图书馆])

VB编程基础教程9–数组

收藏到QQ书签[ 程序乐园]

如果有过用其它语言编程的经历,那么想必会熟悉数组的概念。由于有了数组,可以用相同名字引用一系列变量,并用数字(索引)来识别它们。在许多场合,使用数组可以缩短和简化程序,因为可以利用索引值设计一个循环,高效处理多种情况。数组有上界和下界,数组的元素在上下界内是连续的。因为visual basic对每一个索引值都分配空间,所以不要不切实际声明一个太大的数组。

注意这一部分讨论的数组是程序中声明的变量数组。它们不同于控件数组,控件数组是在设计时通过设置控件的index 属性规定的。变量数组总是连续的;与控件数组不同的是,不能从一个数组的中部加载或卸载数组元素。

一个数组中的所有元素具有相同的数据类型。当然,当数据类型为variant 时,各个元素能够包含不同种类的数据(对象、字符串、数值等等)。可以声明任何基本数据类型的数组,包括用户自定义类型(请参阅―再论编程‖中的―创建自己的数据类型‖)和对象变量(请参阅―用对象编程‖)。

在visual basic 中有两种类型的数组:固定大小的数组—它总是保持同样的大小,以及在运行时大小可以改变的动态数组。在本章后面的―动态数组‖中将要详细讨论动态数组。

声明固定大小的数组

有三种方法声明固定大小的数组,用哪一种方法取决于数组应有的有效范围:

建立公用数组,在模块的声明段用public 语句声明数组。

建立模块级数组,在模块的声明段用private 语句声明数组。

建立局部数组,在过程中用private 语句声明数组。

设定上下界

声明数组时,在数组名之后跟一个用括号括起来的上界。上界不得超过long 数据类型的范围(-2,147,483,648 到2,147,483,647)。例如,下列数组声明可出现在模块的声明段:

dim counters (14) as integer ?15 个元素。

dim sums (20) as double ‘21 个元素。

为建立公用数组,直接用public 取代dim。

public counters (14) as integer

public sums (20) as double

在过程之中同样的声明使用dim:

dim counters (14) as integer

dim sums (20) as double

第一个声明建立了一个有15 个元素的数组,其索引号从0 到14 。第二个声明建立了一个有21 个元素的数组,其索引号从0 到20 。缺省的下界为0。

为了规定下界,用关键字to 显式提供下界(为long 数据类型):

dim counters (1 to 15) as integer

dim sums (100 to 120) as string

在前述声明中,counters 的索引值范围从 1 到15,而sums 的索引值范围从100 到200。包含其它数组的数组

有可能建立variant 数据类型数组,并与不同数据类型的数组共居一处。以下代码建立两个数组,一个包含整数,而另一个包含字符串。然后声明第三个variant 数组,并将整数和字符串数组放置其中:

private sub command1_click ()

dim intx as integer ?声明计数器变量。

‘声明并放置整数数组。

dim countersa (5) as integer

for intx = 0 to 4

countersa (intx) = 5

next intx

?声明并放置字符串数组。

dim countersb (5) as string

for intx = 0 to 4

countersb (intx) = ―hello‖

next intx

dim arrx (2) as variant ‘声明拥有两个成员的新数组。

arrx (1) = coun tersa () ?将其它数组移居到数组。

arrx (2) = countersb ()

msgbox arrx (1) (2) ‘显示每一个数组的成员。

msgbox arrx (2) (3)

end sub

多维数组

有时需要追踪记录数组中的相关信息。例如,为了追踪记录计算机屏幕上的每一个像素,需要引用它的x、y 坐标。这时应该用多维数组存储值。

可用visual basic 声明多维数组。例如,下面的语句声明了一个过程内的10 × 10 的二维数组。

static matrixa (9, 9) as double

可用显式下界来声明两个维数或两个维数中的任何一个:

static matrixa (1 to 10, 1 to 10) as double

可以将所有这些推广到二维以上的数组。例如:

dim multid (3, 1 to 10, 1 to 15)

这个声明建立了三维数组,大小为 4 × 10 × 15。元素总数为三个维数的乘积,为600。

注意在增加数组的维数时,数组所占的存储空间会大幅度增加,所以要慎用多维数组。使

用variant 数组时更要格外小心,因为他们需要更大的存储空间。

用循环操作数组

可以用for 循环嵌套有效的处理多维数组。例如,在matrixa 中基于每个元素在数组中的位置为其赋值:

dim i as integer, j as integer

static matrixa(1 to 10, 1 to 10) as double

for i = 1 to 10

for j = 1 to 10

matrixa (i, j) = i * 10 + j

next j

next i

详细信息关于循环的详细信息,请参阅本章后面的―循环结构‖部分。

VB编程基础教程10–动态数组

收藏到QQ书签[ 程序乐园]

数组到底应该有多大才合适,有时可能不得而知。所以希望能够在运行时具有改变数组大小的能力。

动态数组就可以在任何时候改变大小。在visual basic 中,动态数组最灵活、最方便,有助于有效管理内存。例如,可短时间使用一个大数组,然后,在不使用这个数组时,将内存空间释放给系统。

如果不用动态数组,就要声明一个数组,它的大小尽可能达到最大,然后再抹去那些不必要的元素。但是,如果过度使用这种方法,会导致内存的操作环境变慢。

要创建动态数组,请按照以下步骤执行:

(如果希望数组为公用数组,则)用public 语句声明数组,或者,(如果希望数组为模块级,则)在模块级用dim 语句声明数组,或者(如果希望数组为局部数组,则)在过程中用static 或dim 语句声明数组。给数组附以一个空维数表,这样就将数组声明为动态数组。

dim dynarray ()

用redim 语句分配实际的元素个数。

redim dynarray (x + 1)

redim 语句只能出现在过程中。与dim 语句、static 语句不同,redim 语句是一个可执行语句,由于这一语句,应用程序在运行时执行一个操作。

redim 语句支持这样的语法,它与固定数组中使用的语法相同。对于每一维数,每个redim 语句都能改变元素数目以及上下界。但是,数组的维数不能改变。

redim dynarray (4 to 12)

例如,用第一次声明在模块级所建立的动态数组matrix1:

dim matrix1 () as integer

然后,在过程中给数组分配空间:

sub calcvaluesnow ()

.

.

.

redim matrix1 (19, 29)

end sub

这里的redim 语句给matrix 分配一个20 × 30 的整数矩阵(元素总大小为600)。还有一个办法,用变量设置动态数组的边界:

redim matrix1 (x, y)

注意您可以将字符串赋值给大小可变的字节数组。一个字节数组也可以被赋值给一个可变长的字符串。一定要注意字符串中的字节数会随平台而变化。同一个字符串在unicode 平台上的字节数是它在非unicode 平台上的两倍。

保留动态数组的内容

每次执行redim 语句时,当前存储在数组中的值都会全部丢失。visual basi 重新将数组元素的值置为empty(对variant 数组)、置为0(对numeric 数组)、置为零长度字符串(对string 数组)或者置为nothing(对于对象的数组)。

在为新数据准备数组,或者要缩减数组大小以节省内存时,这样做是非常有用的。有时希望改变数组大小又不丢失数组中的数据。使用具有preserve 关键字的redim 语句就可做到这点。例如,使用ubound 函数引用上界,使数组扩大、增加一个元素,而现有元素的值并未丢失:

redim preserve dynarray (ubound (dynarray) + 1)

在用preserve 关键字时,只能改变多维数组中最后一维的上界;如果改变了其它维或最后一维的下界,那么运行时就会出错。所以可这样编程:

redim preserve matrix (10, ubound (matrix, 2) + 1)

而不可这样编程:

redim preserve matrix (ubound (matrix, 1) + 1, 10)

详细信息关于动态数组的更详细信息,请参阅语言参考中的―redim 函数‖。关于对象数组,请参阅―用对象编程‖。过程概述

将程序分割成较小的逻辑部件就可以简化程序设计任务。称这些部件为过程,它们可以变成增强和扩展visual basic 的构件。

过程可用于压缩重复任务或共享任务,例如,压缩频繁的计算、文本与控件操作和数据库操作。

用过程编程有两大好处:

过程可使程序划分成离散的逻辑单元,每个单元都比无过程的整个程序容易调试。

一个程序中的过程,往往不必修改或只需稍作改动,便可以成为另一个程序的构件。

在visual basic 中使用下列几种过程:

sub 过程不返回值。

function 过程返回值。

property 过程返回并指定值,以及设置对象引用。

详细信息关于属性过程,请参阅―用对象编程‖。

关于子过程和函数过程,请参阅下面的主题:

子过程介绍子过程及其使用。

函数过程介绍函数过程及其使用。

使用过程介绍从应用程序内部调用过程。

向过程传递参数讨论用参数向过程传递数据。

sub 过程

子过程是在响应事件时执行的代码块。将模块中的代码分成子过程后,在应用程序中查找和修改代码变得更容易了。

子过程的语法是:

[private|public][static]sub procedurename (arguments)

statements

end sub

每次调用过程都会执行sub 和end sub 之间的statements。可以将子过程放入标准模块、类模块和窗体模块中。按照缺省规定,所有模块中的子过程为public(公用的),这意味着在应用程序中可随处调用它们。

过程的arguments 类似于变量声明,它声明了从调用过程传递进来的值。

在visual basic 中应区分通用过程和事件过程这两类子过程。

通用过程

通用过程告诉应用程序如何完成一项指定的任务。一旦确定了通用过程,就必须专由应用程序来调用。反之,直到为响应用户引发的事件或系统引发的事件而调用事件过程时,事件过程通常总是处于空闲状态。

为什么要建立通用过程呢?理由之一就是,几个不同的事件过程也许要执行同样的动作。将公共语句放入一分离开的过程(通用过程)并由事件过程来调用它,诚为编程上策。这样一来就不必重复代码,也容易维护应用程序。例如,vcr 示例应用程序使用了一个通用过程,几个不同滚动按钮的click 事件都调用这个通用过程。click 事件中的代码调用按钮管理器的子过程,子过程运行自身的代码,然后将控制返回到click 事件过程。

事件过程

当visual basic 中的对象对一个事件的发生作出认定时,便自动用相应于事件的名字调用该事件的过程。因为名字在对象和代码之间建立了联系,所以说事件过程是附加在窗体和控件上的。

一个控件的事件过程将控件的(在name 属性中规定的)实际名字、下划线(_) 和事件名组合起来。例如,如果希望在单击了一个名为cmdplay 的命令按钮之后,这个按钮会调用事件过程,则要使用cmdplay_click 过程。

一个窗体事件过程将词汇―form‖、下划线和事件名组合起来。如果希望在单击窗体之后,窗体会调用事件过程,则要使用form_click 过程。(和控件一样,窗体也有唯一的名字,但不能在事件过程的名字中使用这些名字。)如果正在使用mdi 窗体,则事件过程将词汇‖ mdiform ‖ 、下划线和事件名组合起来,如mdiform_load。

所有的事件过程使用相同的语法。

控件事件的语法窗体事件的语法

private sub controlname_eventname (arguments )

statements

end sub

private sub form_eventname (arguments)

statements

end sub

虽然可以自己编写事件过程,但使用visual basic 提供的代码过程会更方便,这个过程自动将正确的过程名包括进来。从―对象框‖中选择一个对象,从―过程框‖中选择一个过程,就可在―代码编辑器‖ 窗口选择一个模板。

在开始为控件编写事件过程之前先设置控件的name 属性,这不失为一个好主意。如果对控件附加一个过程之后又更改控件的名字,那么也必须更改过程的名字,以符合控件的新名字。否则,visual basic 无法使控件和过程相符。过程名与控件名不符时,过程就成为通用过程。

详细信息visual basic 可识别各种窗体和控件的各种事件。关于所有事件的说明,请参阅语言参考。

funtion 过程

visual basic 包含内置的、或内部的函数,如sqr、cos 或chr。此外,还可用function 语句编写自己的function 过程。

函数过程的语法是:

private|public][static]function procedurename (arguments) [as type]

statements

end function

与sub 过程一样,function 过程也是一个独立的过程,可读取参数、执行一系列语句并改变其参数的值。与子过程不同,function 过程可返回一个值到调用的过程。在sub 过程与function 过程之间有三点区别:

一般说来,让较大的语句或表达式的右边包含函数过程名和参数(returnvalue = function),这就调用了函数。

与变量完全一样,函数过程有数据类型。这就决定了返回值的类型。(如果没有as 子句,缺省的数据类型为variant。)

给procedurename 自身赋一个值,就可返回这个值。function 过程返回一个值时,该值可成为较大表达式的一部分。

例如,下面是已知直角三角形两直角边的值,计算第三边(斜边)的函数:

function hypotenuse (a as integer, b as integer) as string

hypotenuse = sqr (a ^ 2 + b ^ 2)

end function

在visual basic 中调用function 过程的方法和调用任何内部函数的方法是一样的:

label1.caption = hypotenuse(cint(text1.text), _

cint(text2.text))

strx = hypotenuse (width, height)

详细信息关于函数过程的详细信息,请参阅语言参考中的―function 语句‖。调用各种类型的过程的技巧,在本章后面的―调用过程‖部分有详细讨论。

VB编程基础教程12–使用过程

收藏到QQ书签[ 程序乐园]

创建新过程

要创建新的通用过程,请

在―代码‖窗口输入过程头并按下回车键。过程头以sub 或function 打头,再接一个名字。例如,可以用以下任一方式输入:

sub updateform ()

function getcoord ()

通过完成新过程的模板,visual basic 作出反应。

选择现有过程

要在当前模块中查看过程,请

为了查看现有通用过程,在―代码‖窗口的―对象框‖中选择―通用‖,然后在―过程框‖中选择过程。

-或者-

为查看事件过程,在―代码‖窗口的―对象框‖中选择适当的对象,然后在―过程框‖中选择事件。要查看其它模块中的过程,请

在―视图‖菜单中选取―对象浏览器‖。

在―工程/库‖框中选择工程。

在―类/模块‖列表中选择模块,并在―成员‖列表中选择过程。

选取―查看定义‖。

调用过程

调用过程有诸多技巧,它们与过程的类型、位置以及在应用程序中的使用方式有关。下面的章节说明如何调用sub 过程和function 过程。

调用sub 过程

与sub 过程不同,在表达式中,sub 过程不能用其名字调用。调用sub 过程的是一个独立的语句。sub 过程还有一点与函数不一样,它不会用名字返回一个值。但是,与function

过程一样,sub 过程也可以修改传递给它们的任何变量的值。

调用sub 过程有两种方法:

?以下两个语句都调用了名为myproc 的sub 过程。

call myproc (firstargument, secondargument)

myproc firstargument, secondargument

注意,当使用call 语法时,参数必须在括号内。若省略call 关键字,则也必须省略参数两边的括号。

调用函数过程

通常,调用自行编写的函数过程的方法和调用visual basic 内部函数过程(例如abs)的方法一样;即在表达式中写上它的名字。

‘下面的语句都调用函数todec。

print 10 * todec

x = todec

相关文档