如果不使用程序流程控制语句,程序的执行是简单的从上到下顺序执行的单向流程。这种程序结构所完成的工作功能有限。
过程控制可以分为三个主要的部分:转支(Branching,也称跳转)、循环(Iteration)和条件执行(Condtion execution)。
转支是最基本的一种过程控制,它实际上就是一种跳转的机制,从程序中的一个代码段跳到另一个代码段,而不执行中间的步骤。
循环是指在程序中重复执行一套指令,并且当达到一定次数或者条件时停止。在VB中有三种循环指令。
条件执行是指在程序中,当某些条件为真时,允许执行一系列指令,如果条件为假,则执行另外的指令。这就给程序提供了逻辑判断能力。
一、跳转控制
跳转——从程序的某一行到另一行的直接转移。
它有两种形式:无条件跳转和有条件跳转。
无条件转向语句“Goto”的一般形式:
Goto 语句标号(或行号)
注意:
1)语句标号或行号必须存在,否则会出现错误。Goto语句标号的命名规则与变量名相同。
2)“标号”是一个以冒号结尾的标识符;“行号”是一个整形数,它不以冒号结尾。例如:
Start:
是一个标号,而
1200
是一个行号。
例(见教材P62):
Sub Form_Click ()
Print "She is " Goto Message Print "not" Message: Print "a beautiful girl ."
End Sub
本语句不易实现结构化程序设计,所以不提倡使用。
二、条件结构
在VB过程中可以进行条件测试,然后根据测试结果去执行不同的操作。VB提供以下几种格式的条件语句:If语句、Select Case语句。
1、If语句
(1)If 条件 Then 语句1 [Else 语句2]
这种语句称为单行条件语句。如果条件为真,执行Then后面的语句;如果条件为假,则执行Else后面的语句(语句2)。
说明:
- 语句1和语句2都可以是若干条语句(语句之间用“:”号隔开);
- 单行语句必须写在一个程序行内;
- 其中“Else 语句2”可以省略,省略格式的功能是:当If后的条件成立时,执行Then后面的语句,若不成立,则执行条件语句的下一个程序行。
例如:
Private Sub Command1_Click()
Dim intAge As Integer intAge = InputBox("aaa", "bb") If intAge > 23 Then Print "您已经超龄,无法入选国奥队!"
End Sub
(2)If 条件 Then
语句块1
[Else
语句块2]
End If
这种结构称为简单块If结构。它是这样执行的:
如果条件为真,执行Then后面的语句块1,否则,则执行Else后面的语句块2;若不写Else部分,则执行End If后面的语句。
例如:
If intAge >23 then
Print"您已经超龄,无法入选国奥队"
Print "感谢您对中国足球的关怀"
End If
(3)If 条件1 Then
语句块1
Else If 条件2 Then
语句块2
:
:
Else If 条件n Then
语句块n
[Else
默认语句块]
End If
这种结构称为块If结构。它是这样执行的:
先测试条件1,如果条件1成立,则执行Then后面的语句块1;如果条件1不成立,则继续检测条件2,如果条件2成立,则执行Then后面的语句块2;……。如此测试下去。如果所有条件都不成立,则执行Else后面的默认语句块(如果存在的话,否则,跳到End If下一条语句执行)。这里的n>=2。
注意:
在判定结构中使用的“条件”通常是比较语句(关系运算符,如>、<、<>、=等)。如果要使用更加复杂的条件,可以使用逻辑运算符(And、Or、Not)来连接几个比较语句,例如:
If intAge<23 And strCountry="china" And intSkill>10 Then
Print "欢迎您到国奥队来!"
:
:
End If
2、 Select Case
与If…Then…E1se语句相似,Visual Basic还提供了Select Case结构来实现多分支结构,从而对在多个语句块中有选择地执行其中—个。Select Case语句的能力与If…Then…E1se语句类似,但对多重选样的情况,Select Case语句使代码更加清楚易懂,而且执行也比较快速。Select Case的语法结构是:
Select Case 测试条件
Case 表达式1
语句序列1
[Case 表达式2
语句序列2]
:
:
:
[Case Else
默认序列 ]
End Select
Select Case在结构的上方处理一个测试表达式并只计算一次(在Select Case语句中如果不止一个Case与测试表达式相匹配,则只对第一个匹配的Case执行与之相关联的语句块)。然后VB将表达式的值与结构中的每个Case的值进行比较,如果相等,就执行与该Case相关联的程序段;如果都不相等则执行Case Else对应的默认程序段;如果这时没有定义Case Else子句,则不执行任何分支退出(即执行End Select语句的下一条语句)。Case Else 虽然是选择性的,但是最好使用,以防遗漏测试数据。
Case 后的表达式不仅可以是一个值,还可以是几个值的列表。当列表中有多个值时,就用逗号把值隔开。如下面的例子:
Select Case WeekDay(Date) Case l,2,3,4 Dayname="工作日" Case 5 Dayname="加班" Case E1se Dayname="周末" End Select
Case 后的表达式也可以用To 关键字,指定一个范围。如果是数值,较小的数值必须显示在To之前;如果是字符串常量,必须按字母的顺序写出。例如:
Case -5 To 1
Csse "dvark" To "kear"
也可以使用Is关键字与比较运算符来规定数值的范围。如:
Case Is<5
表示当测试表达式小于5时,执行相应的语句块。
下表提供了有关测试表达式范围的一些示例,读者可参考示例使用该语句。
表达式 |
例子 |
关系
相等
相等(暗含“=”)
明确的范围
多重组合 |
Case Is>=10
Case Is=1.2
Case 1.2
Case -7 To 7
Case Is<>21,Is<100 |
例(见教材P65):
Private Sub Form_Click() Dim Age% Age% = Val(InputBox$("How old you are?")) Select Case Age% Case 1 To 12 MsgBox "you are a child." Case 13 To 19 MsgBox "you are a teenager." Case 20 To 150 MsgBox "you are an adult." Case Else MsgBox "It is impossible!" End Select End Sub
注意:Select Case 语句也可以是嵌套的。但每个嵌套的 Select Case 语句必须要有相应的 End Select 语句。
三、循环结构
循环结构可以重复执行—行或多行代码,VB支持的循环结构主要有四种,每种循环都有各自不同的适用场合,它们分别是:
For…Next For Each…Next Do…Loop While Wend
1、 For ···Next
当循环次数为已知时,用For ···Next语句进行循环。
For…Next循环结构是一种最简单的循环结构,它指定代码重复执行的次数。用户在For语句中可以设置切始值,终值和一个数值变量用来作为计数器。当程序执行到For语句时,首先将计数器赋值为初始值。然后每重复一次循环之后,计数器变量的值就会增加或者减少。当计数器的数值超过终值,则程序退出For循环,继续下面语句的执行。
For循环的语法如下:
For 计数器=初值 To终值 [Step增量]
[If 条件式 Then Exit For] '在特定情况下退出循环 [语句]
Next [计数器]
其中:
计数器——循环变量,决定循环次数;
初值——循环变量的开始值;
终值——循环变量的终了值;
增量——每次循环的步长,它可正可负。
计数器、初值、终值、增量,它们都必须是数值型的表达式,在可能的情况下,最好采用整数类型变量,因为这样,比使用其它类型变量时,程序运行的速度要快,且如果使用单精度和双精度变量时,有数学误差,可能导致循环执行的次数不正确。
初值可以大于终值,也可以小于终值。如果初值大于终值,则增量应为负值;如果省略增量,则默认增量为“1”。
例1(见教材P69):
Private Sub Form_Click()
Dim i,j,counter As Integer i = 6: j = 1 '同一行中有多条语句,用冒号分开。 For counter = i To j Step -1 Print counter Next counter
End Sub
例2 求1+2+……+100的和。(作业1-7)
添加一个文本框、一个命令按钮。
Private Sub Command1_Click()
Cls Dim i As Integer Dim sum As Integer sum = 0 For i = 1 To 100 sum = sum + i Next i Text1.Text = sum
End Sub
2、For Each···Next
For Each…Next循环与For…Next循环类似,但它只是对数组或对象集合中的每一个元素进行循环,而不是重复一定的次数。如果不知道一个集合有多少元素,For Each···Next循环非常有用。
For Each···Next语法如下:
For Each 元素 In 数组或集合
[程序段] [If 条件式 Then Exit For] '在特定情况下退出循环 [程序段]
Next [元素]
其中:元素变量只能是Variant类型或对象类型,对于数组,元素变量只能是Variant类型;对于集合,元素只能是Variant、一般性的Object或任何指定的OLE Automation对象类型的变量。
说明:循环中的数组不能是记录类型的数组。
例(见教材P69-70):
Private Sub Form_Click()
Dim i As Variant For Each i In Form1.Controls i.Enabled = False Next i
End Sub
 |
 |
