在 第二章 我们介绍了 VB应用程序(通常称为工程)的组织结构,它由 窗体模块、标准模块和类模块 组成。 VB程序代码就保存在窗体模块文件
( *,Frm)、标准模块文件( *,Bas)或类模块文件( *,Cls)中。它们形成了工程的一种模块层次结构,如下图所示。
第七章 过程和变量的作用域
7.1 概 述一个应用程序的组成结构
7.1.1 窗体模块
(文件扩展名为,FRM )
窗体模块 。 窗体模块可以包含处理事件的过程,通用过程以及变量,常数,类型和外部过程的窗体级声明 。 如果要在文本编辑器中观察窗体模块,则还会看到窗体及其控件的描述,包括它们的属性设置值 。 写入窗体模块的代码是该窗体所属的具体应用程序专用的;它也可以引用该应用程序内的其它窗体或对象 。
7.1.2 标准模块
(文件扩展名为,BAS)
它们可以包含变量,常数,类型,外部过程和全局过程的全局 (在整个应用程序范围内有效的 )
声明或模块级声明 。 写入标准模块的代码不必绑在特定的应用程序上,则在许多不同的应用程序中可以重用标准模块 。
7.1.3 类模块
(文件扩展名为,CLS)
在 Visual Basic 中类模块是面向对象编程的基础 。 可在类模块中编写代码建立新对象 。 这些新对象可以包含自定义的属性和方法 。 实际上,窗体正是这样一种类模块,在其上可安放控件,可显示窗体窗口 。
7.2 过程的作用域
[Public|Private] Sub 子过程名 ([形式参数列表 ])
…..
End Sub
概念通用子过程和函数过程既可写在 窗体模块中 也可写在标准模块中,在定义时可选用关键字 Private( 局部 ) 和
Public( 全局 ),来决定它们能被调用的范围 。
1,窗体 /模块级过程:
加 Private关键字的过程,只能被定义的窗体或模 块中的过程调用。
2,全局级过程:
加 Public关键字 (或缺省) 的过程,可供该应用程序的所有窗体和所有标准模块中的过程调用。
按过程的作用范围来划分,过程可分为:
模块级过程
全局级过程用例 7.1来说明过程的作用域总结归纳过程的定义及作用域如下表(教材 Pg.163)
几点说明:(教材 Pg.164)
7.3 变量的作用域概述:
在 VB中,由于可以在过程中和模块中声明变量,根据定义变量的位置和定义变量的语句不同,
变量可以分为:
局部变量 ( 过程级变量 )
窗体 /模块级变量 ( 私有的模块级变量,能被本模块的所有过程和函数使用 )
全局级变量 ( 公有的模块级变量 ) 。
7.3.1 过程级变量 ——局部变量局部变量,在过程内用声明的变量,只能在本过程中使用。
在过程内部使用 Dim 或者 Static 关键字来声明的变量,只在声明它们的过程中才能被访问或改变该变量的值,别的过程不可访问。所以可以在不同的过程中声明相同名字的局部变量而互不影响。
例:
Private Sub Form_Load()
Dim n%
n= 10
End Sub
Private Sub From_Click()
Dim n%
Print,n=“;n
End Sub
程序运行后单击窗体,其输出结果是什么?
7.3.2 窗体 /模块级变量窗体 /模块级变量,在,通用声明,段中用 Dim语句或用
Private语句声明的变量,可被本窗体 /模块的任何过程访问 。 但其他模块却不能访问该变量 。
例如:在,通用声明,段声明如下变量
Private s As String
Dim a As Integer,b As Single
7.3.3 全局变量全局变量 也称公有的模块级变量,在窗体模块或标准模块的顶部的,通用,声明段用 Public关键字声明,它的作用范围是整个应用程序,即可被本应用程序的任何过程或函数访问 。
例如:
Public a As Integer,b As single
3种变量声明及使用规则如下表:
一,公用变量与局部变量同名在不同过程中定义同名变量,它们互不影响,但若在一过程中定义使用了与全局变量同名的变量,则就应注意。
7.3.4 关于多个变量同名注意:在过程中,如果定义了与模块级变量(在通用部分使用 Private或 Dim声明的变量),则在该过程内不能引用同名的模块级变量。例如,上面的例子中,如果将定义全局变量的语句 Public Temp As Integer改为
Private Temp As Integer 则在 Command1的单击事件中就不使用模块级的 Temp变量。
Public Temp As Integer ' 定义全局变量
Private Sub Form_Load()
Temp = 1 ' 将全局变量 Temp 的值设置成 1
End Sub
Private Sub Command1_Click()
Dim Temp As Integer ' 定义局部变量
Temp = 2 ' 将局部变量 Temp 的值设置成 2
Print "temp="; Temp
Print "temp="; Form1.Temp
End Sub
Private Sub Command2_Click()
Print "temp="; Temp
End Sub
二,全局变量同名如果不同模块中的全局变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们 。
例如,如果有一个在 Form1 和 Module1 中都声明了公用的 Integer 变量 intX,则把它们作为
Module1.intX 和 Form1.intX 来引用便得到正确值 。 也就是说 如果不同模块中的全局变量使用同一名字,引用时就需要使用,模块名,变量名,的形式来区分它们 。
7.3.5 静态变量除作用域之外,变量还有存活期,在这一期间变量能够保持它们的值。
在应用程序的存活期内一直保持 模块级变量 和 全局变量 的值。但是,对于 Dim声明的局部变量 仅当过程执行期间存在,当一个过程执行完毕,它的局部变量的值就已经不存在,而且 变量所占据的内存也被释放 。当下一次执行该过程时,它的所有局部变量将重新初始化。
概念局部变量的存活期由其定义的关键词来决定。
局部变量声明:
Dim声明,随过程的调用而分配存贮单元,变量的初始化;过程体结束,变量的内容自动消失,存贮单元释放。
Static声明,每次调用过程,变量保持上次调用结束时的值。
声明形式:
Static 变量名 [AS 类型 ]
Static Function 函数过程名 ([参数列表 ]) [As 类型 ]
Static Sub 子过程名 [(参数列表 )]
注意:过程名前加 Static,表示该过程内的局部变量都是静态变量。
例 7.2 有一个人编了下面一段程序,想用变 量 n记 录单击窗体的次数 。
Private Sub Form_Click()
Dim n As Integer
n = n + 1
Print "已单击次数,"; n & "次 "
End Sub
分析程序运行后多次单击窗体的输出结果:
要记录单击窗体次数,如何实现?并比较使用模块变量和静态变量的差别。
例 7.3 教材 P168
Private Sub Form_Click()
Dim i%,isum%
For i = 1 To 5
isum = sum(i)
Print isum,
Next i
End Sub
Private Function sum(n As Integer)
Dim j As Integer
j = j + n
sum = j
End Function 1 2 3 4 5
Static j As Integer 结果如何?
补充例题:
7.4 多重窗体与多模块程序设计一个稍微复杂的应用程序,不仅有多个窗体,还可能有标准模块和类模块,如下图所示 。
本节介绍在多模块程序中,关于启动对象的设置、
窗体的加载与卸载、窗体的加载与卸载时的事件、
多模块间数据的传递等。
7.4.1 设置启动对象在程序运行时,首先被加载并执行的对象,称为程序的启动对象 。 一个程序的启动对象可以是 一个窗体,也可以是标准模块中名为 Main的自定义 Sub过程 。 缺省情况下,
第一个创建的窗体被指定为启动对象 。
1、设置方法:
从“工程”菜单中的最后一项,**属性”,在,**工程属性”对话框中进行设置。
2、如果设置从主过程 Main()启动,则必须在标准模块中编写 Main()过程代码。
例,Pg170.
7.4.2 窗体的加载与卸载过程当一个窗体要显示在屏幕之前,必须先建立,
接着被装入内存( Load语句 ),最后显示( Show
方法 )在屏幕上。同样,当窗体要结束之前,会先从屏幕上隐藏( Hide方法 ),接着从内存中删除( Unload方法 )
在窗体的加载过程的各阶段所用一的语句或方法以及所触发的事件可用下面的图来说明:
在窗体的卸载过程的各阶段所用一的语句或方法以及所触发的事件如下图:
Unload
语句
QueryUnload Unload
1,窗体的加载与显示
( 1) Load语句:装入窗体到内存
Load 窗体名称说明:执行 Load语句后,窗体并不显示出来,但可引用该窗体中的控件及各种属性。
注意:这里的窗体名称是窗体的 Name属性,
而不是窗体的文件名,以下相同。
( 3) Show方法:显示一个窗体
[窗体名称 ].Show [模式 ]
0 - Modeless(非模式):可以对其它窗体进行操作
1 - Model,关闭才能对其它窗体进行操作。
2,窗体的隐藏与卸载
( 1) Unload语句:从内存删除窗体
Unload <窗体名称 >
说明:
当窗体卸载之后,所有在运行时放到该窗体上的控件都不再是可访问的 。 在设计时放到该窗体上的控件将保持不变
在卸载窗体时,只有显示的部件被卸载 。 与该窗体模块相关联的代码还保持在内存中 。
( 2) Hide方法:隐藏,没有删除
[窗体名称,] Hide
7.4.3 与窗体加载与卸载过程的关的事件
1,Initialize事件
2,Load事件
3,Paint事件
4,QueryUnLoad事件
5,UnLoad事件
6,Activate事件与 Deactivate事件
7,Terminate事件例 7.4 验证与窗体加载与卸载过程相关的事件被触发的先后顺序。
7.4.4 应用举例 (教材 Pg.175—— 178)
作业:
( *,Frm)、标准模块文件( *,Bas)或类模块文件( *,Cls)中。它们形成了工程的一种模块层次结构,如下图所示。
第七章 过程和变量的作用域
7.1 概 述一个应用程序的组成结构
7.1.1 窗体模块
(文件扩展名为,FRM )
窗体模块 。 窗体模块可以包含处理事件的过程,通用过程以及变量,常数,类型和外部过程的窗体级声明 。 如果要在文本编辑器中观察窗体模块,则还会看到窗体及其控件的描述,包括它们的属性设置值 。 写入窗体模块的代码是该窗体所属的具体应用程序专用的;它也可以引用该应用程序内的其它窗体或对象 。
7.1.2 标准模块
(文件扩展名为,BAS)
它们可以包含变量,常数,类型,外部过程和全局过程的全局 (在整个应用程序范围内有效的 )
声明或模块级声明 。 写入标准模块的代码不必绑在特定的应用程序上,则在许多不同的应用程序中可以重用标准模块 。
7.1.3 类模块
(文件扩展名为,CLS)
在 Visual Basic 中类模块是面向对象编程的基础 。 可在类模块中编写代码建立新对象 。 这些新对象可以包含自定义的属性和方法 。 实际上,窗体正是这样一种类模块,在其上可安放控件,可显示窗体窗口 。
7.2 过程的作用域
[Public|Private] Sub 子过程名 ([形式参数列表 ])
…..
End Sub
概念通用子过程和函数过程既可写在 窗体模块中 也可写在标准模块中,在定义时可选用关键字 Private( 局部 ) 和
Public( 全局 ),来决定它们能被调用的范围 。
1,窗体 /模块级过程:
加 Private关键字的过程,只能被定义的窗体或模 块中的过程调用。
2,全局级过程:
加 Public关键字 (或缺省) 的过程,可供该应用程序的所有窗体和所有标准模块中的过程调用。
按过程的作用范围来划分,过程可分为:
模块级过程
全局级过程用例 7.1来说明过程的作用域总结归纳过程的定义及作用域如下表(教材 Pg.163)
几点说明:(教材 Pg.164)
7.3 变量的作用域概述:
在 VB中,由于可以在过程中和模块中声明变量,根据定义变量的位置和定义变量的语句不同,
变量可以分为:
局部变量 ( 过程级变量 )
窗体 /模块级变量 ( 私有的模块级变量,能被本模块的所有过程和函数使用 )
全局级变量 ( 公有的模块级变量 ) 。
7.3.1 过程级变量 ——局部变量局部变量,在过程内用声明的变量,只能在本过程中使用。
在过程内部使用 Dim 或者 Static 关键字来声明的变量,只在声明它们的过程中才能被访问或改变该变量的值,别的过程不可访问。所以可以在不同的过程中声明相同名字的局部变量而互不影响。
例:
Private Sub Form_Load()
Dim n%
n= 10
End Sub
Private Sub From_Click()
Dim n%
Print,n=“;n
End Sub
程序运行后单击窗体,其输出结果是什么?
7.3.2 窗体 /模块级变量窗体 /模块级变量,在,通用声明,段中用 Dim语句或用
Private语句声明的变量,可被本窗体 /模块的任何过程访问 。 但其他模块却不能访问该变量 。
例如:在,通用声明,段声明如下变量
Private s As String
Dim a As Integer,b As Single
7.3.3 全局变量全局变量 也称公有的模块级变量,在窗体模块或标准模块的顶部的,通用,声明段用 Public关键字声明,它的作用范围是整个应用程序,即可被本应用程序的任何过程或函数访问 。
例如:
Public a As Integer,b As single
3种变量声明及使用规则如下表:
一,公用变量与局部变量同名在不同过程中定义同名变量,它们互不影响,但若在一过程中定义使用了与全局变量同名的变量,则就应注意。
7.3.4 关于多个变量同名注意:在过程中,如果定义了与模块级变量(在通用部分使用 Private或 Dim声明的变量),则在该过程内不能引用同名的模块级变量。例如,上面的例子中,如果将定义全局变量的语句 Public Temp As Integer改为
Private Temp As Integer 则在 Command1的单击事件中就不使用模块级的 Temp变量。
Public Temp As Integer ' 定义全局变量
Private Sub Form_Load()
Temp = 1 ' 将全局变量 Temp 的值设置成 1
End Sub
Private Sub Command1_Click()
Dim Temp As Integer ' 定义局部变量
Temp = 2 ' 将局部变量 Temp 的值设置成 2
Print "temp="; Temp
Print "temp="; Form1.Temp
End Sub
Private Sub Command2_Click()
Print "temp="; Temp
End Sub
二,全局变量同名如果不同模块中的全局变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们 。
例如,如果有一个在 Form1 和 Module1 中都声明了公用的 Integer 变量 intX,则把它们作为
Module1.intX 和 Form1.intX 来引用便得到正确值 。 也就是说 如果不同模块中的全局变量使用同一名字,引用时就需要使用,模块名,变量名,的形式来区分它们 。
7.3.5 静态变量除作用域之外,变量还有存活期,在这一期间变量能够保持它们的值。
在应用程序的存活期内一直保持 模块级变量 和 全局变量 的值。但是,对于 Dim声明的局部变量 仅当过程执行期间存在,当一个过程执行完毕,它的局部变量的值就已经不存在,而且 变量所占据的内存也被释放 。当下一次执行该过程时,它的所有局部变量将重新初始化。
概念局部变量的存活期由其定义的关键词来决定。
局部变量声明:
Dim声明,随过程的调用而分配存贮单元,变量的初始化;过程体结束,变量的内容自动消失,存贮单元释放。
Static声明,每次调用过程,变量保持上次调用结束时的值。
声明形式:
Static 变量名 [AS 类型 ]
Static Function 函数过程名 ([参数列表 ]) [As 类型 ]
Static Sub 子过程名 [(参数列表 )]
注意:过程名前加 Static,表示该过程内的局部变量都是静态变量。
例 7.2 有一个人编了下面一段程序,想用变 量 n记 录单击窗体的次数 。
Private Sub Form_Click()
Dim n As Integer
n = n + 1
Print "已单击次数,"; n & "次 "
End Sub
分析程序运行后多次单击窗体的输出结果:
要记录单击窗体次数,如何实现?并比较使用模块变量和静态变量的差别。
例 7.3 教材 P168
Private Sub Form_Click()
Dim i%,isum%
For i = 1 To 5
isum = sum(i)
Print isum,
Next i
End Sub
Private Function sum(n As Integer)
Dim j As Integer
j = j + n
sum = j
End Function 1 2 3 4 5
Static j As Integer 结果如何?
补充例题:
7.4 多重窗体与多模块程序设计一个稍微复杂的应用程序,不仅有多个窗体,还可能有标准模块和类模块,如下图所示 。
本节介绍在多模块程序中,关于启动对象的设置、
窗体的加载与卸载、窗体的加载与卸载时的事件、
多模块间数据的传递等。
7.4.1 设置启动对象在程序运行时,首先被加载并执行的对象,称为程序的启动对象 。 一个程序的启动对象可以是 一个窗体,也可以是标准模块中名为 Main的自定义 Sub过程 。 缺省情况下,
第一个创建的窗体被指定为启动对象 。
1、设置方法:
从“工程”菜单中的最后一项,**属性”,在,**工程属性”对话框中进行设置。
2、如果设置从主过程 Main()启动,则必须在标准模块中编写 Main()过程代码。
例,Pg170.
7.4.2 窗体的加载与卸载过程当一个窗体要显示在屏幕之前,必须先建立,
接着被装入内存( Load语句 ),最后显示( Show
方法 )在屏幕上。同样,当窗体要结束之前,会先从屏幕上隐藏( Hide方法 ),接着从内存中删除( Unload方法 )
在窗体的加载过程的各阶段所用一的语句或方法以及所触发的事件可用下面的图来说明:
在窗体的卸载过程的各阶段所用一的语句或方法以及所触发的事件如下图:
Unload
语句
QueryUnload Unload
1,窗体的加载与显示
( 1) Load语句:装入窗体到内存
Load 窗体名称说明:执行 Load语句后,窗体并不显示出来,但可引用该窗体中的控件及各种属性。
注意:这里的窗体名称是窗体的 Name属性,
而不是窗体的文件名,以下相同。
( 3) Show方法:显示一个窗体
[窗体名称 ].Show [模式 ]
0 - Modeless(非模式):可以对其它窗体进行操作
1 - Model,关闭才能对其它窗体进行操作。
2,窗体的隐藏与卸载
( 1) Unload语句:从内存删除窗体
Unload <窗体名称 >
说明:
当窗体卸载之后,所有在运行时放到该窗体上的控件都不再是可访问的 。 在设计时放到该窗体上的控件将保持不变
在卸载窗体时,只有显示的部件被卸载 。 与该窗体模块相关联的代码还保持在内存中 。
( 2) Hide方法:隐藏,没有删除
[窗体名称,] Hide
7.4.3 与窗体加载与卸载过程的关的事件
1,Initialize事件
2,Load事件
3,Paint事件
4,QueryUnLoad事件
5,UnLoad事件
6,Activate事件与 Deactivate事件
7,Terminate事件例 7.4 验证与窗体加载与卸载过程相关的事件被触发的先后顺序。
7.4.4 应用举例 (教材 Pg.175—— 178)
作业: