# Do…Loop 语句应用方案

## 知识概述

### Do...Loop 循环结构

Do…Loop 语句可以重复循环一组语句，但是没有规定循环的次数，而是通过限定循环条件来控制循环，如同 If…Then 语句，当所判定条件的 Boolean 值为 True 时进入循环，为 False 时则不进入循环。

语法：

Do…Loop 语句的语法有 2 种形式。

形式 1：

Do [{While | Until} <表达式>]

[<语句组>]

[Exit Do]

[<语句组>]

Loop

形式 2：

Do

[<语句组>]

[Exit Do]

[<语句组>]

Loop [{While | Until} <表达式>]

Do…Loop 语句语句的参数说明如表 1 所示。

表 1 Do…Loop 语句的参数说明

参数 | 描述
表达式 | 可选参数。数值表达式或字符串表达式，其值为 True 或 False。如果表达式是 Null，则表达式值会被当作 False
While | Until | 可选参数。Visual Basic 关键字。有 While 关键字出现的 Do…Loop 语句属于当型循环语句；而有 Until 关键字出现的 Do…Loop 语句属于直到型循环语句
语句组 | 可选参数。一条或多条语句，Do…Loop 语句中被重复执行的语句组
Exit Do | 可选参数。退出 Do...Loop 循环的方法

#### 1．While 当型循环语句

使用 While 关键字的 Do…Loop 语句即当型循环语句。当表达式值为 True 时，执行语句组中的循环，直到表达式值为 False。使用当型循环语句也可以代替 For…Next 语句。例如将利用 For 循环计算累加的代码用当型循环语句代替。

For 循环代码：

Private Sub Command1_Click()

Dim a As Long, b As Long

For a = 1 To 100

b = b + a

Next a

Text1.Text = b

End Sub

下例使用 While 当型循环语句实现 1～100 的累加。程序代码如下：

Private Sub Command1_Click()

Dim a As Long, b As Long

Do While a < 100

a = a + 1

b = b + a

Loop

Label1.Caption = "0～100 的累加结果为" & b

End Sub

上面代码中的 While 当型循环语句可以理解为：当 a<100 时就循环执行 Do…Loop 语句当中的语句。每次执行，变量 a 自动增加 1，变量 b 等于之前变量 b 的值与每次都自动增加 1 后的变量 a 相加。

#### 2．Until 直到型循环语句

在 Do…Loop 语句中使用 Until 关键字，这个循环就是直到型循环。使用 Until 直到型循环时，程序一直循环 Do…Loop 语句中的语句组，直到 Until 关键字后的表达式值为 True，程序才停止。这与 While 当型循环相反。

使用 Until 直到型循环实现 1～100 的累加。程序代码如下：

Private Sub Command1_Click()

Dim a As Long, b As Long

Do Until a = 100

a = a + 1

b = b + a

Loop

Label1.Caption = "0～100 的累加结果为" & b

End Sub

上面代码中的 Until 直到型循环语句可以理解为：直到 a=100 时才停止循环执行 Do…Loop 语句当中的语句。每次执行，变量 a 自动增加 1，变量 b 等于之前变量 b 的值与每次都自动增加 1 后的变量 a 相加。

#### 3．Exit Do 型循环语句

使用 Exit Do 语句可以跳出任何循环的 Do…Loop 语句，将程序所要执行的语句跳到 Loop 语句之后，而不再执行 Do…Loop 语句的循环中。Exit Do 语句可以放在 Do…Loop 语句中的任意位置，通常都与选择结构语句共同使用，例如如 If…Then 语句。

说明：Exit Do语句属于Exit语句的形式之一。

本例实现单击“最大值”或“最小值”按钮，调用输入对话框，并将输入对话框中输入的数值中最大的或最小的数值显示出来。本例在 Do…Loop 循环语句中使用 InputBox 函数调用输入对话框输入数值，并使用 If …Then 语句判断这些数值。

程序代码如下：

Private Sub Command1_Click()

Dim a, b As Double, c As Boolean

c = False

Do

If c = True Then

a = InputBox("请输入数值，输入非数字结束。目前最大数为" & b, "输入")

Else

a = InputBox("请输入数值，输入非数字结束。", "输入")

