VB学习资料第七章 过程和变量的作用域.docx
《VB学习资料第七章 过程和变量的作用域.docx》由会员分享,可在线阅读,更多相关《VB学习资料第七章 过程和变量的作用域.docx(14页珍藏版)》请在冰豆网上搜索。
VB学习资料第七章过程和变量的作用域
§7.1代码模块的概述
VB应用程序(通常称为工程)的组织结构,它由窗体模块、标准模块和类模块组成。
VB程序代码就保存在窗体模块文件(*.Frm)、标准模块文件(*.Bas)或类模块文件(*.Cls)中。
它们形成了工程的一种模块层次结构,如图7-1所示。
图7-1
一、窗体模块(文件扩展名为.FRM)
窗体模块可以包含处理事件的过程、通用过程以及变量、常数、类型和外部过程的窗体级声明。
如果要在文本编辑器中观察窗体模块,则还会看到窗体及其控件的描述,包括它们的属性设置值。
写入窗体模块的代码是该窗体所属的具体应用程序专用的;它也可以引用该应用程序内的其它窗体或对象。
二、标准模块(文件扩展名为.BAS)
标准模块可以包含变量、常数、类型、外部过程和全局过程的全局(在整个应用程序范围内有效的)声明或模块级声明。
写入标准模块的代码不必绑在特定的应用程序上,则在许多不同的应用程序中可以重用标准模块。
三、类模块(文件扩展名为.CLS)
在VisualBasic中类模块是面向对象编程的基础。
可在类模块中编写代码建立新对象。
这些新对象可以包含自定义的属性和方法。
实际上,窗体正是这样一种类模块,在其上可安放控件,可显示窗体窗口。
§7.2过程的作用域
应用程序中的过程有作用域。
所谓作用域,就是过程可在哪些地方被使用。
作用域的大小和过程所处的位置及定义方式有关。
按过程的作用范围分为:
窗体/模块级过程和全局级过程。
通用子过程和函数过程既可写在窗体模块中也可写在标准模块中,在定义时可选用关键字Private(局部)和Public(全局),来决定它们能被调用的范围。
[Public|Private]Sub子过程名([形式参数列表])
……………
EndSub
1、窗体/模块级过程:
加Private关键字的过程,只能被定义的窗体或模块中的过程调用。
2、全局级过程:
加Public关键字(或缺省)的过程,可供该应用程序的所有窗体和所有标准模块中的过程调用。
总结归纳过程的定义及作用域如表7-1所示。
表7-1
作用范围
模块级
全局级
窗体
标准模块
窗体
标准模块
定义方式
过程名前加Private
例:
PrivateSubMysub1(形参表)
过程名前加Private或缺省
例:
[Private]SubMysub2(形参表)
能否被本模块其它过程调用
能
能
能
能
能否被应用程序本其它模块调用
不能
不能
能,但必须在过程名前加窗体名。
例:
Call窗体名.My2(实参表)
能,但过程名必须唯一,否则要加标准模块名。
例:
Call标准模块名.My2(实参表)
7.3.1过程级变量——局部变量
变量的作用域决定了哪些子过程和函数过程可访问该变量。
变量的作用域分为局部变量、窗体/模块级变量和全局变量。
三种变量作用范围及使用规则如表7-2所示。
表7-2
作用范围
局部变量
窗体/模块级变化
全局变量
窗体
标准模块
声明方式
Dim,static
Dim,private
public
声明位置
在过程中
窗体/模块的“通用声明段”
窗体/模块的“通用声明段”
被本模块的其它过程存取
不能
能
能
被其它模块存取
不能
不能
能,在变量名前加窗体名
能
1、局部变量(过程级变量)
2、窗体/模块级变量(私有的模块级变量,能被本模块的所有过程和函数使用)
3、全局级变量(公有的模块级变量)
过程级变量——局部变量
局部变量:
在过程内用声明的变量,在一个过程内部使用Dim或者Static关键字来声明的变量称为局部变量。
只能在本过程中使用,别的过程不可访问。
所以可以在不同的过程中声明相同名字的局部变量而互不影响。
【例】在一个窗体中可以定义相同名字的局部变量。
PrivateSubCommand1_Click()
DimCountAsInteger
DimSumAsInteger
...
EndSub
PrivateSubCommand2_Click()
DimSumAsInteger
...
EndSub
7.3.2窗体/模块级变量
在“通用声明”段中用Dim语句或用Private语句声明的变量,可被本窗体/模块的任何过程访问。
但其他窗体或模块却不能引用该变量。
以Public声明的变量,允许在其他窗体和模块中引用。
例如:
在“通用声明”段声明变量如图7-2所示。
DimtempAsString
PrivateaAsInteger,bAsSingle
图7-2
7.3.3全局变量
一、全局变量
全局变量也称公有的模块级变量,在窗体模块或标准模块的顶部的“通用”声明段用Public关键字声明,它的作用范围是整个应用程序,即可被本应用程序的任何过程或函数访问。
例如:
PublicaAsInteger,bAssingle
二、应用举例
不同作用域变量的使用。
在Form1窗体代码窗口输入如下程序:
Privatea%'窗体/模块级变量
PrivateSubForm_Click()
Dimc%,s%'局部变量
c=20
s=a+Form2.b+c'引用各级变量
Print"s=";s
EndSub
PrivateSubForm_Load()
a=10'给窗体/模块级变量赋值
Form2.Show
EndSub
添加Form2窗体,在它的代码窗口输入如下代码:
Publicb%'定义全局变量
PrivateSubForm_Load()
b=30'给全局变量赋值
EndSub
运行程序,单击Form1窗体,
s=60
在本例中,在Form1窗体的Click事件过程中引用了Form2窗体中定义的全局级变量b,由此可以看出在代码窗口“通用声明”段中用Public定义的变量确实是在整个应用程序中起作用的。
如果将Form1代码窗口中的Form_Click事件过程做如下变动:
PrivateSubForm_Click()
Dimc%,s%,b%'局部变量
c=20
b=40
s=a+b+c
Print"s=";s
EndSub
s=70
结果发生了变化。
原因是在VB中,当同一应用程序中定义了不同级别的同名变量时,系统优先访问作用域小的变量。
上例改动后,系统优先访问了局部变量b,因此结果当然也相应地改变了。
如果想优先访问全局变量,则应在全局变量前加上窗体/模块名。
7.3.4关于多个变量同名
一、公用变量与局部变量同名
在不同过程中定义同名变量,它们互不影响,但若在一过程中定义使用了与全局变量同名的变量,则应注意。
在过程中,如果定义了与模块级变量(在通用部分使用Private或Dim声明的变量),则在该过程内不能引用同名的模块级变量。
例如:
上面的例子中,如果将定义全局变量的语句PublicTempAsInteger改为PrivateTempAsInteger则在Command1的单击事件中就不使用模块级的Temp变量。
PublicTempAsInteger'定义全局变量
PrivateSubForm_Load()
Temp=1'将全局变量Temp的值设置成1
EndSub
PrivateSubCommand1_Click()
DimTempAsInteger'定义局部变量
Temp=2'将局部变量Temp的值设置成2
Print"temp=";Temp
Print"temp=";Form1.Temp
EndSub
PrivateSubCommand2_Click()
Print"temp=";Temp
EndSub
二、全局变量同名
如果不同模块中的全局变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们。
例如:
如果有一个在Form1和Module1中都声明了公用的Integer变量intX,则把它们作为Module1.intX和Form1.intX来引用便得到正确值。
也就是说如果不同模块中的全局变量使用同一名字,引用时就需要使用“模块名.变量名”的形式来区分它们。
7.3.5静态变量
局部变量除了用Dim语句声明外,还可用Static语句将变量声明为静态变量,它在程序运行过程中可保留变量的值。
也就是说,每次调用过程后,用Static说明的变量会保留运行后的结果;而在过程内用Dim说明的变量,每次调用过程结束,都会将这些局部变量释放掉。
当下一次执行该过程时,它的所有局部变量将重新初始化。
Dim声明:
随过程的调用而分配存贮单元,变量的初始化;过程体结束,变量的内容自动消失,存贮单元释放。
Static声明:
每次调用过程,变量保持上次调用结束时的值。
局部变量的存活期由其定义的关键词来决定。
局部变量声明形式:
Static变量名[As类型]
StaticFunction函数过程名([参数列表])[As类型]
StaticSub子过程名[(参数列表)]
注意:
若在函数名、过程名前加Static,则表示该函数、过程内的局部变量都是静态变量。
【例】使用StaticSub语句的示例
StaticSubSubtest()
DimtAsInteger't为静态变量
t=2*t+1
Printt
EndSub
PrivateSubCommand1_Click()
CallSubtest'调用子过程Subtest
EndSub
程序运行分析:
单击窗体次数,比较使用模块变量和静态变量的差别。
运行后,多次单击命令按钮Command1。
1
3
7
……
将StaticSub改为PrivateSub后,运行过程中多次单击命令按钮Command1。
1
1
1
7.4.1设置启动对象
一个稍微复杂的应用程序,不仅有多个窗体,还可能有标准模块和类模块,如图7-3所示。
在多模块程序中,有启动对象的设置、窗体的加载与卸载、窗体的加载与卸载时的事件、多模块间数据的传递等问题。
图7-3
在程序运行时,首先被加载并执行的对象,称为程序的启动对象。
一个程序的启动对象可以是一个窗体,也可以是标准模块中名为Main的自定义Sub过程。
缺省情况下,第一个创建的窗体被指定为启动对象。
1、设置方法:
从“工程”菜单中的最后一项“**属性(E)”对话框中进行设置。
2、如果设置从主过程Main()启动,则必须在标准模块中编写Main()过程代码。
7.4.2窗体的加载与卸载过程
当一个窗体要显示在屏幕之前,必须先建立,接着被装入内存(Load语句),最后显示(Show方法)在屏幕上。
同样,当窗体要结束之前,会先从屏幕上隐藏(Hide方法),接着从内存中删除(Unload方法)
在窗体的加载过程的各阶段所用一的语句或方法以及所触发的事件可用如图7-4所示来说明:
图7-4
在窗体的卸载过程的各阶段所用一的语句或方法以及所触发的事件如图7-5所示:
图7-5
1、窗体的加载与显示
(1)Load语句:
装入窗体到内存
Load<窗体名称>
说明:
①执行Load语句后,窗体并不显示出来,但可引用该窗体中的控件及各种属性。
②这里的窗体名称是窗体的Name属性,而不是窗体的文件名,以下相同。
③除非在加载窗体时不需要显示窗体,对于一般窗体不需要使用Load语句。
在窗体还未被加载时,对窗体的任何引用会自动加载该窗体。
例如,Show方法在显示窗体前会先加载它。
④当VisualBasic加载Form对象时,先把窗体属性设置为初始值,再执行Load事件过程。
当应用程序开始运行时,VisualBasic自动加载并显示应用程序的启动窗体。
(2)Show方法:
显示一个窗体
[窗体名称].Show[模式]
0-Modeless(非模式):
可以对其它窗体进行操作
1-Model,关闭才能对其它窗体进行操作。
说明:
◆Show方法用于在屏幕上显示一个窗体,使指定的窗体在屏幕上可见,调用Show方法与设置窗体Visible属性为True具有相同的效果。
如果要显示的窗体事先未装入,该方法会自动装入该窗体(相当于先执行Load语句)再显示。
注意:
除非使用Show方法或将窗体的Visible属性设置为True,否则,一个用Load语句加载的窗体是不可见的。
2、窗体的隐藏与卸载
(1)Unload语句:
从内存中删除窗体(卸载)。
Unload<窗体名称>
说明:
◆当窗体卸载之后,所有在运行时放到该窗体上的控件都不再是可访问的。
在设计时放到该窗体上的控件将保持不变。
在卸载窗体时,只有显示的部件被卸载。
与该窗体模块相关联的代码还保持在内存中。
(2)Hide方法:
隐藏,没有从内存中删除窗体。
[窗体名称].Hide
说明:
◆在多窗体的应用程序各窗体之间的切换,可使用窗体的Show方法或Hide方法。
用Hide方法使指定的窗体不显示,但这与将窗体的Visible属性设置为False的效果相同。
7.4.3窗体加载与卸载过程的事件
1、Initialize事件
当应用程序根据用户在设计阶段设计的窗体创建真正的窗体(Form类的实例)时,会发生Initialize事件。
在程序运行阶段,一个窗体可能多次被加载或卸载,但Initialize事件只会发生一次。
2、Load事件
该事件是在一个窗体被装载时发生。
当使用Load语句启动应用程序,或引用未装载的窗体属性或控件时,此事件发生。
通常,Load事件过程用来对窗体进行初始化操作。
3、Paint事件
当一个窗体被移动或放大之后,或当一个覆盖在窗体上的其它窗体被移开之后,此事件
发生。
可通过将窗体的AutoRedraw属性被设置为True,使得重新绘图自动进行,系统将触
发Paint事件。
4、QueryUnLoad事件
在一个窗体关闭之前,该窗体的QueryUnload事件先于该窗体的Unload事件发生。
此
事件的典型应用是在关闭一个应用程序之前,用来确保包含在该应用程序的窗体中没有未完
成的任务。
例如,如果还未保存某一窗体中的新数据,则应用程序会提示保存该数据。
将该
事件过程的Cancel参数设置为True可防止该窗体或应用程序的关闭。
5、UnLoad事件
从内存中卸载窗体时会触发该窗体的UnLoad事件。
将该事件过程的Cancel参数设置为True可防止窗体被卸载。
6、Activate事件与Deactivate事件
当一个窗体成为活动窗口时触发该窗体的Activate事件,当一个窗体不再是活动窗口时触发该窗体的Deactivate事件。
Activate事件在GotFocus事件之前发生,LostFocus事件在Deactivate事件之前发生。
7、Terminate事件
Terminate事件是窗体对象从内存删除之前最后一个触发的事件。
即该事件在Unload事件之后发生。
如果窗体从内存删除,是因为应用程序是非正常结束,例如,使用Ctrl+Break键或出错而被中断,则不会触发Terminate事件,也不触发QueryUnLoad事件和UnLoad事件。
另外,应用程序在从内存中删除窗体之前,调用End语句结束程序,虽然窗体对象也将从内存删除,但不会触发Terminate事件、QueryUnLoad事件和UnLoad事件。
第七章过程和变量的作用域
◆本章主要教学内容总结
本章主要教学内容包括有变量的作用域、变量的存活期、过程的作用域概念,窗体模块、标准模块和类模块功能。
通过应用举例,介绍了局部变量、静态变量、全局变量特点、作用。
变量的作用域及全局变量的定义方法。
理解变量、函数和过程的作用域。
掌握变量的作用范围,正确使用全局变量和局部变量。
掌握变量的存活期(即变量能够保持其值的时间)及用Static关键字在过程中声明的局部变量属于静态变量。
了解多重窗体与多模块程序设计的应用。