过程是程序设计中的重要概念_第1页
过程是程序设计中的重要概念_第2页
过程是程序设计中的重要概念_第3页
过程是程序设计中的重要概念_第4页
过程是程序设计中的重要概念_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第6章 过程“过程”是程序设计中的重要概念,是用于完成某项任务而设计的一段相对独立的程序代码。在VB中,一个程序是由若干个模块组成的,每个模块又是由若干个更小的代码段组成,这些组成模块的代码段称为过程。在VB中过程分为事件过程和通用过程。前面我们已经见过事件过程了,这样的过程是当发生某个事件(如Click,Load,Change)时,对该事件做出响应的程序段,这种事件过程构成了VB应用程序的主体。有时候多个不同事件过程可能需要使用一段相同的程序代码,可以把这一段代码独立出来,作为一个过程,这样的过程叫做“通用过程”(General procedure),它可以单独建立,供事件过程或其他通用过程

2、调用。通用过程又分为子程序过程(Sub过程)和函数过程(Function过程)。在本章主要围绕着VB应用程序中事件过程和通用过程介绍过程中参数的概念、参数的传递及变量的作用域等问题。6.1 事件过程事件过程是附加在对象上,与某个对象直接相关,当某事件发生时,对象对该事件做出响应的程序代码。事件过程只能在窗体模块中,并由事件触发。例如,窗体的单击事件过程等,VB为它提供了框架和接口,用户只需要根据需要填写它的内容即可。定义事件过程的格式如下:Private Sub <对象名>_<事件名>(<形参表列>)语句块1Exit Sub'可用该语句提前结束事件过

3、程语句块2End Sub说明:(1)对象名是一个对象的实际名字(对象的Name属性值)如Form1,Command1等。(2)事件名是该对象要触发的事件名称,如Click,Load等。例6.1:编写程序,当程序运行时在窗体上显示“窗体事件过程_练习程序”,单击窗体时则结束程序的运行。分析:由于该程序需要在Form_Load事件中调用Print方法,故应先将窗体Form1的AutoRedraw属性设置为True,然后再按如下步骤操作:(1)新建一个工程(新建窗体Form1)。(2)双击窗体,打开代码窗口,在对象组合框中选择Form,在事件组合框中选择Load,然后输入代码:Private Sub

4、 Form_Load()Font.Name = "宋体"'设置窗体显示的字体为“宋体”Font.Size = 18'设置窗体显示的字号为“18”PrintPrint Tab(3); "窗体事件过程_练习程序"'提示文本从第3列开始显示Font.Size = 15Font.Bold = TruePrintPrint Tab(6); "结束程序事件单击窗体"End Sub(3)在对象组合框中选择Form,在事件组合框中选择Click,然后输入代码:Private Sub Form_Click() Unload Me

5、End Sub(4)运行程序,结果如图6-1所示:图6-1 事件过程运行效果Load、Click都是常用的窗体事件,Load事件是在窗体装载过程中由系统自动触发的事件,主要用于对窗体属性初始化和对变量赋初值,Click事件是由用户单击窗体而触发的事件。6.2 通用过程通用过程是指将在不同程序中重复出现的一段事件代码单独编写成一个过程,其目的是在于简化程序设计,避免重复编写代码。通用过程是不属于任何一个过程的,它可以放在窗体模块中,也可以放在标准模块中,通用过程必须由事件过程或通用过程调用才可以执行。通用过程根据是否有返回值,又可以分为子程序过程(Sub过程)和函数过程(Function过程)。

6、其中子程序过程在程序运行后没有返回值;而函数过程在程序运行后要返回给调用程序一个值,该值的类型在定义函数过程时声明。下面主要介绍Sub过程和Function过程。 Sub过程VB提供了与Pascal,C语言等类似的子程序调用机制,即子程序和函数过程。1、Sub过程的建立(1)定义子程序Sub过程通用Sub过程的结构与前面介绍的事件过程的结构类似,一般格式如下:Static Private|Public Sub 过程名(参数列表)语句块1Exit Sub语句块2End Sub说明:Private表示Sub过程是一个私有过程,只限于本模块内的其他过程调用。Public表示Sub过程是一个公有过程,