End If

If IsNumeric(a) Then

If c = False Then

b = a

c = True

Else

b = CDbl(IIf(CDbl(a) > b, a, b))

End If

Else

Exit Do

End If

Loop

Label1.Caption = "输入的数中最大的是：" & b

End Sub

使用 Do…Loop 语句，循环使用 InputBox 函数调用输入对话框。使用 If…Then…Else 语句判断对话框输入的内容，如果为数值则继续循环，并将较大的数值赋值给变量 b；当对话框内容不是数值时，执行 Exit Do 语句跳出 Do…Loop 循环语句，然后将变量 b 的值在 Label1 控件中显示出来。

程序代码如下：

Private Sub Command2_Click()

Dim a, b As Double, c As Boolean

c = False

Do

If c = True Then

a = InputBox("请输入数值，输入非数字结束。目前最小数为" & b, "输入")

Else

a = InputBox("请输入数值，输入非数字结束。", "输入")

End If

If IsNumeric(a) Then

If c = False Then

b = a

c = True

Else

b = CDbl(IIf(CDbl(a) < b, a, b))

End If

Else

Exit Do

End If

Loop

Label1.Caption = "输入的数中最小的是：" & b

End Sub

## 应用一：动态数组的使用

下例实现：单击“输入”按钮，使用 InPutBox 函数弹出“输入”对话框，输入一些数据储存在动态数组 A 中，并将动态数组 A 中数据在 TextBox 控件中显示出来。程序运行效果如图 1 所示。

图 1 单击“输入”按钮输入 12 个字符串后的效果

#### 程序完整代码如下：

Private Sub Command1_Click()

Text1.Text = ""

Dim S As Long, i As Long

Dim A()

Do

ReDim Preserve A(S)

A(S) = InputBox("请输入字符串，输入空串时结束", "输入")

S = S + 1

Loop Until A(S - 1) = ""

For i = 0 To S - 2

Text1.Text = Text1.Text & "第" & CStr(i + 1) & "个是：" & CStr(A(i)) & " "

Next i

Erase A

End Sub

## 应用二：获取本地计算机的 IP 地址

通过 Winsock 控件的 LocalIP 属性可以获取本机的 IP 地址，在窗体运行的时候，在 Label 控件中显示本机的 IP 地址，如图 1 所示。

图 1 显示本机的 IP 地址

完整程序代码如下：

Dim portnum As Long

Dim start As String

Private Sub cmdScan_Click()

If txtUB.Text = "" Or Text3.Text = "" Then

MsgBox "端口号不能为空！！"

Exit Sub

End If

wskSocket.Close

start = True

Call SCanningPorts '调用自定义的过程

lstOpenPorts.Text = lstOpenPorts.Text & vbCrLf & "端口" & txtUB.Text & "-" & Text3.Text & "已经扫描成功！"

End Sub

Private Sub cmdStop_Click()

start = False

End Sub

Sub SCanningPorts() '自定义的过程

Dim porttwo As Long

portnum = txtUB.Text

porttwo = Text3.Text

On Error GoTo viriio:

Do

portnum = portnum + 1

DoEvents

If start = True Then

wskSocket.Close

DoEvents

wskSocket.LocalPort = portnum

DoEvents

txtCon.Text = portnum

wskSocket.Listen

DoEvents

Else

portnum = 0

Exit Sub

End If

wskSocket.Close

DoEvents

Loop Until portnum >= porttwo

portnum = 0

viriio:

If Err.Number = 10048 Then

lstOpenPorts.Text = lstOpenPorts.Text & vbCrLf & "端口" & wskSocket.LocalPort & "开放中"

Resume Next

End If

End Sub

Private Sub Form_Load()

txtIP.Text = wskSocket.LocalIP '获取本机的 IP 地址

End Sub

## 应用三：获取 SQL Server 数据表

使用 ADO 的 OpenSchema 方法可以获取数据库模式信息，将其类型设置 adSchemaTables 可以得到表的信息。下面获取 SQL Server 数据库 db_Csell 中的数据表。

最终效果如图所示。

程序代码如下：

★★★★★ frm_deldata ★★★★★★

Private Sub Form_Load()

