§6.1过程定义及分类一、过程定义过程是用来执行一个特定任务的一段程序代码。VB应用程序(又称工程或项目)由若干过程组成,这些过程保存在文件中,每个文件的内容通常称为一个模块。过程又称为子程序。二、过程分类在程序设计过程中,将一些常用的功能编写成过程,可供多个不同的事件过程多次调用,从而可以减少重复编写代码的工作量,实现代码重用,使程序简练、便于调试和维护。在VB6.0中,除了系统提供的内部函数过程和事件过程外,用户可自定义过程分为四种过程:1、“Sub”保留字开始的为子过程。2、“Function”保留字开始的为函数过程。3、“Property”保留字开始的为属性过程。4、“Event”保留字开始的事件过程。6.2.1事件过程在VB中,有两类子过程(Sub)分为:事件过程和通用过程。◆事件过程事件过程是附加在窗体和控件的程序。即当某个事件发生时,对该事件作出响应的程序段,它是VB应用程序的主体。1、窗体事件的语法PrivateSubForm_事件名(参数列表)<语句组>EndSub2、控件事件的语法PrivateSub控件名_事件名(参数列表)<语句组>EndSub6.2.2通用过程(Sub过程)通用过程是独立于事件过程之外,通常用来完成一个特定的功能,可以被其它过程作为一个整体来调用的程序段。定义子过程有以下两种方法:1、用“工具”菜单下的“添加过程”命令定义。2、利用代码窗口直接定义。在窗体或标准模块的代码窗口把插入点放在所有现有过程之外,键入Sub子过程名即可。子过程的定义形式如下:[Public|Private][Static]Sub子过程名([形参表])<局部变量或常数定义><语句组>[ExitSub]<语句组>EndSub说明:◆子过程名:命名规则与变量名规则相同。子过程名不返回值,而是通过形参与实参的传递得到结果,调用时可返回多个值。◆形式参数列表:形式参数通常简称“形参”,仅表示形参的类型、个数、位置,定义时是无值的,只有在过程被调用时,虚实参结合后才获得相应的值。◆过程可以无形式参数,但括号不能省。◆参数的定义形式:[ByVal|ByRef]变量名[()][As类型][,…],ByVal表示当该过程被调用时,参数是按值传递的;缺省或ByRef表示当参数是按地址传递的。【例】编一个交换两个整型变量值的子过程(该过程被调用时,参数是按地址传递的)。PrivateSubSwap(XAsInteger,YAsInteger)DimtempAsIntegerTemp=X:X=Y:Y=TempEndSub6.2.3子过程的建立通过“工具”菜单中的“添加过程”命令,出现“添加过程”对话框(如图6-1所示),选择过程类型(子过程、函数、属性、事件)及作用范围(公有的Public、私有的Private),单击确定后得到一个过程或函数定义的结构框架(模板)。如:PublicSubSort()......EndSub图6-1“添加过程”对话框6.2.4过程的调用要执行一个过程,必须调用该过程。子过程的调用有两种方式,一种是利用Call语句加以调用,另一种是把过程名作为一个语句来直接调用。1、用Call语句调用Sub过程格式:Call子过程名[(参数列表)]例如:Callsum(a,b,c)2、把过程名作为一个语句来使用格式:子过程名[参数列表]与第一种调用方法相比,这种调用方式省略了关键字Call,去掉了“参数列表”的括号。例如:suma,b,c说明:◆参数列表称为实参,它必须与形参保持个数相同,位置与类型一一对应。◆调用时把实参值传递给对应的形参。其中值传递(形参前有ByVal说明)时实参的值不随形参的值变化而改变。而地址传递时实参的值随形参值的改变而改变。◆当参数是数组时,形参与实参在参数声明时应省略其维数,但括号不能省。◆调用子过程的形式有两种,用Call关键字时,实参必须加圆括号括起,反之则实参之间用“,”分隔。【例】编一个求n!的子过程,然后调用它计算7!+11!-10!。(1)定义n!的子过程程序如下:Subjch(n%,p&)Dimi%p=1Fori=1Tonp=p*iNextiEndSub(2)过程调用的执行程序如下:PrivateSubForm_Click()Dima&,b&,c&,d&Calljch(7,a)Calljch(11,b)Calljch(10,c)d=a+b-cPrint7!+11!-10!=;dEndSub6.3.1函数过程(Function过程)定义函数过程是自定义过程的另一种形式。VB函数分为内部函数和外部函数。内部函数,如:Sin(),Sqr()等,在编写程序时,只需写出函数名和相应的参数,就可得到函数值。外部函数是用户根据需要用Function关键字定义的函数过程,同内部函数一样,函数过程也有一个返回值。函数过程的定义方法有两种:1、利用“工具”菜单下的“添加过程”命令定义2、利用代码窗口直接定义在窗体或标准模块的代码窗口把插入点放在所有现有过程之外,键入Function函数名即可。定义形式如下:[Public|Private][Static]Function函数名([参数列表])[As类型]局部变量或常数定义语句块函数体[函数名=返回值][ExitFunction]语句块[函数名=返回值]EndFunction说明:◆函数名:命名规则与变量名规则相同。但不能与系统的内部函数或其它通用子过程同名,也不能与已定义的全局变量和本模块中模块级变量同名。◆在函数体内,函数名可以当变量使用,函数的返回值就是通过对函数名的赋值语句来实现的,在函数过程中至少要对函数名赋值一次。◆AS类型:是指函数返回值的类型,若省略,则函数返回变体类型值(Variant)。◆ExitFunction:表示退出函数过程,常常是与选择结构(If或SelectCase语句)联用,即当满足一定条件时,退出函数过程。◆形参数列表:形参的定义与子过程完全相同。【例】编写一个计算n!的Function过程。FunctionFact(NAsInteger)AsLongDimIAsInteger,FAsLongF=1'F用于保存阶乘值ForI=1ToNF=F*INextIFact=F'给函数过程名赋值EndFunction【例】编写一个Function过程,计算下面表达式的值。FunctionF(X,Y,Z)F=Sqr(Abs(X∧3+Y∧3+Z∧3))EndFunction6.3.2函数的调用调用函数过程形式为:变量名=函数过程名([参数列表])说明:◆在调用时实参和形参的数据类型、顺序、个数必须匹配。调用函数过程可以由函数名带回一个值给调用程序,被调用的函数必须作为表达式或表达式中的一部分,再与其它的语法成分一起配合使用。因此,与子过程的调用方式不同,函数不能作为单独的语句加以调用。函数调用只能出现在表达式中,其功能是求得函数的返回值。【例】编写Function过程求最大公约数,并通过命令按钮的单击事件过程调用该函数过程。当向文本框输入24和16时,两数最大的公约数为8。运行界面如图6-2所示:图6-21、函数过程代码:Functionhcf(mAsInteger,nAsInteger)AsIntegerDimrAsIntegerr=mModnDoWhiler0m=nn=rr=mModnLoophcf=nEndFunction2、命令按钮的单击事件过程代码:PrivateSubCommand1_Click()DimmAsInteger,nAsIntegerm=Val(Text1.Text)n=Val(Text2.Text)Label2.Caption=Str(hcf(m,n))EndSub6.4.1形式参数与实际参数一、过程之间参数的传递VisualBasic中不同模块(过程)之间数据的传递有两种方式:◆通过过程调用实参与形参的结合实现。◆使用全局变量来实现各过程中共享数据。二、形式参数与实际参数(一)形式参数(简称形参)是指在定义通用过程时,出现在Sub或Function语句中的变量名后面园括号内的数,是用来接收传送给子过程的数据,形参表中的各个变量之间用逗号分隔。形式参数可以是变量名和数组名。(二)实际参数(简称实参)实际参数是指在调用Sub或Function过程时,写入子过程名或函数名后括号内的参数,其作用是将它们的数据(数值或地址)传送给Sub或Function过程与其对应的形参变量。实参可由常量、表达式、有效的变量名、数组名(后加左、右括号,如A())组成,实参表中各参数用逗号分隔。注意:形参表和实参表中的对应变量名可以不同,但实参和形参的个数、顺序以及数据类型必须相同。3、定义过程和调用过程的示例“形实结合”是按照位置结合的,即第一个实参值(100)传送给第一个形参t,第二个实参值(“计算机”)传送给第二个形参s,第三个实参值(1.5)传送给第三个形参y。6.4.2参数传递(虚实结合)在调用过程时,一般主调过程与被调过程之间有数据传递,即将主调过程的实参传递给被调过程的形参,完成实参与形参的结合,然后执行被调过程体。一、参数的传递实参与形参的结合有两种方式传址和传值。传址是默认的方法。两种结合方法的区分标志是“ByVal”,形参前加“ByVal”关键字时是是按值传递,否则缺省或加“ByRef”关键字的为按地址传递。二、传址的参数传递过程当调用一个过程时,它将实参的地址传递给形参。因此在被调过程体中对形参的任何操作都变成了对相应实参的操作,因此实参的值就会随形参的改变而改变。当参数是字符串或数组时,使用传址传递直接将实参的地址传递给过程,会使程序的效率提高。三、值的参数传递过程当调用一个过程时,系统将实参的值复制给形参,之后实参与形参便断开了联系。被调过程对形参的操作是在形参自己的存储单元中进行,当过程调用结束时,这些形参所占用的存储单元也同时被释放。因此在过程中对形参的任何操作都不会影响到实参。四、参数传递方式举例设置两个通用过程Test1和Test2,分别按值传递和按地址传递。PrivateSubForm_Load()DimxAsIntegerx=5Print执行test1前,x=;xCalltest1(x)Print执行test1后,test2前,x=;xCalltest2(x)Print执行test2后,x=;xEndSubSubtest1(ByValtAsInteger)'按值传递t=t+5EndSubSubtest2(sAsInteger)'按地址传递s=s-5EndSub执行Test1前,x=5执行Test1后,Test2前,x=5执行Test2后,x=06.4.3过程之间数据传递的几点说明一、数的数据类型在定义子过程和函数过程时,一般要求说明形参变量的数据类型,若形参被默认类型说明,则此时形参为Vriant数据类型。由调用时实参的数据类型来确定,这样程序的执行效低,且容易出错。二、按值传递参数按值传递(关键字ByVal):通过常量传递实际参数,即传递参数值而不是传递它的地址。因为通用过程不能访问实参的内存地址,因而在通用过程中对形参的任何操作都不会影响实参。三、按地址传递参数VB默认的数据传递方式按地址传递(关键字ByRef):把实参变量的内存地址传递给被调过程(如Sub过程),即形参与实参使用相同的内存地址单元,这样通过过程就可以改变变量本身的值。实参必须是变量,不能采用常量或表达式。注意:在子过程和函数过程调用时,如果实参是常量(包括系统常量、用Const自定义的符号常量)或表达式,无论在定义时使用值传递还是地址传递,此时都是按值传递方式将常量或表达式计算的值传递给形参变量。如果形参定义是按传地址方式,但调用时想使实参变量按值方式传递,可以把实参变量加上括号,将其转换成表达式即可。四、使用子过程还是使用函数过程解决一个问题既可以使用子过程,也可以使用函数过程,是使用子过程还是使用函数过程呢?如果是需要求得一个值,一般情况使用函数过程,如不是为了求一个值,而是完