【VB开源代码栏目提醒】:网学会员为广大网友收集整理了,[理学]vb变量与过程的作用范围 - 综合课件,希望对大家有所帮助!
在
VB中应用程序是由若干个过程组成的这些过程一般保存在窗体文件.frm或标准模块文件.bas中。
变量在过程中是必不可少的。
根据变量或过程所处的不同位置可被访问的范围是不相同的。
变量与过程可被访问的范围称为变量与过程的作用域。
8.1 在建立
VB的应用程序时应首先
设计代码的结构。
VB应用程序的结构通常如图8-1所示。
图8-1
VB应用程序的结构 函数过程FunctionSub过程事件过程窗体模块.Frm类模块.ClsSub过程函数过程Function标准模块.BasVB应用程序.
VBP
VB将
代码存储在3种不同的模块中窗体模块窗体、标准模块模块和类模块。
在这3种模块中都可以包含声明常数、变量、动态链接库DLL的声明和过程Sub、Function、Property过程。
它们形成了工程的一种模块层次结构可以较好地组织工程同时也便于
代码的维护如图8-2所示。
图8-2 工程中的模块 8.1.1 窗体模块 每个窗体对应一个窗体模块窗体模块包含窗体及其控件的属性设置、窗体变量的说明、事件过程、窗体内的通用过程、外部过程的窗体级声明。
窗体模块保存在扩展名为.frm的文件中。
默认时应用程序中只有一个窗体因此有一个以.frm为扩展名的窗体模块文件。
如果应用程序有多个窗体就会有多个以.frm为扩展名的窗体模块文件。
如果要在文本编辑器中观察窗体模块则还会看到窗体及其控件的描述包括它们的属性设置值如图8-3所示。
窗体模块中也可以引用该应用程序内的其他窗体或对象。
从“工程”菜单中执行“添加窗体”命令可以添加新窗体模块。
8.1.2 标准模块 标准模块保存在扩展名为.bas的文件中缺省时应用程序中不包含标准模块。
标准模块可以包含公有或模块级的变量、常数、类型、外部过程和全局过程的全局声明或模块级声明。
缺省时标准模块中的
代码是公有的任何窗体或模块中的事件过程或通用过程都可以调用它。
写入标准模块的
代码不必绑在特定的应用程序上在许多不同的应用程序中可以重用标准模块。
在标准模块中可以存储通用过程但不能存储事件过程。
从“工程”菜单中执行“添加模块”命令可以在工程中添加标准模块。
8.1.3 类模块 在
VB中类模块文件扩展名为.cls是面向对象编程的基础。
程序员可在类模块中编写
代码建立新对象这些新对象可以包含自定义的属性和方法可以在应用程序内的过程中使用。
实际上窗体本身正是这样一种类模块在其上可安放控件、可显示窗体窗口。
类模块与标准模块的不同之处在于标准模块仅仅含有
代码而类模块既含有
代码又含有数据类模块可以视为没有物理表示的对象。
8.2 变量的作用范围作用域指变量能被某一过程识别的范围。
当一个应用程序中出现多个过程或函数时在它们各自的子程序中都可以定义自己的常量、变量。
这时自然会提出一个
问题这些常量或变量是否在程序中到处可用回答是否定的。
在
VB中可以在过程或模块中声明变量根据声明变量的位置变量分为两类过程级变量Procedure level和模块级变量Module level。
按照作用范围分类过程级变量属于局部变量而模块级变量则属于全局变量。
8.2.1 过程级变量 在一个过程内部使用Dim或Static关键字声明变量时只有该过程内部的
代码才能访问或改变该变量的值因此被称为“过程级变量”。
过程级变量的作用范围限制在该过程内部。
例如 Dim a As Integer b As Single Static s As String 如果在过程中未作说明而直接使用某个变量该变量也被当成过程级变量。
用Static说明的变量在应用程序的整个运行过程中都一直存在而用Dim说明的变量只在过程执行时存在退出过程后这类变量就会消失。
过程级变量属于局部变量只能在建立的过程内有效即使是在主程序中建立的变量也不能在被调用的子过程中使用。
【例8-1】过程级局部变量示例。
Private Sub Form_Activate Dim a As Integer b As Integer c As Integer 过程级局部变量 a 5: b 3 Print Print Tab15 a Tab25 b Tab35 cab Print 调用Prod前 Tab14 a Tab24 b Tab34 c Call Prod Print 调用Prod后 Tab14 a Tab24 b Tab34 c Print Print 调用Sum前 Tab14 a Tab24 b Tab34 c Call Sum Print 调用Sum后 Tab14 a Tab24 b Tab34 c End Sub Sub Prod 通用过程 Dim a As Integer b As Integer c As Integer 过程级局部变量 图8-7 程序运行结果 c a b Print Prod子过程 Tab14 a Tab24 b Tab34 c End Sub Sub Sum 通用过程 Dim a As Integer b As Integer c As Integer 过程级局部变量 c a b Print Sum子过程 Tab14 a Tab24 b Tab34 c End Sub 程序的运行结果如图8-7所示。
从上面程序的运行结果可以看出主
程序中的变量没有带到子过程中。
8.2.2 模块级变量 在模块的通用段中声明的变量属于模块级变量。
模块级变量分为私有和公有。
1. 私有的模块级变量 私有的模块级变量在声明它的整个模块的所有过程中都能使用但其他模块却不能访问该变量。
声明方法是在模块的通用段中使用Private或Dim关键字声明变量。
例如 Private s As String Dim a As Integer b As Single 在模块的通用段中使用Private或Dim作用相同但使用Private会提高
代码的可读性。
2. 公有的模块级变量 公有的模块级变量在所有模块中的所有过程中都能使用。
它的作用范围是整个应用程序因此公有模块级变量属于全局变量。
声明方法是在模块的通用段中使用Public关键字声明变量。
例如 Public a As Integer b As Single 全局变量是指在所有程序包括主程序和过程中都可以使用的内存变量。
就像在一个过程中定义的变量一样在子过程中可以任意改变和调用全局变量当子过程执行完后其值又带回主程序。
把变量定义为全局变量虽然很方便但这样会增加变量在程序中被无意修改的机会因此如果有更好的处理变量的方法就不要声明全局变量。
另外用Const语句定义的符号常量也能声明为全局的。
【例8-2】公有的模块级全局变量示例。
Public a As Integer b As Integer c As Integer 写在“通用”的“声明”中 Private Sub Form_Activate 事件过程 a 5: b 3 Print Tab15 a Tab25 b Tab35 cab Print 调用Prod前 Tab14 a Tab24 b Tab34 c Call Prod Print 调用Prod后 Tab14 a Tab24 b Tab34 c Print Print Tab15 a Tab25 b Tab35 cab Print 调用Sum前 Tab14 a Tab24 b Tab34 c Call Sum Print 调用Sum后 Tab14 a Tab24 b Tab34 c End Sub 图8-8 程序运行结果 Sub Prod 通用过程 c a b Print Prod子过程 Tab14 a Tab24 b Tab34 c End Sub Sub Sum 通用过程 c a b Print Sum子过程 Tab14 a Tab24 b Tab34 c End Sub 程序的运行结果如图8-8所示。
从程序的运行结果可以看出在模块级中用Public声明的全程变量a、b、c在各过程中都能访问和修改。
8.2.3 变量的生存期 从变量的作用空间来说变量有作用范围从变量的作用时间来说变量有生存期。
假设过程内部有一个变量当程序运行进入该过程时要分配给该变量一定的内存单元一旦程序退出该过程变量占有的内存单元是释放还是保留根据变量在程序运行期间的生命周期把变量分为静态变量Static和动态变量Dynamic。
静态变量不释放内存单元动态变量释放内存单元有时候可能需要某些局部变量是静态变量而其他变量则为动态变量。
【例8-3】下面程序说明了Static关键字的作用。
Private Sub Form_Activate Dim i As Integer For i 1 To 6 TestSub Next i End Sub Sub TestSub Dim x As Integer m As String 图8-9 程序运行结果 Static y n x x 1: y y 1 m m : n n Print x x y y m m n n End Sub 程序的运行结果如图8-9所示。
说明x、y、m、n都是过程TestSub中的局部变量y、n被说明为Static变量每次调用保持上一次的值y、n的值会变化x、m是动态变量每次调用都被重新初始化为0或它们的值总是不变。
为使过程中所有的局部变量为静态变量可在过程头的起始处加上Static关键字。
例如 Static Function RunningTotal num 这就使过程中的所有局部变量都变为静态无论它们是用Static、Dim或Private声明的还是隐式声明的。
8.3 过程也有作用的范围作用域在
VB中过程的作用域分为模块级或称文件级和全局级或称工程级。
8.3.1 模块级过程 模块级过程是在某个模块文件内定义的过程。
如果在Sub或Function前加关键字Private则该过程只能被在本模块文件中定义的过程调用。
即其作用域为本模块文件。
8.3.2 全局级过程 全局级过程是在定义过程时在Sub或Function前加关键字Public可以默认。
全局级过程可被整个应用程序所有模块文件中定义的过程调用。
即其作用域为整个应用程序工程。
8.3.3 调用其他模块中的过程 在工程中的任何地方都能调用其他模块中的全局过程。
调用其他模块中的过程的各种技巧取决于该过程是在窗体模块中、类模块中还是标准模块中。
1 调用窗体中的过程 所有窗体模块的外部调用必须指向包含此过程的窗体模块。
如果在窗体模块Form1中包含SomeSub过程则可使用下面的语句调用Form1中的过程 Call Form1.SomeSub arguments 2 调用类模块中的过程 与窗体中调用过程类似在类模块中调用过程要调用与过程一致并且指向类实例的变量。
例如DemoClass是类Class1的实例 Dim DemoClass as New Class1 DemoClass.SomeSub 不同于窗体的是在引用一个类的实例时不能用类名作限定符。
必须首先声明类的实例为对象变量在这个例子中是DemoClass并用变量名引用它。
3 调用标准模块中的过程 如果过程名是唯一的则不必在调用时加模块名。
无论是在模块内还是在模块外调用结果总会引用这个唯一过程。
如过程仅出现在一个地方这个过程就是唯一的。
如果两个以上的模块都包含同名的过程那就有必要用模块名来限定了。
例如若在Module1中调用Module2中的CommonName过程要用下面的语句 Module2.CommonName arguments 【例8-4】全局级过程的调用如图8-10所示。
应用程序工程中包括两个窗体Forml、Form2和一个标准模块Module1。
在Forml窗体中定义了一个计算矩形面积的全局级Function过程在标准模块Module1中定义了一个计算矩形周长的全局级Function过程。
两个窗体中的命令按钮组的Click事件过程功能相同差别是调用Function过程时所使用的名字。
图8-10 不同窗体对过程的调用 Form1窗体模块中的过程
代码如下 Public Function Areax As Single y As Single As Single Area x y End Function Private Sub Command1_Clickindex As Integer Dim a As Single b As Single a ValText10.Text b ValText11.Text n index If n 0 Then Label20.Caption Areaa b Else Label21.Caption Perimetera b End If End Sub Private Sub Form_Load Form2.Show End Sub Form2窗体模块中的过程
代码如下 Private Sub Command1_Clickindex As Integer Dim a As Single b As Single a ValText10.Text b ValText11.Text n index If n 0 Then Label20.Caption Form1.Areaa b Else Label21.Caption Perimetera b End If End Sub 标准模块Module1中的过程
代码 Public Function Perimeterx As Single y As Single As Single Perimeter 2 x y End Function 8.4 8.4.1 用户定义类型的概念 假设某校的学生成绩见表8-1。
表8-1 学生成绩表 表中每列的数据类型相同都是前面介绍过的基本数据类型在每一行中却有着不同的数据类型。
虽然使用
VB的Variant数组允许数组内的元素有不同的数据类型但却比较浪费内存。
此时
VB允许将基本数据类型按需要组合起来创建自定义的数据类型用户定义类型User Defined Type。
学 号 姓 名 性 别 出生日期 语 文 数 学 总 分 99310 李小华 男 1985年2月22日 85 95 180 99103 张红玉 女 1986年5月18日 73.5 87 160.5 99311 樊利友 男 1984年9月21日 82 79 161 用户定义类型又被称为“记录类型”类似于C语言中的“结构”。
它是一个由若干个基本类型的数据项组合而成的组合项。
如表8-1中的每一列都是基本类型的数据项分别描述同一对象学生的不同属性称为字段或称为数据项字段的名称如学号、姓名、性别、出生日期等称为字段名或称数据项名。
表中的记录类型就是由这7个数据项组成其中每个学生的7个具体属性值的集合就是记录值简称记录表中共有3个记录值每位学生有1个记录。
如果该校有2000名学生则该校学生成绩数据文件中就应该有2000个记录。
8.4.2 创建用户定义类型 可以用Type语句创建用户定义的类型该语句必须置于模块的声明部分。
其格式为 Private Public Type 〈用户类型名〉 〈字段名1〉 As 〈类型1〉 〈字段名2〉 As 〈类型2〉 … 〈字段名n〉 As 〈类型n〉 End Type 8.4.2 创建用户定义类型 例如要建立一个学生成绩处理程序由于每一位学生都需要学号、姓名、学分和平均成绩等数据项字段则可以使用Type语句来定义一个名称为studentrec的记录。
Private Type studentrec stunum As String 6 学号元素为6个字符的定长字符串 names As String 8 姓名元素为8个字符的定长字符串 credit As Integer 学分元素为整型 avg As Single 平均成绩为单精度型 End Type 8.4.3 建立和使用用户定义类型变量 在使用用户定义类型之前必须用Type语句创建数据类型。
1. 建立用户定义类型变量 用户定义类型被创建后可以用Dim、Redim、Static建立一个具有这种数据类型的变量。
例如定义一个具有 studentrec类型的变量stu Dim stu AS studentrec 用户定义类型也可以作为数组元素的数据类型。
例如定义一个拥有100个记录元素的数组student Dim student1 To 100 As studentrec 2. 使用用户定义类型变量 如果要存取用户定义类型变量中的某个字段的数据其格式如下。
〈用户数据类型变量名〉.〈字段名〉 例如要存取用户定义类型变量stu中names这个字段的数据要写为stu.names。
【例8-5】把数据值分别赋给stu变量中的各个字段。
首先在窗体模块的通用段创建用户定义类型 Private Type studentrec stunum As String 6 学号元素为6个字符的定长字符串 names As String 8 姓名元素为8个字符的定长字符串 credit As Integer 学分元素为整型 avg As Single 平均成绩为单精度型 End Type 编写命令按钮的Click事件
代码 Private Sub Command1_Click Dim stu As studentrec ‘ 定义一个具有studentrec类型的变量 stu stu.stunum 990001 stu.names 王 平 stu.credit 65 stu.avg 88 Text10.Text stu.stunum Text11.Text stu.names Text12.Text stu.credit Text13.Text stu.avg End Sub 图8-11 运行结果 程序运行结果如图8-11所示。
8.4.4 用户定义类型数组 如果一个数组中元素的数据类型是用户定义类型则称为用户定义类型数组或记录数组Array of records。
存取记录数组元素的某个字段数据的语法为 〈记录数组元素〉.〈字段名〉 例如存取第1、第28位学生的平均分数要写为 student1.avg student28.avg 8.4.4 用户定义类型数组 【例8-6】假设某班有50位学生每位学生一个记录定义一个包含50个元素的用户定义数组并给第32位学生赋值。
首先在窗体模块的通用段创建用户定义类型 Private Type studentrec stunum As String 6 names As String 8 credit As Integer avg As Single End Type 编写命令按钮的Click事件
代码 Private Sub Command1_Click Dim student1 To 50 As studentrec 定义记录数组 student32.stunum 960001 student32.names 张大力 student32.credit 65 student32.avg 88 Text10.Text student32.stunum Text11.Text student32.names Text12.Text student32.credit Text13.Text student32.avg End Sub 8.4.5 程序举例 【例8-7】输入学生的姓名、学号、语文分数、英语分数、数学分数计算每名学生的个人平均成绩并显示学生的各科成绩如图8-12所示。
首先在窗体的通用段创建用户定义类型并且声明变量 Private Type studentRecord name As String 6 姓名变量定义为6个字符长度 studentNum As String 5 学号变量定义为5个字符长度 chinese As Single 语文变量定义为单精度数 english As Single 英语变量定义为单精度数 math As Single 数学变量定义为单精度数 average As Single 平均成绩定义为单精度数 End Type Dim stu As studentRecord 定义记录数组 编写窗体的Load事件
代码 Private Sub Form_Load ReDim stu0 End Sub 编写“输入”按钮Command1的Click事件
代码 图8-12 显示学生成绩 Private Sub Command1_Click n UBoundstu ReDim stun 1 With stun 1 .studentNum Text10.Text .name Text11.Text .chinese Text12.Text .english Text13.Text .math Text14.Text .average Int.chinese .english .math / 3 100 / 100 cc Format.chinese Format.english _ Format.math FormatStr.average List1.AddItem FormatRTrim.studentNum _ FormatRTrim.name cc End With Text10.SetFocus End Sub 编写“删除”按钮Command2的Click事件
代码 Private Sub Command2_Click If List1.ListIndex –1 Then MsgBox 请选定欲删除的项 Exit Sub End If n List1.ListIndex 1 For i n To UBoundstu – 1 stui stui 1 Next List1.RemoveItem n - 1 Text10.Text stu1.studentNum Text11.Text stu1.name Text12.Text stu1.chinese Text13.Text stu1.english Text14.Text stu1.math End Sub 编写
列表框List1的Click事件
代码 Private Sub List1_Click n List1.ListIndex 1 Text10.Text stun.studentNum Text11.Text stun.name Text12.Text stun.chinese Text13.Text stun.english Text14.Text stun.math End Sub 另外编写文本框组的事件
代码使之方便输入 Private Sub Text1_GotFocusIndex As Integer Text1Index.SelStart 0 Text1Index.SelLength LenText1Index.Text End Sub Private Sub Text1_KeyPressIndex As Integer KeyAscii As Integer If KeyAscii 13 Then i IIfIndex 4 0 Index 1 Text1i.SetFocus End If End Sub