Dim rstSchema As ADODB.Recordset

Dim cnn As New ADODB.Connection

cnn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;Data Source=.;User ID=sa;Initial Catalog=db_CSell"

Set rstSchema = cnn.OpenSchema(adSchemaTables)

Do Until rstSchema.EOF

If Left(rstSchema!TABLE_NAME, 3) <> "sys" And Left(rstSchema!TABLE_NAME, 3) <> "dtp" Then

List1.AddItem rstSchema!TABLE_NAME

End If

rstSchema.MoveNext

Loop

rstSchema.Close

End Sub

## 应用四：邮件发送

随着 Internet 技术的飞速发展和融合，产生了由先进计算机系统集成的管理中心，这种系统极大地改善了企业与用户接触的广度和深度，正在引发一场企业客户服务方式的革命。邮件发送也在客户服务中起着越来越重要的作用。本系统中的“邮件发送”窗体具有邮件发送和群发的功能。

“邮件发送”窗体的运行结果如图 1 所示。

图 1 “邮件发送”窗体的运行结果

#### 1．窗体设计

（1）在工程中新建一个窗体，将窗体的“名称”设置为“Frm_Khxxwh_Yjfs”，“Max- Button”属性设置为“False”，“Caption”属性设置为“邮件发送”。

（2）向窗体上添加 5 个“Frame”控件，其相应的属性设置及摆放位置如图 3.28 所示。

（3）向窗体上添加两个“ListBox”控件，将其“名称”属性分别设置为“Lit_Lxr”和“Lit_Xd”，分别用于显示联系人的邮箱列表信息和选定的邮箱列表信息。

（4）向窗体上添加两个“TextBox”控件，设置其“名称”属性分别为“Txt_Zt”和“Txt_Nr”。其中，“Txt_Zt”用于输入邮件的发送主题，“Txt_Nr”用于输入发送邮件的内容，因此应设置其“MultiLine”属性为“True”，“ScrollBars”属性为“2 – Vertical”。

（5）向窗体上添加两个“CommandButton”控件，设置其“名称”属性分别为“Cmd_Fs”和“Cmd_Exit”，“Caption”属性分别为“发送”和“退出”，分别用于发送邮件和退出本窗体。

（6）向窗体上添加“MAPIMessages”控件和“MAPISession”控件。由于这两个控件属于“ActiveX”控件，因此在使用之前必须从“部件”对话框中添加到工具箱中。添加方法如下：

在“部件”对话框中选中“Microsoft MAPI Controls 6.0”列表项，单击“确定”按钮之后即可将这两个控件添加到工具箱中，如图 2 所示。

（7）向窗体中添加 4 个“Label”控件，并将标签控件设置为控件数组的形式。设置其 Caption 属性分别为“>>”、“>”、“<”、“<<”，其摆放位置如图 3 所示。

“邮件发送”窗体的设计界面如图 3 所示。

图 2 向工具箱中添加“MAPI”控件

图 3 “邮件发送”窗体的设计界面

#### 2．代码设计

当窗体启动的时候，向“Lit_Lxr”列表框中添加联系人的邮箱信息，并建立一个邮件对话连接。窗体启动时的事件代码如下：

Private Sub Form_Load()

Dim rs1 As New ADODB.Recordset '定义数据集对象

'打开数据连接

rs1.Open "select * from tb_Client_lxrxx ", Cnn, adOpenKeyset

If rs1.RecordCount > 0 Then '如果记录数量大于 0

For i = 0 To rs1.RecordCount − 1 '从 0 到记录数减 1 做循环

'向列表框中添加对象

Lit_Lxr.AddItem Trim(rs1.Fields("lxrxx_Email"))

rs1.MoveNext '移至下一条记录

Next i '循环加 1

End If

MAPISession1.SignOn '建立一个邮件会话

End Sub

当用户单击 Label1 控件数组时，对已选定的邮件和全部联系人的邮件信息进行相应的操作。实现的代码如下：

Private Sub Label1_Click(Index As Integer)

Select Case Index

Case 0 '全部选中

For i = 0 To Lit_Lxr.ListCount − 1

Lit_Lxr.ListIndex = i

Lit_Xd.AddItem (Lit_Lxr.Text) '将选中的项目添加到“Lit_Xd”文本框中

Next i '循环加 1

Lit_Lxr.Clear '清空 Lit_Lxr 列表

Case 1 '选择一项

a = 0 '定义变量用于存储未选中的项目

For i = 0 To Lit_Lxr.ListCount − 1

If Lit_Lxr.Selected(i) = False Then

a = a + 1

End If

Next i

If a = Lit_Lxr.ListCount Then

MsgBox "请选择项目", "信息提示"

Else

Lit_Xd.AddItem (Lit_Lxr.Text)

Lit_Lxr.RemoveItem (Lit_Lxr.ListIndex)

End If

Case 2 '退回一项

a = 0

For i = 0 To Lit_Xd.ListCount − 1

If Lit_Xd.Selected(i) = False Then

a = a + 1

End If

Next i

If a = Lit_Xd.ListCount Then

MsgBox "请选择项目", "信息提示"

Else

Lit_Lxr.AddItem (Lit_Xd.Text)

Lit_Xd.RemoveItem (Lit_Xd.ListIndex)

End If

Case 3 '全部退回

For i = 0 To Lit_Xd.ListCount − 1

Lit_Xd.ListIndex = i

Lit_Lxr.AddItem (Lit_Xd.Text)

Next i

Lit_Xd.Clear

End Select

End Sub

当用户选定要发送邮件的邮件信息，并填写好相应的主题和内容后，单击“发送”按钮，将触发“Cmd_Fs”控件的“Click”事件，其实现的代码如下：

Private Sub Cmd_Fs_Click() '发送邮件

On Error GoTo SendErr '如果出错则转到出错处理

j = 0 '定义变量

If Lit_Xd.ListCount > 0 Then '如果选定的邮件数大于 0

Lit_Xd.Selected(0) = True '选定第 1 条记录

Do While j < Lit_Xd.ListCount

Lit_Xd.SetFocus '设置焦点

Lit_Xd.Selected(j) = True '选定记录

MAPIMessages1.MsgIndex = −1

MAPIMessages1.RecipDisplayName = Lit_Xd.Text

MAPIMessages1.MsgSubject = Txt_Zt.Text

MAPIMessages1.MsgNoteText = Txt_Nr.Text

MAPIMessages1.SessionID = MAPISession1.SessionID

MAPIMessages1.Send

j = j + 1 '记录加 1

Loop '循环

MsgBox "邮件发送成功!", "信息提示"

End If

Exit Sub

SendErr: '出错处理

MsgBox Err.Description, "信息提示"

End Sub

## 应用五：自动删除文本中的非法字符

### 实例说明

本实例中不允许用户在文本框中输入数字信息，当用户在文本框中输入数字信息时，系统会自动将其删除。如图 1 所示，用户输入的数字信息不会显示在文本框中。

图 1 自动删除文本中的非法字符

### 思路与技术

可以使用 IsNumeric 函数和 Do…Loop 语句来实现自动删除文本中的非法字符。

其中，IsNumeric 函数返回 Boolean 值，指出表达式的运算结果是否为数。

其语法形式如下：

IsNumeric(expression)

参数说明：

expression 该参数是一个 Variant，包含数值表达式或字符串表达式。

Do...Loop 语句是用 Do 循环重复执行一语句块且重复次数不定。Do...Loop 语句有几种演变形式，但每种都要计算数值条件以决定是否继续执行。如同 If...Then 语句中的 condition 必须是一个数值或者值为 True（非零）或 False（零）的表达式。

如在下面的 Do...Loop 循环中，只要 condition 为 True 就执行 statements。

Do While condition

statements

Loop

### 开发步骤

（1）新建一个标准工程，创建一个新窗体，默认名为 Form1。

（2）在窗体上添加 Label 控件，设置其 Caption 属性为“自动删除文本中的数字”。

（3）在窗体上添加一个 TextBox 控件。设置其 MultiLine 属性为 True，ScrollBars 属性为 2-Vertical。

表 1 Form1 窗体中控件部分属性设置

控件名 | 属性 | 值
Label | Name Caption | Label1 自动删除文本中的数字
TextBox | Name | Text1

（4）为 Form1 窗体添加如下代码。

Private Sub Text1_Change()

If Text1.Text = "" Then

Text1.SetFocus

Exit Sub

Else

'有数字

j = Len(Text1.Text)

Do While (j <> 0)

c = Left(Right(Text1.Text, j), 1)

If IsNumeric(c) Then

Text1.Text = Left(Text1.Text, Len(Text1.Text) - j) + Right(Text1.Text, j - 1)

Text1.SelStart = Len(Text1.Text)

End If

j = j - 1

Loop

End If

End Sub

## 应用六：获取 Access 数据表中的字段信息

### 获取 Access 数据表中的字段信息

OpenSchema 方法的 QueryType 参数值为“adSchemaColumns”时，会提取到指定数据表的字段的信息。

获取数据表的字段信息语句格式为：

Set rs = cn.OpenSchema(adSchemaColumns)

本实例使用 Do…Loop 语句实现循环提取所选择数据表中的字段信息，包括字段的名称、类型和长度信息的提取。程序运行结果如图 1 所示。

图 1 读取 Access 数据表中字段信息

完整程序代码如下：

Dim cn As New ADODB.Connection

Dim rs1 As New ADODB.Recordset

Dim rs2 As New ADODB.Recordset

Dim field As ADODB.field

Private Sub List1_Click()

cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & CommonDialog1.FileName & ";Persist Security Info=False"

Set rs2 = cn.OpenSchema(adSchemaColumns)

'提取数据表的信息

List2.Clear

List2.AddItem "字段的名称" & " " & "字段的类型" & " " & "字段的长度"

Do While Not rs2.EOF

' 字段类型对应值

If rs2!TABLE_NAME = Trim(List1.Text) Then

If rs2!data_type = "2" Then

s = "smallint"

ElseIf rs2!data_type = "3" Then

s = "int "

ElseIf rs2!data_type = "5" Then

s = "float"

ElseIf rs2!data_type = "6" Then

s = "money"

ElseIf rs2!data_type = "128" Then

s = "varbinary"

ElseIf rs2!data_type = "129" Then

s = "varchar"

ElseIf rs2!data_type = "130" Then

s = "nvarchar"

ElseIf rs2!data_type = "7" Then

s = "datetime"

End If

'把字段的名称、类型和宽度都添加到列表框中

List2.AddItem rs2!COLUMN_NAME & " " & s & " " & rs2!character_maximum_length

End If

rs2.MoveNext

Loop

rs2.Close

cn.Close

End Sub

Private Sub Command1_Click()

If cn.State = adStateOpen Then '指示对象是打开的。

cn.Close

List1.Clear

End If

With CommonDialog1

.DefaultExt = "*.mdb"

.Filter = "*.mdb"

.ShowOpen

Text1 = .FileName

cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & .FileName & ";Persist Security Info=False"

Set rs1 = cn.OpenSchema(adSchemaTables)

Do Until rs1.EOF

If Left(rs1!TABLE_NAME, 4) <> "MSys" Then

List1.AddItem rs1!TABLE_NAME

End If

rs1.MoveNext

Loop

rs1.Close

cn.Close

End With

End Sub

## 应用七：证书套打

“套打”是现在应用较为广范的一种打印方式。“套打”是指在使用事先印制有凭证、账簿、报表格式、证书等纸张上进行打印的一种打印方式。这种打印方式在打印时，无须打印表格的表格线及其他固定的格式内容，有利于加快打印速度，节约打印耗材，延长打印机的使用寿命。

最终效果如图所示。

程序代码如下：

★★★★★ frm_print ★★★★★★

Dim A, A1, B, B1, C, c1 As Integer

Dim fld

Dim cn As New ADODB.Connection

Dim rs As New ADODB.Recordset

Private Sub CboTable_Click()

Dim i As Integer

On Error Resume Next

Adodc1.RecordSource = CboTable

Adodc1.Refresh

Text12 = Adodc1.Recordset.RecordCount - 1

If Not Adodc1.Recordset.BOF Then Adodc1.Recordset.MoveNext

For i = 0 To 4

Text1(i + 1).DataField = Adodc1.Recordset.Fields(i).Name

Next i

Command1.Enabled = True

Command2.Enabled = True

End Sub

Private Sub Command1_Click()

'打印证书

A = Val(Text2.Text)

A1 = Val(Text5.Text)

B = Val(Text3.Text)

B1 = Val(Text6.Text)

C = Val(Text4.Text)

c1 = Val(Text7.Text)

Printer.FontName = Text8.Text

Printer.FontSize = Text9.Text

Printer.FontBold = Text11.Text

Printer.Orientation = 2

Printer.CurrentX = 100 + A

Printer.CurrentY = B + 200

Printer.Print Text1(0)

B = B + C

Printer.CurrentX = 100 + A

Printer.CurrentY = B + 200

Printer.Print Text1(1)

B = B + C

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(2)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(3)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(4)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(5)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(6)

B1 = B1 + c1

Printer.EndDoc

Adodc1.Recordset.MoveNext

End Sub

Private Sub Command3_Click()

CommonDialog1.CancelError = True

On Error GoTo ErrHandler

' 设置 Flags 属性

CommonDialog1.Flags = cdlCFEffects Or cdlCFBoth

' 显示“字体”对话框

CommonDialog1.ShowFont

Text8.Text = CommonDialog1.FontName

Text9.Text = CommonDialog1.FontSize

Text11.Text = CommonDialog1.FontBold

For i = 0 To 6

Text1(i).FontName = Text8.Text

Text1(i).FontSize = Text9.Text

Text1(i).FontBold = Text11.Text

Next i

Exit Sub

ErrHandler:

' 用户按了“取消”按钮

Exit Sub

End Sub

Private Sub Command2_Click()

On Error Resume Next

If Not Adodc1.Recordset.BOF Then Adodc1.Recordset.MoveFirst

For i = 1 To Val(Text10.Text) - 1

Adodc1.Recordset.MoveNext

Next i

For i = Val(Text10.Text) To Val(Text12.Text)

A = Val(Text2.Text)

A1 = Val(Text5.Text)

B = Val(Text3.Text)

B1 = Val(Text6.Text)

C = Val(Text4.Text)

c1 = Val(Text7.Text)

Printer.Orientation = 2

Printer.FontName = Text8.Text

Printer.FontSize = Text9.Text

Printer.FontBold = Text11.Text

Printer.CurrentX = 100 + A

Printer.CurrentY = B + 200

Printer.Print Text1(0)

B = B + C

Printer.CurrentX = 100 + A

Printer.CurrentY = B + 200

Printer.Print Text1(1)

B = B + C

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(2)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(3)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(4)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(5)

B1 = B1 + c1

Printer.CurrentX = 100 + A1

Printer.CurrentY = B1 + 200

Printer.Print Text1(6)

B1 = B1 + c1

Printer.EndDoc

Adodc1.Recordset.MoveNext

Next i

End Sub

Private Sub Form_Load()

Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\mydb.mdb;Persist Security Info=False"

Adodc1.CommandType = adCmdTable

cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\mydb.mdb;Persist Security Info=False"

Set rs = cn.OpenSchema(adSchemaTables)

Do Until rs.EOF

If Left(rs!TABLE_NAME, 4) <> "MSys" Then

CboTable.AddItem rs!TABLE_NAME

End If

rs.MoveNext

Loop

rs.Close

CboTable.ListIndex = 0

A = 2350

A1 = 11200

B = 7800 - 1180

B1 = 2560 - 1150

C = 1200

c1 = 1550

End Sub

Private Sub Text2_Change()

A = Val(Text2.Text)

End Sub

Private Sub Text3_Change()

B = Val(Text3.Text)

End Sub

Private Sub Text4_Change()

C = Val(Text4.Text)

End Sub

Private Sub Text5_Change()

A1 = Val(Text5.Text)

End Sub

Private Sub Text6_Change()

B1 = Val(Text6.Text)

End Sub

Private Sub Text7_Change()

c1 = Val(Text7.Text)

End Sub

## 应用八：循环读取 INI 文件内容

### 实例说明

利用 INI 文件可以保存资源信息或系统信息，可以将 INI 文件读取到窗体的文本框中再进行编辑。运行程序，单击“<<”按钮，选择要打开的 INI 文件，单击“打开”按钮将此 INI 文件的数据信息读取到文本框中。实例运行结果如图 1 所示。

图 1 读取 INI 文件

### 思路与技术

在 Open 语句中，通过 Do While 循环语句循环读取 INI 文件中的信息来实现将数据信息读取到窗体文本框中的功能。

本实例中通过 Open 语句读取 INI 文件的语法如下：

Open (Common1.FileName) For Input As #1

Do While Not EOF(1)

Line Input #1, Intext

Text2.Text = Text2.Text & Intext

Loop

Close #1

### 开发步骤

（1）新建一个标准工程，创建一个新窗体。

（2）在窗体上添加一个 Frame 控件，设置其 Caption 属性为“选择要读取的 ini 文件名称”。

（3）在 Frame1 控件中添加一个 TextBox 控件和一个 CommandButton 控件。

（4）在窗体上添加一个 TextBox 控件，将其 MultiLine 属性设置为 Ture，ScrollBars 属性设置为 2-Vartical。

（5）在窗体上添加一个 CommonDialog 控件。该控件属于 ActiveX 控件，在使用前应先将其添加到工具箱中，具体添加方法如下：

选择 VB 菜单的“工程”→“部件”，然后选取 Microsoft Common Dialog Control 6.0（SP3），单击“确定”按钮。此时，CommonDialog 控件出现在工具箱中。

表 1 Form1 窗体中控件部分属性设置

控件名 | 属性 | 值
CommandButton | Name Caption | Command1 <<
CommonDialog | Name | Common1
Frame | Name Caption | Frame1 选择要读取的 ini 文件名称
TextBox | Name | Text1
TextBox | Name | Text2

（6）为 Form1 窗体添加如下代码。

Dim Intext As String

Private Sub Command1_Click()

Common1.Filter = "ini 文件（*.ini）|*.ini"

Common1.ShowOpen

If Common1.FileName = "" Then

Exit Sub

Else

Text2.Text = ""

Text1.Text = Common1.FileName

Open (Common1.FileName) For Input As #1

Do While Not EOF(1)

Line Input #1, Intext

Text2.Text = Text2.Text & Intext

Loop

Close #1

End If

End Sub

Private Sub Form_Load()

Me.Left = (Screen.Width - Me.Width) / 2

Me.Top = (Screen.Height - Me.Height) / 2

End Sub

## 应用九：航班查询

航班查询如图 1 所示。

图 1 航班查询

Dim i As Integer

Private Sub Tree_change()

Dim Key, Text, BH As String

Dim Nod As Node

Key = "所有航班"

Text = "所有航班"

Set Node1 = TreeView1.Nodes.Add(, , Key, Text, 1)

AdoRs.Open "select distinct 省份 from 航班查询 ", Cnn, adOpenKeyset

If AdoRs.RecordCount > 0 Then

AdoRs.MoveFirst

Do While AdoRs.EOF = False

Key = Trim(AdoRs.Fields("省份"))

Text = AdoRs.Fields("省份")

Set Node2 = TreeView1.Nodes.Add(Node1.Index, tvwChild, Key, Text, 2)

AdoRs.MoveNext

Loop

Else

End If

AdoRs.Close

End Sub

Private Sub Form_Load()

Call Tree_change

Adodc1.ConnectionString = PublicStr

Adodc1.RecordSource = "select * from 航班查询"

Adodc1.Refresh

Label2.Caption = "总计查询记录的条数为 " & Adodc1.Recordset.RecordCount

End Sub

Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)

If KeyCode = 13 Then

Adodc1.ConnectionString = PublicStr

Adodc1.RecordSource = "select * from 航班查询 where 省份='" + Text1.Text + "'"

Adodc1.Refresh

Label2.Caption = "总计查询记录的条数为 " & Adodc1.Recordset.RecordCount

End If

End Sub

Private Sub TreeView1_NodeClick(ByVal Node As MSComctlLib.Node)

Adodc1.ConnectionString = PublicStr

Adodc1.RecordSource = "select * from 航班查询 where 省份='" + TreeView1.SelectedItem + "'"

Adodc1.Refresh

Label2.Caption = "总计查询记录的条数为 " & Adodc1.Recordset.RecordCount

End Sub