初始界面 |
运行后界面 |
循环从集合或数组中的一个元素开始,每个元素重复一次循环体语句。下面是一个如何对数组运用这种循环结构的例子:
Private Sub Form_Click()
Dim a(1 To 2) As Single Dim i As Variant For Each i In a() Print "hello!" Next i
End Sub
3、Do…Loop
当不知道程序中循环的次数时,可用Do…Loop语句。
在VB中,Do…Loop语句是最通用因而也是最有用的一种循环结构,包含在Do…Loop之间的语句,只要某个条件存在,或者直到某个条件为真时,就会重复执行循环体。同时也允许在循环开始或结束时说明是否要检查条件。这样Do…Loop语句就演化出了四种形式:Do While…Loop,Do Until…Loop,Do…Loop While,Do…Loop Until。
它们的语法结构分别为:
(1)
Do While 条件式
[程序段] [ If 条件式 Then Exit Do ] '在特定条件下退出循环。 [程序段]
Loop
说明:当条件为真时,循环继续进行,直到条件式变为假为止。
例:
Private Sub Form_Click()
Dim i As Integer i = 1 Do While i <= 5 Print i i = i + 1 Loop
End Sub
运行结果:1 2 3 4 5
(2)
Do Util 条件式
[程序段] [ If 条件式 Then Exit Do ] '在特定条件下退出循环。 [程序段]
Loop
说明:当条件式为假时,循环继续进行,直到条件式变为真为止。
例1:
Private Sub Form_Click()
Dim i As Integer i = 1 Do Util i >5 Print i i = i + 1 Loop
End Sub
运行结果:1 2 3 4 5
例2:找出大于某个数后不能被3整除的100个整数。
界面:两个文本框、两个命令按钮、一个框架。