7、所有模块都可以调用。Static表示Sub过程内的局部变量的值保留到下次调用,否则在每次调用过程时,局部变量都被重新设置为0。不加Private或Public默认是Public。过程名是用户为过程取的名字,过程名是一个长度不超过255个字符的VB合法标识符,同一模块内,Sub过程名不能和Function过程名同名。参数列表含有在调用时传送给该过程的简单变量名或数组名,各个名字之间用逗号隔开,参数列表指明了调用时传递给过程的参数的类型和个数。(2)建立子程序Sub过程前面我们已经见过如何定义Sub过程,通用过程不属于任何一个事件过程,因此不能放在事件过程中,通用过程可以在标准的模块中建立,也可以

8、在窗体模块中建立,如果在标准模块中建立通用过程,则可以使用两种方法:方法一:利用“工具”菜单下的“添加过程”菜单项定义,其步骤如下:单击“工程”菜单下的“添加模块”菜单项,打开“添加模块”对话框,在对话框中选择“新建”选项卡,然后双击模块图标,打开模块代码窗口。单击“工具”菜单下的“添加过程”菜单项,打开“添加过程”对话框,如图6-2所示。图6-2 “添加过程”对话框在“名称”文本框中输入要建立的过程名。在“类型”选项组中选择要建立的过程的类型,如果建立子程序过程,则选择“子程序”;如果要建立函数过程,则应选择“函数”在“范围”选项组中选择“公有的”定义一个全局过程;或选择“私有的”定义一个模

9、块级的局部过程。图6-3 建立子程序过程方法二:单击“工程”菜单下的“添加模块”菜单项,打开“添加模块”对话框,弹出模块代码窗口,然后直接输入过程名字。如:键入“Sub Tryout()”按回车后显示如图6-3所示的结果,即可在Sub和End Sub之间键入程序代码。2、Sub过程的调用调用即引起过程的执行,也就是说,要执行一个过程,必须调用该过程。Sub过程的调用有两种方式:方法一:用Call语句调用Sub过程格式:Call 过程名(参数列表)Call语句把程序控制传送到一个Sub过程,用Call语句调用一个过程时,如果过程本身没有参数,则“参数列表”和括号可以省略;否则应给出相应的实际参数

10、。如:Call Tryout(a,b)。方法二:把过程名作为一个语句来使用格式:窗体名|模块名 过程名 参数列表如:Tryout a,b方法二在调用时省略Call,与第一种方式有两点不同:去掉了关键字Call及“参数列表”的括号。例6.2:编写一个程序,在文本框(Text1)中输入任意一个数,当单击命令按钮(Command1)时,输出该数的阶乘值,运行结果如图6-4所示。分析:根据题意应在Command1_Click事件中取得text1的值,将其通过Val函数转换成数值型数据赋给m,调用求阶乘过程fact(m)。其中fact(n)功能是计算n!,并将其显示在屏幕上。其相应的事件及过程代码如下:

11、Private Sub Command1_Click() Dim m As Integerm = Val(Text1.Text) '将文本框中输入的内容转换成数值 Call fact(m)'调用过程fact()End SubPublic Sub fact(ByVal n As Integer) '过程定义 Dim p As Long, i As Integer p = 1 For i = 1 To n'计算n的阶乘 p = p * i Next i Print p'显示结果End Sub图6-4 阶乘运行结果 函数(Function)过程函数Functi

12、on过程调用后要返回一个值,通常出现在表达式中,下面介绍Function过程的定义和调用。1、Function过程的定义(1)利用菜单定义单击“工具”菜单,选择“添加过程”,显示添加过程对话框,如图6-2所示。在“名称”框中输入函数过程名(过程名中不允许有空格),在“类型”选项组中选取“函数”定义函数过程。在“范围”选项组中选取“公有的”定义一个公共级的全局过程,选取“私有的”定义一个标准模块级/窗体级的局部过程。这时VB建立了一个函数过程的模块,就可以在其中编写代码了。(2)利用代码窗口直接定义在窗体/标准模块的代码窗口把插入点放在所有现有过程之外,直接输入函数过程。定义Function过程

13、的形式如下:StaticPublic|Private Function 过程名 (参数列表)As 数据类型语句块1函数名=返回值Exit Function函数名=返回值语句块2End Function说明:函数过程名的命名规则与变量命名规则相同,不要与VB中的关键字重名,也不要与API函数重名,还不能与同一级别的变量重名。函数过程以Function开头,以End Function结束。函数过程通过函数名返回函数的值,因此,函数过程名要有数据类型,用As(数据类型)定义,如此项缺省,则默认为Variant类型。在函数过程内应该至少有一条给函数过程名赋值的语句。如果在Function过程中没有给函

