Public Sub Conimandl Click()
Module 1.Proce’调用第一个标准模块中的通用过程Proce Module2.Proce’调用第二个标准模块中的通用过程Proce End Sub
Public Sub Command2_Click()
Form2.Proce’调用第二个窗体模块中的通用过程Proce Form2.Show’显示第二个窗体 End Sub
(2)执行“工程”菜单中的“添加窗体”命令,添加一个新的窗体(Form2),在该窗体上 画两个命令按钮,把Caption属性分别设置为“Form2-Commandl”和“Form2-Command2”。 在该窗体模块中编写如下通用过程和事件过程: Public Sub Proceo
MsgBox”这是第二个窗体模块中的通用过程” End Sub
Private Sub Commandl Clicko
Forml.Commandl Click’调用第一个窗体模块中的事件过程Commandl一lick Forml.Proce’调用第一个窗体模块中的通用过程Proce End Sub
Private Sub Command2_Clicko
Forml.Command2 Click’调用第一个窗体模块中的事件过程Command2 Click End Sub
(3)执行“工程”菜单中的“添加模块”命令,添加一个新的标准模块(Modulel),在该 模块中编写如下代码:
Public Sub Proceo
MsgBox”这是第一个标准模块中的通用过程” End Sub
(4)执行“工程”菜单中的“添加模块”命令,添加一个新的标准模块(Module2),在该 模块中编写如下代码:
Public Sub Proceo
MsgBox”这是第二个标准模块中的通用过程” End Sub
以上共建立了4个模块,包括两个窗体模块和两个标准模块,在每个模块中建立了一个通用 过程Proceo由于这4个通用过程名字相同,因此在调用时都用模块名字限定。从上面的程 序可以看出,当在一个模块中调用其他模块中的过程时,被调用的过程必须是“公用的” (Public)。
9.2 Function过程
前面介绍了Sub过程,它不直接返回值,可以作为独立的基本语句调用。而Function 过程要返回一个值,通常出现在表达式中。这一节将介绍Function过程的定义和调用。 9.2.1建立Function过程
Function过程定义的格式如下:
[Static][Private][Public]Function过程名[(参数表列)][As类型] [语句块]
〔过程名=表达式]
[Exit Function] [语句块] End Function 说明:
(1) Function过程以Function开头,以End Function结束,在两者之间是描述过程操作的语句块,即“过程体”或“函数体”。格式中的“过程名”、“参数表列”、\”、“ Private \的含义与Sub过程中相同。\类型”是Function过程返回的值的数据类型,可以是Integer, Long, Single, Double, Currency或String如果省略,则为Variant。
(2)调用Sub过程相当于执行一个语句,不直接返回值;而调用Function过程要返回一 个值,因此可以像内部函数一样在表达式中使用。由Function过程返回的值放在上述格式 中的“表达式”中,并通过“过程名=表达式”把它的值赋给“过程名”。如果在Function 过程中省略“过程名=表达式”,则该过程返回一个默认值—数值函数过程返回0值;字 符串函数过程返回空字符串。因此,为了能使一个Function过程完成所指定的操作,通常 要在过程体中为“过程名”赋值。例如:
Function BinarySearch(Lower, Upper As Integer) As Boolean If Lower=Upper Then BinarySearch=True Exit Function Else
BinarySearch=False End If End Function
该例定义了一个BinarySearch过程,它有两个参数,其返回值为Boolean该过程根据所传 送给它的实参值返回True或False,返回值赋给函数名BinarySearcho
(3)前面讲过,过程不能嵌套。因此不能在事件过程中定义通用过程(包括Sub过程和 Function过程),只能在事件过程内调用通用过程。
前一节提到的建立Sub过程的3种方法(两种方法用于标准模块,一种方法用于窗体模 块)也可用来建立Function过程,只是当用第一种方法建立时,在对话框的“类型”栏内应选择“函数”,另外两种方法中的Sub应换成Function. 例9.3编写一个求最大公约数的函数过程。 程序如下:
Function gcd (ByVal x As Integer, ByVal y As Integer) As Integer Do While y<>0 reminder=x Mod y x=y y=reminder Loop gcd=x End Function
上述过程通过辗转相除求最大公约数,它有两个参数,均为传值参数,函数值为整数。在下 节介绍如何调用这个过程。 9.2.2调用Function过程
Function过程的调用比较简单,因为可以像使用Visual Basic内部函数一样来调用
Function过程。实际上,由于Function过程能返回一个值,因此完全可以把它看成是一个函数,它与内部函数(如Sqr, Str$, Chr$等)没有什么区别,只不过内部函数由语言系统提供,而Function过程由用户自己定义。
前面编写了求最大公约数的函数gcd,该函数的类型为Integer它有两个整型参数。可 以在下面的事件过程中调用该函数: Sub Form Click()
Dim a As Integer, b As Integer a=96: b=64 x=gcd(a, b)
Print \ End Sub
上述事件过程中的“x=gcd(a,b)”就是调用gcd函数的语句。调用时的实际参数分别为96 和64,调用后的返回值放入变量x中。程序的输出结果为32.
例9.4编写程序,打印0-1000之间的伪随机数,要打印的随机数的个数在运行时指 定,要求每5个打印一行,生成随机数的操作用一个Function过程来实现。
产生随机数的方法有很多种,用内部函数Rnd可以产生随机数。这里我们用线性同余 法来产生随机数。根据题意,产生随机数的公式如下:、 x=(x*29+37) mod 1000 此外,x要有一个初值,即“种子数,’. 产生随机数的通用过程如下:
Dim x As Integer’在窗体层定义 Static Function rand() x=x*29+37 x=x Mod 1000 n=x rand=n End Function 编写如下事件过程:
Private Sub Form_Click() FontSize = 12 x = 777 Cls
rannum = Val(InputBox(\需要输出多少随机数?\ Print \输出0到1000之间的随机数:\ Print
For m = 1 To rannum If m Mod 5 = 0 Then Print rand; \
Print Else
Print rand(); \ End If Next m
End Sub
过程rand用线性同余法产生随机数,不带参数,是一个无参过程。每调用一次rand,就产 生一个0-1000之间的伪随机数。在事件过程中,用Mod操作使随机数按5个一行打印。 程序运行后,单击窗体,在输入对话框中输入40,结果如图9.4所示。 变量x在窗体层定义,在事件过程中初始化,即设置“种子数”。如果改变“种子数” 则可产生不同的随机数序列。
例9.5从键盘上输入一个数,输出该数的平方根。
用内部函数Sqr可以得到一个数的平方根,但该数必须大于或等于0。如果是负数,则 其平方根是一个虚数。我们用自己编写的过程来求平方根。 程序如下:
Function SquareRoot(X As Double) As Double Select Case Sgn(X) Case 1
SquareRoot = Sqr(X) Exit Function Case 0
SquareRoot = 0 Case -1
SquareRoot = -1 End Select End Function
Private Sub Form_Click() Dim Msg, SqrN Dim N As Double
N = InputBox(\请输入要计算平方根的数:\ Msg = N & \的平方根\
Select Case SquareRoot(N) Case 0
Msg = Msg & \是0\ Case -1
Msg = Msg & \是一个虚数\ Case Else
Msg = Msg & \是\ End Select MsgBox Msg End Sub
过程SquareRoot用来求平方根。该函数有一个参数,其类型为Double函数的返回值类型 为Double.在该过程中,用Sgn函数判断参数的符号,当参数为正数时,过程返回该参数 的平方根;如果参数为0,则返回0值;如果参数为负数,则返回-1。在事件过程(主程序)中,用从键盘上输入的数调用SquareRoot过程,并根据返回的值进行不同的处理。图9.5是一种输出结果。‘’
以上介绍了过程的定义和调用。Visual Basic应用程序的过程出现在窗体模块和标准模块中。在窗体模块中可以定义和编写子程序过程、函数过程及事件过程,而在标准模块中只
能定义子程序过程和函数过程。其结构关系如图9.6所示。 9.3参数传送
在调用一个过程时,必须把实际参数传送给过程,完成形式参数与实际参数的结合,然 后用实际参数执行调用的过程。 在Visual Basic中,通常把形式参数叫做“参数”,而把实际参数叫做“自变量”。但是,“自变量”一词容易与数学中函数的“自变量”相混淆。为了与其他语言中使用的术语一致,本书仍称为形式参数(简称形参)和实际参数或实在参数(简称实参)。 9.3.1形参与实参 形参是在Sub, Function过程的定义中出现的变量名,实参则是在调用Sub或Function 过程时传送给Sub或Function过程的常数、变量、表达式或数组。在Visual Basic中,可以通过两种方式传送参数,即按位置传送和指名传送。 1.按位置传送
按位置传送是大多数语言处理子程序调用时所使用的方式,在前面的例子中使用的就是 按位置传送方式。当使用这种方式时,实际参数的次序必须和形式参数的次序相匹配,也就 是说,它们的位置次序必须一致。例如,假定定义了下面一个过程: Sub TestSub(pl As Integer, p2 As Single, p3 As String) End Sub
可以用下面的语句调用该过程:
Call TestSub(A%, B!,\
这样就完成了形参与实参的结合,其关系如图9.7所示。 过程调用:Call Test SUb(A%,B!,\ 1 1 1
过程定义:Sub TestSub(p一As Integer,p2 As Single,p3 As String) 图9.7形参与实参
在传送参数时,形参表与实参表中对应变量的名字不必相同,但是它们所包含的参数的 个数必须相同;同时,实参与相应形参的类型必须相同。
形式参数表中各个变量之间用逗号隔开,表中的变量可以是: .除定长字符串之外的合法变量名; .后面跟有左、右括号的数组名。
在形式参数表中只能使用形如x$或x As String之类的变长字符串作为形参,不能用形如X As String*8之类的定长字符串作为形参,但定长字符串可以作为实际参数传送给过程。实际参数表中的各项用逗号隔开,实参可以是: .常数; .表达式;
.合法的变量名;
?后面跟有左、右括号的数组名。 假定有如下的过程定义:
Sub TestSub(A As Integer, Array() As Single, Recvar as Rectype, C As String) 这是带有形参表的Sub过程定义的第一行。形参表中的第一个参数是整型变量;第二个参. 数是单精度数组;第三个参数是一个Rectype类型的记录;第四个参数是一个字符串。在调 用上述过程时,必须把所需要的实参传送给过程,取代相应的形参,执行过程的操作,实参 与形参必须按位置次序传送。用下面的程序段可以调用过程TestSub,并把4个实参传送给 相应的形参:
Type Rectype