代码:
Private Sub Command1_Click()
Dim x As Integer Dim n As Integer x = Val(Text2.Text) n = 1 Do Until n > 100 If x Mod 3 <> 0 Then Text1.Text = Text1.Text & Str(x) & Chr(13) & Chr(10) n = n + 1 End If x = x + 1 Loop
End Sub
Private Sub Command2_Click()
Text1.Text = "" Text2.Text = ""
End Sub
Private Sub Form_Activate()
Text2.SetFocus
End Sub
[程序演示]
(3)
Do
[程序段] [ If 条件式 Then Exit Do ] '在特定条件下退出循环。 [程序段]
Loop While 条件式
说明:当条件式为真时,循环继续进行,直到条件式变为假为止。
例:
Private Sub Form_Click()
Dim i As Integer i = 6 Do Print i i = i + 1 Loop While i <= 5
End Sub
运行结果:6
(4)
Do
[程序段] [ If 条件式 Then Exit Do ] '在特定条件下退出循环。 [程序段]
Loop Until 条件式
说明:当条件式为假时,循环继续进行,直到条件式变为真为止。
例:
Private Sub Form_Click()
Dim i As Integer i = 6 Do Print i i = i + 1
Loop Until i > 5
End Sub
运行结果:6
从以上例子可见:
Do While…Loop和Do Until…Loop都在循环顶部检查进入循环的条件,如果在进入循环之间,退出循环的条件已经满足,则循环体内的指令不再执行。
Do…Loop while和Do…Loop Until在循环的底部检查退出循环的条件,与上面的使用方法相同,Loop while检查条件是否为真,Loop Until检查条件是否为假。与上面不同的是这种循环方式是先循环,再检查条件是否满足,因此总要比上面的循环方式多循环一次。
4、While…Wend
While…Wend循环语句是从旧的Basic语言中保留下来的,它同Do…While循环结构功能相同,但是Do…Loop 语句的功能更强一些,所以一般在编程中不使用这种循环结构。
语法格式:
While 条件式
程序段
Wend
说明:当条件式为真时,执行所有的语句,一直到Wend。然后再回到While语句,并再一次检查条件式,如果条件式还为真,则重复执行。不为真,程序从Wend语句之后的语句继续执行。
四、嵌套控制结构
循环嵌套——一个循环体内又包含一个完整的循环体结构。
上面四种循环都可以互相嵌套。
例1(见教材P71): 求1!+2!+3!+4!并打印结果。
Private Sub Form_Click()
Dim i, j As Integer Dim sum1, sum2 As Integer sum1 = 0 For i = 1 To 4 sum2 = 1 For j = 1 To i sum2 = sum2 * j '求得j!=sum2 Next j sum1 = sum1 + sum2 '求各阶乘的和 Next i Print "1!+2!+3!+4!=" & sum1
End Sub
在VB中,控制结构的嵌套层数没有限制。习惯总是用缩排方式书写判定结构或循环结构,使其更具有可读性。
例2:将1、2、3、4、5、6这6个数分别添入三角形的三条边上,使三角形每一条边上的数字之和相等。
界面:

代码:
Private Sub Command1_Click() For a = 1 To 6 For b = 1 To 6 For c = 1 To 6 For d = 1 To 6 For e = 1 To 6 For f = 1 To 6 m = a + b + c + d + e + f n = a * b * c * d * e * f o = a + b + c p = c + d + e q = e + f + a If m = 21 And n = 720 And o = p And p = q Then '判断6个数各不相同。 Label2.Caption = a Label3.Caption = b Label4.Caption = c Label5.Caption = d Label6.Caption = e Label7.Caption = f Exit Sub End If Next f Next e Next d Next c Next b Next a End Sub
Private Sub Command2_Click() End End Sub
[程序演示]
五、Do Events函数与闲置循环
作用:当程序在执行一长时间循环对其它事件不做响应时,使用“Do Events函数与闲置循环”可避免这种情况,从而能够及时响应其它事件的发生。
Windows监视所有被加载的应用程序,并且轮流给每个应用程序分配CPU时间。VB设计的程序是事件驱动的,只有发生特定事件时,才执行该事件相应的代码,如果没有事件发生,整个程序就被Windows设置于“闲置状态”,因此不占用CPU时间。另一方面,当VB执行一个过程时,将停止对其它事件(如鼠标事件)的处理,直到执行完End Sub或End Funstion指令为止。也就是说,在Windows的多任务环境下,如果过程太长,或者程序运行一个长时间循环,即使其它应用程序也会分到CPU时间,但是该程序在运行循环时,对该程序中的其它事件不做响应。
例如下面的程序在执行一长时间循环时对其它事件不做响应(见教材P71)。
运行界面:

代码:
Private Sub Command1_Click() Dim i As Integer For i = 1 To 15000 Cls Print i Next i End Sub
Private Sub Timer1_Timer() Label1.Caption = Time$ End Sub
程序运行时,单击命令按钮执行循环时。在循环期间,文本框不能输入;标签框显示的时间是循环开始时间,不能显示当前时间;其它操作比如“关闭”按钮也不不能实现。
[程序演示]
可见,运行长时间的循环会占用CPU太多的时间,以致于不能及时响应其它事件的发生。因此,我们在写程序时,“事件过程”不宜写的太长,更不可以有太长的循环。如果要用长的循环,又要避免能够及时响应其它事件的发生,只有采用两种方法:其一,使用DoEvents函数;其二,写成“闲置循环”。
1、DoEvents函数
DoEvents函数将控制权转交给操作系统,以便让系统有机会去检查是否有其他事件需要提供服务,它既可以作为语句,也可以作为函数使用。
语法如下:
[窗体号=] DoEvents[()]
当作为函数使用时,DoEvents返回当前装入VB应用程序工作区的窗体号。如果不想使用这个返回值,则可以随便使用一个变量接收返回值。如:
Dummy = DoEvents( )
当作为语句使用时,可省略前、后的选择项。
在上面的示例中,在循环体中如果使用了Doevents()函数,则在循环执行过程中如果发生定时器事件或编辑框中的输入事件发生时,系统会给以及时响应。
下列示例在循环中使用 DoEvents 函数,每当循环完成 1000 次时,将控制权让给操作系统。
在上例中添加一些代码(如下红色部分),再运行试试。
Dim I, OpenForms
Private Sub Command1_Click() For I = 1 To 15000 If I Mod 1000 = 0 Then ' 如果循环已完成了 1000 次。 OpenForms = DoEvents ' 将控制权让给操作系统。 End If Cls Print I Next I End Sub
Private Sub Timer1_Timer() Label1.Caption = Time$ End Sub
可以看出,使用了DoEvents 函数,则在循环执行过程中,发生定时器事件或文本框中的输入事件发生时,系统会给以及时的响应。
DoEvents 函数提供了一种取消执行当前任务的简便方法。例如,下列代码将显示一个 "Process" 按钮,单击这个按钮时,它将变成 "Cancel" 按钮并且开始执行任务。如果再次单击按钮又将中断正在执行的任务。
该按钮的Caption属性为"Process"。
Private Sub Command1_Click()
Static blnProcessing As Boolean Dim lngCt As Long Dim intYieldCt As Integer Dim dblDummy As Double '过程的所有实例都共享静态变量。 If blnProcessing Then '按下按钮时,检测是否已经在处理。 blnProcessing = False '如果正在处理,则取消处理。 Else Command1.Caption = "Cancel" blnProcessing = True lngCt = 0 '执行一百万次浮点乘法计算。每一千次后,检测是否要取消。 Do While blnProcessing And (lngCt < 1000000) For intYieldCt = 1 To 1000 lngCt = lngCt + 1 dblDummy = lngCt * 3.14159 Next intYieldCt DoEvents 'DoEvents 语句允许其它事件发生,包括第二次按此按钮。 Loop blnProcessing = False Command1.Caption = "Process"
MsgBox lngCt & " multiplications were performed" End If
End Sub
[程序演示]
DoEvents 将控制切换到操作环境内核。只要此环境中的所有应用程序都有机会响应待处理事件,应用程序就又恢复控制。这不会使应用程序放弃焦点,但会使后台事件能够得到处理。
2. 闲置循环
所谓闲置循环,就是当应用程序处于闲置状态时,用一个循环来执行其它操作。但是,当执行闲置循环时,将占用全部的CPU时间,不允许执行其它的事件过程,使系统处于无限循环中,没有任何反应。为此,VB提供了DoEvents语句。当执行闲置循环时,可以用它把控制权交给周围环境使用,然后回到原来程序继续执行。
对vb应用程序来说,事件之间的时间叫做“空闲时间”。在“空闲时间”里,vb自动将控制权交还给windows。当某个应用程序中的一个事件发生时vb再为它向windows请求CPU时间。
编闲置循环时,须添加标准模块,并在代码模块中使用Sub main过程,使应用程序马上开始执行程序(而不必等待窗体上发生事件)。
具体操作为:选择[工程]/[添加模块],然后在其中建立一个叫做main的程序,再通过[工程]/[工程1属性]/[通用]标签/[启动对象]中选择"sub main",然后将DoEvents 当作do ...while的判断条件。
例1:试验闲置循环和DoEvents语句。
界面:
在Form1窗体上建立三个命令按钮,如下图:

代码:
在标准模块中编写程序如下:
Sub main() Form1.Show Do While DoEvents() Form1.Command2.Left = Form1.Command2.Left + 1 Beep Loop End Sub
在Form1窗体中编写程序如下:
Option Explicit
Dim i, x Private Sub Command1_Click() FontSize = 16 Print "执行Command1_click事件过程" For i = 1 To 100000 x = i * 2 Next End Sub
Private Sub Command3_Click() End End Sub
把Sub main()设置为启动过程。
程序说明:程序运行后,进入闲置循环,使标有“闲置循环”的命令按钮右移,并发出声响。如果单击标有“单击此按钮”的命令按钮,则有事件发生。“闲置循环”按钮暂停移动,在窗体上显示相应信息,然后“闲置循环”按钮接着移动。
[程序演示] [程序下载]
例2:(教材P74):
界面:
标准模块中的代码:
Dim i As Integer
Sub Main() Form1.Show Do While DoEvents() Form1.Cls Form1.Print i i = i + 1 Loop End Sub
窗体模块中的代码:
Private Sub Command1_Click() Text1.Text = "现在闲置循环暂停,单击确定后,又会进入循环。" MsgBox "继续循环吗?" End Sub
[程序演示] [程序下载]
|