14、数名赋值,则该Function过程的返回值为数据类型的默认值。例如,数值函数返回值为0,字符串函数返回值为空字符串,可变类型(Variant)函数返回值为空值。2、Function过程的调用Function过程调用比较简单,可以像VB内部函数一样来调用Function过程。实际上由于Function过程能返回一个值,因此完全可以把它看成是一个函数,它与内部函数没有什么区别,只不过内部函数由系统提供,而Function过程由用户自己定义。调用Function过程格式如下:函数过程名(参数列表)说明:(1)“参数列表”称为实参,必须与形参的个数保持相同,位置与类型一一对应。(2)调用时把实参的值传

15、递给形参称为参数传递。(3)当参数是数组时,形参与实参在参数声明时应省略其维数,但括号不能省略。例6.3:编写一函数过程完成例6.2的功能。分析:例6.2中的fact(n)是Sub过程,在程序运行后没有返回值,故在过程内将得到的n!输出;而本题在求n!时用函数过程fact1实现,在程序运行后fact1将n!作为函数值返回给调用程序,故在Command1_Click事件中将结果输出,其具体代码如下:Private Sub Command1_Click() Dim m As Integerm = Val(Text1.Text) '将文本框中输入的内容转换成数值 Print fact1(m)

16、'调用过程fact1(),并将函数值输出End SubPublic Sub fact1(ByVal n As Integer) As Integer '函数过程定义 Dim p As Long, i As Integer p = 1 For i = 1 To n'计算n的阶乘 p = p * i Next i fact1=p'将求得的n!赋给函数名fact1End Sub例6.4:利用函数过程求最大公约数和最小公倍数。分析:求最大公约数的算法思想,对于已知两个数x,y,使得x>y;x除以y得余数r;若r=0,则y为求得的最大公约数,算法结束,返回y;如果r

17、0,则xy,yr,再重复上述步骤。而最小公倍数=两个数之积/最大公约数。其过程如下:Function GYS(ByVal x As Integer, ByVal y As Integer) As Integer'定义函数GYS If x < y Then t = x: x = y: y = t'交换x与y的值 End If r = x Mod y Do While r <> 0 x = y y = r Loop GYS = y'将要返回y的值赋给函数名End Function上述函数过程通过反复相除求最大公约数,可通过下面的GBS过程求最小公倍数:Fu

18、nction GBS(ByVal x As Integer, ByVal y As Integer) GBS = (x * y) / GYS(x, y)End FunctionSub Form_Click()'调用GYS和GBS的事件 Dim a As Integer, b As Integer a = 48: b = 96 m = GYS(a, b)'调用GYS()函数 Print "最大公约数是=" m n = GBS(a, b) Print "最小公倍数是=" nEnd Sub例6.5:编写程序,打印0到1000之间的伪随机数,要打

19、印的随机数的个数在运行时指定,要求每5个打印一行,生成随机数的操作用一个Function过程实现。 分析:产生随机数的方法很多,用内部函数Rnd可以产生随机数,这里我们用线性同余法来产生随机数,表达式如下:x=(x*29+37)Mod 1000,此外x要有一个初值,即“随机种子”。过程rand用线性同余法产生随机数,该过程不带参数,是一个无参过程,每调用一次rand,就产生一个01000之间的伪随机数,在事件过程中,用Mod操作伪随机数按5个打印一行,产生随机数的函数过程rand()的代码如下:Dim x As Integer, n As Integer'在窗体层定义Static Fu

20、nction rand()x=x*29+37x=x mod 1000n=xrand=nEnd Function调用rand()的事件过程如下:Private Sub Form_Click() Dim rannum As Integer, n As Integer FormSize = 12 x = 677 Cls rannum = InputBox("How many random integer to be print:") '输入产生随机数的个数赋给rannum图6-5 例6.5的运行结果 Print "Print Random integer bet

21、ween 0 to 1000;", Chr$(13) Print For m = 1 To rannum If m Mod 5 = 0 Then Print rand(); " " Print Else Print rand(); " " End If Next mEnd Sub程序运行后单击窗体,在输入对话框中输入50后,其运行结果如图6-5所示。6.2.3 函数过程与子程序过程的区别1、函数过程与子程序过程在格式上的区别(1)函数过程定义以Function开头,以End Function结束,子程序过程以Sub开头,以End Sub结束。(

22、2)函数过程通过函数名返回函数的值,因此,函数过程名要有数据类型,用As数据类型定义,如果此项缺省,则默认为Variant类型;子程序过程无返回值。(3)通常,在函数过程内的函数名至少应被赋值一次,使函数获得返回值,否则,函数过程将返回一个默认值,数值函数返回0,字符串函数返回一个空串;而子程序过程内没有对子过程名的赋值。2、函数过程与子程序过程在调用上的区别函数过程与子程序过程在调用上的区别,主要是将函数过程调用写在一个表达式中,作为表达式的一项参与运算,而将子程序过程作为一个程序语句或用CALL命令调用。6.3 参数传递参数传递是主调过程和被调过程之间进行数据交换的主要途径,在调用一个过程

23、时,将主调过程的实际参数传递给被调过程的形式参数,完成形式参数与实际参数的结合,然后用实际参数执行调用的过程。参数传递有两种方式:按值传递和按址传递。6.3.1 形参和实参在过程定义的参数表中出现的参数称为形式参数(简称形参)。在过程被调用之前,形参并未被分配内存,只是说明形参的类型和在过程中的作用。形参列表中的各参数之间用逗号分隔,形参可以是变量名和数组名。在调用过程语句或表达式中出现的参数表称为实在参数(简称实参),在过程调用时,实参将数据传递给形参。实参表可由常量、表达式、有效的变量名、数组名组成,实参表中各参数用逗号分隔。在调用一个过程时,必须把实参传送给过程中的形参,完成形参与实参的

24、结合,这种参数的传递也称为参数的结合。例如,定义一个过程:Sub Sum(x As Integer, y As Integer, z As Integer)End Sub过程调用:Call Sum(a, b, c)则其形参与实参的结合关系为,实参传递给对应的形参,即:ax,by,cz。在传递参数时,形参表与实参表中对应参数的名字可以不同,但要求形参表与实参表中参数的个数、数据类型、位置顺序必须一一对应。因为在调用过程时,形参和实参结合是按位置结合的,即第一个实参与第一个形参结合,第二个实参与第二个形参结合,依次类推。6.3.2 按值传递和按址传递VB中传递参数的方式有两种:一种是按值传递,另一

25、种是按址传递。在过程定义时,形参前加ByVal关键字的是按值传递,形参前加ByRef关键字(或省略)的是按址传递。1、按值传递按值传递参数时,VB给传递的形参分配一个临时的内存单元,将实参的值传递到这个临时单元中去。实参向形参传递是单向的,如果在被调用的过程中改变了形参值,则只是临时单元的值变动,不会影响实参变量本身。当被调用过程结束返回调用过程时,VB将释放给形参分配的临时内存单元,实参变量的值保持不变。如果调用语句中的实参是常量或表达式,此时参数传递是按值传递。例6.6:按值传递示例。分析:在Form_Click()事件中两次调用了过程Sum(),其中Call Sum(1, 2, a +

26、b)里的实参分别是常量和表达式,因此是按值传递。而Call Sum(a), (b), c)里的实参分别是表达式和变量,但形参ByVal z As Integer说明第三个参数也是按值传递,其参数传递过程可以参照图6-6。因此,在Sum过程中形参x,y,z值虽然被改变了,但实参的值不会受到影响。其运行结果如图6-7所示。123123abcxyz123abc356xyz图6-6 按值传递时参数的内存空间分配Private Sub Form_Click() Dim a As Integer, b As Integer, c As Integer a = 1: b = 2: c = 3 Print &

27、quot;调用过程前 a,b,c=" a, b, c Call Sum(1, 2, a + b) '实参是常量或表达式时,是按值传递 Print "第一次调用后a,b,c=" a, b, c Call Sum(a), (b), c) 'a,b用括号括起来了,c所对应的形参前有ByVal,是按值传递如图6-6所示 Print "第二次调用后a,b,c=" a, b, cEnd SubSub Sum(x As Integer, y As Integer, ByVal z As Integer) x = x + y: y = y +

28、z: z = z + x Print "过程调用中 x,y,z=" x, y, zEnd Sub图6-7 按值传递运行结果2、按址传递按址传递参数是指实参变量的内存地址传递给形参,使形参和实参具有相同的地址,这意味着形参和实参共享一段存储单元。因此,在被调用过程中改变形参的值,则相应实参的值也被改变,也就是说,与按值传递参数不同,按址传递参数可以在被调用过程中改变实参的值。当实参是变量,并且形参前无ByVal关键字说明时即按址传递。例6.7:按址传递示例。分析:在本题中形参前均无ByVal且实参均是变量,因此参数的传递方式是按址传递,其参数传递过程可以参照图6-8,其运行结

29、果如图6-9所示。123a地址abcxyz123abcxyzb地址c地址图6-8 变量参数传递示意Sub Sum(x As Integer, ByRef y As Integer, z As Integer) x = x + y: y = y + z: z = z + x Print "过程调用中 x,y,z=" x, y, zEnd SubPrivate Sub Form_Click() Dim a As Integer, b As Integer, c As Integer a = 1: b = 2: c = 3 Print "调用过程前 a,b,c=&quo

30、t; a, b, c Call Sum(a, b, c)'实参是变量,按址传递 Print "调用过程后 a,b,c=" a, b, cEnd Sub图6-9 例6.7运行结果6.3.3 数组参数的传递过程参数可以是任何的数据类型,即基本类型、数组、自定义类型数据和对象均可以作为过程参数,数组作为过程参数分为两种:传递数组中的元素和传递整个数组。1、数组元素作参数当过程中使用数组元素作为实参进行参数传递时,同基本类型的变量作参数的用法一样,即形参前有ByVal关键字时按值传递,否则按址传递。例6.8:数组元素作为参数实例。分析:实例中的Call Sqval(test

31、_array(5,3)语句把数组test_array第5行第3列的元素送到了过程Sqval,在执行过程Sqval之后,改变了Test_array(5,3)的值。Dim test_array() As Integer'定义动态数组test_array()Sub Sqval(a As Integer) a = Sqr(Abs(a) '改变a的值End SubSub Form_Click() ReDim test_array(1 To 5, 1 To 3) '重新定义test_array()为二维数组 test_array(5, 3) = -36'为test_arra

32、y(5, 3)赋值 Print test_array(5, 3)'输出-36 Call Sqval(test_array(5, 3)'通过调用过程Sqval,把实参test_array(5, 3)的值按址传递的方式传给形参aPrint test_array(5, 3)'输出6End Sub2、数组整体作参数当要把整个数组传递给过程处理时,只能按址传递,调用中使用的实参是数组名,向形参传递的是数组的首地址,形参中的数组名后可以用一对空括号,但是形参的数据类型必须与实参一致。VB允许把数组作为实参传递给过程,例如,定义如下过程:Sub S(a(),b()End Sub这个过

33、程有2个形参,a()和b()都是数组,注意数组后的括号,以便与变量区分。可以用下面的语句调用该过程:Call S(p1(),p2()这样把数组p1和p2传递给数组a和b,当用数组作为过程的参数时,使用的是按址传递方式,而不是按值传递方式,即不是把各元素的值传递给过程的数组,而是把数组的p1,p2的起始地址传递给过程。数组一般按址方式传送,在传送数组时除了要遵守一般的规则,还要注意以下几点:(1)为了把一个数组的全部元素传递给一个过程,应将数组分别放入实参和形参列表中,并省略数组的上下界,但括号不能省略。(2)如果不需要把整个数组传递给过程,可以只传递指定的单个元素,这需要在数组名后面的括号里指

34、定元素的下标。例6.9:编写程序实现顺序查找功能。分析:顺序查找根据查找的关键值与数组中的元素逐一比较,若相同,查找成功,若找不到,则查找失败。查找子过程及其子过程调用如下:Public Sub Search(a() As Integer, ByVal key, index) For i = LBound(a) To UBound(a) If key = a(i) Then index = i '如果找到,元素的下标保存在index形参中 Exit Sub '结束查找 End If Next i index = -1 '找不到,index形参的值为-1End SubPr

35、ivate Sub Form_Click() Dim b(1 To 6) As Integer For i = 1 To 6 b(i) = i * 2 + 1 Next i k = Val(InputBox("输入要查找的关键值:") Call Search(b, k, n) If n = -1 Then Print "没有要找的数据!" Else Print "要找的数据在第" n; "个位置" End IfEnd Sub6.3.4 可选参数一般来说,个过程在声明时定义了几个形参,则在调用这个过程时就必须使用相同

36、数量的实参。VB允许在形参前面使用Optional关键字把它设定为可选参数。如果一个过程的某个形参为可选参数,则在调用此过程时可以不提供对应于这个形参的实参。如果在过程定义的形参表中用Optional关键字将某个参数指定为可选参数,则参数表中此参数后面的所有其他参数也必须是可选的,并都要用Optional来修饰。例6.10:编写函数来计算两个数(或三个数)的乘积。分析:编写Multi函数,定义三个参数,其中前两个参数与普通过程中的书写格式相同,最后一个参数没有指定类型(使用默认类型Variant),而是前面加了Optional,表明该参数是一个可选参数。在过程体中,首先计算前两个参数的乘积,并

37、把结果赋给变量n,然后测试第三个数是否存在,如果存在,则把第三个参数与前两个参数的乘积相乘,最后输出乘积。并且在过程体中通过IsMissing函数来测试调用时是否传递可选参数。当调用时,提供了可选参数,则IsMissing函数的返回值为Flase,如果没有提供可选参数,则IsMissing函数返回值为True。具体的过程代码如下:Function Multi(fir As Integer, sec As Integer, Optional third) Dim n As Integer n = fir * sec If Not IsMissing(third) Then'判断第3个参数

38、是否存在 n = n * third End If Multi = nEnd FunctionPrivate Sub Form_Click() Print Multi(2, 3) '提供2个参数 Print Multi(2, 3, 4)'提供3个参数End Sub 可变参数如果一个过程的最后一个参数是使用ParamArray关键字声明的数组,则这个过程在被调用时可以接受任意多个实参。调用这个过程时使用的多个实参值均按顺序存于这个数组中。ParamArray关键字不能与Byval、ByRef或Optional关键字针对同一个形参一起使用。使用ParamArray关键字修饰的参数只

39、能是Variant类型,一个过程只能有个这样的形参。当有多个形参时,ParamArray修饰的形参必须是形参表中的最后一个。例6.11:编写函数来计算多个数的乘积。分析:编写Multi函数,定义可变参数ParamArray Num(),在调用时将实参分别传给数组Num,函数体内运用For循环将在数组Num中的每一个元素相乘,最后将乘积作为函数值返回。具体的过程代码如下:Function Multi(ParamArray Num() Dim n As Integer n = 1 For Each x In Num n = n * x Next x Multi = nEnd FunctionPri

40、vate Sub Form_Click() Print Multi(2, 3) '提供2个参数 Print Multi(2, 3, 4)'提供3个参数 Print Multi(1, 2, 3, 4, 5)'提供5个参数End Sub 对象参数和传统的程序设计语言一样,通用过程一般用变量作为形式参数。但是,和传统的程序设计语言不同,VB还允许使用对象,即窗体或控件作为过程的参数。在有些情况下,这样可以简化程序设计,提高效率。下面我们来看用窗体和控件作为通用过程参数的操作。1、窗体参数我们首先通过一个例子来说明窗体参数的使用:例6.12:设计一个多窗体的程序,该程序含有4个

41、窗体,要求这4个窗体的位置,大小都相同,单击窗体后四个窗体按照设定的Form1,Form2,Form3,Form4的顺序切换。分析:窗体的大小,位置通过left、Top、Width及Height属性来设置。每个窗体通过4个语句确定其大小和位置,除窗体名称不同外,其他都一样。因此,可以用窗体作为参数,编写一个调用过程:Sub FormSet(FormNum As Form) FormNum.Left = 2000 FormNum.Top = 3000 FormNum.Width = 5000 FormNum.Height = 3000End Sub上面通用过程有一个形式参数,该参数的类型为窗体(

42、Form),在调用时,可以用窗体作为实参,例如:FormSet Form1将按过程中给出的数值设置窗体Form1的大小和位置。为了调用上面的通用过程,可以在该工程中添加4个窗体,即Form1,Form2,Form3和Form4,在默认的情况下,Form1是启动窗口。对Form1编写如下事件过程:Private Sub Form_Load() FormSet Form1 FormSet Form2 FormSet Form3 FormSet Form4End Sub 对4个窗体分别编写如下事件过程:Form1中添加代码:Private Sub Form_Click() Form1.Hide Fo

43、rm2.ShowEnd SubForm2中添加代码:Private Sub Form_Click() Form2.Hide Form3.ShowEnd Sub Form3中添加代码:Private Sub Form_Click() Form3.Hide Form4.ShowEnd SubForm4中添加代码:Private Sub Form_Click() Form4.Hide Form1.ShowEnd Sub上述程序运行后,首先显示Form1,单击该窗体后,Form1消失,显示Form2,单击Form2窗体,Form2 消失,显示Form3,以此类推。所显示的每个窗体的大小和位置均相同。2

44、、控件参数和窗体参数一样,控件也可以作为通用过程的参数,即在一个通用过程中设置相同性质控件所需要的属性,然后在调用此过程时使用不同的控件作实参。例6.13:对文本框中输入的数据进行检查。分析:一个界面中有若干个文本框用于输入数据,现要求文本框中输入的数据均为数值型的,因此,在文本框的失去焦点(LostFocus)事件中,要检查输入数据是否是数值型的,如果不是数值型的,则出现MsgBox对话框提示出错,并且用SetFocus方法将焦点移回文本框。显然,在每个文本框的失去焦点事件中,均需要编写进行数据检查的代码,可以编写一个通用过程txtCheck进行数据检查,在文本框的失去焦点事件过程中调用这个

45、通用过程。编写的txtCheck通用过程,将文本框作为参数,调用这个通用过程时,将文本框的对象名作为实参传递给形参,从而使得同一个txtCheck通用过程可以对不同文本框进行检查。程序示例代码如下:Private Sub txtCheck(txt As TextBox) '定义文本框输入数据检查的通用过程 If IsNumeric(txt.Text) = True Then txtNumber = Val(txt.Text) Else MsgBox ("输入数据出错!") txt.Text = "" txt.SetFocus End IfEnd

46、SubPrivate Sub Text1_LostFocus() Call txtCheck(Text1) '调用txtCheck过程判断text1输入的是不是数字End SubPrivate Sub Text2_LostFocus() Call txtCheck(Text2) End Sub6.4 变量和过程的作用域VB的应用程序由若干个过程组成,这些过程一般保存在窗体文件(.frm)或标准模块文件(.bas)中。变量在过程中是必不可少的。一个变量、过程随所处的位置不同,可被访问的范围不同,变量、过程可被访问的范围称为变量、过程的作用域。 过程的作用域一般VB的应用程序组成可用图6-

47、10描述。本章只讨论窗体和标准模块文件。过程的作用域分为:窗体/模块级和全局级。应用程序工程(.vbp)窗体模块(.frm文件)类模块(.cls文件)标准模块(.bas文件)声明部分子程序过程(Sub)函数过程(Function)事件过程声明部分子程序过程(Sub)函数过程(Function)图6-10 VB应用程序组成1、窗体/模块级指在某个窗体或标准模块内定义的过程,定义过程前加Private关键字。这类过程只能被本窗体(在本窗体内定义)或本标准模块(在本标准模块内定义)中的过程调用。2、全局级指在窗体或标准模块中定义的过程,默认是全局的,也可加Public进行说明。全局过程可供该应用程序

48、的所有窗体和所有标准模块中的过程调用,但根据过程所处的位置不同,其调用方式有所不同。(1)在窗体中定义的过程。外部过程要调用时,必须在过程名前加该过程所处的窗体名。(2)在标准模块中定义的过程。外部过程均可调用,但过程名必须唯一,否则要加标准模块名。有关规则参见表6-1。表6-1 不同作用范围的过程定义及调用规则作用范围模块级全局级窗体标准模块窗体标准模块定义方式过程名前加Private例:Private Sub S1(形参表)过程名前加Public或缺省例:Public Sub S2(形参表)能否被本模块其他过程调用能能能能能否被本应用程序其他模块调用不能不能能,但必须在过程名前加窗体名例:

49、Call 窗体名.S2(实参表)能,但过程名必须唯一,否则要加标准模块名例:Call 标准模块名.S2(实参表) 变量的作用域变量的作用域与过程类似,它决定了哪些过程可访问该变量。根据变量的作用域不同,变量可以分为:局部变量、窗体/模块级变量和全局变量。表6-2列出了变量的作用范围及使用规则。1、局部变量局部变量是指在过程内用Dim语句声明的变量(或不加声明直接使用的变量),只能在本过程中使用的变量,其他过程不可访问。局部变量随过程的调用而分配存储单元,并进行变量的初始化,在此过程体内进行数据的存取,一旦该过程体结束,则内容自动消失,占用的存储单元释放。不同的过程中可有相同名称的变量,彼此互不

50、相干,使用局部变量,有利于程序的调试。例6.14:在下面的过程Command1_Click中定义了局部变量a、b,在过程中也定义了局部变量a、b。分析:在这两个过程中定义的同名局部变量互不相干,它们的作用域分别是它们所在的过程。每次执行Command1_Click过程的结果都一样。具体的代码如下:Private Sub Command1_Click() Dim a As Integer, b As Integer'局部变量 a = 1: b = 2 Call S1(a, b) Print a, b'输出1,2End SubSub S1(ByVal x As Integer, B

51、yVal y As Integer) Dim a As Integer, b As Integer'局部变量 a = x + 2 b = y + 3 Print a, b'输出3,5End Sub2、窗体/模块级变量窗体/模块级变量是指在一个窗体/模块的任何过程外,即在“通用声明”段中用Dim语句或用Private语句声明的变量,可被本窗体/模块的任何过程访问。例6.15:将例6.14中的变量a、b在窗体的通用声明段中定义。分析:在窗体通用声明段中定义的变量为窗体/模块级变量,故在本窗体的所有过程中都能引用这些变量。具体的代码如下:Dim a As Integer, b As

52、Integer'窗体/模块级变量Private Sub Command1_Click() a = 1: b = 2 Call S1(a, b) Print a, b'输出3,5End SubSub S1(ByVal x As Integer, ByVal y As Integer) a = x + 2 b = y + 3 Print a, b'输出3,5End Sub3、全局变量全局变量是指只能在标准模块的任何过程或函数外,即在“通用声明”段中用Public语句声明的变量,可被应用程序的任何过程或函数访问。全局变量的值在整个应用程序中始终不会消失和重新初始化,只有当整个

53、应用程序执行结束时,才会消失。表6-2列出了变量的作用范围及使用规则。表6-2 不同作用范围的变量声明及使用规则作用范围局部变量窗体/模块级变量全局变量窗体标准模块声明方式Dim,StaticDim,PrivatePublic声明位置在过程中窗体/模块的“通用声明”段窗体/模块的“通用声明”段被本模块的其它过程存取不能能能被其它模块存取不能不能能,但在变量名前加窗体名能 变量的生命周期所谓变量的生命周期,是指能够保存变量值的时间。如果说变量的作用域是从空间角度来看待变量的,那么生命周期则是从变量存在的时间上来理解的。根据变量的生存期不同可以将变量分为动态变量和静态变量。1、动态变量在应用程序中

54、的变量如果不使用Static语句进行声明,则属于动态变量。对于过程级的动态变量,在程序运行到变量所在的过程时,系统为变量分配存储空间,并进行变量的初始化工作;当该过程结束时,释放变量所占用的存储空间,其值不再存在。窗体/模块级动态变量在运行窗体/模块时被初始化,在退出窗体/模块时释放其所占用的存储空间。全局级动态变量在应用程序执行时分配存储空间,在退出应用程序时释放存储空间。2、静态变量如果一个变量用Static语句声明,则该变量只被初始化一次,在应用程序运行期间保留其值,即在每次调用该变量所在的过程时,该变量不会被更新初始化,而在退出变量所在的过程时,不释放该变量所占的存储空间。在Sub过程

55、、Function过程的定义语句中使用Static修饰词,表明该过程内所有的变量均为静态变量。例6.16:用Static关键字来声明局部变量示例。分析:当每次单击Command1时,j的值都会在上次执行的结果上加1。程序运行后,第1次单击在文本框中显示1,第2次单击在文本框中显示2,以此类推,第n次单击时在文本框中显示n。如果将Static j As Integer改为Dim j As Integer,则程序在执行时无论单击多少次都会在文本框中显示1。模块/窗体级和全局变量的生命周期是程序的运行期,不必使用Static关键字进行声明。Private Sub Command1_Click() S

56、tatic j As Integer j = j + 1 Text1.Text = jEnd Sub例6.17:模块/窗体级变量示例。分析:本题将例6.16中的局部变量j改为模块/窗体级变量,其运行结果同上题。也可将Dim j As Integer改为Public j As Integer或Private j As Integer。Dim j As IntegerPrivate Sub Command1_Click() j = j + 1 Text1.Text = jEnd Sub6.5 递归递归就是某一事物直接地或间接地由自己组成。一个过程直接或间接地调用自身,便构成了过程的递归调用,前者称为直接递归调用,后者称为

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论