b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

toolbar弹出mid窗体_richtextbox vb_richtextbox和textbox

电脑杂谈  发布时间:2017-01-21 03:03:47  来源:网络整理

第一篇:vb编程

Visual Basic 程序设计简明教程 第 二 版 Visual Basic第一章程序设计简明教程Visual Basic程序设计概述(1)第二章 VB简单的程序设计(3) 第三章 VB语言基础(2) 第四章 基本的控制结构(6) 第五章 数组(4) 第六章 过程(5) 第七章 常用控件(4) 第八章 界面设计(3) 第九章 文件(2) 第十章 图形(3) 第十一章 技术(1) 第一章 Visual Basic程序设计概述(1学时)1.1 1.2 1.3 引例 VB主要功能和特点 VB集成开发环境 1.1 引例1.1一行内容在窗体左、右移动; 移动两种方法:手动和自动,当自动时,文字闪烁显 示; 当内容超出窗体,进行反弹。 1.1 引例 2.1对输入的字符进行转换的程序。

转换规则:? 大写字母转换成小写字母, ? 小写字母转换成大写字母 ? 空格不转换 ? 其余转换成“*”。要求:每输入一个字符,马上就进行判断和转 换。

通过上述两例说明VB面向对象、可视化、事件驱 动的特点。 1.2 VB主要功能和特点 1. 具有面向对象的可视化设计工具;

2. 事件驱动的编程机制;

3. 提供了易学易用的应用程序集成开发环境;

4. 结构化的程序设计语言;

5. 支持多种系统的访问;

6. Active技术;

7. VB 6.0在开发环境上、网络功能等的增强;

8. 完备的help联机帮助功能。 1.3 VB集成开发环境工程窗口 工具箱窗体窗口属性窗口窗体布局立即窗口 1. 主窗口 应用程序窗口,由标题栏、菜单栏和工具栏组成。

2. 窗体(form)窗口 设计VB程序的界面。

4. 属性(properties)窗口 所有窗体或控件的属性设置。

5. 工程资源管理器(project expror)窗口 保存一个应用程序所有的文件。

6. 工具箱(toolbox)窗口 显示各种控件的制作工具,供用户在窗体上设计。 第二章 VB简单的程序设计(3学 2.1 程序设计方法的发展 时)2.2 2.3 2.4 2.5 2.6 2.7 2.8 VB中的有关概念 建立简单的应用程序 基本控件和属性 工程的管理及环境的设置 生成可执行文件和制作安装盘 程序调试 常见错误 2.1程序设计方法的发展1. 初期的程序设计高运行效率、少占用内存为目标。2. 结构化程序设计程序的可读性、可维护性为目标。

程序= 算法+数据结构 的面向过程的程序设计。3. 面向对象的程序设计降低程序的复杂性、提高软件的开法效率和改善工作界 面为目标。

程序=对象+消息 的面向对象的程序设计。 2.2对象的有关概念1. 类 类是创建对象实例的模板, 包含了创建对象的属性描述和 行为特征的定义。

2. 对象 是类的一个实例,继承了类的属性、方法。

VB中常用的对象有:窗体、控件等。

3. 对象的建立和命名 4. 对象的三要素 (1)属性 对象的性质,即用来描述和反映对象特征的参数。

(2)方法 对象的行为,即将一些通用的过程编写好并封装起来,作 为方法供用户直接调用。 (3)事件 响应对象的动作称为事件,它发生在用户与应用程序交 互时。如单击控件、鼠标移动、键盘按下等。

事件过程 指附在该对象上的用户编写的程序代码,是事件的处理程 序。

事件驱动过程 是图形用户界面的本质,由用户控制而代码作出响应。

5. VB程序的执行步骤如下:

(1)启动应用程序,装载和显示窗体; (2)窗体(或窗体上的控件)等待事件的发生; (3)事件发生时,执行对应的事件过程; (4)重复执行步骤(2)和(3) ; (5) 直到遇到END结束语句结束程序的运行; 或按“结束”强行停止程序的运行。 2.3建立简单的应用程序以例2.1为例:

1. 建立用户界面的对象; 2. 对象属性的设置; 3. 对象事件过程及编程; 4. 程序运行和调试; 5. 保存文件。 2.4一、常用属性基本控件和窗体1. Name名称属性 创建的对象名称,有默认的名。在程序中,控件名是作为对 象的标识而引用,不会显示在窗体上。

2. Caption标题属性 该属性决定了控件上显示的内容。

3. Height、width、top和left属性TopL e ft W id t hH e ig 4. Enabled属性 控件是否可操作。当设置为false时,呈暗淡色,禁止用户进 行操作。

5. Visible属性 控件是否可见。当设置为false时,用户看不到,但控件本身存 在。

6. Font属性 Fontname:字体;Fontsize:字体大小;Fontbold:是否是粗 体; Fontitalic:是否斜体;Fontstrikethru:是否加一删除线。

Fontunderline:是否带下划线。

例2.2 在窗体是建立两个命令按钮 Command1和Command2, Command2 的Font通过属性窗口设置, 其余属性 通过代码实现 7. Forecolor前景颜色属性 设置控件的前景颜色(即正文颜色).。其值是一个十六进 制常数,用户可以在调色板中直接选择所需颜色。

8. Backcolor背景颜色属性 9. Backstyle背景风格属性 0-transparent:透明显示,即控件背景颜色显示不出来。

10. BorderStyle边框风格属性 0-None:控件周围没有边框 。

1-Fixed Single:控件带有单边框。

11. Alignment属性 控件上正文水平对齐方式 0:正文左对齐 ;1:右对齐;2:居中。

12. AutoSize属性 控件是否根据正文自动调整大小, False 13. WordWarp属性 AutoSize True时,WordWarp才有效。

按正文字体大小在垂直方向上改变显示区域的大小。 14.TabIndex属性 决定了按Tab键时,焦点在各个控件移动的顺序。各个控件默认 TabIndex值就是以控件建立时 的顺序,第一个为0。

15.控件默认属性 反映该控件最重要的属性,使用时可省略属性名。

注意:Command的默认属性为Default,当该属性为True,当按 Enter键,该控件起作用。例2.3控件设置默认控件名 标题 有关属性设置 Name Caption 颜色、对齐、 Form1 MousePointer=99,MouseIcon=Key04.ico 鼠标属性例 左对齐 Alignment=0, BorderStyle =1 Label1 居中 Alignment=1,BorderStyle =1 Label2 自动 AutoSize=True, WordWarp=False, BorderStyle =1 Label3 背景白 BackColor= &H00FFFFFF&, BorderStyle =0 Label4 前景红 ForeColor= &H000000FF&, BorderStyle =0 Label5效果 二.窗体图标标题最小化按钮 最小化按钮1.属性 控 制 Caption标题 菜 单 MaxButton、MinButton 框 Icon、ControlBox Picture、AutoRedraw BorderStyle (0 1 2 3 4 5 ) WindowsState (0-正常、1-最小化、2-最大化) 2.事件 Click、DblClick和Load Load 当装入窗体时激发,通常用于对属性和变量初始化 3.方法 Print、Cls和Move等 例2.4 上述属性、Click、DblClick和Load 事件演示。边 框 样 式 三、标签 Label用于显示文本(输出)信息,不能作为输入信息的界面。

? PassWord:口令字符; Text属性返回输入的数据,屏幕显示该字符; ? SelStart、SelLength、SelText:选中文本的起始、长度、内容。例2.6 复制选中的文本 2.常用事件 ? Change:当改变文本框的Text属性时会引发该事件。? KeyPress(KeyAscii As Integer):同上,并可返回一个KeyAscii参数 KeyAscii 为13,按回车键;为0 去除刚输入的字符。

? LostFocus:当控件失去焦点时发生。

? GotFocus:当控件获得焦点时发生。3.常用方法[对象.]SetFocus:是把光标移到指定的文本框对象中。4.文本框的应用 数据过滤例2.7 要求输入合法的数字数据。当输入结束时(按Tab键),对于 输入正确的数据,显示正确信息;对输入的非数字数据,则响铃 (Beep)、显示错误信息、清除文本框中的内容,并使焦点重新回到文 本框。

? Text2_ LostFocus 当输入结束按Tab键时,该事件激发。

? IsNumeric(Text2):判断是否输入非数字数据。

? Text2.SetFocus:使焦点重新回到文本框。 五、命令按钮CommandButton接受用户输入的命令。输入命令可以有三种方式:

鼠标单击、Tab键焦点到该按钮、快捷键。1. 其他属性Caption:命令按钮显示的内容,可设置快捷键,例 &Ok,显示 Ok。

Value:

检查该按钮是否按下。该属性在设计时无效。

Picture :按钮可显示图片文件(.bmp和.Ico),当Style为1时有 效。

Style:确定显示的形式,0 只能显示文字,1 文字、图形均可 。

ToolTipText :设置工具提示,和Picture结合使用。2. 事件 Click 3. 例 2.8 建立一个允许剪切、复制和粘贴的简单便笺板程序。

可增加内容:利用MouseMove事件决定命令按钮的有效性, 即当选中内容,“剪切”、“复制”按钮有效,否则无效。 六、常用方法方法是面向对象的,故使用的形式为:

[对象.]方法 1.Print方法形式:

[对象.]Print[{Spc(n)|Tab(n)}][表达式列表][;|,] 作用:在对象上输出信息 对象:窗体、图形框或打印机(Printer) ,省略对象在窗体上输出。

Spc(n)函数:插入n个空格,允许重复使用。

Tab(n)函数:左端开始右移动n列,允许重复使用。

;(分号):光标定位上一个显示的字符后。

,(逗号):光标定位在下一个打印区的开始位置处。

无 ;,时换行。

开始打印的位置是由对象的CurrentX和CurrentX属性决定, 缺省为打印对象的左上角0,0。

注意:Print方法在Form _Load事件过程中起作用,必须设置窗体的 AutoRedraw为True。 例2.9 显示图形 Private Sub Form_Click() For i = 1 To 5 Print Tab(i);

String(6 - I, "▼");

Spc(6);

String(I, "▲") Next i End Sub注意:

String(number, character)返回指定长度重复字符 的字符串。

考虑:

若把Spc(6)换成Tab(6), 效果如何? 2. Cls方法 形式:[对象.]Cls 作用:清除运行时在窗体或图形框中显示的文本或图形。

注意:不清除在设计时的文本和图形。

3. Move方法 形式:[对象.]Move 左边距离[,上边距离[,宽度[,高度]]] 作用:移动窗体或控件,并可改变其大小。

对象:可以是窗体及除时钟、菜单外的所有控件 例2.10 图形移到窗体的中心。 七、应用举例例2-11 编一计算月支付贷款的程序。现要求根据房产商提供的 信息,买房者选择房型、面积、单价、按揭期等信息,计算每月 支付代款的程序。

窗体1:列表框选择数据、标签显示数据、文本框输入数据; 窗体2:图形框显示房屋的平面图。

Pmt函数计算月支付贷款。 2.5 工程的管理及环境的设置一、工程的组成 工程文件包含了一个应用程序的所有文件: 窗体文件(.frm):控件及属性、事件过程和自定义过 程;

窗体的二进制数据文件(.frx),自动产生同名.frx文件;

标准模块文件(.bas);

类模块的文件(.cls);

资源文件(.res);

ActiveX控件的文件(.ocx). 二、创建、打开和保存工程 三、添加、删除和保存文件1. 窗体名和窗体文件名概念 窗体名:窗体的Name属性, 窗体文件名 在代码中用来引用该窗体,同一 窗体名 工程不能有相同的窗体名; 窗体文件名:窗体存放在磁盘上的文件名,该文件包含了该窗体 的所有控件属性和代码,同一文件夹不能有相同的文件名。

2. 在工程中添加现存的窗体时,只是对该窗体文件的引用纳入工程。

因此,如果更改窗体并保存它,会影响包含此窗体文件的任何工程。

3. 在工程中删除窗体时,仅将此窗体从工程里删除掉,但是窗体文件 仍存在于磁盘上。但是,如果在VB之外删除一个窗体文件,VB不能更新 此工程文件,当打开此工程时,将显示一个文件丢失的错误信息。

4. 对窗体文件改名方法 1) 打开工程 “另存为…Form”实现文件的复制——保存工程文件。

2. 制作安装盘 在向导的指导下运行V B6.0中文版工具“Package &

Deployment”; “打包”:把工程中用到的各种类型的文件进行打包压缩后,存 放到特定的目录下。

“展开”:再把这些打包的文件展开到用户可以携带的安装介质 软盘、光盘等。

? 运行模式[运行] 执行“运行/启动”命令,可以查看程序代码,但不能修改 ? 。

? 中断模式[中断] 当在运行模式,按了“中断”命令或当程序出现运行时错误 时进入中断模式。可以查看代码、修改代码、检查数据。(2)调试窗口有三个调试窗口,它们是:“立即”窗口、“监视”窗口、和 “本地”窗口。可单击视图菜单中的对应命令打开这些窗口。 (3)设置断点和逐语句跟踪断点是告诉VB挂起程序执行的一个标记,当程序执 行到断点处即暂停程序的运行,进入中断模式。设置或 删除断点的步骤:

中断模式下,直接查看某个变量的值,只要把鼠标指 向所关心的变量处,稍停一下,就在鼠标下方显示该变 量的值。断点标记当前行 2.8 常 见 错 误1. 使用中文标点符号 系统产生“无效字符”,以红色显示。

2. 字母和数字形状相似 小写字母“l”和数字“1”形式相同、小写字母“o”与数字“0”。

3. 对象名称(Name)属性写错 Text1、Text2、Command1 txtInput、txtOutput、cmdOk 4. 对象的属性名、方法名、标准函数名写错 尽量使用自动列出成员功能。正确的系统按规定的大小写表示。

5. 无意形成控件数组 建立控件时小心使用“复制”、“粘贴”按钮。

6. 打开工程时找不到对应的文件 保存文件时先保存窗体.frm文件、再保存.vbp文件,注意路径。 第三章 VB语言基础 (2学时)3.1 3.2 3.3 3.4 3.5 3.6 编码规则 数据类型 变量与常量 运算符和表达式 常用函数 常见错误 3.1编 码 基 础1. VB代码不区分字母的大小写 系统保留字自动转换每个单词的首字母大写; 用户自定义行以第一次为准。

2. 语句书写自由 一行可书写几句语句,之间用冒号分隔; 一句语句可分若干行书写,用续行符_连接一行<=255个字 符。

3. 注释有利于程序的维护和调试 Rem开始 或 单撇号

4. 保留行号与标号 3.2标准数据类型数 据 类 型 3.3 变量与常量一、变量和常量的命名规则变量:在程序运行中其存储的值可以改变。

常量:在程序运行中其值不可以改变。

命名规则:

1. 以字母或汉字开头,后可跟汉字、字母、数字或下划线 组成,长度小于等于255个字符; 2. 不要使用VB中的关键字; 3. VB中不区分变量名的大小写; 4. 为了增加程序的可读性,可在变量名前加一个缩写的前 缀来表明该变量的数据类型。 二、变量声明 1.用Dim语句显式声明变量形式:Dim 变量名 [AS 类型] Dim 变量名类型符 例 Dim iCount As integer , sAllsum As single 等价于 Dim iCount%, sAllsum!2.隐式声明未进行上述的声明而直接使用,其类型为 Variant 类 型。

建议不使用。

注意: 在通用声明处加 Option Explicit 语句可强制显式声明 变量。 三、常量 1. 用户声明常量形式:

Const 常量名 [AS 类型] = 表达式 省略 [AS 类型] ,常量的类型由表达式值的类型决定。

为使与变量名区分,一般常量名使用大写字母。

例 Const MAX=1002. 系统提供的常量系统定义常量位于对象库中,可通过“对象浏览器”查看。

例:vbNormal vbMinimized、vbbCrLf等 3.4 运算符和表达式 一、运算符1. 算术运算符例:5+10 mod 10 \ 9 / 3 +2 ^2 结果:10 2. 字符串运算符 & 、+ 字符串连接 "

123 "

+ "

456 "

结果 "

123456 "

"

123 "

&

"

456 "

结果 "

123456 "

区别:+ 两边必须是字符串,&

不一定 例如:

"abcdef"

&

12345

结果为 "abcdef12345 "

"abcdef "

+ 12345

出错 "123"

&

456

结果为"

123456 "

“123” + 456

结果为 579 注意:

"123 "

+ True

结果为 122 True转换为数值-1,False转换为数值0 3.关系运算符将两个操作数进行大小比较,结果为逻辑量。

字符串比较,则按字符的ASCII码值从左到右一一比较,直到出现 不同的字符为止.。

例:

"ABCDE "

>

"

ABRA ""男字"结果为 False>

"女字"

按汉字的拼音字母比较 4. 逻辑运算符将操作数进行逻辑运算,结果是逻辑值:

条件表达式1 And 条件表达式2T; 条件表达式均为T, 结果为 条件表达式有一个为T 结果为条件表达式1 Or 条件表达式2 T。 二、表达式1. 组成变量、常量、函数、运算符和圆括号。

2.书写规则 (1) 运算符不能相邻。例a+ -b是错误的。

(2) 乘号不能省略。例x 乘以y 应写成:x*y。

(3) 括号必须成对出现,均使用圆括号。

(4) 表达式从左到右在同一基准上书写,无高低、大小。

3. 不同数据类型的转换 运算结果的数据类型向精度高的数据类型靠。

Integer<Long<Single<Double<Currency 4. 优先级 算术运算符>=字符运算符>关系运算符>逻辑运算 表达式书写举例abcd efga*b*c*d/e/f/ge10 + ln 10 sin 45o + x + y +1或a*b *c*d/(e*f*g)sin(45*3.14/180)+(exp(10)+log(10))/sqr(x+y+1) 例:用人单位招聘秘书:年龄小于40岁的女性,专科或本科, 年龄<40,性别=“女”,(=“专科”,=“本科”) And And Or 考虑:若分别写成:

年龄<40 And 性别= "女"

And (= "专科"

And = "本科") 年龄<40 Or 性别= "女"

Or (= "专科"

Or = "本科") 例:表示算术表达式:

3 ≤ x ≤ 7 正确的VB表达式:

3〈=x And x <=7 错误的VB表达式:

3<=x<=7a 小数或 3<=x Or x<=7b 大数比a小,比b大 用 Or 比a大,比b小 用 Anda 小数b 大数 3.5 常用内部函数1. 数学函数 Rnd函数返回0和1(包括0但不包括1)之间的双精度随机数。

每次运行时,要产生不同序列的随机数,执行Randomize 语 句。

例产生1~100的随机数:

Int(Rnd *100)+1 2. 转换函数 Chr(66) "B"

Asc ("B") 66 Asc(Chr(99)) 99 Chr(Asc("K")) "K"

Ucase$("abcdefg") "ABCDEFG"

3.日期函数 Time返回系统时间、Date返回系统日期、Now返回系统日期和时间 DateAdd(要增减日期形式,增减量,要增减的日期变量) DateDiff(要间隔日期形式,日期1,日期2) 例如求离你毕业还有多少天:

DateDiff("d",date, #2006/07/01# )假定2006年毕业 4. 字符串编码和函数(1)字符串编码 Windows系统对字符采用了DBCS编码,中文2字节,西文1字节 VB中字符Unicode编码,任何字符2字节。

Len(“中国good ”)为6;LenB(“中国good ”)为12。

StrConv() 进行DBCS与Unicode之间转换。

(2)字符串函数 Mid$("ABCDEFG",2,3) InStr(2, "ABCDEFG", "EF") S=Split("123,56,ab",",") Join(S,"") "123 56 ab"

“AB123AB123” "BCD"

5 S(0)="123”,S(1)="56”,S(2)="ab"Replace("ABCDABCD","CD","123") 5. 格式输出函数 例3.1 利用Format函数显示有关的日期和时间。

Private Sub Form_Click( ) FontSize = 12 MyTime = #9:21:30 PM# MyDate = #7/21/1997# Print Tab(2);

Format(MyDate, "m/d/yy") Print Tab(2);

Format(MyDate, "mmmm-yy") Print Tab(2);

Format(MyTime, "h-m-s AM/PM") Print Tab(2);

Format(MyTime, "hh:mm:ss A/P") Print Tab(2);

Format(Date, "dddd,mmmm,dd,yyyy") Print Tab(2);

Format(Now, "yyyy年m月dd日 hh:

mm") Print FormatDateTime(Now)

VB6.0新提供的函数 End Sub 6. Shell函数Shell函数负责执行一个可执行文件,返回一个Variant,如果成 功,代表这个程序的进程ID,若不成功,则会返回0。

形式:Shell(命令字符串,窗口类型) 窗口类型值为1表示正常窗口,缺省窗口最小化为图标。

i = Shell("c:\windows\calc.exe") j= Shell("c:\command.com", 1)提示:如果不知道应用程序的路径名,可用Start命令启动程序 i = Shell(start &

"calc.exe") ; i = Shell(start &

"

vb6.exe ") 3.6常 见 错 误1. 逻辑表达式书写错,在VB没有造成语法错而形成逻辑错 例如,数学表达式 3≤x<10 VB表达式写为 3<=x<10。

问题在于VB中的逻辑量与数值量可相互转换。

2. 同时给多个变量赋值,在VB没有造成语法错而形成逻辑错 例如:Dim x%,y%,z% x=y=z=1 3. 标准函数名写错 4. 变量名写错 检查方法:在通用声明段加Option Explicit 5. 语句书写位置错 在通用声明段只能有Dim语句,不能有赋值等其他语句 第四章 基本的控制结构 (8学时)4.1 4.2 4.3 4.4 4.5 4.6 顺序结构 选择结构 循环结构 其他辅助控制语句 常用算法(一) 常见错误 (顺序、条件、循环) 4.1一、赋值语句顺 序 结 构形式:[LET]变量名=表达式作用:

将表达式的值赋值给变量名。

一般用于给变量赋值或对控件设定属性值。

例:

sRate!=0.1 Text1.Text = "欢迎使用Visual Basic 6.0 "

当表达式的类型与变量的类型不一致时,强制转换成左边 的精度,如 iA% = 10 / 3 iA中的结果为3 注意:虽然赋值号与关系运算符等于号都用“=”表示,VB 系统会根据所处的位置自动判断是何种意义的符号。 二、与用户交互函数和过程1. InputBox函数InputBox(提示[,标题][,缺省][,x 坐标位置][,y坐标位置]) 其中:提示:

提示信息;标题:

对话框标题;缺省:输入区缺省 值 函数返回字符类型。

例要在屏幕上显示图示的对话框:

相应的语句如下:Dim strName As String * 40strName= InputBox("请输入你的姓名"

+ vbCrLf + "然后单击确定"

, "输入框"

)也可以使用如下语句:

Dim strName As String * 40, strS1 As String * 40 strS1 = "请输入你的姓名"

+ Chr(13) + Chr(10) + "然后单击确定"

strName= InputBox(strS1, "输入框"

, , 100,100) 当键盘输入“王晓明” 后,变量strName获得键盘输入的值。 2. MsgBox函数和MsgBox过程函数形式:变量[%] = MsgBox(提示[,按钮][,标题]) 过程形式:MsgBox 提示[,按钮][,标题]按钮值如下:

值:

函数返回所选按钮整数 例4.1 编一帐号和密码检验程序。

要求:

帐号不超过6位数字,有错,清除原内容再输入。

密码输入时在屏幕上以 “*”代替; 若密码错,显示有关信 息,选择“重试”按钮,清除原内容再输入,选择“取消”按 钮,停止运行。

分析:

帐号6位,MaxLength为6,LostFocus判断数字IsNumeric函 数 密码PassWordChar为“*”,MsgBox函数设置密码错对话 框。 常见错误数据合法性检查中引起程序的死循环 Private Sub Text1_LostFocus() If Not IsNumeric(Text1) Then Text1 = ""

Text1.SetFocus End If End SubText1 Text2Private Sub Text2_LostFocus() If Not IsNumeric(Text2) Then Text2 = ""

Text1.SetFocus End If End Sub确定If Text2 <>

""

And Not IsNumeric(Text2) 4.2选 择 结 构1. If…Then语句(单分支结构) If <表达式>

Then 语句块 End If 或 If <表达式>

Then <语句>例:已知两个数x和y,比较它们的大 小, 使得x大于y. If x<y Then t=x x=y y=t End If 或 If x<y Then t=x: x=y: y=t 重要的是学会两个数的交换,若上述语句次序变一下,结果如何? 2. If…Then…Else语句(双分支结构)If <表达式>

Then <语句块1>

Else <语句块2>

End If If <表达式>

Then <语句1>

Else <语句2>?sin x + x 2 + 1 x ≠ 0 ? 计算分段函数:

y = ? ?cos x ? x 3 + 3x x = 0 ? 单分支结构实现:

y=cos(x)-x^3+3*x If x<>0 Then y=sin(x)+sqr (x*x+1) 双分支结构实现:

If x<>0 Then y=sin(x)+sqr (x*x+1) Else y=cos(x)-x^3+3*x End If 3. If…Then…ElseIf语句(多分支结构)形式:

If <表达式1>

Then <语句块1>

ElseIf <表达式2>Then <语句块2>

… [Else 语句块 n+1 ] End If 例4.2 已知变量strC中存放了一个字符,判断该字符是字母字 符、数字字符还是其他字符。

用多分支结构实现: If Ucase(strC) >="A"

And Ucase (strC) <="Z"

Then Print strC + "是字母字符"

ElseIf strC >="0"

And strC <="9"

Then Print strC + "是数字字符"

Else Print strC + "其他字符"

End If 不管有几个分支,依次判断,当某条件满足,执行相应的语句, 其余分支不再执行;若条件都不满足,且有Else子句,则执行该 语句块,否则什么也不执行。. ElseIf不能写成 Else If。

例4.2a 根据边长判断三角形类型 例4.3 已知百分制成绩mark,显示对应的五级制成绩 哪些正确,哪些错误?方法一 方法二 If mark >= 90 Then If mark <

60 Then Print "优"

Print "不及格"

ElseIf mark >= 80 Then ElseIf mark <

70 Then Print "良"

Print "及格"

ElseIf mark >= 70 Then ElseIf mark <

80 Then Print "中"

Print "中"

ElseIf mark >= 60 Then ElseIf mark <

90 Then Print "及格"

Print "良"

Else Else Print "不及格"

Print "优"

End If End If 方法三 If mark >= 60 Then Print "及格"

ElseIf mark >= 70 Then Print "中"

ElseIf mark >= 80 Then Print "良"

ElseIf mark >= 90 Then Print "优"

Else Print "不及格"

End If返回72 4.If语句的嵌套 If语句的嵌套是指If或Else后面的语句块中又包含If语句。

形式如下:

F x<y If <表达式1>

Then T If <表达式11>

Then … x 与 y 交换 End If x >y … End If F x >

y>

z y<z 例4.4 已知x,y,z三个数,使得x>y>z用一个IF语句和一个嵌套的IF语句实现T y 与 z 交换 z 为最小数 FIf x<y Then t=x: x=y: y=t If y<z Then t=y: y=z: z=t If x<y Then t=x: x=y: y=t End If End Ifx<

yT x 与 y 交换 使 得 x >yIf语句的嵌套注意事项:书写锯齿型; If 与End If配对。 5. Select Case语句(情况语句)形式:Select Case 变量或表达式 Case 表达式列表1 语句块1 Case 表达式列表2 语句块2 … [Case Else 语句块n+1] End Select<表达式列表>:与<变量或表达式>同类型的下面四种形式之一:

表达式 一组枚举表达式(用逗号分隔) 表达式1 To 表达式2 Is 关系运算符表达式 例: 数值型或字符串表达式"

A"2,4,6,8 60 To 100 Is <

60 例4.5 变量strC中存放了一个字符,判断该字符类型。在例4.2中用多分支结构实现:

If Ucase(strC) >="A"

And Ucase (strC) <="Z"

Then Print strC + "是字母字符"

ElseIf strC >="0"

And strC <="9"

Then Print strC + "是数字字符"

Else Print strC + "其他字符"

End If用Select Case语句实现:Select Case strC Case "a"

To "z","A"

To "Z"

Print strC + "是字母字符"

Case "0"

To "9"

Print strC + "是数字字符"

Case Else Print strC + "其他字符"

End Select 例4.6 已知坐标点(x,y),判断其落在哪个象限。方法一 方法二 If x >

0 And y >0 Then Select Case x,y Case x >

0 And y >

0 Print "在第一象限"

Print "在第一象限"

ElseIf x <

0 And y >

0 Then Case x <

0 And y >

0 Print "在第二象限"

Print "在第二象限"

ElseIf x <

0 And y <

0 Then Case x <

0 And y <

0 Print "在第三象限"

Print "在第三象限"

ElseIf x >

0 And y <0 Then Case x >

0 And y <0 Print "在第四象限"

Print "在第四象限"

End If End Select哪个能实现,哪个不能实现? 方法二代码错误:1. Select Case 后不能出现多个变量; 2. Case后不能出现变量及有关运算符。

返回72 例4.7由计算机来当一年级的算术老师,要求给出一系列的1~10的 操作数和运算符,学生输入该题的答案,计算机根据学生的答案判 断正确与否,当结束时给出成绩。

分析:产生1~10操作数,可通过Int(10 * Rnd + 1) 实现 设置的控件名 Label1 Text1Command1Picture1 6.条件函数(1)IIf函数形式是:IIf(表达式,当表达式为True时的值,当表达式为False时的值) 例如,求x,y中大的数,放入Tmax变量中,语句如下:

Tmax=IIf(x >

y,x,y) (2)Choose函数形式是:

Choose(数字类型变量,值为1的返回值,值为2的返回值……) 例如,Nop是1-4的值,转换成 + 、-、×、÷运算符的语句如下:

Op= Choose(Nop,"+","-","×","÷") 当值为1,返回字符串“+”,然后放入Op变量中,值为2,返回字 符串“-”,依次类推;当Nop是1-4的非整数,系统自动取Nop的整 数办法在判断;若Nop不在1~4之间,函数返回Null值。

(3) Switch函数形式是:

Switch(条件表达式1,条件表达式1为True时的值 [,条件表达式2,条件表达式2为True时的值……]) 常 见 错 误1.在选择结构中缺少配对的结束语句 对多行式的If块语句中,应有配对的 End If语句结 束。

2. 多边选择ElseIf关键字的书写和条件表达式的表示 ElseIf 不要写成Else If; 多个条件表达式次序问题,见例4.3。

3. Select Case语句的使用 Select Case 后不能出现多个变量;Case子句后不 能出现变量,见例4.6。 4.3循 环 结 构循环变量得初值<

循环变量 =终值1. For循环语句 (一般用于循环次数已知) 形式 For 循环变量=初值 to 终值 [Step 步长] 语句块 [Exit For] 循环体 语句块 Next 循环变量 例4.8 计算1~100的奇数和,程序段如下:Dim i %, s% s=0 For i = 1 To 100 step 2 s=s+i Next i 等价于:

Dim i %, s% s=0 :

i = 1 re: If i <= 100 Then s=s+i i = i +2 GoTo re End IfF T语句块Exit For语句块 循环变量加步长 步长>0 初值<终值 =1 时,可省略 <0 初值>终值 =0 死循环循环次数= Int ( 终值 ?初值 + 1) 步长要注意:

出了循环,循环控制变量值的问题。

例程序段:

? 循环执行次数 = Int ( 133 2 + 1) = 4 For i=2 To 13 Step 3 Print i , 输出 i的值分别为: Next i 2 5 8 11 Print : Print “I=“, i 出了循环输出为: I=14 在循环体内对循环控制变量可多次引用;但最好不要对其 赋值,否则影响原来的循环控制规律。 例4.9 改变循环控制变量对循环的影响。

Private Sub Command1_Click() j=0 For i = 1 To 20 Step 2 i=i+3 j=j+1 Print "第";

j;

"次循环i=";

i Next i Print "退出循环后i=";

i End Sub 正常情况:i=1,3,5,7,9,11,13,15,17,19 现在:i=4,9,14,19 例4.10 输出可打印的ASCII码字符与它的编码值。 2. Do…Loop循环语句(用于控制循环次数未知) 形式2:

形式1:

Do Do { While|Until }<条件>

语句块 语句块 [Exit Do [Exit Do 语句块] 语句块] Loop { While|Until} <条件>

Loop表达式列表 1F语句块T语句块 Exit D o 语句块Exit D o 语句块T表达式列表 1F图 1-3-15DoW hile… Loop图 1-3-16Do… LoopW hile 例4.11 我国有13亿人口,按人口年增长0.8%计算,多少年 后我国人口超过26亿。分析:解此问题两种方法,可根据公式:26=13*(1+0.008)n 直接利用标准对数函数求得;也可利用循环求得,程序如下:

Private Sub Command1_Click() x = 13 n=0 Do While x <

26 x = x * 1.008 n=n+1 Loop Print n, x End Sub 例4.12用辗转相除法求两自然数m,n的最大公约数和最小公倍数。

分析:求最大公约数的算法思想:

(1)对于已知两数m,n,使得m>n; (2) m除以n得余数r; (3)若r=0,则n为最大公约数结束;否则执行(4); (4)m n,n r,再重复执行(2)。

例 求 m=14 ,n=6 的最大公约数. If m <

n Then t = m: m = n: n = t r=m mod n Do While (r <>

0) m=n n=r r= m mod n Loop Print "最大公约数=", nm 14 6n 6 2r 2 0辗转相减法 m=m-n m>n n=n-m n>m m=n m、n为公约数 Do While m <>

n m n If m >

n Then 14 6 m=m–n 8 6 Else 2 6 n=n–m 2 4 End If 2 2 Loop 3. 循环的嵌套一个循环体内又包含了一个完整的循环结构称为循环的嵌套. 例4.13打印九九乘法表. For i = 1 To 9 For j = 1 To i For j = 1 To 9 se = i &

"×"

&

j &

"="

&

i * j Picture1.Print Tab((j - 1) * 9 + 1);

se;

Next j Picture1.Print Next i思考:打印上三角或下三角程序如何改动?要打印下三角? 对于循环的嵌套,要注意以下事项:

内循环变量与外循环变量不能同名; 外循环必须完全包含内循环,不能交叉; 不能从循环体外转向循环体内,反之则可以。

正确 错误For ii =1 To 10 For jj=1 To 20 … Next jj Next ii For ii =1 To 10 … Next ii For ii =1 To 10 … Next iiFor ii =1 To 10 For jj=1 To 20 … Next ii Next jj For ii =1 To 10 For ii=1 To 20 … Next ii Next ii 4.4其他辅助控制语句1. Go To 语句 形式: Go To {标号|行号} 作用:无条件地转移到标号或行号指定的那行语句. 标号是一个字符序列,行号是一个数字序列. 2.Exit语句 多种形式:

Exit For、Exit Do、Exit Sub、Exit Function等。

作用:退出某种控制结构的执行。

3. End语句 多种形式:

End、 End If、 End Select、 End With、 End Type、 End Sub、 End Function、 作用:End结束一个程序的运行;其余表示某个结构的结束,与 对应的结构语句配对出现。 4.With 语句With 对象 语句块 End With 作用:对某个对象执行一系列的操作,而不用重复指出对象的 名称。

With Label1 .Height = 2000 .Width = 2000 等价 .FontSize=22 .Caption = "MyLabel"

End With Label1.Height = 2000 Label1.Width = 2000 Label1.FontSize=22 Label1.Caption = "MyLabel"

形式如下: 4.51. 累加、连乘常用算法(一)算法是对某个问题求解过程的描述1~100的5或7的倍数的和 Sum = 0 For i = 1 To 100 If i Mod 5 = 0 Or i Mod 7 = 0 Then Sum = Sum + i End If Next i Print Sum 时会产生什么情况?3~10的乘积 t=1 For i =3 To 10 t=t*i Next i Print t思考:若把循环体前面置各变量初值的语句放在循环体内,程序运行 例4.14 求自然对数e的近似值,要求其误差小于0.00001,近似公式为:m ∞ 1 1 1 1 1 1 e = 1 + + + + ... + + ... = ∑ ≈ 1 + ∑ 1! 2! 3! i! i = 0 i! i =1 i!该例题涉及两个问题:

(1)用循环结构求级数和的问题。本例根据某项值的精度来控制 循环的结束与否。

循环体外对累加和的变量清零 e=0 (2)累加:e=e+t 连乘:n=n*i 循环体外对连乘积变量置1 n=1 Private Sub Form_Click() Dim i%,n&, t!, e! e = 0 : n = 1 ‘ e存放累加和、n存放阶乘 i = 0 : t = 1 ‘ i计数器、t第i项的值 Do While t >

0.00001 e = e + t : i = i + 1 ‘ 累加、连乘 n = n * i : t = 1 / n Loop Print "计算了 ";

i;

"

项的和是 ";

e End Sub 2. 求素数 素数是一个大于2,且不能被1和本身以外的整数整除的整数。

判别某数m是否为素数最简单的方法是: 对于m 从 i=2,3,…,m-1判别m能否被i整除,只要有一个能整 除,m不是素数,否则m是素数。例4.15 求100以内素数的代码:求100以内的素数For m = 2 To 100 For i = 2 To m - 1If (m Mod i) = 0 Then GoTo NotNextMNext i Print m NotNextM: Next mm是否为素数思考:

此例用Go To语句对非素数不作判断,若不用GoTo语句, 如何修改程序? 3.穷举法“穷举法”也称为“枚举法”或“试凑法”,即将可能出现的各 种情况一一测试,判断是否满足条件,一般采用循环来实现。

例4.16 百元买百鸡问题。假定小鸡每只5角,公鸡每只2元,母鸡每 只3元。现在有100元钱要求买100只鸡,编程列出所有可能的购鸡方 案。

设母鸡、公鸡、小鸡各为x、y、z只,根据题目要求,列出方程为:

x+y+y=100 3x+2y+0.5z=100 三个未知数,两个方程,此题有若干个解。

解决此类问题采用“试凑法”,把每一种情况都考虑到。

方法一:最简单三个未知数利用三重循环来实现。

方法二:从三个未知数的关系,利用两重循环来实现。 4.递推法“递推法”又称为“迭代法”,其基本思想是把一个复杂的计算过程转 化为简单过程的多次重复。每次重复都从旧值的基础上递推出新值,并由 新值代替旧值。

例4.17 猴子吃桃子。小猴在某天摘桃若干个,当天吃掉一半多一个;第二 天吃了剩下的桃子的一半多一个;以后每天都吃尚存桃子的一半多一个, 到第7天要吃时只剩下一个,问小猴共摘下了多少个桃子? 分析:这是一个“递推”问题,先从最后一天推出倒数第二天的桃子,再 从倒数第二天的桃子推出倒数第三天的桃子……。设第n天的桃子为xn,那 么它是前一天的桃子数的xn-1 的一半减1,即xn =( xn-1 +1)×2 5.最小、最大值在若干个数中求最大值,一般先假设一个较小的数为最大值的初值, 若无法估计较小的值,则取第一个数为最大值的初值;然后将每一个 数与最大值比较,若该数大于最大值,将该数替换为最大值;依次逐 一比较。

例 随机产生10个100~200之间的数,求最大值。

Private Sub Command1_Click() Max = 100 For i = 1 To 10 x = Int(Rnd * 101 + 100) Print x;

If x >

Max Then Max = x Next i Print Print "最大值=";

Max End Sub 例4.18 实际应用,求最短残料。

有一根长度为321米的钢材料,要将它截取成两种规格a、b的长度分 别为17米和27米的短料,每种至少1段,问分隔成a,b各多少段后, 剩余的残料r最少? 分析,该题利用“试凑法”通过二重循环求残料r的最小值正数,残料 不可能是负数。程序如下:Private Sub Command1_Click() Dim a%, b%, r!, ia%, ib% r = 321 For b = 1 To 321 \ 27 For a = 1 To 321 \ 17 - b t = 321 - b * 27 - a * 17 If t >

0 And t <

r Then r=t ia = a ib = b End If Next a Next b Print ia, ib, r End Sub ‘ 最小值初值取钢材料的长度 ‘ b最多的段数 ‘ a最多的段数 ‘ 当前的残料 ‘ 求最短的残料 ‘ 最短残料时a的段数 ‘ 最短残料时b的段数 4.6常 见 错 误1. 不循环或死循环的问题主要是循环条件、循环初值、循环终值、循环步长的设置有问 题。

2. 循环结构中缺少配对的结束语句 For 少 配对的Next 3. 循环嵌套时,内外循环交叉 4. 累加、连乘时,存放累加、连乘结果的变量赋初值问题 (1)一重循环 在一重循环中,存放累加、连乘结果的变量初值设置应在循环语 句前。

(2)多重循环 这要视具体问题分别对待。 第五章 数 组 (4学时)5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 数组的概念 静态数组及声明 动态数组及声明 数组的基本操作 控件数组 自定义数据类型 常用算法(二) 常见错误 5.11.引例数组的概念例5.1若我们要求一个班100个学生的平均成绩,然后统计高于平均分 的人数。

按以前简单变量的使用和循环结构相结合,求平均成绩程序段如下:aver = 0 For i = 1 To 100 mark = InputBox("输入"

+ i + "位学生的成绩") aver = aver + mark Next i aver = aver / 100 但若要统计高于平均分的人数,则无法实现。mark是一个简单变量,存放的是最后一 个学生的成绩。

已有知识解决方法:再重复输入成绩,带来两个问题:

(1)输入数据的工作量成倍增加; (2)若本次输入的成绩与上次不同,则统计的结果不正确。

解决此问题的根本方法,引入数组,始终保持输入的数据,一次输入,多次使用。 5.21. 静态数组及声明静态数组及声明数组不是一种数据类型,而是一组相同类型的变量的集合,数组必须先声明后使 用。

两类数组:

静态(定长)数组、动态(可变长)数组形式:

Dim 数组名(下标1[,下标2…]) [As 类型] 声明了数组的名、维数、大小、类型 维数:几个下标为几维数组,最多60维。

下标:[下界 To ] 上界 省略下界为0 ,必须为常数。

每一维大小:上界-下界+1 数组大小:

每一维大小的乘积 例:Dim mark(1 to 100) As Integer Dim lArray( 0 To 3, 0 To 4) As Long 等价于: Dim lArray(3, 4) As Long共有 4×5个元素注意:(1)下界缺省为0,也可在重新定义数组的下界。例如:Option Base 1 (2)错误的声明,下标是变量 n =Inputbox("输入n "

):Dim x(n) As Single (3)在数组声明中的下标说明了数组的整体,即每维的大小; 而在程序其他地方出现的下标表示数组中的一个元素。两者写法形式 相同,但意义不同。

例如:

Dim x(10) As Integer

声明了x数组有11个元素 x(10)=100

对x(10)这个数组元素赋值 5.3 动态数组及声明动态数组指在声明数组时未给出数组的大小(省略括号中的下标),当要使用 它时,随时用ReDim语句重新指出数组大小。形式如下:

ReDim 数组名(下标[,下标2…]) [As 类型] 例 Sub Form_Load( ) Dim x( ) As Single 例5.2 求若干个学生的平均分。

…… End Sub 说明:

? Dim、Private、Public变量声明语句是说明性语句,可出现在过程内或通用 声明段;ReDim语句是执行语句,只能出现在过程内。

? 在过程中可多次使用ReDim来改变数组的大小和维数。

? 使用ReDim语句会使原来数组中的值丢失,可以在ReDim语句后加Preserve 参数来保留数组中的数据。使用Preserve只能改变最后一维的大小,前面几维 大小不能改变。

ReDim中的下标可以是常量,也可以是有了确定值的变量。

? 静态数组在程序编译时分配存储单元,动态数组在运行时分配存储单元。n =Inputbox(“输入n”) ReDim x(n) 5.4 数组的基本操作1. 数组元素的赋初值 (1)用循环 For i = 1 To 10 iA(i)=0 Next i (2) Array函数 Dim ib As Variant ib = Array("abc", "def", "67") For i = 0 To UBound(ib) Picture1.Print ib(i);

"

";

Next i注意:

? 利用Array对数组各元素赋值,声明的数组是可调数组或连圆括号 都可省,并且其类型只能是Variant。

? 数组的下阶为零,上界由Array函数括号内的参数个数可决定,也 可通过函数Ubound获得。 2.数组的赋值 在VB6.0中,提供了数组直接对数组的赋值。例如:

Dim a() As Variant, b() As Variant, i% a = Array(1, 2, 3, 4, 5) For i = 0 To UBound(a) ReDim b(UBound(a)) b(i) = a(i) b=a Next i注意:赋值号左边的数组只能声明为Variant的可调数组或简单变量。3. 数组的输出 输出方阵sC中的下三角元素 For i = 0 To 4 For j = 0 To i sc(i, j) = i * 5 + j Print sc(i, j);

"

";

Next j Print

换行 Next I 4. 求数组中最大元素及所在下标 Dim Max As Integer,iMax As Integer Max=iA(1):iMax=1 For i = 2 To 10 If iA(i)>Max Then Max=iA(i) iMax=i End If Next I 5. 将数组中各元素交换 For i =1 To 10\2 t=iA(i) iA(i)=iA(10-i+1) iA(10-i+1)=t Next I 5.5控 件 数 组一组相同类型的控件组成。

它们共用一个控件名,具有相同 的属性,建立时系统给每个元素赋一个唯一的索引号(Index)。

控件数组共享同样的事件过程,通过返回的下标值区分控件 数组中的各个元素。

例:

Private Sub cmdName _Click(Index As Integer)…If Index = 3 then ‘ 处理第四个命令按钮的操作 End If … End Sub1.在设计时建立控件数组在窗体上画出控件,进行属性设置,这是建立的第一个元素 选中该控件,进行“Copy”进行若干次和“Paste”操作建立了所需 个数的控 件数组元素。

进行事件过程的编程。 例5. 3 建立含有四个命令按钮的控件数组,当单击某个命令按钮,分 别显示不同的图形或结束操作。Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 …… "画直线"

Case 1 …… "画矩形"

Case 2 …… "画圆"

Case Else End End Select End Sub控件名 Command1 Command1 Command1 Command1 Picture1Index 0 1 2 3 空白Caption 直线 矩形 圆 结束 —— 2运行时添加控件数组建立的步骤如下:

在窗体上画出某控件,设置该控件的Index值为0,表示该控件为数 组,这是建立的第一个元素。

在编程时通过Load方法添加其余的若干个元素,也可以通过Unload 方法删除某个添加的元素 每个新添加的控件数组通过Left和Top属性确定其在窗体的位置, 并将Visible 属性设置为True。例5.4 利用在运行时产生控件数组,构成一个国际象棋棋盘。

当单击棋格,显示对应的序号,并且将所有棋格颜色变反。 5.6 自定义数据类型一组不同类型变量的集合。相当于C语言中的结构类型;Pascal中 的记录类型。1.自定义类型的定义形式如下:

Type 自定义类型名 元素名:表示自定义类型中的一个成员 元素名[(下标)] As 类型名 下标:表示是数组 … 类型名:为标准类型 [元素名[(下标)] As 类型名] End Type 例如,以下定义了一个有关的自定义类型:

Type StudType No As Integer

学号 Name As String * 20

姓名 Sex As String * 1

性别 Mark(1 To 4) As Single

4门课程成绩 Total As Single

总分 End Type 注意:(1)自定义类型一般在标准模块(.BAS)中定义,默认是Public;在窗体必须是 Private。

(2)自定义类型中的元素类型可以是字符串,但应是定长字符串。

(3)不要将自定义类型名和该类型的变量名混淆,前者表示了如同Integer、 Single等的类型名,后者VB根据变量的类型分配所需的内存空间,存储数据。

(4)自定义类型一般和数组结合使用,简化程序的编写。2.自定义类型变量的声明和使用(1) 声明形式:

Dim 变量名 As 自定义类型名 例 Dim Student As StudType (2) 引用 形式:变量名.元素名 例 表示Student变量中的姓名,第4门课程的成绩,则表示如下:

Student.Name,Student.Mark(4)3.自定义类型数组的应用例5.5 利用自定义类型数组,编写一个输入、显示、查询程序。 5.7 常用算法(二)1. 统计例5.6 输入一串字符,统计各字母出现的次数,不区分字母大小写。分析:

? 统计26个字母出现的个数,先声明一个具有26个元素的数组,每个元素的 下标表示对应的字母,元素的值表示对应字母出现的次数。

? 从输入的字符串中逐一取出字符,转换成大写字符(不区分大小写),进 行判断。

运行界面:For I = 1 To le c = UCase(Mid(Text1, I, 1)) If c >= "A"

And c <= "Z"

Then j = Asc(c) - 65 + 1 a(j) = a(j) + 1 End If Next I 2.大量数据的输入例5.7 输入一系列的数据,并将它们分离后存放在数组中。对 输入的数据允许修改和自动识别非数字数据。

分析:

(2)输入结束利用Rplace函数去除重复输入的分隔符; (3)对利用Split函数按分隔符分离,放到数组中; (4)还可利用Join函数将数组中各元素合并成一个字符串。 3.数组排序(选择法)例5.8 对已知存放在数组中的n个数,用选择法按递增顺序排序。

(1) 从n个数的序列中选出最小的数(递增),与第1个数交换位置; (2) 除第1个数外,其余n-1个数再按(1)的方法选出次小的数,与第2 个数交换位置; (3) 重复(1)n-1遍,最后构成递增序列。

For i = 1 To n - 1 iMin= i For j = i+1 To n If iA(j) <

iA(iMin) Then iMin = j Next j t= iA(i): iA(i) = iA(iMin) : iA(iMin) = t Next I原始数据 a (1 ) a (2 ) a (2 ) a (3 ) a (3 ) a (3 ) a (4 ) a (4 ) a (4 ) a (4 ) a (5 ) a (5 ) a (5 ) a (5 ) a (5 ) a (6 ) a (6 ) a (6 ) a (6 ) a (6 ) 第 1 趟交换后 第 2 趟交换后 第 3 趟交换后 第 4 趟交换后 第 5 趟无交换 2 2 2 2 2 8 6 3 3 3 3 6 9 9 6 6 6 9 3 6 9 7 7 3 8 8 8 8 8 2 7 7 7 9 9 7图 1 .3 .2 5排序过程 排序(冒泡法)例5.9 选择法排序在每一轮排序时找最小(递增次序)数的下标,出了 内循环(一轮排序结束),再交换最小数的位置;而冒泡法排序在每一 轮排序时只要将第一个与其他几个比较,只要次序不对,就交换,出 了内循环,最小数已冒出。排序进行的过程见下表。

For i = 1 To n-1

进行n-1轮比较 For j = i+1 To n

从n~i个元素进行两两比较 If iA(j) <

iA(i) Then

若次序不对,则马上进行交换位置 t = iA(j) : iA(j) = iA(i) : iA(i) = t End If Next j

出了内循环,一轮排序结束,最小数已冒到最上面 Next i 4.数组元素的插入与删除(1) 插入 例5.10 在有序数组a(1 to n)(原有n-1个元素)插入一个值Key元素,算法:

?查找要插入的位置k(1<=k<=n-1) ?腾出位置,把最后一个元素开始到第k个元素往后移动一个位置 ?第k个元素的位置腾出,就可将数据Key插入 ④ ③ ② ①1(2) 删除4710 141316 k192225要找到欲删除的元素的位置k;然后从k+1到n个位置开始向前移 动;最后将数组元素减1。① ② ③ ④ ⑤1471013 k1416192225 5.8 数组中常见错误和注意事项 1.静态数组声明下标出现变量n = InputBox("输入数组的上界") Dim a(1 To n) As Integer 2.数组下标越界 引用的下标比数组声明时的下标范围大或小。

Dim a(1 To 30) As Long, i% a(1) = 1: a(2) = 1 For i = 2 To 30 a(i) = a(i - 2) + a(i - 1) a(0)不存在 Next i 3.数组维数错 数组声明时的维数与引用数组元素时的维数不一致。

Dim a(3, 5) As Long a(i)=10 4.Aarry函数与Split函数使用问题 只能对Variant 的变量或动态数组赋值。

5.获得数组的上界、下界 Ubound 、Lbound函数 第六章 过 程 (5学时)6.1 6.2 6.3 6.4 6.5 6.6 6.7 函数过程的定义与调用 子过程的定义与调用 参数传递 变量、过程的作用域 递归 常用算法(三) 重点和难点 6.1 函数过程的定义除了系统提供的内部函数过程和事件过程外,用户可自定义过程:

b 以Sub保留字开始的为子过程; a S1 以Function保留字开始的为函数过程。

c1. 引例6.1S2area = c (c ? x )( c ? y )( c ? z )e 已知多边形的各条边的长度,要计算多边形的面积。g S3 计算多边形面积,可将多边形分解成若干个三角形。

f 计算三角形面积的公式如下:

x 1dc=2( x + y + z)y z定义函数过程area:

Public Function area(x!, y!, z!) As Single Dim c! c = 1 / 2 * (x + y + z) area = Sqr(c * (c - x) * (c - y) * (c - z)) End Function调用函数过程:

Sub command1_click() …… 输入若干个三角形边长 S=area(a,b,c)+area(c,d,e) S=S+area(e,f,g) Print S End Sub 2.函数过程的定义自定义函数过程有两种方法:

(1)利用“工具”菜单下的“添加过程”命令定义,生成一个函数 的框架。

(2)利用代码窗口直接定义。

函数过程形式:

Function 函数过程名([参数列表]) [As 类型] 局部变量或常数定义 语句块 函数名 = 返回值 函数过程体 [Exit Function] 语句块 函数名 = 返回值 End Function 函数过程名:命名规则同变量名 参数列表形式: [ByVal]变量名[()][As 类型] 称为形参或哑元,仅表示参数的个数、类型,无值。

函数名 = 返回值 在函数体内至少对函数名赋值一次。

[Exit Function] :

表示退出函数过程。 例6.2 定义MyReplace(S,OldS,NewS)函数过程,具有Replace函数功能。

Function MyReplace(s$, OldS$, NewS$) As StringDim i%, lenOldS% lenOldS = Len(OldS) i = InStr(s, OldS) Do While i >

0 i = InStr(s, OldS) Loop MyReplace = s

替换后的字符串赋值给函数过程名

取OldS字符子串长度

在字符串中找有否OldS字符子串

找到用NewS 字符子串替换OldS字符子串

找下一个OldS字符子串s = Left(s, i - 1) + NewS + Mid(s, i + lenOldS)End Function假定S为“abcdefgabcd”,Oolds为“cd”,News为“3”,调用MyReplace函 数的返回值为“ab3efgab3”。上述程序循环执行2次:

(“abcdefgabcd”,“cd”,“3”) 第1 次 i=3 结果 “ab3efgabcd” (“ab3efgabcd”,“cd”,“3”) 第2 次 i=9 结果 “ab3efgab3” 3.函数过程的调用 函数过程调用同标准函数调用,形式:函数过程名([参数列表]) 参数列表:称为实参或实元,它必须与形参个数相同,位置与 类型一一对应。可以是同类型的常量、变量、表达式。程序运行的流程 :Private Sub Command1_Click() s= “VB程序设计教程5.0版” "

VB程序设计教程5.0版"

Print MyReplace(s, "5.0", "6.0") End SubS”5.0””6.0”MyReplace$(s$, OldS$, NewS$)Function MyReplace$(s$, OldS$, NewS$) Dim i%, lenOldS% lenOldS = Len(OldS) i = InStr(s, OldS) Do While i >

0 s= Left(s, i - 1) + NewS + Mid(s, i + lenOldS) i = InStr(s, OldS) Loop MyReplace = s End Function 6.2函数过程的不足:子 过 程(1)不是为了获得某个函数值,而是为了某种功能的处理,如例 1.1。

(2) 要获得多个结果。

1.引例6.3 编写一个两个数交换的过程供多次调用。

Swap (x,y)子过程的定义 主调程序调用Swap子过程 Public Sub Swap(x, y) Private Sub Form_Click() Dim t Dim a, b t=x a = 10 x=y b = 20 y=t Call Swap (a, b) End Sub Print "a=";a,",b=";

b End Sub 2.子过程定义 Sub 子过程名[(参数列表)]局部变量或常数定义 语句 [Exit Sub] 语句End Sub 3.子过程的调用 子过程名 [参数列表] 或 Call 子过程名(参数列表) 4.子过程与函数过程区别:

(1)函数过程名有值,有类型,在函数体内至少赋值一次; 子过程名无值,无类型,在子过程体内不能对子过程名赋值; (2)调用时,子过程调用是一句独立的语句。

函数过程不能作为单独的语句加以调用,必须参与表达式运算。

(3)一般当过程有一个函数值,使用函数过程较直观; 反之若过程无返回值,或有多个返回值,使用子过程较直观。 例6.4分别编一计算某级数部分和的子过程和函数过程,并调用。x x 级数为:

+ x + 1 + ... + + ... 2! n!函数过程实现求部分级数和Function jishu1(x!, eps#) As Double Dim n%, s#, t# n = 1: s = 0: t = 1 Do While (Abs(t) >= eps) s = s + t t = t * x / n n = n + 1 Loop jishu1 = s2nxn 精度为:

<

eps n!子过程实现求部分级数和Sub jishu2(s#, x!, eps#)Dim n%, t# n = 1: s = 0: t = 1 Do While (Abs(t) >= eps) s = s + t t = t * x / n n = n + 1 LoopEnd SubEnd Functionf1 = jishu1(2#, 0.000001)

调用函数过程 Call jishu2(f2, 2#, 0.000001)‘ 调用子过程 或 jishu2 f2,2#,0.00001 程序运行流程:Private Sub Command1_Click() Dim f1#, f2# 找函数名调用jishu1 ① f1 = jishu1(2#, 0.000001) 函数名带了值返回 ④ 找子过程名调用jishu2 ② Function jishu1(x!, eps#) As Doubl … jishu=表达式 ③ End Function ⑥ Sub jishu2(s#, x!, eps#) … ⑦ ⑧ s=表达式 End Sub⑤Call jishu2(f2, 2#, 0.000001) Print "f1=";

f1, "f2 = ";

f2 End Sub 6.3 参数传递指主调过程的实参传递给被调过程的形参。

1. 传址与传值 传址:

形参得到的是实参的地址,当形参值的改变同时也改变实参的值。

传值:

形参得到的是实参的值,形参值的改变不会影响实参的值。

例6.5 两个变量的交换。

Sub Swap2(x%, y%) Sub Swap1(ByVal x%, ByVal y%) t% = x: x = y: y = t t% = x: x = y: y = t End Sub End Sub Private Sub Command1_Click() 传地址 ByVal 传值 a% = 10: b% = 20: Swap1 a, b 传值 a a Print "A1=";

a, "B1=";

b 实参 10 10 a = 10: b = 20: Swap2 a, b 传址 x x Print "A2=";

a, "B2=";

b End Sub 形参 10 a 的地址 例6.6 求若干个数的最大公约数。 2. 数组参数的传递当参数是数组通过传址方式进行传递。注意:

? 在实参和形参中写数组名,忽略维数的定义,但圆括号不能省。

? 被调过程可通过Lbound和Ubound函数确定实参数组的下、上界。

Lbound和Ubound函数的形式如下:

{L|U}bound(数组名[,维数]) 其中:维数指明要测试的是第几维的下标值,缺省是一维数组。

例 6.7 编一函数tim,求任意一维数组中各元素之积。

调用tim,求 t1 = ∏ aii =1 5和 t 2 = ∏ bii =38Function tim(a() As Integer) Dim t#, i% t=1 For i = Lbound(a) To Ubound(a) t = t * a(i) Next i tim = t End Function调用:

Sub Command1_Click() Dim a%(1 To 5),b%(3 To 8) … t1# = tim(a()) t2 #= tim(b()) Print t1, t2 End Sub 使用过程注意事项:1. 确定自定义的过程是子过程还是函数过程 函数过程名有值,子过程名无值。

2.过程中形参的个数和传递方式的确定 过程中参数的作用是实现过程与调用者的数据通信。

(1)从主调程序获得初值,值传递。

(2)将结果返回给主调程序,地址传递。

3. 实参与形参结合时对应问题 个数、类型、位置、次序一一对应。

形参是值传递,对应实参可以是表达式、常量、数组元素。

形参是地址传递,对应实参只能是简单变量。

数组、记录类型、对象只能是地址传递。 实验6.2子过程DeleStr(s1,ByVal s2 As String)形参的确定s1,要处理的字符串,从主调程序得初值,删除子串后结果在s1 中,所以用地址传递。

s2删除的子串,值传递。实验6.3函数过程 MaxLength(s)形参的确定s 要处理的字符串,值传递。

MaxLength函数名,最长的单词长度。实验6.4回文数的判断中形参的确定1. 函数过程,用一个形参,值传递对所判断的数字;函数名是否为回 文数。

Function IsH(ByVal ss As String) As Boolean 2. 子过程,用两个形参,值传递对所判断的数字,地址传递是否为回 文数。

Sub hui(ByVal ss As String, Tag As Boolean) 6.4变量、过程的作用域作用域:变量、过程随所处的位置不同,可被访问的范围。

1.过程的作用域 窗体/模块级:加Private关键字的过程,只能被定义的窗体 或模块中的过程调用。

全局级:加Public关键字(缺省)的过程,可供该应用程序 的所有窗体和所有标准模块中的过程调用。 2. 变量的作用域 局部变量:在过程内用声明的变量,只能在本过程中使用。

窗体/模块级变量:在“通用声明”段中用Dim语句或用 Private语句 声明的变量,可被本窗体/模块的任何过程访问。

全局变量:在“通用声明”段中用Public语句声明的变量,可 被本应用程序的任何过程或函数访问。 例如在下面一个标准模块文件中不同级的变量声明:

Public Pa As integer

全局变量 Private Mb As string *10

窗体/模块级变量 Sub F1( ) Dim Fa As integer

局部变量 … End Sub Sub F2( ) Dim Fb As Single

局部变量 … End Sub 若在不同级声明相同的变量名,系统按局部、窗体/模块、全局次 序访问如: Public Temp As integer

全局变量 Sub Form_Load() Dim Temp As Integer

局部变量 Temp=10

访问局部变量 Form1.Temp=20

访问全局变量必须加窗体名 Print Form1.Temp, Temp

显示 20 10 End Sub 3. 静态变量局部变量声明:

Dim 声明,随过程的调用而分配存贮单元,每次调用都对变量 初始化;过程体结束,变量的内容自动消失,存储单元释放。

Static 声明,每次调用过程,变量保持原来的值。

声明形式:Static 变量名 [AS 类型] Static Function 函数过程名([参数列表]) [As 类型] Static Sub 子过程名[(参数列表)] 过程名前加Static,表示该过程内的局部变量都是静态变量。

例6.9 Private Sub Form_Click() Private Function sum(n As Integer) Dim i% ,isum% Dim j As Integer For i = 1 To 5 j=j+n isum = sum(i) sum = j Print isum End Function Next i End Sub 结果为:1,2,3,4,5 Static j As Integer,结果? 6.5 递归过程的直接调用 Sub f1(x) Sub Command1_Click() Function f2(x) Function f3(x) … …… …… …… Call f1(y) x=f2(xx)*3… f2=f3(x)+3 End Sub End Sub 过程的递归调用 Sub Command1_Click() …… Call f1(y) End Sub Sub f1(x) … Call f1(y) End Sub End Sub f3=x*x End Sub 1.递归的概念 用自身的结构来描述自身就称为“递归”。例对阶乘的定 义:n! = n ? ( n ? 1)! ( n ? 1)! = ( n ? 1) ? ( n ? 2)!2. 递归过程n =1 ?1 例6.10 编fac(n)=n! 的递归函数 fac(n) = ? ?n * fac(n ? 1) n >

1过程在自身定义的内部调用自己。Function fac(n As Integer) As Integer If n = 1 Then fac = 1 Sub Command1_Click() Else Print “fac(4)=”;fac(4) fac = n * fac(n - 1) End Sub End If 结果:

fac(4)=24 End Function 递推fac(4)=4*fac(3) fac(4)=4*6 fac(3)=3*fac(2) fac(3)=3*2 fac(2)=2*fac(1)回归fac(1)=1 fac(2)=2*1在递归处理中,用栈来实现。栈中存放形参、局部变量、返回地址。

递推过程:每调用自身,当前参数压栈,直到达到递归结束条件。

回归过程:不断从栈中弹出当前的参数,直到栈空。

递归算法设计简单,但消耗的机时和占据的内存空间比非递归大。

思考:

若上述fac函数中少了 :

If n = 1 Then fac = 1 即仅有语句:

fac = n * fac(n - 1) 或 n<=0 程序运行将造成何结果?由此可见构成递归的结构如下:

递归结束条件及结束时的值; 能用递归形式表示,并且递归向终止条件发展。 例6.11利用递归求最大公约数? n gcd( m , n ) = ? ?gcd( n, m Mod n )m Mod n = 0 m Mod n ≠ 0Public Function gcd(m As Integer, n As Integer) As Integer If (m Mod n) = 0 Then gcd = n Else gcd = gcd(n, m Mod n) End If End Function Private Sub Form_Click() Print gcd(10, 4) End Sub 分析以下子过程的功能 ,当n=100,r=8,结果是多少? Public Sub f(ByVal n %, ByVal r %) If n >r Then Call f(n \ r, r)

① Print n Mod r;

② End Sub Private Sub Command1_Click() Call f(100, 8) End Subn 12 100 r 8 8 返回地址 2 2显示结果 1 4 4 例6.12 打印分形图 递归常见错误:

1.递归调用出现“栈溢出”在递归调用时,其中的参数要向终止方向收敛。

如下求阶乘的递归函数过程:

Public Function fac(n As Integer) As Integer If n = 1 Then fac = 1 Else fac = n * fac(n - 1) End If End Function Private Sub Command1_Click() Print "

fac(5)= "

;fac(5) Print "

fac(5)= "

;fac(-5)

栈溢出 End Sub 6.6 常用算法(三)1.数制转换例6.13 将一个十进制整数m转换成 r (2~16)进制字符串。

方法:将m不断除 r 取余数,直到商为零,以反序得到结果。 2.例6.14加密和解密 简单加密的思想是:

将每个字母C加一序数K,式子 c=chr(Asc(c)+k), 例如序数k为5,这时 “A” “F”,“a” “f”,“B” “G”… 当加序数后的字母超过“Z”或“z”则 c=hr(Asc(c)+k -26)。

解密为加密的逆过程。返回224 3.查找(1)顺序查找 例6.15。顺序查找根据查找的关键值与数组中的元素逐一比较(数组可无序) Public Sub Search(a() As Variant, ByVal key As Variant, index%) Dim i% For i = LBound(a) To UBound(a) If key = a(i) Then

找到,元素的下标在index中,结束查找 index = i Exit Sub End If Next i index = -1

找不到, index形参的值为-1 End Sub平均查找次数 n/2 (2)二分法查找要查找的数组必须有序。

思想:要查找的关键值Key同数组的中间mid项元素比较: Key<a(mid) high=mid-1 查找区域缩小一半,继续 Key=a(mid) 找到 结束 Low 12 34 56 78 111 222 333 444 555 666 777 888Key>a(mid) low=mid+1 查找区域缩小一半,继续直到找到或查找区域中无元素. 本例用递归实现6.16Sub birsearch(a(), low%, high%, key , index%) mid444 Key high 4.排序选择、冒泡、插入法排序等。

前两种排序欲排序的数据全部输入后,再进行排序; 插入法排序每输入一项,马上插入到数组应在的位置,数组始终有序。

例6.17 实现的步骤:(1)输入欲排序的数据项x;在数组a中找x应所处的位置j;

(2)从数组的最后一个元素开始到下标j依次往后移,使j位置空出; (3)将x放入位置j处,一个数据插入完成; (4)有若干个数重复(1)~(3)。 5. 例6.18 高次方程求根 有牛顿迭代法、二分法、弦截法等 (1)牛顿迭代法 迭代公式:f (x)f ( xi ) xi +1 = xi ? f

( xi )x1x0思想:

对方程给定一个初值x0作为方程的 近似根,利用迭代公式,求得x1, 当x1 ? x0 ≤ εx1为求得的近似根,否则x1作为x0再迭代。 (2) 二分法求根思想:

已知求根区间[a,b]有一根,每次把求根区间缩小一半,直到找到解 或求根区间足够小。

方法:求[a,b]的中点c,判断:

f(c)=0,,c为求得的根,结束; f(a)与f(c)同号,则[a,c]无根,代替a; 否则[c,b]无根,c代替b; 使求根区间缩小一半,重复上述步骤,直到区间小于精度。

Public Function halfRoot(ByVal a!, ByVal b!) Dim c! Do While Abs(b - a) >

0.00001 c = (a + b) / 2 If f(c) = 0 Then Exit Do ElseIf f(a) * f(c) >

0 Then a=c Else b=c End If Loop halfRoot = c End Functionf(x)a a c bx 6.例6.19数值积分 有矩形法、梯形法、抛物线法(又称辛卜生法)等。

梯形法积分的思想是:

将积分区间[a,b]n等分,小区间的长度为, h = b ?f ( x i ) + f ( x i +1 ) si = ×h 第i块小矩形的近似面积为:

2an整个积分的结果为这n块小面积的累加,即 :

n ?1 f ( xi ) + f ( xi +1 ) S ≈∑ × h ≈ ? ( f ( a ) + f (b )) + 2 i =1 ?2? f ( x i )? × h i =1 ? Public Function trapez(ByVal a!, ByVal b!, ByVal n%) As Single Dim sum!, h!, x! h = (b - a) / n sum = (f(a) + f(b)) / 2 For i = 1 To n - 1 x=a+i*h sum = sum + f(x) Next i trapez = sum * h End Function∑n ?1 7.字符串处理 例6.20 编写一个英文打字训练的程序.要求如下:

(1)在标签框内随机产生30个字母的范文; (2)当焦点进入文本框时开始计时,并显示当时时间; (3)在键入文本框按产生的范文输入相应的字母; (4)当键入满了30个字母后结束计时,禁止向文本框输入 内容 ,与范文逐一比较,显示打字的速度和正确率。 6.7重点和难点1. 确定自定义的过程是子过程还是函数过程 函数过程名有值,子过程名无值。过程有一个返回值,则使用函数过程; 若返回多个值或无返回值,一般使用子过程。2.过程中形参的个数和传递方式的确定 过程中参数的作用是实现过程与调用者的数据通信。

(1)从主调程序获得初值,值传递。

(2)将结果返回给主调程序,地址传递。

3. 实参与形参结合时对应问题 个数、类型、位置、次序一一对应。

形参是值传递,对应实参可以是表达式、常量、数组元素。richtextbox vb

形参是地址传递,对应实参只能是简单变量。

数组、记录类型、对象只能是地址传递。 4. 变量的作用域问题 局部变量、静态变量、全局变量特点、作用 5. 递归调用出现“栈溢出” 递归过程中有终止的条件和终止时的值或某种操作; 每递归调用一次,其中的参数要向终止方向收敛。 第七章 常 用 控 件7.1 单选按钮和复选框 7.2 框架 7.3 列表框和组合框 7.4 滚动条和Slide控件 7.5 时钟 7.6 ProgressBar控件 7.7 UpDown控件 7.8 Animation控件 7.9 SSTab控件 7.10 鼠标器和键盘 1. 标准控件内部控件 出现在工具箱上的控件20个。2. ActiveX控件ActiveX部件:是可以重复使用的编程代码和数据。

是由用ActiveX技术创建的一个或多个对象所组成 。

ActiveX部件文件:扩展名OCX,在Windows的SYSTEM目录中。

ActiveX控件 ActiveX文档 ActiveX部件 ActiveX DLL ActiveX EXE ActiveX控件添加到工具箱:

工程/部件 选定控件 常用ActiveX控件所在的文件:ActiveX控件 通用对话框 (CommonDialog) ToolBar StatusBar ProgressBar Slider Animation UpDown Microsoft Windows Common Control-2 6.0 MSCOMCT2 .OCX Microsoft Windows Common Control 6.0 ActiveX部件 Microsoft Common Dialog Control 6.0 文件名 COMDLG32 .OCX MSCOMCTL .OCX ActiveX控件与ActiveX DLL/EXE的区别:

ActiveX控件:

有界面; 用“工程/部件”命令加载; 工具箱上有图标。

ActiveXDLL/EXE:

没有界面; 用“工程/引用”设置引用; 工具箱上没有图标。3. 可插入对象Windows应用程序的对象; 可插入对象可添加到工具箱上; 同标准控件一样使用。

例如:Microsoft Excel工作表。 7.1 单选钮和复选框 Caption属性:文本标题。

Alignment属性 0:控件钮在左边,标题显示在右边。

1:控件钮在右边,标题显示在左边。

Value属性单选钮(逻辑型) 检查框(数值型)True:选定 0--Unchecked:未被选定 False:未选定 1--Checked:选定 2--Grayed:灰色,禁止选择 Style属性 0--Standard:标准方式 1--Graphical:图形方式 事件:Click 因为单击时自动改变状态,故不需要编写过程。例7.1 用单选钮和检查框设置文本框的字体。 7.2 框架(Frame)设Caption为 "字体"框架框架内控件的创建方法:

方法1:单击工具箱上的工具,然后用出现的“+”指针,在框架 中适当位置拖拉出适当大小的控件。

不能使用双击工具箱上图标的自动方式。

方法2:将控件“剪切”到剪贴板,然后粘贴(Ctrl+V)到框架。 Caption属性:框架标题 Enabled属性 False:标题呈灰色,不允许对框架内的对象进行操作。

Visible属性 True:框架及其控件可见。

False:框架及其控件被隐含起来。

Click、DblClick事件:

一般不需要编写框架的事件过程。例7.2 框架用法示例。 7.3 列表框和组合框列表框各主要属性的值:List1 List1.ListIndex = 3 (下标从0开始的) List1. ListCount = 5 List1. Selected(3) = True,其余为False。

List1. Sorted = False,没有排序。

List1. Text 为 “cox” , 与List1. List(List1. ListIndex)相等 Combo1下拉式组合框 简单组合框 下拉式列表框列表框各主要属性的值:List1.ListIndex = 0 List1. ListCount = 8 List1. Selected(3) = True 其余为False。

List1. Sorted = False List1. Text 为 “李宁” 1. 共有的重要属性 (P:可在程序中设置或引用,D:可在设计状态设置。) List :PD 字符型数组,存放列表框的项目,下标是从0开始。

ListIndex:P 选中的项目的序号,没有项目被选定时为-1 ListCount:P 项目的数量,ListCount-1是最后一项的下标。

Sorted:D True:按字母顺序排列。

False:按加入先后顺序排列。

Text:P 列表项中被选定的内容, List 1.List(List 1.ListIndex) = List1.Text。 2. 列表框的特有属性 Selected:P逻辑数组。

Selected(i)的值为True表示第i+1项被选中。MultiSelect0-None:禁止多项选择。

1-Simple:简单多项选择。

2-Extended:扩展多项选择。3. 列表框的特有属性Style类型 下拉式组合框 简单组合框 下拉式列表框 Style 0 1 2 输入 能 能 不能 4. 方法AddItem 对象.AddItem item [, index] RemoveItem 对象.RemoveItem index Clear 对象.Clear5. 事件列表框:Click、DblClick。

组合框:Click,只有简单组合框才有DblClick事件。

一般不需要编写Click事件过程。

通常在单击命令按钮或发生DblClick事件时才读取Text属 性。 例7.3 对列表框进行项目添加、修改和删除操作。例7.4 对列表框进行项目添加、修改和删除操作。Check1 Combo1 Text1Check2 Option1 Option2 7.4 滚动条和Slider控件垂 直 滚 动 条 水 平 滚 动 条 SmallChange Min Value Max SmallChange Slider 控 件Min 属性 Max 属性 SmallChange 属性 LargeChange 属性LargeChange LargeChange共同具有的重要属性 Max:最大值 -32 768~32 767 Min:最小值 -32 768~32 767 SmallChange 最小变动值,单击箭头时移动的增量值。

LargeChange 最大变动值,单击空白处时移动的增量值。

Value 滑块所处位置所代表的值。 事件:

Scroll:拖动滑块时会触发Scroll事件。

Change:Value属性改变时触发Change事件。

属性 Interval属性 单位:ms(0.001s),0.5秒是500。

Interval=0:屏蔽计时器。

Enabled属性 True:有效计时 False:停止时钟工作 事件 Timer例7.8 定时的闹钟 例7.9 蝴蝶飞舞 7.6 ProgressBar控件Max 属性 Min 属性 MousePointer 属性 BorderStyle 属性 Appearance 属性 Orientation 属性 Scrolling 属性位于Microsoft Windows Common Control 6.0部件。重要属性:Max、Min:该控件的界限。

Value:决定控件被填充多少。例7.10 用进度条指示一个大数组的计算进度。 7.7 UpDown控件位于Microsoft Windows Common Control-2 6.0。

通常与伙伴控件 “捆绑”在一起使用。BuddyControlBuddyPropertyValue IncrementMinMaxUpDown应用示例。 7.8 Animation控件位于Microsoft Windows Common Control-2 6.0。

属性:

Center:决定是否在控件的播放。

AutoPlay属性:决定在用Open方法打开文件时是否自动播 放。

方法:

Open:打开文件; Play:

播放; Stop:

停止播放; Close:关闭文件。

例7.11 为例7.10配上。 7.9 SSTab控件位于Microsoft Tabbed Dialog Control 6.0。重要属性:Style:选项卡样式; Tabs:

选项卡总数; TabsPerRow:每一行选项卡的数目; Rows:选项卡总行数; TabOrientation:选项卡的位置; ShowFocusRect:决定选项卡上的焦点矩形是否可视; Tab:当前选项卡的序号。序号从0开始,如果Tab为1, 则第 二个选项卡为当前活动的选项卡。例7.12 选项卡制作示例。 7.10 鼠标器和键盘1. 鼠标器事件 注意:鼠标事件发生在什么对象上,是窗体上还是控件上。

MouseDown事件Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)(发生在窗体上的事件过程)MouseUp事件Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) (发生在窗体上的事件过程)MouseMove事件Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) (发生在窗体上的事件过程) (1) Button参数b2 b1 b0B0为1:按下了左键; B1为1:按下了右键; B2为1:按下了中键。

例如:Button为2(010B),即B1 为1,表示按下了右键; 如果按了左键,则B0为1, B1和B2为0, Button为1(001B)If Shift = 1 Then 或者 If Shift = vbLeftButton Then …

这是按了左健后执行的代码 … Endif使用符号常数:1—vbLeftButton:用户按下左键触发了鼠标事件; 2—vbRightButton:用户按下右键触发了鼠标事件; 4—vbMiddleButton:用户按下中键触发了鼠标事件。 (2) Shift参数b2 b1 b0B0为1:按下了Shift键; B1为1:按下了Ctrl键; B2为1:按下了Alt键。

例如:Button为2(010B),即B1 为1,表示仅按下了Shift键; 如果同时按了Ctrl和Shift键,则B0和B1为1,B2为0,Button为3(011B) 注意:

可能同时按下两个或三个键。如果Button<>1成立,并不表示没有按下Shift,因为可能其他键也被按下了。如果要测试按下了某个键,则应用and进行 位运算。例如Button and 1成立,表示肯定按下了Shift(可能其他键也被按下 了)。

If Shift = 1 and Button = 2 Then …

这是仅按住Ctrl了健单击鼠标后执行的代码 … End If思考:

Shift = 1 and Button and 2 表示什么意义? 符号常数:

1—vbShiftMask; 2—vbCtrlMask; 4—vbAltMask 。

Shfit And vbCtrlMask为真:

例7.14 画圆程序。

按下鼠标右键画圆,按下鼠标左键移动时画线。

在画线时用note14.ico作为鼠标的指针。 2. 键盘事件KeyPress事件过程 Sub Form_KeyPress(KeyAscii As Integer) Sub object_KeyPress([index As Integer,]KeyAscii As Integer) KeyDown事件过程 Sub Form_KeyDown(keycode As Integer, shift As Integer) Sub object_KeyDown([index As Integer,]keycode As Integer, shift As Integer) KeyUp和KeyDown事件过程 Sub Form_KeyUp(keycode As Integer, shift As Integer) Sub object_KeyUp([index As Integer,]keycode As Integer, shift As Integer)参数说明Shift与鼠标事件过程Shift相同。

KeyCode:键盘扫描码; K A ii 字符ASCII码 区别KeyDown和 KeyUp 输入一个ASCII字符 按任意一个键 KeyAscii接收到 字符的ASCII值 事件发生一次 97 65 KeyCode接收到 键的扫描码 事件发生两次 第一次是17 第二次是65 第一次是17 第二次是65 KeyPress事件发生的时间 参数值 按Shift+A时 事件发生的次数 按Shift+A时参数值 (键盘处于大写状态) 按Shift+A时参数值 (键盘处于小写状态) 窗体的KeyPreview为True 焦点在控件上输入窗体的:

KeyPress KeyDown KeyUp控件的:

KeyPress KeyDown KeyUp在这里作一点修改 影响所有控件在这里作一点修改 影响一个控件假定窗体KeyPreview为True,并有下面事件过程, 则当文本框中输入“1”时,实际上是得到的是“3”Sub Form_KeyPress(KeyAscii AsInteger) KeyAscii = KeyAscii + 1 End Sub Sub Text1_KeyPress(KeyAscii As Integer) KeyAscii = KeyAscii + 1 End Sub?窗体KeyPreview为False时在文本框中输入“1”时,实际上 得到的是什么。 对输入的数据进行验证、限制和修改1. 修改输入数据 接收大写字符。将KeyPreview设置为True时:Sub Form_KeyPress(KeyAscii As Integer) If KeyAscii >= Asc("a") And KeyAscii <= Asc("z") Then KeyAscii = KeyAscii + Asc("A") - Asc("a") End If End Sub如果把它改为某个控件的事件过程,效果一样吗? 2. 限制数据输入 文本框只能接收“0”~“9”的数字字符。Sub txtExample_KeyPress(KeyAscii As Integer) If KeyAscii <

48 Or KeyAscii >

57 Then KeyAscii = 0 End If End Sub 例7.15 编写一个程序,当按下Alt+F5时终止程序的运行。先把窗体的KeyPreview设置为True,再编写如下的程序:

Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) 按下Alt键时,Shift的值为4 If (KeyCode = vbKeyF5) And (Shift = 4) Then End End If End Sub 例7.16 “锤打红心”游戏Image1Image2(1) 利用上、下、左、右四个箭头键控制“铁锤” :

“ ”:37(&H25) “ ”:38(&H26) “ ”:39(&H27) “ ”:40(&H28) (2) 如 果 Abs(Image1.Left - Image2.left <

300) And Abs(Image1.Top Image2.Top <

320)成立,则认为是重叠,“铁锤”锤打到“红心”。

(3) 在窗体上的时钟控件(Timer1)过程中控制“红心”移动。Timer1的Interval 属性为200,即每1秒产生5个Timer事件。 3.拖放 自动拖放手工拖放 (1DragMode属性 0:(缺省),手工拖动模式 ; 1:自动拖动模式 。

( 2 )DragIcon属性 拖动过程中显示的图标(Ico或Cur文件)。

lblExample1.DragIcon=LoadPicture ("C:\Icons\Mail.ico") lblExample2.DragIcon=picIcon.Picture ( 3 ) Drag方法 当DragMode为0时,需用Drag方法启动拖放。

[控件名称.]Drag 参数 0:开始拖放操作; 1(省略):结束拖放操作; 2:取消拖放操作。 例7.17 拖放应用示例。例7.18 拖放应用示例。 4. OLE 拖放 OLEDragMode属性(源控件设置):

0----Manual:缺省,手工; 1----Automatic:自动。

OLEDropMode属性(目标控件设置):

0----None:缺省,目标控件不接受“放”; 1----Manual:手工实现“放”操作; 2----Automatic:自动实现“放”。

完全支持自动OLE拖放:

PictureBox Image TextBox。

示例 支持自动“拖”操作,不支持自动“放”:

ComboBox FileListBox DirListBox和ListBox。

示例 只支持OLE拖放事件的控件有:

CheckBox Frame OptionButton、 Label DriveListBox CommandButton 例7.19从Windows资源管理器把文件的文件名拖到标签 上。OLEDropMode为1(Manual)Sub Label1_OLEDragDrop(Data As DataObject, Effect As Long, _ Button As Integer, Shift As Integer, X As Single, Y As Single) Label1.Caption = Data.Files(1)

在资源管理器中选定文件且拖出时,系统就把所选定的文件名

保存在Data对象的Files属性中,Files属性实质上是一个数组 Label1.Caption = Data.Files(1)将保存的第一个文件名显示在标签 中 End Sub 第八章 界 面 设 计(3学时)8.1 通用对话框 8.2 菜单设计 8.3 多重窗体和多文档界面 8.4 工具栏和状态栏 8.5 RichTextBox控件 8.6 应用程序向导 8.1 通用对话框(CommonDialog)通用对话框添加到工具箱:工程/部件 打开通用对话框:

选定 部件标签通用对话框的类型 打开(Open) 另存为(Save As) 颜色(Color) 字体(Font) 打印机(Printer) 和帮助(Help)选定Microsoft CommDialog Control 6.0Action 1 2 3 4 5 6 方法 ShowOpen ShowSave ShowColor ShowFont ShowPrinter ShowHelp确定属性Action:打开通用对话框。

DialogTiltle:对通用话框标题。

CancelError True:选择“取消”按钮,出现错误警告; Err.Number置为32755(cdCancel)。

False(缺省):选择“取消”按钮,没有错误警告。 1.文件对话框(打开、保存)需设置的属性InitDirFileName FilterIndexFilter “打开”文件对话框属性页DialogTiltle FileName InitDir Filter DefaultExt FilterIndex属性 FileName:包含路径; FileTitle:不包含路径。

Filter:例如,Documents(*.DOC)|*.DOC|Text Files(*.TXT)|*.txt|All Files|*.*FilterIndex:决定在文件类型列表框中显示第几组类型的文件。

InitDir:初始化路径。 例8.1 用命令按钮的Click事件显示文件打开对话框。

CommonDialog1.InitDir= "C:\Windows "

CommonDialog1.Filter = "文本文件 | *.Txt"

CommonDialog1.CancelError = True CommonDialog1. ShowOpen 2. “另存为”对话框 没有提供真正的存储文件操作,仍需要编程完成储存操作。

属性 DefaultExt:缺省扩展名。

3. “颜色”对话框 属性 Color:返回或设置选定的颜色。

例8.2 “颜色”对话框的使用。

设置初始目录

过滤文件类型

控制取消按钮

打开对话框 4.“字体”对话框FontName FontBold、FontItalic FontSizeMin、MaxFontStrikethru FontUnderline ColorFlags属性:指示所显示的字体类型,必须设置。cdlCFScreenFonts cdlCFPrinterFonts cdlCFBoth&H3 cdlCFEffects &H1 屏幕字体 &H2 打印机字体 打印机字体和屏幕字体。

&H100 显示删除线和下划线检查框以及颜色组合框例8.3 字体对话框的使用。 5. “打印”对话框 属性 FromPage:起始页号; ToPage:终止页号; Copies:打印份数。如果打印驱动程序不支持多份打印,该属性有可能始终返回 1。例8.4 打印对话框的使用。

6. “帮助”对话框 帮助文件需要用其他的工具制作,如Microsoft Windows Help Compiler。

步骤:

1.在菜单设计时,加入一个菜单项,其Index为0(菜单数组), Visual为False。

2.在程序运行时,通过Load方法向菜单数组增加新的菜单项。

例8.7 在8.6中的文件菜单中保留最近打开的文件清单。

同样,要删除所建立的菜单项,使用UnLoad方法向菜单数组 减少菜单项。 三、 弹出菜单(快捷菜单)弹出菜单是独立于窗体菜单栏而显示在窗体内的浮动菜单。显 示位置取决于单击鼠标键时指针的位置。设计与普通菜单相同(如 果 不 希 望 菜 单 出 现 在 窗 口 的 顶 部 , 该 菜 单 名Visible 属性设置为 False )。菜单弹出的方法:[对象.]PopupMenu 菜单名, 标志, x, y标志,表示弹出的位置和触发的键Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = 2 Then PopupMenu EditMenu, vbPopupMenuCenterAlign End Sub例8.7弹出菜单。 8.3 多重窗体和多文档窗体一、多重窗体 1. 添加窗体“工程|添加窗体” 现存新建添加“现存”窗体时要注意:

防止多个窗体的Name相同而不能添加; 添加的窗体实际是将其他工程中已有的窗体加入,多个工程共 享窗体; 通过“另存为”命令以不同的窗体文件名保存,断开共享。2.保存窗体一个工程中有多个窗体,应分别取不同文件名保存在磁盘上, VBP工程文件中记录了该工程的所有窗体文件名。 3. 设置启动窗体“工程/属性” “启动对象”设置启动对象4. 窗体语句 (1)Load语句:装入窗体到内存但没有显示窗体 形式:

Load 窗体名称 (2)Unload语句:从内存删除窗体 形式:

Unload 窗体名称 5. 窗体方法 (1)Show方法:显示一个窗体(当窗体没有Load,自动Load) [窗体名称].Show [模式] 0 - Modal:关闭才能对其他窗体进行操作。

1 - Modeless,可以对其他窗体进行操作。

(2) Hide方法:隐藏窗体,没有Unload删除 [窗体名称.] Hide 6. 不同窗体间数据的存取 (1)存取控件的属性 另一窗体名.控件名.属性 (2)存取变量的值 另一窗体名.全局变量名 例8.8 输入和计算学习成绩。模块:

Public MATH As Single Public PHYSICS As Single Public CHEMISTRY As Single Public CHINESE As Single Public ENGLISH As Single 二、 多文档界面(MDI)例8.9 1. 创建和设计MDI窗体及其子窗体(1) 创建和设计MDI窗体 创建:

“工程/添加MDI窗体”命令标准窗体 MDI 窗体 MDI 子窗体(v6b8-1)设计:一般有菜单栏、工具栏、状态栏 (2) 创建和设计MDI子窗体 创建:

MDI子窗体是一个MDIChild属性为True的普通窗体。

要创建多个子窗体,通过窗体类来实现:Public Sub FileNewProc() Dim NewDoc As New frmMDIChild No = No + 1 MDI子窗体的Name NewDoc.Caption = "no"

&

No NewDoc.Show End Sub设计:可有菜单栏,但必须有文本框。 2. MDI窗体与子窗体的交互 (1)活动子窗体和活动控件 MDI窗体的两个属性:ActiveForm 和ActiveContro。l 例:将子窗体的文本框中所选文本复制到剪贴板上。

ClipBoard.SetText frmMDI.ActiveForm.ActiveControl.SelText (2)显示MDI窗体及其子窗体 显示任何窗体的方法为show,还有有关规则:

?加载子窗体时,其父窗体会自动加载并显示;反之则无。

?MDI窗体有AutoShowChildren属性,决定是否自动显示子窗体。

(2)排列窗口 利用Arrange方法进行层叠、平铺和排列图标。

形式:

MDI窗体对象.Arrange 的排列方式:常数 vbC ascade vbTileH orizontal vbTileV ertical vbA rrangeIcons 值 0 1 2 3 描述 层叠所有非最小化 水平平铺所有非最小化 垂直平铺所有非最小化 重排最小化 8.4 工具栏和状态栏“Microsoft Windows Common Controls 6.0”将控件添加到工具箱, 通过ToolBar、ImageList组合使用建立工具栏,步骤:

(1)在ImageList控件中添加所需的图像。

(2) 在ToolBar控件中创建Button对象。

(3)在ButtonClick事件中用Select Case语句对各按钮进行相应的编程。一、在ImageList控件中添加图像ImageList控件不单独使用,专门为其他控件提供图像库。索引(Index)、 关键字(Key) 在ToolBar中引用 图像文件的扩展名 为:

.ico、.bmp、.gif 、.jpg等。 二、在ToolBar控件中添加按钮1.为工具栏连接图像ToolBar与 ImageList的连接工具栏样式 2.为工具栏增加按钮索引(Index)、关键字(Key)每个按钮 的编号、标识, ButtonClick事件中引用;样式(Style),共6种图像(Image) ImageList对象中的 图像,值可以是Key或Index除菜单按钮(5)外的5种样式S ty le = 0S ty le = 3S ty le = 4S ty le = 1S ty le = 2 三、 响应ToolBar控件事件ToolBar控件常用的事件有两个:ButtonClick和ButtonMenuClick。前 者对按钮样式为0~2,后者对样式为5的菜单按钮。

(1)用索引Index确定按钮 (2)用关键字Key确定按钮Private Sub Toolbar1_ButtonClick(Byval Button As ComctlLib.Button) Select Case Button.Key Select Case Button.Index Case 1 Case "TNew"

FileNewProc FileNewProc Case 2 Case "TOpen"

选择“Microsoft Rich TextBox Controls 6.0”将控件添加到工具箱。

1.文件操作方法 (1)LoadFile方法 LoadFile方法能够将RTF文件或文本文件装入控件,其形式如下:

对象.LoadFile 文件标识符[,文件类型] 文件类型:

0或rtfRTF为RTF文件(缺省);1或rtfTEXT为文本文件 (2)SaveFile方法 SaveFile方法将控件中的文档保存为RTF文件或文本文件,其形式:

对象. SaveFile(文件标识符[,文件类型]) 2.常用格式化属性 格式化属性,可对该控件中选中的任何部分的文本使用不同的格式。分类 选中文本 字体、字号 字型 属性 SelText SelStart SelLength SelFontName SelFontSize SelBold SelItalic SelUnderline SelStrikethru 上、下标 颜色 缩排 对齐方式 SelCharOffset SelColor SelIndent elRightIndent SelHangingIndent SelAlignment 整型 0 左 1 右 2 中 整型 整型 数值型 缩排单位以 ScalMode 决定 逻辑量 下划线 删除线 >0 上标 <0 下标 以 Twip 为单位 值类型 说明 意义同 Text 控件对应属性 同上 粗体 斜体 3. 应用例8.9字号、字型和对齐4. 插入图像 在RichTextBox控件中可插入 (*.bmp)的图像文件,形式如下:

对象.OLEObjects.Add [索引],[关键字],文件标识符 其中:OLEObjects是集合,包含一组添加到RichTextBox控件的对象; 索引和关键字表示添加的元素编号和标识,可省,但逗号不能省。

例如: RichTextBox1.OLEObjects.Add , ,"c:\windows\circles.bmp" 8.6 应用程序向导是方便的程序,用来生成一个应用程序的界面。

选择“文件/新建工程”命令,在其对话框选中“B应用程序向导”。

Item = "窗体文件(*.FRM)"

cboType.AddItem Item + Space(20 - Len(Item)) + "*.FRM"

Item = "位图文件(*.BMP)"

cboType.AddItem Item + Space(20 - Len(Item)) + "*.BMP"

cboType.ListIndex = 2 End Sub Sub cboType_Click() filFile.Pattern = Mid(cboType.Text, 21) End SubSub filFile_Click( )┆End Sub Sub filFile_DblClick( )┆End Sub例9.1示例程序 1. 驱动器列表框Drive属性:

[对象.]Drive [= drive] Change事件:

重新设置Drive属性引发Change事件2. 目录列表框Path属性 :

[对象.]Path [= pathname] Change事件:

重新设置Path 属性引发Change事件 3. 文件列表框Path属性:

显示该路径下的文件。

重新设置Path属性引发PathChange事件。

Pattern属性:

显示的文件类型。

[对象.]Pattern [= value] 重新设置Pattern属性引发PatternChange事件。

例如:filFile.Pattern = "*.frm",显示*.frm文件。

多个文件类型用分号;分界。例如:

"*.frm;*.frx"

FileName属性:

[对象.]FileName [= pathname] 引用时只返回文件名,相当于ilFile.List(filFile .ListIndex), 需用Path属性得到其路径;设置时可带路径。 Click、DblClick事件:例如,单击输出文件名。

Sub filFile_Click( ) MsgBox filFile.FileName End Sub 例如,双击执行可执行程序:

Sub filFile_DblClick( ) ChDir (dirDirectory.Path)

改变当前目录

执行程RetVal = Shell(filFile.FileName, 1) 序 End Sub 9.2 文件的读写文件:存储在外部介质上数据的集合。

按名存取 1. 记录 由若干个相互关联的数据项组成。

例如,由学生的学习成绩信息组成的记录:学号数据项姓名数学成绩语文成绩物理成绩总分2. 文件及其种类 文件是记录的集合。

顺序访问模式:顺序文件,记录可长可短; 随机访问模式:随机文件,记录的长度相同; 二进制访问模式:二进制文件(可认为记录长度为1)。 (1) 顺序文件 按顺序依次把记录写入文件; 按顺序依次把记录读出来。记录 1 记录 2 …… 记录 N 文件结束标志文本文件:一行一条记录,记录可长可短,以“换 行”字符为分隔符号。

(2) 随机文件 随机文件可以直接访问文件中的任意一个记录。

记录长度相同; 根据记录号访问;#1 记录 1 #2 记录 2 …… #N 记录 N(3) 二进制文件 直接把二进制码存放在文件中。 一、 顺序访问模式打开文件 读出或写入 关闭文件1. 打开文件Open 文件名 [For 模式] As [#]文件号 [Len=记录长度](1) 模式OUTPUT:写操作; INPUT:读操作; APPEND:追加到文件末尾。(2) 文件号 1~511,可以用FreeFile函数获得下一个可利用的文件 号。

(3) 记录长度小于或等于32767的整数,它指定数据缓冲区的大小。

例如,打开C:\VB\SCORE,供写入数据,指定文件号为#1。OPEN "C:\VB\SCORE"

FOR OUTPUT AS #1 2. 写入命令 Print #文件号,[输出列表] 保存文本框假定文本框的名称为Text1,文件名为TEST.DAT。方法1:把整个文本框的内容一次性地写入文件。Open "TEST.DAT"

For Output As #1 Print #1, Text1 Close #1方法2:把整个文本框的内容一个字符一个字符地写入文件。Open "TEST.DAT"

For Output As #1 For i=1 To len(Test1) Print #1,Mid(Text1, i, 1);

Next i Close #1 Write #文件号,[输出列表] 紧凑格式。数据项之间插入“,”,并加上双引号。

例如,命令:Write #1,"One","Two",123 内容:"One","Two",123 3. 关闭文件 Close [[#]文件号][, [#]文件号]... 例如,Close #1, #2, #3 4. 读顺序文件 INPUT #文件号,变量列表把读出的每个数据项分别存放到所对应的变量。LINE INPUT #文件号,字符串变量读一行到变量中,主要用来读取文本文件。INPUT$(读取字符数,#文件号)随意读取字符5. 函数 LOF(文件号):返回文件的长度(总字节数)。

EOF(文件号):返回读写位置。

指针在文件尾时,EOF函数为True,否则为 False。 读文本文件到文本框 假定文本框名称为Text1,文件名为MYFILE.TXT。

方法1:一行一行读 Text1.Text = ""

Open "MYFILE.TXT"

For Input As #1 Do While Not EOF(1) Line Input #1, InputData Text1.Text = Text1.Text + InputData+vbCrLf Loop Close #1 方法2:一次性读 Text1.Text = ""

Open "MYFILE.TXT"

For Input As #1 Text1.Text = Input$( LOF(1), 1) Close #1 方法3:一个个字符读 Dim InputData as String*1 Text1.Text = ""

Open "MYFILE.TXT"

For Input As #1 Do While Not EOF(1) InputData= Input$(1,#1) Text1.Text = Text1.Text + InputData Loop Close #1 例9.2读入文本文件。 例9.3 文件加密程序。Private Sub File1_DblClick() Open tfilename For Input As #1 Text1.Text = ""

Do While Not EOF(1) indata = Input(1, #1) Text1.Text = Text1.Text + indata Loop End SubCommonDialog1.Action = 2 Open CommonDialog1.FileName For Output As #1 For i = 1 To Len(Text1.Text) Print #1, Mid(Text1.Text, i, 1);

Next i Close #1参阅例6.14 二、随机文件1. 打开 Open 文件名 For Random As #文件号 [Len=记录长 度] 2. 写操作 Put [#]文件号,[记录号],变量名将一个记录变量的内容写到指定的记录位置处。

忽略记录号,则表示在当前记录后的位置插入一条记录。3. 读操作 Get [#]文件号,[记录号],变量名忽略记录号,则读出当前记录后的那一条记录。 例9.4 管理程序。追加记录(Command1):将一个学生的信息作为一条记录添 加到随机文件末尾。

显示记录(cmdDisplay):显示在右边文本框(text4)中指定的 记录。 三、二进制文件 1. 打开 Open 文件名 For Binary As #文件号 2. 写操作 Put [#]文件号,[位置],变量名 写入长度等于变量长度的数据。

3. 读操作 GET [#]文件号,[位置],变量名 从指定位置开始读出长度等于变量长度的数据 存入变量中,数据读出后移动变量长度位置,如果 忽略位置,则表示从文件指针所指的位置开始读出 数据,数据读出后移动变量长度位置。 例9.5 文件复制Dim char As Byte Dim FileNum1,FileNum2 as Integer FileNum1 = FreeFile 打开源文件 Open "C:\STUDENT.DAT"

For Binary As # FileNum1 FileNum2 = FreeFile

打开目标文件 Open "C:\STUDENT.BAK"

For Binary As # FileNum2 Do While Not EOF(作文FileNum1) Get #1, , char

从源文件读出一个字节 Put #2, , char

将一个字节写入目标文 件 Loop Close #FileNum1 Close #FileNum2 9.3 常用的文件操作语句和函数1. FileCopy语句格式:FileCopy source , destination 功能:复制一个文件。

说明:

FileCopy语句不能复制一个已打开的文件。2. Kill语句格式:Kill pathname 功能:删除文件。

说明:pathname中可以使用统配符“*”和“?”。

例如:Kill "*.TXT"3. Name 语句格式:Name oldpathname As newpathname 功能:重新命名一个文件或目录。

说明:(1) Name具有移动文件的功能。

(2) 不能使用统配符“*”和“?”,不能对一个已打开的文件上使 用 Name语句。 4. ChDrive 语句格式:ChDrive drive 功能:改变当前驱动器。

说明:如果drive为 “ ”,则当前驱动器将不会改变;如果drive中有多个 字 符,则ChDrive只会使用首字母。5. MkDir 语句格式:MkDir path 功能:创建一个新的目录。6. ChDir 语句格式:ChDir path 功能:改变当前目录。

例如:ChDir "D:\TMP"7. RmDir 语句格式:RmDir path 功能:删除一个存在的目录。

说明:只能删除空目录。 8. CurDir函数格式:CurDir[(drive)] 功能:利用CurDir函数可以确定任何一个驱动器的当前目录。

说明:

drive为"

"

,则CurDir返回当前驱动器的当前目录。

例9.6 利用ChDrive和ChDir语句改写例9.1中的File1_DblClick()事件过 程。

Sub File1_DblClick() ChDrive Drive1.Drive

设置缺省驱动器 ChDir File1.Path

设置缺省目录 RetVal = Shell(File1.FileName, 1) End Sub 例9.7 为例9.1添加事件过程File1_MouseDown(),使之支持Del键,即按 下Del键删除选定的文件。

Sub File1_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyDelete Then ChDrive Drive1.Drive ChDir File1.Path Kill File1.FileName File1.Refresh

文件删除后更新文件列表框 End If End Sub 第十章 图 形 操 作 (3学时)10.1 10.2 10.3 10.4 图形操作基础 绘图属性 图形控件 图形方法*10.5 应用 10.1.1 坐标系统10.1图形操作基础每个容器都有一个坐标系,构成一个坐标系,需要三个要 素:坐标原点、坐标度量单位、坐标轴的长度与方向。坐标度 量单位由容器对象的ScaleMode属性决定。缺省时为Twip。每 英寸1440个Twip,20个Twip为一磅。原点 Height ScaleHeight 10.1.2 自行定义坐标系方法一:通过ScaleTop,ScaleLeft,ScaleWidth和ScaleHeight属性实 现。(ScaleTop,ScaleLeft)例10.1 在Form_Paint 事件中定义窗体的坐标系。 方法二:采用Scale方法来设置坐标系:

[对象.]Scale [(xLeft,yTop)-(xRight,yBotton)](xLeft,yTop) (xRight,yBotton)例如,Form1.Scale (-200,250) - (300, -150)将建立和例10.1一样的坐标系。

可在程序中使用Scale方法改变坐标系统。当Scale方法不带参数时,取 消用户定义的坐标系,采用缺省坐标系。

改变坐标系后产生的影响:

例10.1a 例10.1b Line (0, 0) - (1000, 1000)在不同坐标系的效果。

控件对象在坐标系内与X轴和Y轴的位置保持相对不变。 10.1.3 图形层层 次 最上层 中间层 最下层 三个图形层放置的对象 对象类型 工具箱中除标签、 线条、 形状外的空件对象 工具箱中标签、线条、形状空件对象 由图形方法所绘制的图形利用图形层的特点,实现悬浮效果。

在命令按钮后放置一个表面色 彩为黑色的标签,如图所示。

同一图形层内控件对象排列顺序称为Z序列。

Zorder方法的语法为:

对象.Zorder [position] position =0 表示该控件被定位于Z序列的前面; position = 1表示该控件被定位于Z序列的后面。

例 Zorder方法的使用。 10.2.1 当前坐标10.2绘 图属性CurrentX,CurrentY属性给出窗体或图形框或打印机在绘图时的当 前坐标。

这两个属性在设计阶段不能使用。

例10.2 利用CurrentX,CurrentY属性在窗体上随机打印100个“★”。10.2.2 线宽与线型窗体、图形框或打印机的DrawWidth属性给出这些对象上所画线的宽 度或点的大小。DrawWidth属性以像素为单位来度量,最小值为1。

例10.3 用DrawWidth属性改变直线宽度。 窗体或图形框或打印机的DrawStyle属性给出这些对象上所画线的形 状。设置值 0 1 2 3 4 5 6 线 型 实线(缺省) 长划线 点线 点划线 点点划线 透明线 内实线 图 示10.2.3 填充与色彩 Visual Basic 默认采用对象的前景色(ForeColor属性)绘图,也 可以通过以下颜色函数指定色彩。

1. RGB(红,绿,蓝)函数 数。

2. QBColor(颜色码) 颜色码使用0~15之间的整数。

例10.4 颜色的渐变过程。

红、绿、蓝三基色使用0~255之间的整10.3 图 形 控 件10.3.1 Picture Box(图形框)主要作用:显示图片、也可作为其他控件的容器。

装入图形:图形框对象.Picture = LoadPicture(“图形文件名”) 删除图形:图形框对象.Picture = LoadPicture( ) Autosize属性设置为True时,图形框能自动调整大小与显示的图片匹配 。 10.3.2 Image(图像框)图像框比图形框占用更少的内存块。图像框内不能保存其他控件。

Stretch属性=False,图像框可自动改变大小,以适应其中的图形。

Stretch属性=True, 图形可自动调整尺寸,以适应图像框的大小。

例10.5 图形框Autosize属性与图像框的Stretch属性对加载图形的影 响。

SavePicture对象名.属性,文件名 把绘制或装在窗体、图形框和图像框内的图形保存到Bmp格式文件内。10.3.3 Line(画线工具) 10.3.4 Shape(形状)例10.6 例10.7 10.4.1 Line方法 10.4 图 形 方 法画直线或矩形:

[对象.] Line [ [Step] (x1,y1)]-(x2,y2)[,颜色][,B[F]] 其中:对象可以是窗体或图形框。

(x1,y1) ,(x2,y2)为线段的起终点坐标或矩形的左上角右下坐标。

关键字B表示画矩形,关键字F表示用画矩形的颜色来填充矩形。

例10.8 用Line方法在一个窗体上画坐标轴与坐标刻度。

例10.9 用Line方法在一个窗体上画随机射线。10.4.2 Circle方法Circle方法 用于画圆、椭圆、 圆弧和扇形。 10.4.3 Pset方法Pset方法用于画点:

[对象.] Pset [Step] (x,y) [,颜色] 参数(x,y)为所画点的坐标,关键字Step表示采用当前作图位置的相对值。

例10.10 本例用Pset方法绘制阿基米德螺线10.4.4 Point方法Point方法用于返回指定点的RGB颜色,其语法格式如下:

[对象.] Point (x,y) 其中参数对象与(x,y)的意义与前述相同。

如果( x, y)点位于对象之外,Point 方法将返回True。

例10.11 用Point方法获取一个区域的信息。

利用例10 .11的处理方法可使图片产生朦胧的效果。 10.5.1 几何图形绘制10.5 应用利用Line方法和Circle方法及DrawWidth、DrawStyle和DrawMode属性。

例10.12 用Circle方法在窗体上绘制由圆环构成的艺术图案。

算法:等分半径为r的圆周为n份,以等分点为圆心,半径r1绘制n个圆。

例10.13 用Line方法绘制函数f(x)=x2 在区间[a,b]之间积分面积 图。

为了能绘制任意区间[a,b]上函数f(x) 积分面积图,可在窗体上放置一个 图形框和两个文本框。文本框用于指定积分上下限的值,图形框用于绘 图。根据区间[a,b]的值设置图形框的左上角坐标为(a-1,b×b+1),右下 角坐标为(b+1,-1)。将区间[a,b]等分为n 份,在每一等分点i上,用 Line方法连线到(i,i*i)。 10.5.2 简单设计:有计划地移动一个对象包括改变对象的形状和尺寸。

编程时可以采用帧原理,即通过一系列静态图辅之以连续快速变化产 生效果,也可以通过Move方法改变图形对象的Top及Left属性来移动 图形。的速度使用时钟控制。

例10.14 通过改变图形形状演示一个陀螺在图形框内转动。

例10.15 演示地球图标的转动,在转动时同时使地球图标在窗体内移动, 并变化地球图标的尺寸。

(用PictureClip控件来存放一组图片)10.5.3 图形漫游滚动图形通过滚动条的滑块移动,只要设置图形框的Left或Top为滑块当前 值的负数,就可形成图形相对移动。

例10.16 本例在窗体内显示一幅地图,移动滚动条漫游地图。 10.5.4 图形处理技术1. 操作象素 通过PaintPicture方法访问内置在操作系统中的BitBlt服务程序。

dpic.PaintPicture spic,dx,dy,dw,dh,sx,sy,sw,sh,rop 其中:

参数dpic为目标图形对象,spic为传送源, dx,dy是传送目标矩形区域左上角坐标(目标控件内任一位 置)。

dw,dh是目标形矩形区域的宽和高。

sx,sy是要传送图形矩形区域左上角坐标。

sw,sh是要传送图形矩形区域的大小。

rop指定传送的象素与目标中现有的象素组合模式(如表所 常 量 数 值 说 明 示)。vbDstInvert vbNotSrcCopy vbSrcCopy vbSrcInvert &H00055009 &H00330008 &H00cc0020 &H00660046 逆转目标位图 复制源位图的逆到目标位图 复制源位图的到目标位图 用 XOR 组合源位图与目标位图 (dx,dy) (sx,sy)shPaintPicture 方法dhsw dw 传送源spic 目标dpicdpic.PaintPicture spic,dx,dy,dw,dh,sx,sy,sw,sh,rop dw,dh sw,sh至少8个Twip 复制图形:设置目标区域左上角坐标和大小与源矩形区域相同。

翻转图形:只需改变坐标系,设置图形宽为负数,则水平翻转图 形;图形高度为负数,则上下翻转图形;如果宽度和高度都为负数,则 两个方向翻转图形。

放大图形:改变目标图形的宽度和高度。

旋转图形:要需要对原始图片按行和列的顺序或按列和行的顺序 扫描象素点,然后在目标图形区颠倒行和列的顺序复制象素点。

例10.17 PaintPicture方法翻转放大位图。例10.17a 本例使用PaintPicture方法实现百叶窗效果。

2. 使用DrawMode属性绘制图形 DrawMode属性可以将新象素与原有象素用不同的方法组合。两次Xor运 算恢复原有象素。

例10.18 用鼠标选定图形中的区域复制到指定的图片框。

例10.18a 在Xor运算符下图形叠加的效果。 10.5.5 改变窗体对象外观通过调用Windows的API函数可改变窗体的外观形状。VB应用程序要 访问API函数,必须在VB应用程序中用Declare语句将API函数声明为外部 过程。Declare语句 将API函数声明为外部过程返回访问Visual Basic应用程序 将API函数声明为外部过程,操作流程如下:通过“工程/添加模块”在当前工程内加入一个BAS模块文件。

执行VB程序组中的API文本浏览器,启动API函数查看工具。

单击“文件|加载文本文件”命令,装入Win32api.Txt文件。

添加指定的API函数到选定项框中,并将函数声明复制到剪贴 板。

将剪贴板中的内容粘贴到BAS模块文件中。 文件/加载文本文件API文本浏览 器应用程序 选定API函数复制到剪贴板1。选择信息类型3。2。选定4。送剪贴板 例10.19 建立一个椭圆形状的窗体。

API函数CreateEllipticRgn建立椭圆外形区域,SetWindowRgn显示该区域。

CreateEllipticRgn函数参数说明:

(x1,y1) (x2,y2) 坐标参数采用象数值。实际显示的窗体区域由窗体的Height、Width属性确 定。需要使用ScaleX和ScaleY方法对窗体的度量单位进行转换。

SetWindowRgn函数参数说明:

hWnd窗口句柄,hRgn为窗口形状,bRedraw图形重绘控制,为一逻辑值。

句柄(Handle)可看作一个对象的指针,通过它可访问该对象。可通过API函数 或对象的属性返回句柄。

使用API的区域设置函数不仅可以改变窗体外观,也可以改变控件外观。 10.5.6 在程序中加入后台音乐API函数sndPlaySound可以直接播放音频文件或系统声音。sndPlaySound 函数有两个参数,lpszSoundName指定播放的音频文件或系统声音,uFlags 设定播放状态。uFlags设置 uFlags SND_SYNC SND_ASYNC SND_NODEFAULT SND_LOOP SND_NOSTOP 设 置 &H00 &H01 &H02 &H08 &H10 说 明 同步播放 非同步播放 找不到指定的语音文件时也不播放预设的声音 重复播放 不要停止其他正在播放的语音例10.20 本例示范用sndPlaySound函数播放音频文件。

调用形式:k = sndPlaySound(音频文件名,播放方式) 播放文件为空,就可停止音乐播放 注:本例要求有多媒体设备 第十一章 Visual Basic与(1学时)11.1 11.2 11.3 *11.4 *11.5 *11.6 11.7 概念 管理器 数据控件 ADO数据控件 结构化查询语言(SQL) 报表制作 错误处理 11.1概念表就是一组排列成易于处理和读取的相关信息的集合。

关系模型已经成为设计事实上的标准。 关系型模型字段 主键 学号 990001 990002 990101 990102 990103 990201 990202 991103 991104 姓名 万林 庄前 丁保华 姜沛棋 朱克良 程玲 黎敏艳 章万京 陈友良 性别 男 女 男 女 男 女 女 男 男 物理 物理 数学 数学 数学 计算机 计算机 电气 电气 出生年月 82-1-21 82-9-21 82-4-4 81-12-2 82-10-1 82-11-14 83-2-21 82-6-3 83-5-5按 学 号 索 引记录 一个可以由多个表组成,表与表之间可以用不同的方式相互 关联。若第一个表中的一条记录内容与第二个表中多条记录的数据相 符,但第二个表中的一条记录只能与第一个表的一条记录的数据相符, 这样的表间关系类型叫做一对多关系。基本情况表 学号 990001 990002 … 姓名 万林 庄前 … 学号 990001 990001 …一对多关系学生成绩表 课程 数学 外语 … 成绩 85 90 …若第一个表的一条记录的数据内容可与第二个表的多条记录的数据 相符,反之亦然,这样的表间关系类型叫做多对多关系。 可以将一个或几个表中的数据构成记录集Recordset对象,记录集也 由行和列构成,它与表类似。学号 990001 课程 数学 成绩 85 学号 姓名 性别 出生日期 990001 万林 男 物理 82-1-11 990002 庄前 女 物理 82-9-21。。。

。。。

。。richtextbox vb

。。。

。。。(表一)学号 姓名 课程 成绩 990001 万林 物理 数学 85 990002 庄前 物理 外语 90。。。

。。。

。。。

。。。。。记 录 集 在VB中内的表格不允许直接访问,而只能通过记录集对象 进行记录的操作和浏览,因此,记录集是一种浏览的工具。记录集记录集类 Table Dynaset SnapShot说 明 是表格直接显示的数据。它比其他类型记录集处理速度 快,内存开销较大。

一个或者几个表中的记录的引用,动态集和产生动态集的 基本表可以互相更新。是最灵活的,功能最强的记录集。

一瞬间的状态,显示的数据是静态、只读状态,内 存开销最少。 VB的管理器(Visdata.exe)可用于管理。在VB开发环 境内单击外接程序菜单中的可视化数据管理器命令可打开可视数据管理 器。11.2 管理器 建立Student.mdb ,所含学生基本情况表结构如 下:字段名 学号 姓名 性别 类 型 Text Text Text 宽 度 字段名 类 型 6 Text 10 出生年月 Date 2 照片 Binary 宽 度 10 8管理器使用小结:

1.建立新表:

鼠标右键单击窗口,弹出菜单,选择对应命令。

2.打开、删除表,修改表结构和建立表间的关联等操作:

右键单击窗口内的表名,弹出菜单,选择对应命令。

指定具体使用的文件名,包括所有的路径名。

确定具体可访问的数据,这些数据构成记录集对象。

确定记录集类型。注:

RecordSource属性可以是中的单个表名,也可以是使用SQL查询语言的一个查询字符串。如果连接的是单表,则 DatabaseName属性应设置为文件所在的子目录名,而具体文件 名放在RecordSource属性中。 数据控件只能连接产生记录集,不能显示记录集中的数据, 要显示记录集中的数据必须通过能与它绑定的控件来实现。绑定控件记录集姓名 庄前 性别 女常用绑定控件 绑定控件具有DataSource 和DataField两个重要属性,其作用如下:属 性 DataSource DataField 绑定控件绑定属性说明 指定一个有效的数据控件连接到上。

设置有效的字段与绑定控件建立联系。学号 姓名 课程 成绩 990001 万林 物理 数学 85 990002 庄前 物理 外语 90。。。

。。。

。。。

。。。。。记 录 集Data控件、记录集与绑定控件 例11.1 设计一个窗体显示在11.2节中建立的的Student.mdb中基 本情况表的内容。

例11.2 用一个数据网格控件MsFlexGrid显示Student.mdb中基本 情况表的内容。属性:

Rows 、Cols (网格的行或列数); FixedRows 、FixedCols (不可卷动的行或列数)。 11.3.2 数据控件的事件事 件 Reposition 说 明 发生在一条记录成为当前记录后,这个事件中 显示当前指针的位置。

移动记录指针前、修改与删除记录前或卸载含 Vaildate 有数据控件的窗体时触发该事件。参数Save可 判断绑定控件内的数据是否发生变化。 11.3.3 数据控件的常用方法方 Refresh UpdateControls UpdateRecord 法 说 明 激活对数据控件属性的改变,使对的操作有效。

将数据从中重新读到被数据控件绑定的控件内。

将绑定控件内的数据写入到中而不触发数据控件 的Vaildate事件。Refresh 11.3.4 记录集的属性与方法1. 属性 Bof学号 990001 姓名 物理 物理 。。

建筑 课程 数学 外语 。。

建筑学 成绩 85 90 。。

90RecordCount万林 庄前。。

黎明BookMark990002 。。

990010Eof 2. 记录集的方法学号MoveFirst姓名 物理 物理 。。

建筑课程 数学 外语 。。

建筑学成绩 85 90 。。

90MoveLast MoveNext990001 990002 。。

。万林 庄前。。

黎明MovePrevious990010Nomarch =FalseData1.Recordset. FindFirst"姓名=

黎明

"?FindFirst 、 FindLast 、 FindNext 、 FindPrevious 方 法 可 在 指 定 的 Dynaset或Snapshot类型的记录集对象中查找。?Seek方法在Table表中查找。

Nomarch属性可判定是否找到。

例11.3 在窗体上用Move方法代替数据控件对象的4个箭头的操 作。

例11 4 使用Fi d方法查找记录 11.3.5 记录的增删改操作学号 990001 990002 990010 姓名 物理 物理 建筑 课程 数学 外语 建筑学 成绩 85 90 90UpData 增加记录 删除记录 调用Delete方法。

? 给各字段赋值。

? 调用Update方法。例11.5 对提供增、删、改和查找功能。 11.411.4.1 ADO对象模型ADO数据控件ADO是Microsoft处理信息的最新技术,它是一种ActiveX对 象,采用了被称为OLE DB的数据访问模式。它是数据访问对象DAO、 远程数据对象RDO和开放互连ODBC三种方式的扩展。ADO对 象模型更为简化,不论是存取本地的还是远程的数据,都提供了统一 的接口。11.4.2 使用ADO数据控件在使用ADO数据控件前,必须先通过“工程/部件”菜单命令选择 “Microsoft ADO Data Control 6.0(OLE DB)”选项,将ADO数据控件添 加到工具箱。ADO数据控件与Visual Basic的内部数据控件很相似,它 允许使用ADO数据控件的基本属性快速地创建与的连接。 工具箱内 ADO控件 图标形状画在窗体 上的外观能够利用三种记录集对象访问中的数据,连接方法:ADO控件连接设置 连接属性 ConnectionString RecordSource ADO控件属性说明 包含了用于与数据源建立连接的相关信息 (ADO控件没有DatabaseName属性) 。

确定具体可访问的数据,这些数据构成记 录集对象Recordset。 连接操作------鼠标右击ADO控件,选择快捷菜单 “ADODC属性”命令,打开ADO控件属性页窗:单击 选定选定 选定设置完成后,ADO控件的ConnectionString属性为:

Provider=Microsoft.Jet.OLEDB.3.51;

Persist Security Info=False;

步骤1:执行“外接程序”菜单中的“数据窗体向导”命令。 步骤2:选择类型。 步骤3:选择具体的文件。 步骤4:设置应用窗体的工作特性。 步骤5:选择记录源(所需要的实际数据)。 步骤6:选择所需要的操作按钮。例11.7 11.5 结构化查询语言(SQL)11.5.1 结构化查询语言结构化查询语言SQL是操作的工业标准语言。在SQL 语言中,指定要做什么而不是怎么做。不需要告诉SQL如何 访问,只要告诉SQL需要做什么。

利用SQL,可以确切指定想要检索的记录以及按什么顺序检 索。可以在设计或运行时对数据控件使用SQL语句。用户提 出一个查询,返回所有与该查询匹配的记录。 结构化查询语言 常用SQL命令 CREAT DELETE SELECT UPDATE 常用SQL命令子句 FROM WHERE GROUP BY HING ORDER BY 合计函数 G COUNT SUM MAX MIN 描 述 创建新的表、字段和索引 从表中删除记录。

在中查找满足特定条件的记录。

改变特定记录和字段的值。

描 述 用来为从其中选定记录的表命名。

用来指定所选记录必须满足的条件。

用来把选定的记录分成特定的组。

用来说明每个组需要满足的条件。

用来按特定的次序将记录排序。

描 述 用来获得特定字段中的值的平均数 用来返回选定记录的个数 用来返回特定字段中所有值的总和 用来返回指定字段中的最大值 用来返回指定字段中的最小值 11.5.2 使用SELECT语句查询1.使用SELECT语句 从中的获取数据称为查询,查询通过使用 SELECT语句。常见的SELECT语句形式为:

Select 字段表 From 表名 Where 查询条件 Group By 分组字段 Order By 字段[Asc|Desc] 可以在设计或代码中对数据控件的RecordSource属性设置SQL 语句,也可将SQL语句赋予对象变量。

在建立SQL语句时,如果需要通过变量构造条件,则需要在应用 程序中将变量连接到SELECT语句。例如:

"Select * From 基本情况 Where =

"

&

Text1 &

"

"

例11.8将例11.4中的查找功能改用SQL语句处理。

例11.9用SQL语句从两个数据表中选择数据构成记录集。

例11.10用SQL指令按统计Student.mdb各的人数。 例11.11 在ADO数据控件上使用SQL语句。将例11.9中的Data控件改 用ADO数据控件,用SQL语句从Student.mdb的两个数据表中 选择数据构成记录集。

例11.12 设计一个窗体,计算Student.mdb内学生成绩表中每个 学生的平均成绩,产生姓名、平均成绩和最低成绩三项数据,按平均 成绩升序排列数据,并用该数据作图。

*2. 使用UPDATE语句修改记录 UPDATE创建一个更新查询来按照某个条件修改特定表中的字段值。

其语法如下:

UPDATE [表集合] SET [表达式] WHERE [条件] 例11.12a 本例把学生平均成绩字段的值增加了10%,并刷新网格。

*3. 使用DELETE语句查询 可以创建删除查询来删除FROM子句中列出的、满足WHERE子句的一 个或多个表中的记录,其语法所示如下:

DELETE [表字段] FROM [表集合] WHERE [条件] 例11.12b 删除例11.12a所产生temp表中平均成绩<80的全部记录,并 刷新网格。 *11.5.3使用对象变量访问DAO对象定义了一个可编程的对象集合。可按下列方法定义数据 库对象和记录集对象,不必在窗体上放置数据控件。方 法 Dim db As Database Set db = OpenDatabase() Dim rs As Recordset Set rs = db.OpenRecordset(记录源) 说 明打开,返回一个 Database类型的对象db。

返回一个记录集对象rs。要想在程序中使用DAO对象,必须先为当前工程引用DAO对象 的引擎库。

引用方式:执行工程菜单的引用命令,启动引用对话框,在清单中选 取“Microsoft DAO 3.51 Object Library”项目。 使用DAO模型访问的例题。例11.12d 使用DAO模型访问,分页显示基本情况表的记录。

本程序通过Bookmark属性设置当前记录的书签,用于当前页上记录的定 位。例11.12e 使用DAO模型访问,约束绑定控件。

记录集的字段对象 可以使用如下几种方法获取:

Recordset.Fields("字段名称"

)、Recordset("字段名称") Recordset.Fields("数字")、Recordset("数字") 在DAO中记录集对象为对象变量,故字段可用rs(j)表示。 *11.5.4 ADO对象使用ADO对象访问比DAO对象模型更为简化,不论是存取 本地的还是远程的数据,都提供了统一的接口。ADO的连接方法 方 法 Dim db As Connection Set db = New Connection db.Open 数据源连接字符串 Dim rs As Recordset Set rs = New Recordset rs.Open 数据源,连接对象,指针,锁类型 打开记录集。

返回查询结果。

连接数据源。

返回一个连接对象db。

说 明 11.6 报 表 制 作 数据报表设计器属于ActiveX Designer组中的一个成员,在使用前需要执行“工程|添加Data Report”命令,将报表设计器加入到当前工程中 ,产生一个DataReport1对象,并在工具箱内产生一个“数据报表”标签。标签 文本 图形 线条 形状 函数 “标签”控件在报表上放置静态文本 “文本”控件在报表上连接并显示字段的数据 “图形”控件可在报表上添加图片 “线条”控件在报表上绘制直线 “形状”控件在报表上绘制各种各样的图形外形 “函数”控件在报表上建立公式。

报表标头区包含整个报表最开头的信息,一个报表只有一个报表 头,可使用“标签”控件建立报表名 报表注脚区包含整个报表尾部的信息,一个报表也只有一个注脚 区 页标头区设置报表每一页顶部的标题信息;页注脚区包含每一页 底部的信息;细节区包含报表的具体数据,细节区的高度将决定 报表的行高。 例11.13 建立新工程,在窗体上放置两个命令按钮。

在当前工程内加入一个DataEnvironent1对象。完成与指定 的连接。在Connection1下创建Command1对象。

在当前工程中加入报表设计器DataReport1 ,设置报表设计 器的DataSource属性为数据环境对象,DataMember属性为 Command1对象。

将数据环境设计器中Command1对象内的字段拖动到数据 报表设计器的细节区。

使用“标签”控件,在报表标头区插入报表名,页标头区 设置报表每一页顶部的标题信息等。

使用“线条”控件在报表内加入直线,使用“图形”控件 和“形状”控件加入图案或图形。

在命令按钮Click事件内加入代码DataReport1.Show显示 报表,DataReport1.PrintReport打印报表。 错误处理步骤:

1. 用On Error语句设置错误陷阱,捕捉错误。11.7错 误 处 理2. 编写错误处理程序,根据可预知的错误类型决定采取何种措施。

捕捉错误示意:On ErrorNumber 错误号Err对象其他可根据Err.Number 的值来编写出错处理程序。 On Error语句有如下几种形式:

(1) On Error Resume Next ─── 忽略错误行,继续执行下一语句。

(2) On Error GoTo 标号───使程序转跳到语句标号所指示的程序块 (3) On Error GoTo 0───不使用错误处理程序块。

处理方法:

Resume ─── 重新执行引起错误的语句或指令。

Resume Next ─── 忽略错误行,继续执行下一语句。

Resume 标号 ─── 忽略错误行,转跳到由<标号>指明的语句继续执 行。若<标号>为0,则表示终止程序执行。 例11.14 错误处理的基本方法 Sub OnErrorStatementDemo()Dim Response ,Msg, Style, Title As String Dim db As Database, rs As Recordset On Error GoTo ErrorHandler Set db = OpenDatabase("A:\Student.mdb")

打开 Set rs = db.OpenRecordset("基本情况")

设置记录集 …… Exit Sub

正常退出本程序 ErrorHandler:

错误处理块入口 Style = vbRetryCancel + vbCritical + vbDefaultButton2 Select Case Err.Number Case 53

出错号53为文件不存在 Msg = "文件不存在!"

Response = MsgBox(Msg, Style, "出错提示") If Response = vbCancel Then Exit Sub Case 71

71号驱动器未准备好 Msg = "

A盘未准备好"

Response = MsgBox(Msg, Style, "出错提示") If Response = vbCancel Then Exit Sub Case Else

当发生其他不可预知的错误,退出本程序 Exit Sub End Select Resume

再次执行原出错语句End Sub 例11.15 下列程序用于处理删除一个已打开的文件所产生的错误。

Sub ResumeStatementDemo() On Error GoTo ErrorHandler

设置错误陷阱 Open "

testfile "

For Output As #1 Kill "testfile"

企图删除一个打开的文件 Exit Sub ErrorHandler: Select Case Err.Number Case 55

文件已打开错误 Close #1

处理方法:关闭文件 Case Else …… End Select Resume End Sub 例11.16 采用忽略错误的方法处理错误。

Sub OnErrorStatementDemo() On Error GoTo ErrorHandler

设置错误陷阱 Open "

testfile "

For Output As #1 Kill "

testfile "

企图删除一个打开的文件 On Error Goto 0

关闭错误陷阱 On Error Resume Next

忽略Kill "testfile"出错行指令 Err.Clear

清除出错号 Exit Sub ErrorHandler: Select Case Err.Number Case 55 Close #1 Case Else … … End Select Resume End Sub 例11.17 处理被零除、溢出和非法的过程调用三种情况产生的错误。

Function Divide (numer, denom) as Variant Const mnErrDivByZero = 11

用于代表被零除 Const mnErrOverFlow = 6

溢出 Const mnErrBadCall = 5

非法的过程调用 On Error GoTo MathHandler Dim Msg as String Divide = numer / denom

计算 Exit Function MathHandler: If Err.Number = MnErrDivByZero Or Err.Number = ErrOverFlow _ Or Err = ErrBadCall Then Divide = Null 产生错误则返回 NULL Else

显示意想不到的错误信息。

Msg = "Unanticipated error "

&

Err.Number Msg = Msg &

": "

&

Err.Description MsgBox Msg, vbExclamation End If Resume Next

不管什么情况,Resume Next End Function

第一篇:vb编程

送给 Visual Basic 6.0 的初学者应朋友的要求,写这么个东西,这里主要介绍一些学习 VB 过程中应该注意的问题,因为其他的东西可以从任何一本教材中看到。

1、学习 Visual Basic 之前最好做好一下几种准备:

?知道 Windows 操作系统中常见部件的名称,例如“按钮”、“文本框”、“单选按钮”、“滚动条”等。

?掌握一定的编程思想或数学思想。或者说有一定的逻辑分析能力。

?能经常上机实践,当然最好的学习方法是边看书边实际操作。

初学者推荐阅读高等教育出版社出版的《全国计算机?二级 Visual Basic 语言程序设计》(附带一本课后习题答案)、清华大学出版社出 版的《Visual Basic 程序设计》(谭浩强主编)。其他的书在很多问题上讲的不清楚。不推荐参考。

2、VB 中的主要内容:

VB 也是一门计算机语言,所以也就避免不了要有各种语法,主要是“变量类型”、“选择程序结构”、“循环程序结构”、“数组”、“子函数和子过程”、 “文件”。另外由于 VB 是可视化的编程工具,所以比传统的 QBASIC 和 C 语言多了“控件”这一部分。具体需要那些控件教材里面有介绍。

3、各个章节的重点难点介绍:

这里的“章节”并不是按照教材上的“章节”介绍的,而是按照刚才我划分的“块”介绍。并且是按照国家计算机二级 VB 考试的标准叙述的。

1)、变量类型 变量和常量的概念。主要的变量类型有:integer、string、long、Boolean、currency、float、double。其中 integer、string 和 Boolean 最为常见。

2)选择程序结构 几种常见的选择结构。书上都有介绍。学习过程中记得如何判断条件的“真”“假”,选择不同的程序走向。如果条件为“真”,则怎么样;如果条件 为“假”,又该怎么样。最后不要忘了 End If。

在学习选择程序结构的时候注意培养自己良好的编码风格。看一个例子:

Private Sub number_Click(Index As Integer) If lastinput <>

"nums"

Then disp = Number(Index).Caption Else disp = disp + Number(Index).Caption End If lastinput = "nums"

End Sub 不管你是否能看懂这段程序写的是什么,况且这也不是我让你看这段程序的主要目的。你应该注意这段程序的编码风格,就是格式。VB 里面几 乎每段代码都在一个“Sub”和“End Sub”中间,所以你在写程序的时候最好使第一行代码向右缩进一个 Tab 键,按一下键盘上的 Tab 键,然后输入代 码。如果出现“If”等语句的时候,“Then”后面一行的代码要缩进两个 Tab 键。不知道是否明白。不明白也没有关系。多看一些优秀代码就明白了。

3)循环结构 这一部分可以说对初学者来说比较头疼。特别是循环条件的判定。什么时候要执行循环,什么时候不用执行循环。哪些语句比那些语句少(多) 执行一次循环。

主要的循环语句教材上都有详细的讲解,这一部分要多揣摩,多练习。可以在源程序上用笔划出语句执行的顺序。其实用不了多长时间就明白了。

给出一个典型的例子:“百钱买百鸡” Private Sub Command1_Click() Dim x%, y%, z%, t As Data, t1 As Data For x = 0 To 100 For y = 0 To 100 For z = 0 To 100 If x + y + z = 100 And 3 * x + 2 * y + 0.5 * z = 100 Then Print "能买母鸡";

x;

"只,公鸡";

y;

"只,小鸡";

z;

"只"

End If Next z, y, x End Sub 这段程序可以算是初学者比较经典的算法。100 块钱,要买三种鸡,母鸡 3 元一只,公鸡 2 元一只,小鸡 0.5 元一只。问一共可以买几只。研究 完算法之后别忘了看格式。其中 Next z,y,x 的顺序不能颠倒,也可以写成如下格式:

Private Sub Command1_Click() Dim x%, y%, z%, t As Data, t1 As Data For x = 0 To 100 For y = 0 To 100 For z = 0 To 100 If x + y + z = 100 And 3 * x + 2 * y + 0.5 * z = 100 Then Print "能买母鸡";

x;

"只,公鸡";

y;

"只,小鸡";

z;

"只"

End If Next z Next y Next x End Sub 4)数组 数组是一种重要的数据结构。要多练习。其中 VB 里面最容易出错的就是下标!例如定义一个数组 Arr(4),那么它一共 5 个变量:Arr(0)开始,一 直到 Arr(4)。

5)子函数和子过程 这里我沿用 QBASIC 里面的叫法。在子函数(过程)部分最容易搞不懂的概念就是“传地址”和“传值”,即“ByRef”和“ByVal”,ByRef 是默认的。

也就是说如果没有在函数的参数列表中注明是那种传递方式,默认按照传地址进行处理。函数中的数值既可以由主函数传递到子函数(过程)中, 也可以由子函数(过程)回到主函数中。其实我这里说的“主函数”是不确切的,应该叫做“主调函数”。另外还有一个与之相关的概念是“形参”和“实 参”,就是“实际参数”和“形式参数”。实际参数是子函数(过程)中的参数,而形式参数是“主调函数”中的参数。

我觉得 VB 中子函数参数调用应该是比其他计算机语言简单的一个地方,包括 C/C++等。在 C/C++中,参数传递默认的是传值。就是不能把子函 数(过程)的参数传回主调函数,如果要进行这样的操作,就要借助指针变量。

看一个简单的子函数(过程)调用的例子:

Public Sub Swap(x,y) Dim t As Integer t=x x=y y=t End Sub Private Sub Form_Click() Dim a As Integer Dim b As Integer a=10 b=20 Swap a,b Print ”a=”;

a , ”b=”;b End Sub Form_Click 是主调函数,Swap 是子函数(过程)。在主调函数的倒数第三行调用了子函数(过程),输出结果为:“a=20,b=10”。

6)文件 这一部分单独考试出题不多,实际应用中用到的也不多,但是它总是在某些考试中以压轴题的姿态出现。并且更为严重的是:如果对这一部分不 清楚,会使整道题都无从下手。所以还是要好好看看这部分为好。

7)常见控件 对于控件最令初学者头疼的是“属性”、“事件”和“方法”这三个概念。

这三个概念是“面向对象程序设计”专用的。VB6 虽然不能算是标准的“面向对象程序语言”,但是具备了很多的面向对象特征,唯独不具备“类的继 承”特征。考虑到初学者对面向对象编程没有基础,所以关于上述三个概念就不能给出确切的定义。但是我们可以这样去理解这三个概念:“属性”就 是某个控件的固有性质,拿 Command(按钮)控件为例,它的“属性”就有“长度”、“宽度”、“是否显示图片”等。简单来说,大多数初学者接触的控 件属性,都可以在 VB6 开发环境中的属性栏找到(如果找不到的属性称为“只读属性”)。

“事件”很容易理解。比如我们用鼠标单击一个按钮,这时候“按钮”这个控件就接收鼠标的单击,换句话说就是“按钮上发生了单击事件”。那么发 生单击事件以后程序会做什么呢?那就是运行你编写的针对此事件的程序。现在你打开 VB6 的界面,随便画一个按钮,然后双击这个按钮,进入代 码视图,在 Private Sub Command_Click()和 End Sub 之间写代码。那么你写的这段代码就是名称为 Command 的按钮发生 Click 事件执行的代码。

“方法”的概念最不容易理解。按照标准的面向对象编程描述,方法是一个函数,它被封装在类中。其实我们也可以把方法想想成一个“函数”,类 似上文中描述的“子函数(过程)”。初学者常用的 VB6 方法不多,其中最常用的就是“Print”。正如您所想象的那样,刚才使用的时候也没有发现它 有多么特殊。其实我们已经在使用 Print 方法了。只不过它所归属的对象我们不需要知道而已。

关于控件的使用这里就不多说了,因为教科书上介绍的比我介绍的详细的多。

4、结束语:

Visual Basic6.0 可以说算是最简单的一门计算机语言。学习的时候多用心。其实前面“变量”部分即使记不住也无妨,在后续的学习过程中会不断 牢固以前的知识的。更何况现在的考试都带有 MSDN,就是 VB 的帮助系统。如果有哪些关键字或者用法记不清楚了,可以随时查阅 MSDN 的相关 文档。

最后祝各位 VB 愉快! 附:送上几例经典的算法 求最大公约数和最小公倍数 Private Sub Command3_Click() Dim m1%, m%, n%, n1%, r%, b% m1 = Val(InputBox("输入一个数:")) n1 = Val(InputBox("请输入另一个数:")) If m1 >

n1 Then m = m1: n = n1 Else m = n1: n = m1 Do r = m Mod n If r = 0 Then Exit Do m = n n = r Loop Print m1;

"和";

n1;

"的最大公约数为:";

n b = m1 * n1 / n Print m1;

"和";

n1;

"的最小公倍数为:";

b End Sub求 100 到 200 之间所有的素数(质数) Private Sub Command2_Click() Dim i%, m% For m = 101 To 199 Step 2 For i = 2 To Int(Sqr(m)) If (m Mod i) = 0 Then GoTo notnextM 一旦被 2 到 sqr(m)的数整除就转到下一个数 Next i Print m notnextM: Next m End Sub 注意!程序中使用了 GoTo 语句!VB 编程基础教程一代码模块Visual Basic 的代码存储在模块中。模块有三种类型:窗体、标准和类。

简单的应用程序可以只有一个窗体,应用程序的所有代码都驻留在窗体模块中。而当应用程序庞大复杂时,就要另加窗体。最终可能会发现在几个 窗体中都有要执行的公共代码。因为不希望在两个窗体中重复代码,所以要创建一个独立模块,它包含实现公共代码的过程。独立模块应为标准模 块。此后可以建立一个包含共享过程的模块库。

每个标准模块、类模块和窗体模块都可包含:

声明。可将常数、类型、变量和动态链接库 (DLL) 过程的声明放在窗体、类或标准模块的模块级。过程。Sub、Function 或者 Property 过程包含可以作为单元来执行的代码片段。本章后面的“过程概述”一节中将讨论这些内容。

标准模块 标准模块(文件扩展名为 .BAS)是应用程序内其它模块访问的过程和声明的容器。它们可以包含变量、常数、类型、内有效的)声明或模块级声明。写入标准模块的代码不必绑在特定的应用程序上;如果不小心用名称引用窗体和控件,则在 许多不同的应用程序中可以重用标准模块。

类模块 在 Visual Basic 中类模块(文件扩展名为 .CLS)是面向对象编程的基础。可在类模块中编写代码建立新对象。这些新对象可以包含自定义的属性 和方法。实际上,窗体正是这样一种类模块,在其上可安放控件、可显示窗体窗口。

详细信息 关于在类模块中编写代码的更详细的信息,请参阅“用对象编程”。

注意 Visual Basic 的版和企业版也包含 ActiveX 文档、ActiveX 设计器和用户控件。它们介绍了具有不同文件扩展名的新模块类型。从编写代 码的角度来看,这些模块应视同为窗体模块。

在窗体模块中,该列表包含 一个通用段,一个属于窗体自身的段以及窗体所包含的每一控件的段。对于类模块,列表包括一个通用段和一个类段;对于标准模块,只有一个通 用段被显示。

每一段代码都可包含几个用“过程列表框”访问的不同过程。对窗体或控件的每一个事件过程,窗体模块的过程列表都包含一个独立的段。例如,La bel 控件的过程列表就包含 Change 事件段、Click 事件段和 DblClick 事件段等等。类模块只列举类本身的事件过程— 初始化和终止。标准模块不 列举任何事件过程,因为标准模块不支持事件。

模块通用段的过程列表只包含唯一段— 声明段,其中放置模块级的变量、常数和 DLL 声明。当在模块中添加子过程或函数过程时,那些过程被添 加到声明段下方的“过程列表框”中。

在代码中输入一控件名时, “自动列出成员特性”会亮出这个控件的下拉式属性表(图 5.5) 。键入属性名的前几个字母,就会从表中选中该名字,按 Tab 键将完成这次输入。当不能确认给定的控件有什么样的属性时,这个选项是非常有帮助的。即使选择了禁止“自动列出成员特性” 仍可使用 CT , RL + J 组合键得到这种性能。 图 5.5 “自动列表成员功能”“自动快速信息”功能显示语句和函数的语法(图 5.6) 。当输入合法的 Visual Basic 语句或函数名之后,语法立即显示在当前行的下面,并用黑体字 显示它的第一个参数。在输入第一个参数值之后,第二个参数又出现了,同样也是黑体字。

“自动快速信息”也可以用 CTRL+I 组合键得到。

将单行语句分成多行 可以在“代码”窗口中用续行符(一个空格后面跟一个下划线)将长语句分成多行。由于使用续行符,无论在计算机上还是打印出来的代码都变得易 读。下面用续行符 ( _) 将代码分成若干行:Data1.RecordSource = _ "SELECT * FROM Titles, Publishers"

_ &

"WHERE Publishers.PubId = Titles.PubID"

_ &

"AND Publishers.State = CA"

在同一行内,续行符后面不能加注释。至于在什么地方可以使用续行符,还是有某些限制的。

将多个语句合并到同一行上 通常,一行之中有一个 Visual Basic 语句,而且不用语句终结符。但是也可以将两个或多个语句放在同一行,只是要用冒号 (:) 将它们分开。Text1.Text = "Hello"

: Red = 255 : Text1.BackColor = _ Red 但是,为了便于阅读代码,最好还是一行放一个语句。

. 详细信息 关于详细信息,请参阅“Visual Basic 的规范、限制和文件格式”。 在代码中添加注释 阅读本手册的例子时常会遇到注释符 ()。这个符号告诉 Visual Basic,忽略该符号后面的内容。这些内容是代码段中的注释,既是为了方便开发者, 也是为了方便以后可能检查源代码的其他程序员。例如:

这是从屏幕左边

开始的注释。

Text1.Text = "Hi!"

在文本框中放欢迎词。

注释可以和语句在同一行并写在语句的后面,也可占据一整行。上述代码对这两种情况都作了示范。记住,不能在同一行上,将注释接在续行符之 后。

理解数字系统 在本文档中,大多数的数值都是十进制的(基数为 10)。但有时用十六进制数(基数为 16)或八进制数(基数为 8)更方便。Visual Basic 用前 缀 &H 表示十六进制数,而用 &O 表示八进制数。下表说明同一个数的十进制、八进制和十六进制表示。

十进制 八进制 十六进制 9 &O11 &H9 15 &O17 &HF 16 &O20 &H10 20 &O24 &H14 255 &O377 &HFF通常不必掌握十六进制或八进制数制,因为计算机可以用任何数制的数工作。但是,对某些任务来说,有的数系就比其它数系更合适,例如利用十 六进制数设置屏幕和控件的颜色。

Visual Basic 的命名约定 在编写 Visual Basic 代码时,要声明和命名许多元素(Sub 和 Function 过程、变量、常数等等)。在 Visual Basic 代码中声明的过程、变量和常 数的名字,必须遵循这些规则:

它们必须以字母开头。它们不可以包含嵌入的句号或者类型声明字符(规定数据类型的特殊字符)。它们不能超过 255 个字符。控件、窗体、类和模块的名字不能超过 40 个字符。它们不能和受到限制的关键字同名。 受到限制的关键字是 Visual Basic 使用的词,是语言的组成部分。其中包括预定义语句(比如 If 和 Loop)、函数(比如 Len 和 Abs)和操作符 (比如 Or 和 Mod)。

详细信息 关于关键字表的更详细信息,请参阅语言参考。

窗体和控件可以和受到限制的关键字同名。例如,可以将某个控件命名为 Loop。但在代码中不能用通常的方法引用该控件,因为 Visual Basic 会 认为 Loop 意味着关键字。例如,这样的代码就会出错。

出错。Loop.Visible = True为了引用那些和受到限制的关键字同名的窗体或控件,就必须限定它们,或者将其用方括号 [ ] 括起来。例如,下面的代码就不会出错。MyForm.Loop.Visible = True 将其限定。

[Loop].Visible = True用窗体名方括号起了作用。

在引用窗体和控件时都可以用这种方式使用方括号,但在声明变量或定义过程期间,当变量名或过程名与受到限制的关键字相同时,这种方式是不 能使用的。方括号还可以用来强制 Visual Basic 接受其它类型库提供的名称,这些名称与受到限制的关键字冲突。

注意 因为键入方括号也是令人厌倦的事情,所以希望少用受到限制的关键字作窗体或控件名。但是,如果 Visual Basic 的新版本定义了与现有窗 体或控件冲突的新关键字,那么,在为使用新版本而更新代码时,可以使用这个技巧。

变量在 Visual Basic 中执行应用程序期间,用变量临时存储数值。变量有名字(用来引用变量所包含的值的词)和数据类型(确定变量能够存储的数据 的种类) 。

可以把变量看作内存中存放未知值的所在处。例如,假定正在为水果铺编一个销售苹果的软件。在销售实际发生之前并不知道苹果的价格和销量。

此时,可以设计两个变量来保存未知数— 将它们命名为 ApplePrice 和 ApplesSold。每次运行程序时,用户就这两个变量提供具体值。为了计算总 的销售额,并且将结果显示在名叫 txtSales 的文本框中,代码应该是这样的:txtSales.txt = ApplePrice * ApplesSold 每次根据用户提供的数值,这个表达式返回不同的金额。由于有了变量,就可以设计一个算式,而不必事先知道实际的输入是多少。

在这个例子中,ApplePrice 的数据类型是货币,而 ApplesSold 的数据类型是整数。变量还可以表示许多其它数值,比如:文本数值、日期、各种数 值类型,甚至对象也在此列。

toolbar弹出mid窗体_richtextbox和textbox_richtextbox vb

存储和检索变量中的数据 用赋值语句进行计算,并将结果赋予变量:ApplesSold = 10将值 10传给变量。 ApplesSold = ApplesSold + 1 增一。变量值注意,例子中的等号是赋值符,并不是等于操作符;它将数值 (10) 赋予变量 (ApplesSold)。

声明变量 声明变量就是事先将变量通知程序。要用 Dim 语句声明变量,Dim 语句提供了变量名:Dim variablename [As type] 在过程内部用 Dim 语句声明的变量,只有在该过程执行时才存在。过程一结束,该变量的值也就消失了。此外,过程中的变量值对过程来说是局 部的— 也就是说,无法在一个过程中访问另一个过程中的变量。由于这些特点,在不同过程中就可使用相同的变量名,而不必担心有什么冲突和意 想不到变故。

变量名:

必须以字母开头。不能包含嵌入的句号或者嵌入的类型声明字符。不得超过 255 个字符。在同一个范围内必须是唯一的。范围就是可以引用变量的变化域— 一个过程、一个窗体等等。

由于 Dim 语句中的可选的 As type 子句,可以定义被声明变量的数据类型或对象类型。数据类型定义了变量所存储信息的类型。String、Integer 和 Currency 都是数据类型的例子。变量也可以包含来自 Visual Basic 或其它应用程序的对象。Object、Form1 和 TextBox 都是 Visual Basic 对象 类型或类的实例。

详细信息 关于对象的更详细的信息,请参阅“用对象编程”和“用部件编程” 在本章后面的“数据类型”部分将详细讨论数据类型。

声明变量的其它方式:

不在过程内部,而在窗体、标准或类模块的声明段声明变量,这将使变量对模块中的所有过程有效。用 Public 关键字声明变量,这将使变量在整个应用程序中有效。用 Static 关键字声明一个局部变量,那么,即使过程结束,变量的值也仍然保留着。

隐式声明 在使用一个变量之前并不必先声明这个变量。

例如,可以书写这样一个函数,在其中就不必在使用变量 TempVal 之前先声明它: Function SafeSqr (num) TempVal = Abs (num) SafeSqr = Sqr (TempVal) End Function Visual Basic 用这个名字自动创建一个变量,使用这个变量时,可以认为它就是显式声明的。虽然这种方法很方便,但是如果把变量名拼错了的话, 会导致一个难以查找的错误。例如,假定写了这样一个函数:Function SafeSqr (num) TempVal = Abs (num) SafeSqr = Sqr (TemVal) End Function 乍看起来,这两段代码好象是一样的。但是因为在倒数第二行把 TempVal 变量名写错了,所以函数总是返回 0。当 Visual Basic 遇到新名字,它 分辨不出这是意味着隐式声明了一个新变量呢,还是仅仅把一个现有变量名写错了,于是只好用这个名字再创建一个新变量。

显式声明 为了避免写错变量名引起的麻烦,可以规定,只要遇到一个未经明确声明就当成变量的名字,Visual Basic 都发出错误警告。

要显式声明变量,请 在类模块、窗体模块或标准模块的声明段中加入这个语句:

如果对包含 SafeSqr 函数的窗体或标准模块执行该语句,那么 Visual Basic 将认定 TempVal 和 TemVal 都是未经声明变量,并为两者都发出错误 信息。随后就可以显式声明 TempVal。Function SafeSqr (num) Dim TempVal TempVal = Abs (num) SafeSqr = Sqr (TemVal) End Function 因为 Visual Basic 对拼错了的 TemVal 显示错误信息,所以能够立刻明白是什么问题。由于 Option Explicit 语句有助于抓住这些类型的错误,所 以最好在所有代码中使用它。

注意 Option Explicit 语句的作用范围仅限于语句所在模块,所以,对每个需要 Visual Basic 强制显式变量声明的窗体模块、标准模块及类模块, 必须将 Option Explicit 语句放在这些模块的声明段中。如果选择“要求变量声明” Visual Basic 会在后续的窗体模块、标准模块及类模块中自动插入 , Option Explicit,但是不会将它加入到现有代码中。必须在工程中通过手工将 Option Explicit 语句加到任何现有模块中。

理解变量的范围 变量的范围确定了能够知晓该变量存在的那部分代码。在一个过程内部声明变量时,只有过程内部的代码才能访问或改变那个变量的值;它有一个 范围,对该过程来说是局部的。但是,有时需要使用具有更大范围的变量,例如这样一个变量,其值对于同一模块内的所有过程都有效,甚至对于 整个应用程序的所有过程都有效。Visual Basic 允许在声明变量时指定它的范围。

指定变量的有效范围 一个变量在划定范围时被看作是过程级(局部)变量,还是模块级变量,这取决于声明该变量时采用的方式。

范围 专用 公用 过程级 变量对于这种过程是专用的,在该过程中出现了这些变量。

不可使用。不能在一个过程中声明公用变量。

模块级 变量对于这种过程是专用的,在该过程中出现了这些变量。

变量可用于所有模块。过程内部使用的变量 过程级变量只有在声明它们的过程中才能被识别。也称它们为局部变量。用 Dim 或者 Static 关键字来声明它们。例如:Dim intTemp As Integer — 或者 —Static intPermanent As Integer 在整个应用程序运行时,用 Static 声明的局部变量中的值一直存在,而用 Dim 声明的变量只在过程执行期间才存在。

对任何临时计算来说,局部变量是最佳选择。例如,可以建立十来个不同的过程,每个过程都包含称作 intTemp 的变量。只要每个 intTemp 都声明 为局部变量,那么每个过程只识别它自己的 intTemp 版本。任何一个过程都能够改变它自己的局部的 intTemp 变量的值,而不会影响别的过程中的 intTemp 变量。

模块内部使用的变量 按照缺省规定,模块级变量对该模块的所有过程都可用,但对其它模块的代码不可用。可在模块顶部的声明段用 Private 关键字声明模块级变量, 从而建立模块级变量。例如:Private intTemp As Integer 在模块级,Private 和 Dim 之间没有什么区别,但 Private 更好些,因为很容易把它和 Public 区别开来,使代码更容易理解。

所有模块使用的变量 为了使模块级的变量在其它模块中也有效,用 Public 关键字声明变量。公用变量中的值可用于应用程序的所有过程。和所有模块级变量一样,也在 模块顶部的声明段来声明公用变量。例如:Public intTemp As Integer 注意 不能在过程中声明公用变量,只能在模块的声明段中声明公用变量。 详细信息 有关变量的其它信息,请参阅 “高级变量主题” 。高级变量主题 使用多个同名的变量 如果不同模块中的公用变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们。例如,如果有一个在 Form1 和 Module1 中 都声明了的公用 Integer 变量 intX,则把它们作为 Module1.intX 和 Form1.intX 来引用便得到正确值。

为了看清这是如何工作的,在一个新工程中插入两个标准模块,并在窗体上画上三个命令按钮。

在第一个标准模块 Module1 之中声明一个变量 intX。Test 过程设置它的值:

声明 Module1 的 intX。Public intX As Integer Sub Test ()设置 Module1 的 intX 变量的值。

intX = 1 End Sub 在第二个标准模块 Module2 中声明了第二个变量 intX,它有相同的名字。又是名为 Test 的过程设置它的值:

声明了 Module2 的 intX。Public intX As Integer Sub Test ()设置 Module2 的 intX 变量的值。

intX = 2 End Sub 在窗体模块中声明了第三个变量 intX。名为 Test 的过程又一次设置它的值。

声明了该窗体的 intX 变量。Public intX As Integer Sub Test ()

设置 form 中的 intX 变量值。

intX = 3 End Sub 在三个命令按钮的 Click 事件过程中,每一个都调用了相应的 Test 过程,并用 MsgBox 来显示这三个变量的值。Private Sub Command1_Click () Module1.Test

调用 Module1 中的 Test。

显示 Module1 的 intX。MsgBox Module1.intX End SubPrivate Sub Command2_Click () Module2.Test

调用 Module2 中的 Test。

显示 Module2 的 intX。MsgBox Module2.intX End SubPrivate Sub Command3_Click () Test MsgBox intX End Sub 运行应用程序,单击三个命令按钮中的每一个按钮。于是将看到三个公用变量被分别引用。注意在第三个命令按钮的 Click 事件过程中,在调用 F orm1 的 Test 过程时不必指定 Form1.Test,在调用 Form1 的 Integer 变量的值时也不必指定 Form1.intX 。如果多个过程或变量同名,则 Visual Basic 会取变化更受限制的值,在这个例子中,就是 Form1 变量。

公用变量与局部变量的比较 在不同的范围内也可有同名的变量。例如,可有名为 Temp 的公用变量,然后在过程中声明名为 Temp 的局部变量。在过程内通过引用名字 Temp 来访问局部变量;而在过程外则通过引用名字 Temp 来访问公用变量。通过用模块名限定模块级变量就可在过程内访问这样的变量。

调用 Form1 中的 Test。

显示 Form1 的 intX。Public Temp As Integer Sub Test () Dim Temp As Integer Temp = 2

Temp 的值为 2。

Form1.Temp 的值为 1。MsgBox Form1.Temp End SubPrivate Sub Form_Load () Temp = 1 End Sub Private Sub Command1_Click () Test End Sub 一般说来,当变量名称相同而范围不同时,局限性大的变量总会用“阴影”遮住局限性不太大的变量(即优先访问局限性大的变量) 。所以,如果还有 名为 Temp 的过程级变量,则它会用“阴影”遮住模块内部的公用变量 Temp。

阴影窗体属性和控件 由于阴影效应,窗体属性、控件、常数和过程皆被视为窗体模块中的模块级变量。窗体属性或控件的名称与模块级变量、常数、自定义类型或过程 的名称相同是不合法的,因为它们的范围相同。

在窗体模块内,和窗体中控件同名的局部变量将遮住同名控件。因此必须引用窗体名称或 Me 关键字来限定控件,才能设置或者得到该控件的值或 它的属性值。例如:

将 Form1.Temp 的值设置成 1。Private Sub Form_Click () Dim Text 1 , BackColor 假定该窗体有一个控件也叫做 Text1。

Text1 = "Variable"

Me.Text1 = "Control"

变量用“阴影”遮住控件。

要得到控件,必须用?Me?限定。 Text1.Top = 0 Me.Text1.Top = 0 BackColor = 0 Me.BackColor = 0 End Sub导致出错! 要得到控件,必须用?Me?限定。

变量用“阴影”遮住属性。

要得到窗体属性,必须用?Me?限定。使用同名的变量和过程 专用模块级变量和公共模块级变量的名字也会和过程名冲突。模块中的变量不能和任何过程同名,也不能和模块中定义的类型同名。但可以和公用 过程或其它模块中定义的类型或变量同名。在这种情况下,从别的模块访问这个变量时,就必须用模块名来限定。

虽然上面讨论阴影规则并不复杂,但是用阴影的方法可能会带来麻烦,而且会导致难以查找的错误。因此,对不同的变量使用不同的名称才是一种 好的编程习惯。在窗体模块中应尽量使变量名和窗体中的控件名不一样。静态变量除范围之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和公用变量的值。但是,对于 Dim 声明的局部变量以及声明局部变量的过程, 仅当过程在执行时这些局部变量才存在。

通常, 当一个过程执行完毕, 它的局部变量的值就已经不存在, 而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。

但可将局部变量定义成静态的,从而保留变量的值。在过程内部用 Static 关键字声明一个或多个变量,其用法和 Dim 语句完全一样:Static Depth 例如,下面的函数将存储在静态变量 Accumulate 中的以前的运营总值与一个新值相加,以计算运营总值。Function RunningTotal (num) Static ApplesSold ApplesSold = ApplesSold + num RunningTotal = ApplesSold End Function 如果用 Dim 而不用 Static 声明 ApplesSold,则以前的累计值不会通过调用函数保留下来,函数只会简单地返回调用它的那个相同值。

在模块的声明段声明 ApplesSold,并使它成为模块级变量,由此也会收到同样效果。但是,这种方法一旦改变变量的范围,过程就不再对变量排他 性存取。由于其它过程也可以访问和改变变量的值,所以运营总值也许不可靠,代码将更难于维护。

声明所有的局部变量为静态变量 为了使过程中所有的局部变量为静态变量,可在过程头的起始处加上 Static 关键字。例如:Static Function RunningTotal (num) 这就使过程中的所有局部变量都变为静态,无论它们是用 Static、Dim 或 Private 声明的还是隐式声明的。可以将 Static 放在任何 Sub 或 Funtion 过程头的前面,包括事件过程和声明为 Private 的过程 常数经常会发现代码包含一些常数值,它们一次又一次地反复出现。还可发现,代码要用到很难记住的数字— 而那些数字没有明确意义。

内部的或系统定义的常数是应用程序和控件提供的。在“对象浏览器”中的 Visual Basic ( VB ) 、和 Visual Basic for applications ( VBA ) 对象库 中列举了 Visual Basic 的常数。其它提供对象库的应用程序,如 Microsoft Excel 和 Microsoft Project,也提供了常数列表,这些常数可与应用程 序的对象、方法和属性一起使用。在每个 ActiveX 控件的对象库中也定义了常数 关于使用“对象浏览器”的详细信息,请参阅“用对象编程” 。符号的或用户定义的常数是用 Const 语句来声明的。下节“创建属于自己的常数”中将说明用户定义的常数。

在 Visual Basic 中,常数名采用大小写混合的格式,其前缀表示定义常数的对象库名。来自 Visual Basic 和 Visual Basic for applications 对象库 的常数以 "vb"

开头— 例如 vbTileHorizontal。

设计前缀时应尽力防止发生意外冲突,不能出现常数名称相同但表示不同数值的情况。即使使用了前缀,两个对象库也仍可能包含表示不同值的相 同常数。在这种情况下,引用哪个常数取决于哪个对象库具有更高的优先级。关于改变对象库优先级的信息,请参阅 “引用对话框”部分。

为了绝对确保不发生常数名字冲突,可用以下语法来限定对常数的引用:[libname.][modulename.]constname Libname 通常是控件或库的类名。Modulename 是定义常数的模块的名字。Constname 是常数名。在对象库中定义了每个元素,并能在“对象浏览器” 中查看元素。

创建属于自己的常数 声明常数的语法是:[Public|Private] Const constantname[As type] = expression 参数 constantname 是有效的符号名(其规则与建立变量名的规则一样) ,expression 由数值常数或字符串常数以及运算符组成;但在 expression 中 不能使用函数调用。

Const 语句可以表示数量或 Date / Time 量:Const conPi = 3.14159265358979 Public Const conMaxPlanets As Integer = 9 Const conReleaseDate = #1/1/95# 也可用 Const 语句定义字符串常数: Public Const conVersion = "07.10.A"

Const conCodeName = "Enigma"

如果用逗号进行分隔,则在一行中可放置多个常数声明:Public Const conPi = 3.14, conMaxPlanets = 9, _ conWorldPop = 6E+09 等号 ( = ) 右边的表达式往往是数字或文字串,但也可以是其结果为数或字符串的表达式(尽管表达式不能包含函数调用) 。甚至可用先前定义过 的常数定义新常数。Const conPi2 = conPi * 2 一旦已定义常数,就可将其放置在代码中,使代码更可读。例如:Static SolarSystem (1 To conMaxPlanets) If numPeople >

conWorldPop Then Exit Sub 设定用户自定义常数的范围 和变量声明一样, Const 语句也有范围,也使用相同的规则:

为创建仅存在于过程中的常数,请在这个过程内部声明常数。为创建一常数,它对模块中所有过程都有效,但对模块之外任何代码都无效,请在模块的声明段中声明常数。为创建在整个应用程序中有效的常数,请在标准模块的声明段中进行声明,并在 Const 前面放置 Public 关键字。在窗体模块或类模块中不能声明 Public 常数。

详细信息 关于范围的更详细信息,请参阅本章前面的“理解变量的范围”一节。

避免循环引用 由于常数可以用其它常数定义,因此必须小心,在两个以上常数之间不要出现循环或循环引用。当程序中有两个以上的公用常数,而且每个公用常 数都用另一个去定义时就会出现循环。

例如:

在 Module1 中:

Public Const conA = conB * 2 中有效。

在 Module 2:

Public Const conB = conA / 2 中有效。

在整个应用程序 在整个应用程序 如果出现循环,在试图运行此应用程序时,Visual Basic 就会产生错误信息。不解决循环引用就不能运行程序。为避免出现循环,可将公共常数限 制在单一模块内,或最多只存在于少数几个模块内。VB 编程基础教程二数据类型变量是用来存储值的所在处;它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。在声明变量时也可指 定它的数据类型。所有变量都具有数据类型,以决定能够存储哪种数据。

根据缺省规定,如果在声明中没有说明数据类型,则令变量的数据类型为 Variant。Variant 数据类型很象一条变色龙— 它可在不同场合代表不同数 据类型。当指定变量为 Variant 变量时,不必在数据类型之间进行转换,Visual Basic 会自动完成各种必要的转换。

但是,如果知道变量确实总是存储特定类型的数据,并且还声明了这种特定类型的变量,则 Visual Basic 会以更高的效率处理这个数据。例如,存 储人名的变量最好表示成 String 数据类型,因为名字总是由字符组成。

除变量外,数据类型也用于其它场合。在给属性赋值时,这个值就有数据类型;函数的参数也有数据类型。事实上,在 Visual Basic 中,凡是与数 据有关的东西就与数据类型有关。

也可声明任何基本类型的数组。

详细信息 关于更详细信息,请参阅本章后面的“数组”部分。在“性能和兼容性的设计”中还将讨论通过选择数据类型来提高应用程序的性能。

声明带数据类型的变量 在使用非 Variant 变量之前,必须使用 Private、Public、Dim 或 Static 语句将变量声明为 As type。例如,下列语句分别声明了 Integer、Double、 String 和 Currency 类型的变量:Private I As Integer Dim Amt As Double Static YourName As String Public BillsPaid As Currency 一个声明语句可将多个声明组合起来,请看下列语句:Private I As Integer,Amt As Double Private YourName As String,BillsPaid As Currency Private Test,Amount,J As Integer 注意 如果不提供数据类型,则指定变量为缺省类型。在上例中,变量 Test 和 Amount 是 Variant 数据类型。如果由于其它编程语言的经验使人感 到同一个声明语句中的所有变量都有相同的指定数据类型(此例中为 Integer),那么,此处的结果可能会令人感到新鲜。

Numeric 数据类型 Visual Basic 支持几种 Numeric 数据类型— Integer(整型)、Long(长整型)、Single(单精度浮点型)、Double(双精度浮点型)和 Currency (货币型)。与 Variant 类型相比,Numeric 类型占用的存储空间通常要少。

如果知道变量总是存放整数(如 12 )而不是带小数点的数字(如 3.57),就应当将它声明为 Integer 类型或 Long 类型。整数的运算速度较快, 而且比其它数据类型占据的内存要少。在 For...Next 循环内作为计数器变量使用时,整数类型尤为有用。

详细信息 关于控制结构的详细资料,请参阅本章后面的“控制结构概述”。

如果变量包含小数,则可将它们声明为 Single、Double 或 Currency 变量。Currency 数据类型支持小数点右面 4 位和小数点左面 15 位;它是一 个精确的定点数据类型,适用于货币计算。浮点(Single 和 Double)数比 Currency 的有效范围大得多,但有可能产生小的进位误差。

注意 浮点数值可表示为 mmmEeee 或 mmmDeee ,其中 mmm 是假数,而 eee 是指数(以 10 为底的幂)。Single 数据类型的最大正数值为 3. 402823E+38,或 3.4 乘以 10 的 38 次方;Double 数据类型的最大正数值是 1.79769313486232D+308 或 1.8 乘以 10 的 308 次方。用 D 将数 值文字中的假数部分和指数部分隔开,就会导致将该值作为 Double 数据类型来处理。同样,用这种方式使用 E,也会导致将该值作为 Single 数据 类型来处理。

Byte 数据类型 如果变量包含二进制数,则将它声明为 Byte 数据类型的数组。(本章后面的“数组”中将讨论数组)。在转换格式期间用 Byte 变量存储二进制数据 就可保留数据。当 String 变量在 ANSI 和 Unicode 格式间进行转换时,变量中的任何二进制数据都会遭到破坏。在下列任何一种情况下,Visual Basic 都会自动在 ANSI 和 Unicode 之间进行转换:

读文件时写文件时调用 DLL 时调用对象的方法和属性时 除一元减法外,所有可对整数进行操作的运算符均可操作 Byte 数据类型。因为 Byte 是从 0 - 255 的无符号类型,所以不能表示负数。因此,在 进行一元减法运算时,Visual Basic 首先将 Byte 转换为符号整数。

所有数值变量都可相互赋值,也可对 Variant 类型变量赋值。

在将浮点数赋予整数之前, Visual Basic 要将浮点数的小数部分四舍五入,而不是将 小数部分去掉。

详细信息 关于 Unicode 和 ANSI 转换的详细信息,请参阅“国际化”。

String 数据类型 如果变量总是包含字符串而从不包含数值,就可将其声明为 String 类型。 Private S As String 然后可将字符串赋予这个变量,并用字符串函数对它进行操作。S = "Database"

S = Left (S,4) 按照缺省规定,String 变量或参数是一个可变长度的字符串,随着对字符串赋予新数据,它的长度可增可减。

也可以声明字符串具有固定长度。可 用以下语法声明一个定长字符串:String * size 例如,为了声明一个长度为 50 字符的字符串,可用下列语句:Dim EmpName As String * 50 如果赋予字符串的字符少于 50 个,则用空格将 EmpName 的不足部分填满。如果赋予字符串的长度太长,已不能成为定长字符串,则 Visual Bas ic 会直接截去超出部分的字符。

因为定长字符串用空格填充尾部多余的空间,所以在处理定长字符串时可发现,删除空格的 Trim 和 RTrim 函数是很有用的。

可将标准模块中的定长字符串声明为 Public 或 Private。在窗体和类模块中,必须将定长字符串声明为 Private。

详细信息 请参阅语言参考中的“Ltrim、RTrim Function 和 Trim 函数”。

交换字符串和数字 如果字符串表示数值,则可将字符串赋予数值变量。也可将数值赋予字符串变量。例如,将命令按钮、文本框和列表框放置在窗体中。在命令按钮 的 Click 事件中输入下列代码。运行应用程序并单击命令按钮。Private Sub Command1_Click () Dim intX As Integer Dim strY As String strY = "100.23"

intX = strY 将字符串传递给数值变量。

将字符串中数值的余弦值。List1.AddItem Cos (strY)添加到列表框中。

strY = Cos (strY) Text1.Text = strY End Sub Visual Basic 会自动强制变量为适当的数据类型。在转换字符串和数值时要小心;如果传送字符串中的值不是数值,则在运行时会出错。

Boolean 数据类型 将余弦值传递给字符串变量。

在文本框中显示字符串。 若变量的值只是“true/false”、“yes/no”、“on/off”信息,则可将它声明为 Boolean 类型。Boolean 的缺省值为 False。在下面的例子中,blnRunning 是 Boolean 变量,存储简单的 yes/no 设置。Dim blnRunning As Boolean 查看磁带是否在转。

If Recorder.Direction = 1 Then blnRunning = True End if Date 数据类型 Date 和 Time 值既可包含在特定的 Date 数据类型中,又可包含在 Variant 变量中。一般的 Date 特性适用于这两种类型。

详细信息 请参阅《联机手册》的“高级变量主题”中的“在 Variant 变量中存储 Date/Time 值”部分。

当其它数值数据类型转换为 Date 时,小数点左边的值表示 Date 信息,小数点右边的值则代表 Time。午夜为 0,正午为 0.5。负数表示公元 189 9 年 12 月 31 日之前的 Date。

Object 数据类型 Object 变量作为 32 位(4 个字节)地址来存储,该地址可引用应用程序中或某些其它应用程序中的对象。可以随后(用 Set 语句)指定一个被声 明为 Object 的变量去引用应用程序所识别的任何实际对象。Dim objDb As Object Set objDb = OpenDatabase ("c:\Vb5\Biblio.mdb") 在声明对象变量时, 请试用特定的类, 而不用一般的 Object 例如用 TextBox 而不用 Control, ( 或者象上面的例子那样, Database 取代 Object) 用 。

运行应用程序之前,Visual Basic 可以决定引用特定类型对象的属性和方法。因此,应用程序在运行时速度会更快。在“对象浏览器”中列举了特定 的类。

当使用其它应用程序的对象,并在“对象浏览器”中的“类”列表中列举对象时,不要用 Variant 或一般的 Object,而应声明对象。这样可确保 Visual Basic 能够识别引用的特定类型对象,在运行时解决引用问题。

详细信息 关于创建和指定对象以及对象变量的更详细信息,请参阅本章后面的“创建对象”部分。

转换数据类型 Visual Basic 提供了几种转换函数,可用来将值转换成特定数据类型。例如,用 CCur 函数将值转换成 Currency 类型:PayPerWeek = CCur (hours * hourlyPay) 转换函数 将表达式转换成 Cbool Boolean Cbyte Byte Ccur Currency Cdate Date CDbl Double Cint Integer CLng Long CSng Single CStr String Cvar Variant CVErr Error注意 对目标数据类型,传递到转换函数的值必须是有效的,否则会发生错误。例如,如果想把 Long 型数转换成 Integer 型数,那么,Long 型数 必须在 Integer 数据类型的有效范围之内。

详细信息 在联机帮助中查找指定的转换函数。

Variant 数据类型 Variant 变量能够存储所有系统定义类型的数据。如果把它们赋予 Variant 变量,则不必在这些数据的类型间进行转换; Visual Basic 会自动完成 任何必要的转换。例如:Dim SomeValue SomeValue = "17"缺省为 Variant。

SomeValue 包含 "17"(双字符的串)。

现在, SomeValue 包含数值 2。

现在, SomeValue 包含 "U2"

(双字符的串)。SomeValue = SomeValue - 15 SomeValue = "U"

&

SomeValue不必过多关注 Variant 变量中数据的类型就可对 Variant 变量进行操作,但须避免落入陷阱。

如果对 Variant 变量进行数学运算或函数运算,则 Variant 必包含某个数。更详细的信息,请参阅《联机手册》中“高级变量主题”中的“变量中存储 的 Numeric 值”部分。如果正在连接两个字符串,则用 "

&

"

操作符而不用 "

+ "

操作符。更详细的信息,请参阅《联机手册》中“高级变量主题”中的“Variant 变量中 存储的 Strings”部分。

除了可以像其它标准数据类型一样操作外,Variants 还包含三种特定值:Empty,Null 和 Error。

Empty 值 有时需要知道是否已将一个值赋予所创建的变量。在赋值之前,Variant 变量具有值 Empty。值 Empty 是异于 0、零长度字符串 ("") 或 Null 值的 特定值。可用 IsEmpty 函数测试 Empty 值:If IsEmpty (Z) Then Z = 0 当 Variant 变量包含 Empty 值时,可在表达式中使用它;将其作为 0 或零长度字符串来处理,这要根据表达式来定。

只要将任何值(包括 0、零长度字符串或 Null)赋予 Variant 变量,Empty 值就会消失。而将关键字 Empty 赋予 Variant 变量,就可将 Variant 变量恢复为 Empty。

Null 值 Variant 数据类型还可包含一特定值:Null。Null 通常用于应用程序,表示未知数据或丢失的数据。

由于在中使用 Null 方法,Null 具有某些唯一的特性:

对包含 Null 的表达式,计算结果总是 Null。于是说 Null 通过表达式“传播”;如果表达式的部分之值为 Null,那么整个表达式的值也为 Null。将 Null 值、含 Null 的 Variant 变量或计算结果为 Null 的表达式作为参数传递给大多数函数,将会使函数返回 Null。Null 值经由返回 Variant 数据类型的内在函数传播。

也可用 Null 关键字指定 Null 值。Z = Null 也可用 IsNull 函数测试 Variant 变量是否包含 Null 值。If IsNull (X) And IsNull (Y) Then Z = Null Else Z = 0 End If 如果将 Null 值赋予 Variant 以外的任何其它类型变量,则将出现可以捕获的错误。而将 Null 值赋予 Variant 则不会发生错误,Null 将通过包含 Variant 变量的表达式传播(尽管 Null 并不通过某些函数来传播)。可以从任何具有 Variant 返回值的函数过程返回 Null。

除非明确将 Null 赋予变量,否则变量不会设置成 Null 值,所以,如果不在应用程序中使用 Null,就不必书写测试 Null 和处理 Null 的程序。

详细信息 关于如何在表达式中使用 Null 的详细信息,请参阅语言参考的“Null”部分。

Error 值 在 Variant 中,Error 是特定值,指出已发生的过程中的错误状态。但是,与其它类型错误不同,这里并未发生正常的应用程序级的错误处理。因此, 程序员或应用程序本身可根据 Error 值进行取舍。利用 CVErr 函数将实数转换成错误值就可建立 Error 值。

详细信息 关于如何在表达式中使用 Error 值,请参阅语言参考中的“CVErr 函数”部分。关于错误处理的信息,请参阅“调试代码和处理错误”。有关 Variant 数据类型的更详细信息,请参阅《联机手册》中的“高级变量主题”。高级变量主题数值在变量中的内部表示 Variant 变量维护它们所存储的数值的内部表示。这个表示将决定 Visual Basic 在执行比较操作和其它操作时如何处理这些值。将值赋予 Variant 变量时,Visual Basic 会用最紧凑的表示正确记录这个值。以后的操作可能使 Visual Basic 改变这个用于特定变量的表示。

(Variant 变量不是无类 型变量,而是能够随意改变类型的变量。

)这些内部表示与本章前面在“数据类型”中讨论的数据类型相一致。 注意 Variant 总保持 16 位,无论其中存储了什么数据。对象、字符串和数组,在物理上并非存于 Variant 之中;在这些情况下,用四个字节的 Va riant 来保持对象引用、或者字符串或数组的指针。而真正的数据存在其它地方。

很多时候, 不必了解 Visual Basic 为特殊变量使用哪一种变量类型; Visual Basic 会自动转换类型。

若想了解 Visual Basic 正在使用哪种变量类型, 可使用 VarType 函数。

例如,如果在 Variant 变量中存储二进制值,Visual Basic 就会用 Double 内部表示。如果知道应用程序并不需要 Double 值提供的高精度(以及由 此而来的低速度) ,那么将此值转换成 Single 甚至转换成 Currency 就可以加快计算速度:If VarType (X) = 5 Then X = CSng (X)转换成单精度。对 Array 变量,VarType 的值等于数组元素与数据类型返回值之和。例如,这个数组包含 Double 值:Private Sub Form_Click () Dim dblSample (2) As Double MsgBox VarType (dblSample) End Sub Visual Basic 的今后版本可能会增加新的 Variant 表示,所以,任何根据 VarType 函数的返回值做出判断的代码都应能适当地处理非当前定义的返 回值。

详细信息 关于 VarType 函数的信息,请参阅语言参考中的“VarType 函数” 关于数组的更详细信息,请参阅本章后面的“数组” 关于转换数据类型的 。

详细信息,请参阅本章前面的“数据类型” 。

Variant 变量中存储的 Numeric 值在 Variant 变量中存储整个数时,Visual Basic 使用最紧凑的表示。例如,若是存储不带小数点的微小的数值,Variant 对该值使用 Integer 表示。

如果此后赋予一个较大的数,则 Visual Basic 将使用 Long 值,如果这个数非常大或者有小数部分,则 Visual Basic 将使用 Double 值。

有时想对一个数使用特定表示。例如,为了在以后的计算中避免舍入误差,可能希望 Variant 变量将数值作为 Currency 存储起来。Visual Basic 提 供了几种转换函数,可以用它们将值转换成指定的类型(参阅本章前面的“转换数据类型” 。例如,用 Ccur 函数可将值转换成 Currency 类型:

)PayPerWeek = CCur (hours * hourlyPay) 如果 Variant 变量不含数或者不含可以解释为数的内容,则对 Variant 变量执行数学运算或函数计算就会出错。例如,不能对 U2

这个值进行任何 算术运算,尽管它包含一个数值字符 2,但整个值并非合法的数。同样不能对值 1040EZ 进行任何计算,但是,可以对 +10 或 -1.7E6 进行计算, 因为它们是有效的数。因此经常需要判定 Variant 变量是否包含可以当作数使用的值。IsNumeric 函数可以完成这样的任务:Do anyNumber = InputBox ("Enter a number") Loop Until IsNumeric (anyNumber) MsgBox "The square root is: "

&

Sqr (anyNumber) 当 Visual Basic 将一个非数值的表示(如包含一个数的字符串)转换成数值时,它会使用地区设置(在 Windows 的“控制面板”中规定)来解释千 位分隔符、小数点符号和货币符号。

于是,如果 Windows 的“控制面板”中的国家/地区设置值被设置成美国、加拿大或澳大利亚,则这两个语句将返回 True:IsNumeric ("$100") IsNumeric ("1,560.50") 而下面两个语句则返回 false:IsNumeric ("DM100") IsNumeric ("1.560,50") 但是,如果在 Windows 的“控制面板”中的国家/地区设置值被设置成德国,则情况正好相反:前两个语句返回 false,而后两个语句返回 true。

如果把包含数的 Variant 赋给字符串变量或属性,Visual Basic 自动把数的内部表示转换成字符串。如果想显式地将数转换成字符串,可以用 CStr 函数。还可以用 Format 函数将数转换成字符串,字符串包含某种格式,如货币符,千位分隔符和小数点符号。Format 函数按照 Windows“控制面 板”中的“地区设置”对话框自动使用相应的符号。

详细信息 请参阅的语言参考中的 "Format 函数"

以及关于转换函数的主题。关于编写分布在国外市场的应用程序的更详细信息,请参阅“国际化” 。

Variant 变量中存储的字符串 一般说来,在 Variant 变量中存储和使用字符串不会出什么问题。但是如前所述,有时在使用两个 Variant 值时,"

+ "

运算符的结果可能很含糊。

如果两个 Variant 变量都包含数,则 "

+ "

运算符执行加法运算。如果两个 Variant 变量都包含字符串,则 "

+ "

运算符执行字符串连接。但是, 如果一个值代表数,而另一个值代表字符串,则情况就很复杂了。Visual Basic 首先试图把字符串变成数。如果转换成功,那么 "

+ "

运算符把两 者加在一起;如果不成功,则产生一个“类型不匹配”错误。

为了确保执行的动作为字符串连接,不管变量中的表示如何,都用 &

运算符。例如,以下代码:Sub Form_Click () Dim X , Y X = "6"

Y = "7"

Print X + Y,X &

Y X = 6 Print X + Y,X &

Y End Sub 在窗体上产生如下结果:67 1367 67 注意 Visual Basic 在内部用 Unicode 存储字符串。关于 Unicode 的更详细的信息,请参阅“国际化"。

Variant 变量中存储的 Date/Time 值 Variant 变量还可以包含 Date/Time 值。有几个函数返回 Date/Time 值。例如,DateSerial 返回该年所剩的天数。Private Sub Form_Click () Dim rightnow , daysleft , hoursleft , minutesleft rightnow = Now Now 返回当前的 Date 和 Time。daysleft = Int(DateSerial(Year(rightnow) _ + 1, 1, 1) - rightnow) hoursleft = 24 - Hour (rightnow) minutesleft = 60 - Minute (rightnow) Print daysleft &

"

days left in the year."

Print hoursleft &

"

hours left in the day."

Print minutesleft &

"

minutes left in the hour."

End Sub 还可以对 Date/Time 值进行运算。通过加减一个整数来增加或减少天数;通过加减一个分数来增加或减少时间。所以,加 20 就是加 20 天,而减 掉 1/24 就是减去一小时。

存储在 Variant 变量中的 Date 值的有效范围从公元 0100 年 1 月 1 日到公元 9999 年 12 月 31 日。计算 Date 时不考虑 Gregorian 历法采用 之前的日期。所以如果计算 Gregorian 历法被采用那年(在英国及其殖民地为 1752 年;其它国家/地区则或早一些或晚一些)之前的日期,结果可 能会不正确。

在代码中可以采用 Date/Time 文字,只要用一对 "

# "

号将它们括起来,如同对字符串用一对双引号 ( ""

) 括起来一样。例如,可以将包含 Dat e/Time 值的 Variant 和一串表示 Date 的文字作比较:If SomeDate >

#3/6/93# Then 下面的例子将包含 Date/Time 值的 Variant 变量和一串表示 Date 和 Time 的文字相比较:If SomeDate >

#3/6/93 1:20pm# Then 如果 Date/Time 值不包括 Time,则 Visual Basic 自动将该值的 Time 部分设定为午夜(一天的开始) 。如果 Date/Time 值不包括 Date,则 Visual Basic 自动将该值的 Date 部分设定为公元 1899 年 12 月 30 日。

Visual Basic 接受许多种文字的 Date 和 Time 格式。下面的 Date/Time 值全部有效:SomeDate = #3-6-93 13:20# SomeDate = #March 27 , 1993 1:20am# SomeDate = #Apr-2-93# SomeDate = #4 April 1993# 详细信息 有关用国际格式处理 Date 的信息,请参阅“国际化” 。 用 IsNumeric 函数可测试一个 Variant 变量是否包含一个值,这个值可以看作有效的数值,同样,用 IsDate 函数可测试一个 Variant 变量是否包含 一个值,这个值可以看作有效的 Date/Time 值。然后可用 CDate 函数将该值转换成 Date/Time 值。

例如,以下代码用 IsDate 测试文本框的 Text 属性。如果属性包含被看作有效 Date 的文本,则 Visual Basic 将此文本转换成 Date 并计算到年底 还有几天。

Dim SomeDate , daysleft If IsDate (Text1.Text) Then SomeDate = CDate (Text1.Text) daysleft = DateSerial(Year(SomeDate) + _ 1, 1, 1) - SomeDate Text2.Text = daysleft &

"

days left in the year."

Else MsgBox Text1.Text &

"

is not a valid date."

End If 详细信息 关于各种 Date 和 Time 函数的信息,请参阅的语言参考中的“Date Function” 。

Variant 变量中存储的 Objects 可以将 Objects 存储在 Variant 变量中。当需要高效地处理包括 Objects 在内的各种数据类型时,这可能十分有用。例如,一个数组中的所有元素 都必须具有相同的数据类型。将数组的数据类型设置成 Variant 就可将 Objects 连同其它数据类型一起存入同一个数组中。

数组如果有过用其它语言编程的经历,那么想必会熟悉数组的概念。由于有了数组,可以用相同名字引用一系列变量,并用数字(索引)来识别它们。

在许多场合,使用数组可以缩短和简化程序,因为可以利用索引值设计一个循环,高效处理多种情况。数组有上界和下界,数组的元素在上下界内 是连续的。因为 Visual Basic 对每一个索引值都分配空间,所以不要不切实际声明一个太大的数组。

注意 这一部分讨论的数组是程序中声明的变量数组。它们不同于控件数组,控件数组是在设计时通过设置控件的 Index 属性规定的。变量数组总 是连续的;与控件数组不同的是,不能从一个数组的中部加载或卸载数组元素。

一个数组中的所有元素具有相同的数据类型。当然,当数据类型为 Variant 时,各个元素能够包含不同种类的数据(对象、 字符串 、数值等等) 。

可以声明任何基本数据类型的数组,包括用户自定义类型(请参阅 “再论编程”中的“创建自己的数据类型” 和对象变量(请参阅“用对象编程” 。

) ) 在 Visual Basic 中有两种类型的数组:固定大小的数组— 它总是保持同样的大小,以及在运行时大小可以改变的动态数组。在本章后面的“动态数 组”中将要详细讨论动态数组。

声明固定大小的数组 有三种方法声明固定大小的数组,用哪一种方法取决于数组应有的有效范围:

建立公用数组,在模块的声明段用 Public 语句声明数组。 建立模块级数组,在模块的声明段用 Private 语句声明数组。建立局部数组,在过程中用 Private 语句声明数组。

设定上下界 声明数组时,在数组名之后跟一个用括号括起来的上界。上界不得超过 Long 数据类型的范围(-2,147,483,648 到 2,147,483,647) 。例如,下列数组 声明可出现在模块的声明段:

15 个元素。

21 个元素。Dim Counters (14) As Integer Dim Sums (20) As Double为建立公用数组,直接用 Public 取代 Dim。Public Counters (14) As Integer Public Sums (20) As Double 在过程之中同样的声明使用 Dim:Dim Counters (14) As Integer Dim Sums (20) As Double 第一个声明建立了一个有 15 个元素的数组,其索引号从 0 到 14 。第二个声明建立了一个有 21 个元素的数组,其索引号从 0 到 20 。缺省的 下界为 0。

为了规定下界,用关键字 To 显式提供下界(为 Long 数据类型) :Dim Counters (1 To 15) As Integer Dim Sums (100 To 120) As String 在前述声明中,Counters 的索引值范围从 1 到 15,而 Sums 的索引值范围从 100 到 200。

包含其它数组的数组 有可能建立 Variant 数据类型数组,并与不同数据类型的数组共居一处。以下代码建立两个数组,一个包含整数,而另一个包含 字符串。然后声明 第三个 Variant 数组,并将整数和字符串数组放置其中:Private Sub Command1_Click () Dim intX As Integer 声明计数器变量。声明并放置整数数组。

Dim countersA (5) As Integer For intX = 0 To 4 countersA (intX) = 5 Next intX 声明并放置字符串数组。 Dim countersB (5) As String For intX = 0 To 4 countersB (intX) = "hello"

Next intX Dim arrX (2) As Variant arrX (1) = countersA () arrX (2) = countersB () MsgBox arrX (1) (2) MsgBox arrX (2) (3) End Sub 多维数组 有时需要追踪记录数组中的相关信息。例如,为了追踪记录计算机屏幕上的每一个像素,需要引用它的 X、Y 坐标。这时应该用多维数组存储值。

可用 Visual Basic 声明多维数组。例如,下面的语句声明了一个过程内的 10 × 10 的二维数组。

显示每一个数组的成员。

声明拥有两个成员的新数组。

将其它数组移居到数组。Static MatrixA (9, 9) As Double 可用显式下界来声明两个维数或两个维数中的任何一个:Static MatrixA (1 To 10, 1 To 10) As Double 可以将所有这些推广到二维以上的数组。例如:Dim MultiD (3, 1 To 10, 1 To 15) 这个声明建立了三维数组,大小为 4 × 10 × 15。元素总数为三个维数的乘积,为 600。

注意 在增加数组的维数时,数组所占的存储空间会大幅度增加,所以要慎用多维数组。使用 Variant 数组时更要格外小心,因为他们需要更大的存 储空间。

用循环操作数组 可以用 For 循环嵌套有效的处理多维数组。例如,在 MatrixA 中基于每个元素在数组中的位置为其赋值:Dim I As Integer, J As Integer Static MatrixA(1 To 10, 1 To 10) As Double For I = 1 To 10 For J = 1 To 10 MatrixA (I, J) = I * 10 + J Next J Next I 详细信息 关于循环的详细信息,请参阅本章后面的“循环结构”部分。

动态数组 数组到底应该有多大才合适,有时可能不得而知。所以希望能够在运行时具有改变数组大小的能力。

动态数组就可以在任何时候改变大小。在 Visual Basic 中,动态数组最灵活、最方便,有助于有效管理内存。例如,可短时间使用一个大数组,然 后,在不使用这个数组时,将内存空间释放给系统。

如果不用动态数组,就要声明一个数组,它的大小尽可能达到最大,然后再抹去那些不必要的元素。但是,如果过度使用这种方法,会导致内存的 操作环境变慢。

要创建动态数组,请按照以下步骤执行:

(如果希望数组为公用数组,则)用 Public 语句声明数组,或者, (如果希望数组为模块级,则)在模块级用 Dim 语句声明数组,或者(如果希 望数组为局部数组,则)在过程中用 Static 或 Dim 语句声明数组。给数组附以一个空维数表,这样就将数组声明为动态数组。

Dim DynArray () 用 ReDim 语句分配实际的元素个数。

ReDim DynArray (X + 1) ReDim 语句只能出现在过程中。与 Dim 语句、Static 语句不同,ReDim 语句是一个可执行语句,由于这一语句,应用程序在运行时执行一个操作。

ReDim 语句支持这样的语法,它与固定数组中使用的语法相同。对于每一维数,每个 ReDim 语句都能改变元素数目以及上下界。但是,数组的维 数不能改变。ReDim DynArray (4 to 12) 例如,用第一次声明在模块级所建立的动态数组 Matrix1:Dim Matrix1 () As Integer 然后,在过程中给数组分配空间:Sub CalcValuesNow () . . . ReDim Matrix1 (19, 29) End Sub 这里的 ReDim 语句给 Matrix 分配一个 20 × 30 的整数矩阵(元素总大小为 600) 。还有一个办法,用变量设置动态数组的边界:ReDim Matrix1 (X, Y) 注意 您可以将字符串赋值给大小可变的字节数组。一个字节数组也可以被赋值给一个可变长的字符串。一定要注意字符串中的字节数会随平台而变 化。同一个字符串在 Unicode 平台上的字节数是它在非 Unicode 平台上的两倍。

保留动态数组的内容 每次执行 ReDim 语句时,当前存储在数组中的值都会全部丢失。Visual Basi 重新将数组元素的值置为 Empty(对 Variant 数组) 、置为 0(对 Nu meric 数组) 、置为 零长度字符串(对 String 数组)或者置为 Nothing(对于对象的数组) 。

在为新数据准备数组,或者要缩减数组大小以节省内存时,这样做是非常有用的。有时希望改变数组大小又不丢失数组中的数据。使用具有 Preser ve 关键字的 ReDim 语句就可做到这点。例如,使用 UBound 函数引用上界,使数组扩大、增加一个元素,而现有元素的值并未丢失:ReDim Preserve DynArray (UBound (DynArray) + 1) 在用 Preserve 关键字时,只能改变多维数组中最后一维的上界;如果改变了其它维或最后一维的下界,那么运行时就会出错。所以可这样编程:ReDim Preserve Matrix (10, UBound (Matrix, 2) + 1) 而不可这样编程:ReDim Preserve Matrix (UBound (Matrix, 1) + 1, 10) 详细信息 关于动态数组的更详细信息,请参阅语言参考中的“ReDim 函数” 关于对象数组,请参阅“用对象编程” 。

。VB 编程基础教程三过程概述将程序分割成较小的逻辑部件就可以简化程序设计任务。称这些部件为过程,它们可以变成增强和扩展 Visual Basic 的构件。

过程可用于压缩重复任务或共享任务,例如,压缩频繁的计算、文本与控件操作和操作。

用过程编程有两大好处:

过程可使程序划分成离散的逻辑单元,每个单元都比无过程的整个程序容易调试。一个程序中的过程,往往不必修改或只需稍作改动,便可以成为另一个程序的构件。

在 Visual Basic 中使用下列几种过程:

Sub 过程不返回值。Function 过程返回值。 property 过程返回并指定值,以及设置对象引用。

详细信息 关于属性过程,请参阅“用对象编程”。

关于子过程和函数过程,请参阅下面的主题:

子过程 介绍子过程及其使用。

函数过程 介绍函数过程及其使用。

使用过程 介绍从应用程序内部调用过程。

向过程传递参数 讨论用参数向过程传递数据。

Sub 过程子过程是在响应事件时执行的代码块。将模块中的代码分成子过程后,在应用程序中查找和修改代码变得更容易了。

子过程的语法是:[Private|Public][Static]Sub procedurename (arguments) statementsEnd Sub 每次调用过程都会执行 Sub 和 End Sub 之间的 statements。可以将子过程放入标准模块、类模块和窗体模块中。按照缺省规定,所有模块中的子 过程为 Public(公用的) ,这意味着在应用程序中可随处调用它们。

过程的 arguments 类似于变量声明,它声明了从调用过程传递进来的值。

在 Visual Basic 中应区分通用过程和事件过程这两类子过程。

通用过程 通用过程告诉应用程序如何完成一项指定的任务。一旦确定了通用过程,就必须专由应用程序来调用。反之,直到为响应用户引发的事件或系统引 发的事件而调用事件过程时,事件过程通常总是处于空闲状态。

为什么要建立通用过程呢?理由之一就是,几个不同的事件过程也许要执行同样的动作。将公共语句放入一分离开的过程(通用过程)并由事件过 程来调用它,诚为编程上策。这样一来就不必重复代码,也容易维护应用程序。例如,VCR 示例应用程序使用了一个通用过程,几个不同滚动按钮 的 Click 事件都调用这个通用过程。图 5.7 说明了通用过程的使用。Click 事件中的代码调用按钮管理器的子过程,子过程运行自身的代码,然后 将控制返回到 Click 事件过程。

图 5.7 通用过程如何被事件过程调用事件过程 当 Visual Basic 中的对象对一个事件的发生作出认定时,便自动用相应于事件的名字调用该事件的过程。因为名字在对象和代码之间建立了联系, 所以说事件过程是附加在窗体和控件上的。

一个控件的事件过程将控件的(在 Name 属性中规定的)实际名字、下划线 (_) 和事件名组合起来。例如,如果希望在单击了一个名为 cmdPlay 的命令按钮之后,这个按钮会调用事件过程,则要使用 cmdPlay_Click 过程。一个窗体事件过程将词汇 "Form"、下划线和事件名组合起来。如果希望在单击窗体之后,窗体会调用事件过程,则要使用 Form_Click 过程。

(和 控件一样,窗体也有唯一的名字,但不能在事件过程的名字中使用这些名字。

)如果正在使用 MDI 窗体,则事件过程将词汇 "

MDIForm "

、下划 线和事件名组合起来,如 MDIForm_Load。

所有的事件过程使用相同的语法。

在开始为控件编写事件过程之前先设置控件的 Name 属性,这不失为一个好主意。如果对控件附加一个过程之后又更改控件的名字,那么也必须更 改过程的名字,以符合控件的新名字。否则,Visual Basic 无法使控件和过程相符。过程名与控件名不符时,过程就成为通用过程。

详细信息 Visual Basic 可识别各种窗体和控件的各种事件。关于所有事件的说明,请参阅语言参考。Funtion 过程Visual Basic 包含内置的、或内部的函数,如 Sqr、Cos 或 Chr。此外,还可用 Function 语句编写自己的 Function 过程。

函数过程的语法是:Private|Public][Static]Function procedurename (arguments) [As type] statementsEnd Function 与 Sub 过程一样,Function 过程也是一个独立的过程,可读取参数、执行一系列语句并改变其参数的值。与子过程不同,Function 过程可返回一 个值到调用的过程。在 Sub 过程与 Function 过程之间有三点区别: 一般说来,让较大的语句或表达式的右边包含函数过程名和参数 (returnvalue = function),这就调用了函数。与变量完全一样,函数过程有数据类型。这就决定了返回值的类型。

(如果没有 As 子句,缺省的数据类型为 Variant。

)给 procedurename 自身赋一个值,就可返回这个值。Function 过程返回一个值时,该值可成为较大表达式的一部分。

例如,下面是已知直角三角形两直角边的值,计算第三边(斜边)的函数:Function Hypotenuse (A As Integer, B As Integer) As String Hypotenuse = Sqr (A ^ 2 + B ^ 2) End Function 在 Visual Basic 中调用 Function 过程的方法和调用任何内部函数的方法是一样的:Label1.Caption = Hypotenuse(CInt(Text1.Text), _ CInt(Text2.Text)) strX = Hypotenuse (Width, Height) 详细信息 关于函数过程的详细信息,请参阅语言参考中的“Function 语句” 调用各种类型的过程的技巧,在本章后面的“调用过程”部分有详细讨论。

。使用过程创建新过程 要创建新的通用过程,请 在“代码”窗口输入过程头并按下回车键。过程头以 Sub 或 Function 打头,再接一个名字。例如,可以用以下任一方式输入:

Sub UpdateForm () Function GetCoord () 通过完成新过程的模板, Visual Basic 作出反应。

选择现有过程 要在当前模块中查看过程,请 为了查看现有通用过程,在“代码”窗口的“对象框”中选择“通用” 然后在“过程框”中选择过程。

, -或者- 为查看事件过程,在“代码”窗口的“对象框”中选择适当的对象,然后在“过程框”中选择事件。

要查看其它模块中的过程,请 在“视图”菜单中选取“对象浏览器” 。在“工程/库”框中选择工程。在“类/模块”列表中选择模块,并在“成员”列表中选择过程。选取“查看定义” 。

调用过程 调用过程有诸多技巧,它们与过程的类型、位置以及在应用程序中的使用方式有关。下面的章节说明如何调用 Sub 过程和 Function 过程。

调用 Sub 过程 与 Sub 过程不同,在表达式中,Sub 过程不能用其名字调用。调用 Sub 过程的是一个独立的语句。Sub 过程还有一点与函数不一样,它不会用名 字返回一个值。但是,与 Function 过程一样,Sub 过程也可以修改传递给它们的任何变量的值。

调用 Sub 过程有两种方法:

以下两个语句都调用了名为 MyProc 的 Sub 过程。

Call MyProc (FirstArgument, SecondArgument) MyProc FirstArgument, SecondArgument 注意,当使用 Call 语法时,参数必须在括号内。若省略 Call 关键字,则也必须省略参数两边的括号。

调用函数过程 通常,调用自行编写的函数过程的方法和调用 Visual Basic 内部函数过程(例如 Abs)的方法一样;即在表达式中写上它的名字。下面的语句都调用函数 ToDec。

Print 10 * ToDec X = ToDec If ToDec = 10 Then Debug.Print "Out of Range"

X = AnotherFunction ( 10 * ToDec) 就像调用 Sub 过程那样,也能调用函数。下面的语句都调用同一个函数:Call Year (Now) Year Now 当用这种方法调用函数时,Visual Basic 放弃返回值。

调用其它模块中的过程 在工程中的任何地方都能调用其它模块中的公用过程。可能需要指定这样的模块,它包含正在调用的过程。调用其它模块中的过程的各种技巧,取 决于该过程是在窗体模块中、类模块中还是标准模块中。

窗体中的过程 所有窗体模块的外部调用必须指向包含此过程的窗体模块。如果在窗体模块 Form1 中包含 SomeSub 过程,则可使用下面的语句调用 Form1 中的 过程:Call Form1.SomeSub(arguments) 类模块中的过程 与窗体中调用过程类似,在类模块中调用过程要调用与过程一致并且指向类实例的变量。例如,DemoClass 是类 Class1 的实例:Dim DemoClass as New Class1 DemoClass.SomeSub 但是不同于窗体的是,在引用一个类的实例时,不能用类名作限定符。必须首先声明类的实例为对象变量(在这个例子中是 DemoClass )并用变量 名引用它。

详细信息 可在“用对象编程”中找到关于对象变量和类模块的详细信息。

标准模块中的过程 如果过程名是唯一的,则不必在调用时加模块名。无论是在模块内,还是在模块外调用,结果总会引用这个唯一过程。如果过程仅出现在一个地方, 这个过程就是唯一的。

如果两个以上的模块都包含同名的过程,那就有必要用模块名来限定了。在同一模块内调用一个公共过程就会运行该模块内的过程。例如,对于 M odule1 和 Module2 中名为 CommonName 的过程,从 Module2 中调用 CommonName 则运行 Module2 中的 CommonName 过程,而不是 Modu le1 中的 CommonName 过程。

从其它模块调用公共过程名时必须指定那个模块。例如,若在 Module1 中调用 Module2 中的 CommonName 过程,要用下面的语句:Module2.CommonName (arguments)向过程传递参数过程中的代码通常需要某些关于程序状态的信息才能完成它的工作。信息包括在调用过程时传递到过程内的变量。当将变量传递到过程时,称变量 为参数。

参数的数据类型 过程的参数被缺省为具有 Variant 数据类型。不过,也可以声明参数为其它数据类型。例如,下面的函数接受一个字符串和一个整数:Function WhatsForLunch(WeekDay As String, Hour _ As Integer) As String 根据星期几和时间,返回午餐菜单。

If WeekDay = "Friday"

then WhatsForLunch = "Fish"

Else WhatsForLunch = "Chicken"

End If If Hour >

4 Then WhatsForLunch = "Too late"

End Function 详细信息 关于 Visual Basic 的数据类型,请参阅本章前面部分。也可以在语言参考中查找指定的数据类型。

按值传递参数 按值传递参数时,传递的只是变量的副本。如果过程改变了这个值,则所作变动只影响副本而不会影响变量本身。用 ByVal 关键字指出参数是按值 来传递的。

例如:Sub PostAccounts (ByVal intAcctNum as Integer) . . 这里放语句。

. End Sub 按地址传递参数 按地址传递参数使过程用变量的内存地址去访问实际变量的内容。结果,将变量传递给过程时,通过过程可永远改变变量值。按地址传递参数在 Vi sual Basic 中是缺省的。

如果给按地址传递参数指定数据类型,就必须将这种类型的值传给参数。可以给参数传递一个表达式,而不是数据类型。Visual Basic 计算表达式, 如果可能的话,还会按要求的类型将值传递给参数。

把变量转换成表达式的最简单的方法就是把它放在括号内。例如,为了把声明为整数的变量传递给过程,该过程以字符串为参数,则可以用下面的 语句:Sub CallingProcedure () Dim intX As Integer intX = 12 * 3 Foo (intX) End SubSub Foo (Bar As String) MsgBox Bar End Sub 使用可选的参数 在过程的参数列表中列入 Optional 关键字,就可以指定过程的参数为可选的。如果指定了可选参数,则参数表中此参数后面的其它参数也必是可选 的,并且要用 Optional 关键字来声明。下面两段示例代码假定有一个窗体,其内有一命令按钮和一列表框。

Bar 的值为字符串? 36 ? 。 例如,这段代码提供所有可选参数:Dim strName As String Dim strAddress As StringSub ListText(Optional x As String, Optional y _ As String) List1.AddItem x List1.AddItem y End SubPrivate Sub Command1_Click () strName = "yourname"

Optional strAddress = 12345 提供了两个参数。Call ListText (strName, strAddress) End Sub 而下面的代码并未提供全部可选参数:Dim strName As String Dim varAddress As VariantSub ListText (x As String, Optional y As Variant) List1.AddItem x If Not IsMissing (y) Then List1.AddItem y End If End SubPrivate Sub Command1_Click () strName = "yourname"

数。

Call ListText (strName) End Sub 在未提供某个可选参数时,实际上将该参数作为具有 Empty 值的变体来赋值。上例说明如何用 IsMissing 函数测试丢失的可选参数。

提供可选参数的缺省值 也可以给可选参数指定缺省值。在下例中,如果未将可选参数传递到函数过程,则返回一个缺省值。

未提供第二个参Sub ListText(x As String, Optional y As _ Integer = 12345) List1.AddItem x List1.AddItem y End SubPrivate Sub Command1_Click () strName = "yourname"

数。

Call ListText (strName) “12345” 。

End Sub 使用不定数量的参数 一般说来,过程调用中的参数个数应等于过程说明的参数个数。可用 ParamArray 关键字指明,过程将接受任意个数的参数。于是可以这样来编写 计算总和的 Sum 函数:

添加“yourname”和 未提供第二个参Dim x As Integer Dim y As Integer Dim intSum As IntegerSub Sum (ParamArray intNums ()) For Each x In intNums y = y + x Next x intSum = y End SubPrivate Sub Command1_Click () Sum 1, 3, 5, 7, 8 List1.AddItem intSum End Sub 用命名的参数创建简单语句 对许多内建函数、语句和方法,Visual Basic 提供了命名参数方法来快捷传递参数值。对命名参数,通过给命名参数赋值,就可按任意次序提供任 意多参数。为此,键入命名参数,其后为冒号、等号和值 (MyArgument := "SomeValue") ,可以按任意次序安排这些赋值,它们之间用逗号分开。

注意,下例中的参数顺序和所要参数的顺序相反:Function ListText (strName As String, Optional strAddress As String) List1.AddItem strName List2.AddItem strAddress End SubPrivate Sub Command1_Click () ListText strAddress:=”12345”, strName:="Your Name"

End Sub 如果过程有若干不必总要指定的可选参数,则上述内容更为有用。

确定对命名参数的支持 要确定哪一个函数、语句和方法支持命名参数,用“代码”窗口中的“AutoQuickInfo”功能,检查“对象浏览器” 或者参阅语言参考。使用命名参数时要 , 注意以下几点:

在 Visual Basic (VB) 对象库中的对象的方法不支持命名参数。

Visual Basic for applications (VBA) 对象库中的所有的语言关键字都支持命名的 而 参数。在语法中,命名参数是用粗体和斜体字表示的。所有其它参数只用斜体字表示。

重点 使用命名参数时不能省略所需参数的输入。

可以只省略可选参数。

对于 Visual Basic (VB) 和 Visual Basic for applications (VBA) 对象库, “对 象浏览器”对话框将可选参数用方括号 [ ] 括起来。

详细信息 请参阅语言参考中的 "ByVal"、"ByRef"、"Optional"

和 "ParamArray"。VB 编程基础教程四控制结构概述有了控制结构就可控制程序执行的流程。如果未复选控制流语句,程序便从左至右、自顶向下地贯穿这些语句。有些简单程序可以只用单向流程来 编写,有些流程可以依靠运算符的优先级来控制,但任何编程语言的效力和用途皆由其通过结构和循环改变语句顺序的能力而得。

关于控制结构的详细信息,请参阅下面的主题:判定结构 用于分支的判定结构。

循环结构 用于重复处理的循环结构。

使用控制结构 在代码中运用控制结构的基础。

判定结构Visual Basic 过程能够测试条件式,然后根据测试结果执行不同的操作。Visual Basic 支持的判定结构有:If...ThenIf...Then...Else Select Case If...Then 用 If...Then 结构有条件地执行一个或多个语句。单行语法和多行块语法都可以使用:If condition Then statementIf condition Then statementsEnd If Condition 通常是比较式,但它可以是任何计算数值的表达式。Visual Basic 将这个值解释为 True 或 False:一个为零的数值为 False,而任何非 零数值都被看作 True。若 condition 为 True,则 Visual Basic 执行 Then 关键字后面的所有 statements。可以使用单行或多行语法有条件地执行 一个语句(下面两个例子等价) :If anyDate <

Now Then anyDate = NowIf anyDate <

Now Then anyDate = Now End If 注意:If...Then 的单行格式不用 End If 语句。如果 condition 为 True 时要执行多行代码,则必须使用多行块 If...Then...End If 语法。If anyDate <

Now Then anyDate = Now Timer1.Enabled = False End If 定时器控制失效。If...Then...Else 用 If...Then...Else 块定义几个语句块,执行其中一个语句:If condition1 Then [statementblock-1] [ElseIf condition2 Then [statementblock-2]] ... [Else [statementblock-n]]End If Visual Basic 首先测试 condition1。如果它为 False,Visual Basic 就测试 condition2,依次类推,直到找到一个为 True 的条件。当它找到一个为 True 的条件时,Visual Basic 就会执行相应的语句块,然后执行 End If 后面的代码。作为一个选择,可以包含 Else 语句块,如果条件都不是 Tr ue,则 Visual Basic 执行 Else 语句块。 If...Then…ElseIf 只是 If...Then...Else 的一个特例。注意,可以使用任意数量的 ElseIf 子句,或者一个也不用。可以有一个 Else 子句,而不管有 没有 ElseIf 子句。

例如,应用程序可以根据菜单控件数组中哪个控件被单击而采取相应的动作:Private Sub mnuCut_Click (Index As Integer) If Index = 0 Then CopyActiveControl ClearActiveControl ElseIf Index = 1 Then CopyActiveControl ElseIf Index = 2 Then ClearActiveControl Else “粘贴”命令。

“清除”命令。

“复制”命令。

“剪切”命令。

调用通用过程。PasteActiveControl End If End Sub 注意,总是可以添加更多的 ElseIf 块到 If...Then 结构中去。但是,当每个 ElseIf 都将相同的表达式比作不同的数值时,这个结构编写起来很乏 味。在这种情况下可以使用 Select Case 判定结构。

详细信息 请参阅语言参考中的“If...Then...Else 语句” 。Select Case Visual Basic 提供 Select Case 结构替代 If...Then...Else,从而可在多个语句块中有选择地执行其中一个。Select Case 语句的能力与 If...Then...Els e 语句类似,但对多重选择的情况,Select Case 语句使代码更加易读。

Select Case 在结构的上方处理一个测试表达式并只计算一次。然后,Visual Basic 将表达式的值与结构中的每个 Case 的值进行比较。如果相等, 就执行与该 Case 相关联的语句块。Select Case testexpression [Case expressionlist1 [statementblock-1]] [Case expressionlist2 [statementblock-2]] . ..[Case Else [statementblock-n]] End Select 每一个 expressionlist 是一个或几个值的列表。如果在一个列表中有多个值,就用逗号把值隔开。每一个 statementblock 中含有零个或多个语句。

如果不止一个 Case 与测试表达式相匹配,则只对第一个匹配的 Case 执行与之相关联的语句块。如果在表达式列表中没有一个值与测试表达式相 匹配,则 Visual Basic 执行 Case Else 子句(此项是可选的)中的语句。

调用通用过程。CopyActiveControl ClearActiveControl Case 1“复制”命令。

“清除”命令。

“粘贴”命令。CopyActiveControl Case 2ClearActiveControl Case asteActiveControl Case Else frmFind.Show End Select End Sub 注意 Select Case 结构每次都要在开始处计算表达式的值。而 If...Then...Else 结构为每个 ElseIf 语句计算不同的表达式。只有在 If 语句和每一个 ElseIf 语句计算相同表达式时,才能用 Select Case 结构替换 If...Then...Else 结构。

循环结构 显示找到的对话框。循环结构允许重复执行一行或数行代码。Visual Basic 支持的循环结构有:Do...LoopFor...NextFor Each...Next Do...Loop 用 Do 循环重复执行一语句块,且重复次数不定。Do...Loop 语句有几种演变形式,但每种都计算数值条件以决定是否继续执行。如同 If...Then c ondition 必须是一个数值或者值为 True(非零)或 False(零)的表达式。

在下面的 Do...Loop 循环中,只要 condition 为 True 就执行 statements。 Do While condition statementsLoop 当 Visual Basic 执行这个 Do 循环时会首先测试 condition。如果 condition 为 False(零) ,则跳过所有语句。如果 condition 为 True(非零) , 则 Visual Basic 执行语句,然后退回到 Do While 语句再测试条件。

因此,只要 condition 为 True 或非零,循环可以随意执行多少次。如果 condition 一开始便为 False,则不会执行语句。例如,以下过程将计算某 一目标字符串在另一字符串中出现的次数,只要发现目标串就执行循环:Function CountStrings (longstring, target) Dim position, count position = 1 Do While InStr (position, longstring, target) position = InStr(position, longstring, target)_ + 1 count = count + 1 Loop CountStrings = count End Function 如果目标字符串未出现在另一个字符串中,则 InStr 返回 0,而且不再执行循环。

Do...Loop 语句的另一种演变形式是先执行语句,然后在每次执行后测试 condition。这种形式保证 statements 至少执行一次:Do statementsLoop While condition 其它两种演变形式类似于前两个,所不同的是,只要 condition 为 False 而不是 True,它们就执行循环。

循环零次或多次 至少循环一次 Do Until condition statements Loop Do statements Loop Until condition. For...Next 在不知道循环内需要执行多少次语句时,宜用 Do 循环。但是,在知道要执行多少次时,则最好使用 For...Next 循环。与 Do 循环不同, For 循 环使用一个叫做计数器的变量,每重复一次循环之后,计数器变量的值就会增加或者减少。For 循环的语法如下:For counter = start To end [Step increment] statementsNext [counter] 参数 Counter、Start、end 和 increment 都是数值型的。

注意 increment 参数可正可负。如果 increment 为正,则 Start 必须小于等于 end,否则不能执行循环内的语句。如果 increment 为负,则 Start必须大于等于 end,这样才能执行循环体。如果没有设置 Step,则 increment 缺省值为 1。

在执行 For 循环时,Visual Basic 设置 counter 等于 start。测试 counter 是否大于 end。若是的话,则 Visual Basic 退出循环。

(若 increment 为负,则 Visual Basic 测试 counter 是否小于 end。

) 执行语句。counter 增加一,或者增加 increment(如果已指定的话) 。重复步骤 2 到步骤 4。

以下代码打印出所有有效的屏幕字体名:Private Sub Form_Click () Dim I As Integer For i = 0 To Screen.FontCount Print Screen.Fonts (i) Next End Sub 在 VCR 示例应用程序中,HighlightButton 过程使用 For...Next 循环,一步步经过 VCR 窗体的控件集合,并显示适当的 Shape 控件:Sub HighlightButton (MyControl As Variant) Dim i As Integer For i = 0 To frmVCR.Controls.Count - 1 If TypeOf frmVCR.Controls (i) Is Shape Then If frmVCR.Controls (i).Name = MyControl Then frmVCR.Controls (i).Visible = True Else frmVCR.Controls (i).Visible = False End If End If Next End SubFor Each...Next For Each...Next 循环与 For...Next 循环类似,但它对数组或对象集合中的每一个元素重复一组语句,而不是重复语句一定的次数。如果不知道一个 集合有多少元素, For Each...Next 循环非常有用。

For Each...Next 循环的语法如下:For Each element In group statementsNext elementt 例如,下面的子过程打开 Biblio.mdb,把每一个表的名字加到列表框中。Sub ListTableDefs () Dim objDb As Database Dim MyTableDef as TableDef Set objDb = OpenDatabase("c:\vb\biblio.mdb", _ True, False) For Each MyTableDef In objDb.TableDefs () List1.AddItem MyTableDef.Name Next MyTableDef End Sub 请记住使用 For Each...Next 时的几点限制:

对集合,element 只能是 Variant 变量,或一般的 Object 变量,或“对象浏览器”中列出的对象。对数组,element 只能是 Variant 变量。For Each...Next 不能与用户自定义类型的数组一起使用,因为 Variant 不可能包含用户自定义类型。使用控制结构 嵌套控制结构 可以把控制结构放入另一个控制结构之内(例如在 For...Next 循环中的 If...Then 块) 。一个控制结构内部包含另一个控制结构叫做 nest(嵌套) 。

在 Visual Basic 中,控制结构的嵌套层数没有限制。按一般习惯,为了使判定结构和循环结构更具可读性,总是用缩排方式书写判定结构或循环 的正文部分。

例如,下面的过程要把打印机和屏幕共有的字体名全部打印出来:Private Sub Form_Click () Dim SFont, PFont For Each SFont In Screen.Fonts () For Each PFont In Printer.Fonts () If SFont = PFont Then Print SFont End If Next PFont Next SFont End Sub 注意,第一个 Next 关闭了内层的 For 循环,而最后一个 For 关闭了外层的 For 循环。同样,在嵌套的 If 语句中,End If 语句自动与最靠近的 前一个 If 语句配对。嵌套的 Do...Loop 结构的工作方式也是一样的,最内圈的 Loop 语句与最内圈的 Do 语句匹配。

退出控制结构 用 Exit 语句可以直接退出 For 循环、Do 循环、子过程或函数过程。Exit 语句的语法很简单:Exit For 在 For 循环中出现的次数没有限制,Exi t Do 在 Do 循环中出现的次数也没有限制。For counter = start To end [Step increment] [statementblock] [Exit For] [statementblock]Next [counter[, counter] [,...]]Do [{While | Until} condition] [statementblock] [Exit Do] [statementblock]Loop Exit Do 语句可以在 Do 循环语法的所有版本中使用。 Exit For 和 Exit Do 非常有用,因为它有时适于立即退出循环,而且不再执行循环中的任何进一步迭代或者语句。例如,在前面的打印屏幕和打 印机共有字体的例子中,程序不断将打印机字体和给定的屏幕字体作比较,甚至在已经找到了一个相符的打字机字体后还在继续寻找。对这个函数 有一个效率更高的改进版,在此,只要找到相匹配的字体后就立即退出循环:Private Sub Form_Click () Dim SFont, PFont For Each SFont In Screen.Fonts () For Each PFont In Printer.Fonts () If SFont = PFont Then Print Sfont Exit For End If Next PFont Next SFont End Sub 正如此例所表明的, Exit 语句几乎总是出现在 If 语句或 Select Case 语句内部,而 If 语句或 Select Case 语句在循环内嵌套。

用 Exit 语句中断循环时,计数器变量的值会因退出循环的方式而不同:

在完成循环时,计数器的值等于上限值加上步进值。

退出内圈循环。在提前退出循环时,计数器变量保持其值,并遵从有关取值范围的一般规则。在集合之外叠代时,如果计数器变量为 Object 类型,则其值为 Nothing;如果计数器变量为 Variant 类型,则其值为 Empty。

退出子过程或函数过程 也可从控制结构内部退出过程。Exit Sub 和 Exit Function 的语法,和上一节“退出控制结构”中的 Exit For 和 Exit Do 相似。Exit Sub 可以出现 在子过程主体内的任何地方,出现的次数随需要而定。

当过程已完成每个任务并可直接返回时,Exit Sub 和 Exit Function 是非常有用的。例如,如果想改动前面的例子,使得对查找到的打印机和屏幕 的共有字体,只打印其中的第一个,则可用 Exit Sub :Private Sub Form_Click () Dim SFont, PFont For Each SFont In Screen.Fonts () For Each PFont In Printer.Fonts () If SFont = PFont Then Print Sfont Exit Sub End If Next PFont Next SFont 退出过程。 End SubVB 编程基础教程五使用对象在 Visual Basic 中创建应用程序之际,也就是和对象打交道之时了。可以使用 Visual Basic 提供的对象— 比如控件、窗体和数据访问对象。也可 以在一个 Visual Basic 应用程序内部控制另一个应用程序对象。甚至还可建立自己的对象,定义它们的属性和方法。

以下主题将详细讨论对象:

对象是什么 介绍对象的基本概念。

用对象能做什么 讨论应用程序中使用对象的几种方法。

使用对象初步 介绍对象的属性和方法。

对象之间的关系 讨论对象的层次、集合和容器。

创建对象 讨论在运行时如何创建和使用对象。

对象是什么对象是代码和数据的组合,可以作为一个单位来处理。对象可以是应用程序的一部分,比如可以是控件或窗体。整个应用程序也是一个对象。下表 列出了在 Visual Basic 中可能用到的几种类型的对象:

示例 描述 命令按钮 窗体上的控件,象命令按钮和框架,它们都是对象。

窗体 Visual Basic 工程中的每一个窗体都是独立的对象。

是对象,并且还包含其他对象,如字段、索引等。

图表 Microsoft Excel 中的图表是对象。对象从何而来 Visual Basic 中的每个对象都是用类定义的。用饼干模子和饼干之间的关系作比,就会明白对象和它的类之间的关系。饼干模子是类。它确定了每 块饼干的特征,比如大小和形状。用类创建对象。对象就是饼干。

下面再用两个例子进一步说明 Visual Basic 中类与对象之间的关系。

在 Visual Basic 的“工具箱”上,控件代表类。直到在窗体上画出这些被称作控件的对象为止,它们实际上并不存在。在创建控件之时也就是在复制 控件类,或建立控件类的实例。这个类实例就是应用程序中引用的对象。在设计时操作的窗体是类。在运行时,Visual Basic 建立窗体的类实例。

“属性”窗口显示 Visual Basic 应用程序中的对象的类和 Name 属性,如图 5.8 所示。 图 5.8 “属性”窗口中显示的对象和类名把对象看作是类的原原本本的复制品,从而建立所有对象。一旦它们以单个对象的形式存在,属性就可改变。例如,如果在窗体上画了三个命令按 钮,则每个命令按钮对象都是命令按钮类的实例。

每个对象都具有一组由类定义的公共的特征和功能(属性、方法和事件)。但是,每个对象都有 自己的名字,都能分别设置成有效或无效,都能放在窗体的不同位置,等等。

为简单起见,本章之外的大部分内容将不过多引用对象的类。例如,只要记住术语“ListBox 控件”意味着“列表框类的一个实例”。

用对象能做什么对象可提供现成代码,省却书写麻烦。例如,可以自己创建打开文件和保存文件的对话框,但实际上大可不必。取而代之的是利用 Visual Basic 提 供的 CommonDialog 控件(一个对象) 。虽然用户也能撰写日程管理和资源管理的程序,但也大可不必。在此亦可使用 Microsoft Project 提供的 C alendar、Resources 和 Task 对象。

可把 Visual Basic 内部的控件结合在一起,也可使用其它应用程序提供的对象。考虑把下列对象放入 Visual Basic 窗体:

Microsoft Excel Chart 对象Microsoft Excel Worksheet 对象Microsoft Word Document 对象 可用这些对象建立如图 5.9 所示的支票簿应用程序。由于不必书写代码,重建已由 Microsoft Excel 和 Word 等对象提供的功能,因而节省很多时 间。

用对象能做什么对象可提供现成代码,省却书写麻烦。例如,可以自己创建打开文件和保存文件的对话框,但实际上大可不必。取而代之的是利用 Visual Basic 提 供的 CommonDialog 控件(一个对象) 。虽然用户也能撰写日程管理和资源管理的程序,但也大可不必。在此亦可使用 Microsoft Project 提供的 C alendar、Resources 和 Task 对象。

Microsoft Excel Chart 对象Microsoft Excel Worksheet 对象Microsoft Word Document 对象 可用这些对象建立如图 5.9 所示的支票簿应用程序。由于不必书写代码,重建已由 Microsoft Excel 和 Word 等对象提供的功能,因而节省很多时 间。

图 5.9 略 使用对象初步Visual Basic 对象支持属性、方法和事件。在 Visual Basic 中,称对象的数据(设置和属性)为属性,称各种可在对象上操作的过程为方法。事件 是可被对象识别的动作,例如单击鼠标和按下键盘键,还可编写代码来响应事件。

改变对象的属性就可改变对象的特性。用收音机打比方,收音机的一个属性是音量。用 Visual Basic 的行话来说,就是收音机有个“Volume”属性, 改变其值就可调节音量大小。假定收音机的音量值可设置在 0 到 10 之间。

如果能够通过 Visual Basic 控制收音机,则可在一个过程中写代码, 把“Volume”属性值从 3 提高到 5,使声音更响一些:Radio.Volume = 5 除了属性以外,对象还有方法。方法和属性都是对象的一部分。一般说来,方法就是要执行的动作,而属性就是要设置或检索的特性。以拨号打电 话为例。可以说电话有一个“拨号”方法,拨一个 7 位电话号码的语法就是:Phone.Dial 5551111 对象还有事件。当对象的某方面有变动时就触发了事件。例如,收音机可能有“VolumeChange”事件。电话可能有“Ring”事件,等等。

用属性控制对象 个别属性随着可以设置和取得它们的值的时间不同而不同。有的属性可在设计时设置。可在“属性”窗口设置这些属性的值而无需编写任何代码。而 有的属性在设计时是不可用的;因此,这些属性只有通过代码在运行时设置。

在运行时可以设置并可获得值的属性叫做读写属性。在运行时只能读取的属性叫做只读属性。

设置属性值 在想改变对象的外观或特性时设置属性的值。例如,通过改变 TextBox 控件的 Text 属性,就可以改变文本框的内容。

用下列语法设置属性值: object.property = expression 下面是设置属性的语句:

设置 Top 属性为 200 缇。

显示文本框。

在文本框中显示 "hello"。Text1.Top = 200 Text1.Visible = True Text1.Text = "hello"

读取属性值想要在代码执行附加动作(例如给另一个对象赋值)之前得知对象的状态,这时就要读取属性值。例如,在运行代码之前能够返回 TextBox 控件的 Text 属性值,以确定文本框的内容,这里,代码可能改变值。

在大多数情况下可以用以下语法获得属性值:variable = object.property 属性值可以作为较复杂的表达式的一部分,而不必将属性赋予变量。下面的代码计算控件数组中的一个新成员的 Top 属性,它等于前一个成员的 Top 属性加上 400。Private Sub cmdAdd_Click ()

[语句] optButton (n).Top = optButton (n-1).Top + 400

[语句] End Sub 提示 如果不只一次使用一个属性值,而且将这个值存储到一个变量中,则代码执行起来会更快。

用方法来执行动作 方法能够影响属性值。例如在用收音机打比方的例子中,SetVolume 方法改变了 Volume 属性。与此类似,在 Visual Basic 中列表框具有 List 属 性,而 Clear 和 AddItem 方法可以改变这一属性。

在代码中使用方法 在代码中使用方法时如何书写语句,这取决于该方法要求多少参数,以及是否返回一个值。如果方法不要求参数,则用以下语法编写代码:object.method 下例中,用 Refresh 方法重画图片框:

强迫重画控件。Picture1.Refresh有些方法,如上面的 Refresh ,既无参数又不返回值。

如果方法要用多个参数,就用逗号将它们分开。例如, Circle 方法就要用代表窗体上圆的位置、半径和颜色的参数:

画一个半径为 1200 缇的蓝色园。

Form1.Circle (1600, 1800), 1200, vbBlue 如果要保存方法的返回值,就必须把参数用括号括起来。例如, GetData 方法从剪贴板返回一张图片:Picture = Clipboard.GetData (vbCFBitmap) 如果没有返回值,则参数不会出现在括号中。例如,AddItem 方法没有返回值。

在列表框中添加 "yourname"。List1.AddItem "yourname"详细信息 关于 Visual Basic 对所有方法提供的语法和参数,请参阅语言参考 对象之间的关系在同一窗体上放置两个命令按钮时,它们是两个具有不同 Name 属性设置值(Command1 和 Command2)的分开的对象,但都分享同一个类— 命 令按钮。

它们也共享这样一个特征,即它们在同一窗体上。在本章前面已看到,窗体上的控件也包含在窗体中。这就把控件放在一个层次上。要引用控件就 必须先引用窗体,就如同打电话拨号一样,首先要拨国家/地区号码或区域号码,然后再拨具体的电话号码。

这两个命令按钮也共享这样一个特征,即它们都是控件。所有控件都具有公共特性,使它们不同于窗体以及 Visual Basic 环境中的其它对象。以下 章节中将说明 Visual Basic 如何用集合使相关的对象分组。

对象的层次 对象层次提供了一种组织结构,它决定了对象间的相互关系以及访问它们的方法。在大多数情况下不必考虑 Visual Basic 对象的层次。但是:

在操作其它应用程序的对象时,应当熟悉那个应用程序的对象层次。关于定位对象层次的信息,请参阅“用部件编程” 。在使用数据访问对象时,应当熟悉数据访问对象层次。就象在 Professional Features 一书上的《数据访问对象指南》部分描述的那样,该书包括在 Visual Basic 的版和企业版中。

在 Visual Basic 中,一个对象包含其它对象的一般情况时有发生。

下面我们要详细讨论。

使用对象集合 集合对象有自己的属性和方法。对象集合中的对象作为集合的成员被引用。集合中的每个成员从 0 开始顺次编号;这就是成员的索引号。例如,控 件集合包含已给定窗体上的所有控件 ,如图 5.10 所示。如果对集合中的所有对象都必须执行相同操作,则可用集合简化代码。

图 5.10 控件集合 例如,下列代码遍历控件集合,并在列表框中列出每个成员的名字。Dim MyControl as Control For Each MyControl In Form1.Controls 把每个控件的名字送到列表框。

List1.AddItem MyControl.Name Next MyControl 应用集合成员的属性与方法 有两种通用方法可用来对集合对象成员寻址:

指定成员的名称。以下两个表达式等价:

Controls ("List1") Controls!List1 利用成员的索引号:

Controls (3) 一旦能够从整体上对全体成员寻址,而且还能够个别地对单个成员寻址,就可用下面随便一种方式应用属性和方法:

将 ListBox 控件的 Top 属性设置为 200。

Controls!List1.Top = 200 -或者-Dim MyControl as Control For Each MyControl In Form1.Controls () 将每一个成员的 Top 属性设置为 200。

MyControl.Top = 200 Next MyControl 包含其它对象的对象 在 Visual Basic 中,一些对象包含其它对象。例如,窗体通常包含一个或数个控件。把一个对象当作其它对象的容器,这样做的好处在于,在代码 中引用容器即可明了要使用哪个对象。例如,图 5.11 说明在一个应用程序中可有两个不同的窗体,一个用来输入应付帐交易,另一个用来输入应 收帐交易。

图 5.11 两个不同窗体可以包含同名的控件两个窗口可以有名为 IstAcctNo 的列表框。通过引用包含列表框的窗体就可准确指定要使用的列表框:frmReceivable.lstAcctNo.AddItem 1201 -或者- frmPayable.lstAcctNo.AddItem 1201 Visual Basic 中的公共集合 在 Visual Basic 中一个对象包含其它对象的一般情况时有发生。下表简要叙述 Visual Basic 中最常用的集合。

集合 描述 Forms 包含载入的窗体。

Controls 包含窗体上的控件。

Printers 包含可用的打印机对象。在 Visual Basic 中也可实现对象控制。

详细信息 关于对象容器的详细信息,请参阅“再论编程”中的“使用集合替代数组” 关于打印机集合的信息,参阅“使用文本和图形” 关于窗体集合和 。

控件集合的详细信息,请参阅语言参考。

容器属性 在窗体内,可用 Container 属性改变对象的容器。以下控件可包含其它控件:

Frame 控件PictureBox 控件ToolBar 控件(仅对版和企业版而言) 如何在窗体上将命令按钮从一个容器移动到另一个容器,该例对此作了演示。打开新工程,并在窗体上画出 Frame 控件、PictureBox 控件和 Com mandButton 控件。

下列代码在窗体单击事件中,这些代码使计数器变量增加,并通过 Select Case 循环使命令按钮在容器之间移动。Private Sub Form_Click () Static intX as Integer Select Case intX Case 0 Set Command1.Container = Picture1 Command1.Top= 0 Command1.Left= 0Case 1 Set Command1.Container = Frame1 Command1.Top= 0 Command1.Left= 0 Case 2 Set Command1.Container = Form1 Command1.Top= 0 Command1.Left= 0End Select intX = intX + 1 End Sub 详细信息 请参阅语言参考中的“Container 属性” 。

对象之间的通讯 除了在 Visual Basic 中使用和创建对象外,还可与其它应用程序通讯并在自己的应用程序中操作其它应用程序的对象。在应用程序之间共享数据的 能力是 Microsoft Windows 操作系统的关键性能之一。有了 Visual Basic,与其它应用程序进行通讯变得极为灵活。

详细信息 关于使用其它应用程序的对象及其通讯的详细信息,请参阅“用部件编程” 。

创建对象创建对象的最简单方法是在“工具箱”中双击控件。但是,对 Visual Basic 中的所有可用对象以及来自其它应用程序的所有可用对象,要想充分体现 它们的优势,可在运行时用 Visual Basic 的可编程性能创立对象。

用对象变量创建对象引用。用类模块“从零开始”创建自己的对象。用集合对象创建自己的集合。

详细信息 其它章节会介绍如何访问对象。例如,在“用部件编程”中将讨论 CreateObject 和 GetObject 函数。

使用对象变量 除了存储值以外,变量可引用对象。如同给变量赋值一样,基于下列相同理由,可把对象赋给变量:

变量名往往比变量所含的值(或者,在此情况下,所含值就是它们引用的对象)短而好记。在运行代码时,为了引用其它对象,应改变变量。引用包含对象的变量比反复引用对象本身有更高的效率。

使用对象变量与使用常规变量一样,只不过多了把对象赋予变量这一步: 首先声明变量:

Dim variable As class 然后把对象赋予变量:

Set variable = object 声明对象变量 声明对象变量的方法和声明其它变量一样,要用 Dim、ReDim、Static、Private 和 Public。仅有的不同在于可选的 New 关键字和 Class 参数,本 章后面将会对 New 关键字和 Class 参数都作介绍。语法是:{Dim | ReDim | Static | Private | Public} variable As [New] class 例如,可以声明一个对象变量,它引用应用程序中的被称做 frmMain 的窗体:Dim FormVar As New frmMain 的对象变量。声明一个类型为 frmMain也可以声明一个对象变量,它引用应用程序中的任何窗体:Dim anyForm As Form一般窗体变量。类似地,可以声明一个对象变量,它能够引用应用程序中的任何文本框:Dim anyText As TextBox可以引用任何文本框(但只能是一个文本框) 。

还可以声明一个对象变量,它能够引用任何类型的控件:Dim anyControl As Control一般控件变量。注意,可以声明一个引用应用程序中的指定窗体的窗体变量,但不能声明引用特定控件的控件变量。可以声明能够引用控件的特定类型(如 TextBo x 或列表框)的控件变量,但不是引用那种类型的一个特定控件(如 txtEntry 或 List1) 。但是,可把特定的控件赋予那种类型的变量。例如,对于 具有列表框 lstSample 的窗体可以这样编码:Dim objDemo As ListBox Set objDemo = lstSample 赋值对象变量 用 Set 语句将对象赋予对象变量:Set variable = object 无论何时,只要希望对象变量引用对象,就可使用 Set 语句。 有时可用对象变量,尤其可用控件变量直接缩短要键入的代码。例如,原来的代码是这样的:If frmAccountDisplay!txtAccountBalance.Text <

0 Then frmAccountDisplay!txtAccountBalance.BackColor = 0 End If 如果使用控件变量,程序就可显著缩短:

frmAccountDisplay!txtAccountBalance.ForeColor = 255Dim Bal As TextBox Set Bal = frmAccountDisplay!txtAccountBalance If Bal.Text <

0 Then Bal.BackColor = 0 Bal.ForeColor = 255 End If 特定对象类型与一般对象类型 特定的对象变量必须引用特定类型的对象或类。特定的窗体变量只能引用应用程序中的一个窗体(尽管可在该窗体的诸多实例中引用其中之一) 。与 此相似,特定的控件变量只能引用应用程序中的特定类型的控件,比如 TextBox 或者列表框。请看一例,打开新的工程,在窗体中放置一文本框。

将下列代码添加到窗体中:Private Sub Form_Click () Dim anyText As TextBox Set anyText = Text1 anyText.Text = "Hello"

End Sub 运行应用程序并单击窗体。文本框的 Text 属性将变成 "Hello"。

一般对象变量可在多种特定对象类型中引用其中一种。例如,一般窗体变量可引用应用程序中的任何窗体;一般控件变量可引用应用程序中任何窗 体上的任何控件。请看一例,打开新的工程并在窗体中按任意顺序放置若干 Frame、Label 和 CommandButton 控件。将下列代码添加到窗体中:Private Sub Form_Click () Dim anyControl As Control Set anyControl = Form1.Controls (3) anyControl.Caption = "Hello"

End Sub 运行程序并单击窗体。刚才放入窗体中的第三个控件的标题将变成 "Hello"。

Visual Basic 中有四种一般对象:

一般对象类型 可引用的对象 Form 应用程序中的任何窗体(包括 MDI 子窗体和 MDI 窗体) 。

Control 应用程序中的任何控件。 MDIForm 应用程序中的 MDI 窗体(如果应用程序有 MDI 窗体的话) 。

Object 任何对象。在不知道变量运行时是否引用特定类型的对象时,一般对象变量是很有用的。例如,如果要书写代码,并使之在应用程序的任何窗体中都可操作, 则必须使用一般窗体变量。

注意 由于应用程序中只能有一个 MDI 窗体,因此不必使用一般的 MDIForm 类型。无论何时,一旦需要声明引用 MDI 窗体的窗体变量,就可用 特定的 MDIForm 类型(或者是 MDIForm1,或者是对 MDI 窗体的 Name 属性指定的任何名称) ,而不用一般的 MDIForm 类型。实际上,由于 在运行应用程序前,Visual Basic 就能够决定引用特定窗体类型的属性和方法,因此总应使用特定的 MDIForm 类型。

只是出于完整性的考虑才提供一般的 MDIForm 类型;在 Visual Basic 的今后版本中,单个应用程序中可以拥有多个 MDI 窗体,这将是非常有用 的。

作为对象的窗体 窗体最常用到的是构造应用程序界面,但也常常是应用程序中其它模块调用的对象。窗体与类模块关系密切。两者之间的主要区别在于,窗体是可 视对象,而类模块却没有可视界面。

添加自定义方法和属性 可对窗体添加自定义方法和属性,并可从应用程序中的其它模块访问它们。为了创建窗体的新方法,请添加用 Public 声明的过程。

自定义 Form1 的方法。

Public Sub LateJobsCount () . .

<me>

. End Sub 可用下面这个语句从其它模块调用 LateJobsCount 过程:Form1.LateJobsCount 创建窗体的新属性就象在窗体模块中声明一个公用变量那样简单:Public IDNumber As Integer 可用下面两个语句从其它模块设置和返回 Form1 的 IDNumber 值:Form1.IDNumber = 3 Text1.Text = Form1.IDNumber 也可用 Property 过程向窗体添加自定义属性。

详细信息 “用对象编程”提供了 Property 过程的详细材料。 注意 不必加载窗体就可调用窗体的变量或自定义方法, 还可设置窗体的自定义属性。

于是, 不必将窗体加载到内存就可运行有关窗体的代码。

同样, 引用控件而不引用其属性或方法时也不会加载窗体。

使用 New 关键字 用 New 关键字创建新对象,这个对象被视为它的类所定义的对象。可用 New 创建集合、窗体的实例以及类模块中定义的类。

在窗体上使用 New 关键字 在设计时创建的窗体是类。可用 New 关键字创建这个类的新实例。为了看到这一工作过程,请在窗体上画出一个命令按钮和其它几个控件。在“属 性”窗口中将窗体的 Name 属性设置成 Sample。在命令按钮的 Click 事件过程中添加下列代码:Dim x As New Sample x.Show 运行应用程序,并单击命令按钮数次。把最前面的窗体移到一边。因为窗体是具有可视界面的类,所以可看到附加副本。每个窗体在相同位置上都 有相同控件,而且这些位置也正是窗体在设计时的位置。

注意 要使窗体变量和已加载窗体的实例一直存在,请用 Static 或 Public 变量,而不要用局部变量。

也可将 New 关键字与 Set 语句并用。请试用命令按钮的 Click 事件过程中的代码:Dim f As Form1 Set f = New Form1 f.Caption = "hello"

f.Show 将 New 关键字和 Set 语句并用会加快运行速度,因此,这种方法值得推荐。

对其它对象使用 New 关键字 可用 New 关键字从类模块中定义的类创建集合和对象。试用下例说明这一工作过程。

此例说明了 New 关键字是如何创建类的实例的。打开新工程,在 Form1 上画出一个 CommandButton 控件。从“工程”菜单中选择“添加类模块”命 令,从而在工程中添加一个类模块。设置类模块的 Name 属性为 ShowMe 。

Form1 中的下列代码创建了类 ShowMe 的新实例,还调用了包含在类模块中的过程。Public clsNew As ShowMe Private Sub Command1_Click () Set clsNew = New ShowMe clsNew.ShowFrm End Sub 类模块中的 ShowFrm 过程创建类 Form1 的新实例,显示窗体,然后使其最小化。 Sub ShowFrm () Dim frmNew As Form1 Set frmNew = New Form1 frmNew.Show frmNew.WindowState = 1 End Sub 为了应用这个例子,请运行应用程序并单击命令按钮数次。在创建 ShowMe 类的每一个新实例时将看到最小化的窗体图标出现在桌面上。

详细信息 关于利用 New 创建对象的信息,请参阅“用部件编程” 。

New 关键字的限制 下表说明不能用 New 关键字做什么。

不能用 New 创建 不允许的代码的例子 基本数据类型的变量。

Dim X As New Integer 任何一般对象类型的变量。

Dim X As New Control 任何特定控件类型的变量。

Dim X As New ListBox 任何特定控件的变量。

Dim X As New lstNames释放对对象的引用 每个对象都使用内存和系统资源。当不再使用对象时及时释放这些资源,这是良好的编程习惯。

用 Unload 从内存中卸载窗体或控件。用 Nothing 释放对象变量占用的资源。用 Set 语句将 Nothing 赋予对象变量。

详细信息 请参阅语言参考中的“Unload 事件”和“Nothing”部分。

给过程传递对象 可在 Visual Basic 中将对象传递给过程。在下面的代码例子中假定窗体中有一 CommandButton 控件:Private Sub Command1_Click () 调用 Demo 子过程,并将窗体传递给它。

Demo Form1 End SubPrivate Sub Demo (x As Form1) 在屏幕中使窗体居中。

x.Left = (Screen.Width - x.Width) / 2 End Sub 可以通过引用把对象传递给参数,然后在过程内将参数设置成新对象。为了看到这一工作过程,打开工程并插入第二个窗体。在每个窗体中安放一 个图片框。需要改变的属性设置值如下表所示:

对象 属性 设置 Form2 上的 图片框 Name Picture Picture2 c:\vb\icons\arrows\arw01dn.icoForm1_Click 事件过程调用 Form2 中的 GetPicture 过程,并把一个空的图片框传递给它。Private Sub Form_Click () Form2.GetPicture Picture1 End Sub Form2 中的 GetPicture 过程把 Form2 上的图片框的 Picture 属性赋予 Form1 上的空图片框。Private objX As PictureBox Public Sub GetPicture (x As PictureBox) 将传递进来的图片框赋予对象变量。

Set objX = x 将 Picture 属性值赋予 Form1 的图片框。

objX.Picture = picture2.Picture End Sub 为了应用这个例子,请运行程序并单击 Form1。在 Form1 的图片框中将看到出现了 Form2 中的图标。

详细信息 上述主题意在概述对象。更详细内容,请参阅“用对象编程”和“用部件编程” 〔完〕 。

第一篇:vb编程

Visual Basic 程序设计教程主讲教师 廖成斌2007年春 2007年春电话:

电话:2936580 邮箱:

邮箱:liaochb@163.com兰州理工大学计算机与通信学院 Visual Basic 程序设计第一章 Visual Basic概述 概述 第二章 Visual Basic程序设计概述 程序设计概述 第三章 Visual Basic程序设计语言基础 程序设计语言基础 第四章 顺序结构程序设计 第五章 选择结构和循环结构程序设计 第六章常用控件过程 第七章数组 第八章 过程 菜单、 第九章 菜单、多重窗体与多重文档界面 第十章 文件 第二章 Visual Basic程序设计概述 程序设计概述2.1 程序设计方法的演变 2.2 Visual Basic 可视化编程的基本概念 建立简单的Visual Basic 应用程序 2.3 建立简单的 2.4 窗体和基本控件 2.5 Visual Basic 应用程序的结构和工作方式 2.6 工作环境设置和程序调试 2.1 程序设计方法的演变自从第一台计算机诞生以来,程序 设计方法与程序设计语言不断发展。

先 后经历了这几个发展阶段:

1.早期的程序设计 2.结构化的程序设计 3.面向对象的程序设计 1.早期的程序设计早期,由于计算机硬件条件的限制,片 面追求程序的高效率,程序员过分依赖技巧, 不太注重编写程序的结构,这一时期可以说 是无固定程序设计方法的时期。

早期的程序设计高运行效率、少占用内 存为目标 2.结构化的程序设计结构化程序设计方法的主要技术是自顶向 下、逐步求精,采用单入口/单出口的控制结构。

自顶向下是一种分解问题的技术,与控制结构无 关;逐步求精指结构化程序的连续分解,最终成 为3种基本控制结构的组合。结构化程序设计的 结果是使一个结构化程序最终由若干个过程组成, 每个过程完成一个确定的功能。

结构化的程序设计以程序的可读性、可维 护性为目标。

程序=算法+数据结构 (的面向过程的程序设计) 3.面向对象的程序设计 20世纪90年代以来,随着计算机硬 件的飞速发展,应用对软件系统在规模 与复杂程度方面的要求在不断提高。人 们普遍认为,传统的软件工具、软件技 术和抽象层次,越来越难以适应 复杂软件系统的开发特点。在这样的情 况下,面向对象的程序设计方法应运而 生了。 面向对象是一种新的非常有效的程 序设计方法,对于提高软件的生产率、 可靠性、可重用性等都是很有帮助的。

面向对象的程序设计降低程序的复杂性、 提高软件的开法效率和改善工作界面为 目标。

程序=对象+消息 的面向对象的程序设计 2.2 V B可视化编程的基本概念 可视化编程的基本概念1.类 1.类 类是创建对象实例的模板, 包含了创建对象 的属性描述和行为特征的定义. 2.对象 2.对象 是类的一个实例,继承了类的属性、方法。

VB中常用的对象有:窗体、控件等。

3.对象的建立和命名 3.对象的建立和命名 4.对象的三要素 4.对象的三要素 (1)属性 对象的性质,即用来描述和反映对象特征的 参数。

(2)方法 对象的行为,即将一些通用的过程编写好并 封装起来,作为方法供用户直接调用的处理 程序。 (3)事件 响应对象的动作称为事件, 响应对象的动作称为事件,它发生在用户与应 用程序交互时。如单击控件、鼠标移动、键盘按下 用程序交互时。如单击控件、鼠标移动、 等。

事件过程 指附在该对象上的用户编写的程序代码,是事 指附在该对象上的用户编写的程序代码 是事 件的处理程序。

件的处理程序。VB的特征众所周知,VB应用程序的执行是由事件驱动的 众所周知,VB应用程序的执行是由事件驱动的,当用 应用程序的执行是由事件驱动的, 户触发某一事件时,执行相应的事件过程, 户触发某一事件时,执行相应的事件过程,这些事件过程之 间并没有特定的执行次序。但在每一个事件过程内部, 间并没有特定的执行次序。但在每一个事件过程内部,是有 一定的执行控制流程的,这就是通常所说的三种基本结构:

一定的执行控制流程的,这就是通常所说的三种基本结构:

顺序结构、分支结构、循环结构。

顺序结构、分支结构、循环结构。顺序结构是最简单的一种 结构,该结构按语句排列的先后顺序执行。

结构,该结构按语句排列的先后顺序执行。 2.3 建立简单的 应用程序 建立简单的VB应用程序 VB开发应用程序的一般步骤 1.建立用户界面的对象 2.对象属性的设置 3.对象事件过程及编程 4.程序运行和调试 5.保存文件 例一:

例一: 2.4 窗体和基本控件创建VB应用程序的第一步是创建 应用程序的第一步是创建 创建 用户界面。

用户界面的基础是窗体, 用户界面 。

用户界面的基础是窗体 , 各 种控件对象必须建立在窗体上。

种控件对象必须建立在窗体上。

启动VB后 启动 后 , 即在屏幕上显示一个窗 体,如下图所示。 标题最小化 按钮关闭 按钮图标 最大化 按钮边框 窗口区 2.4.1 窗体的主要属性 窗体的属性决定了窗体的外观和操作。

窗体的大部分属性可用两种方法来设置:通 过属性窗口设置和通过程序代码设置。有少 量的属性不能在程序代码中设置。

1.Name(名称)属性 创建的对象名称,有默认的名。在程序 中,控件名是作为对象的标识而引用,不会 显示在窗体上。窗体的缺省名称为 Form1。

2.Caption(标题)属性 该属性决定了控件上显示的内容。设置 窗体的标题内容。标题内容应概括说明本窗 体作用。 3.Height、width、top和left属性 Left和Top属性指明了对象左上角点 在它所在容器对象里的相对位置坐标, 相对坐标系如下图所示。 4.Enabled属性 控件是否可操作. 当设置为false时,呈暗 淡色,禁止用户进行操作.属性值为True或False, 设置对象是否能够对用户产生的事件做出反 应。一般在程序中设置,用于临时屏蔽对窗 体或其它控件的的控制。

5. Visible属性 控件是否可见.当设置为false时, 用户看不 到,但控件本身存在 6. MaxButton 属性和 MinButton 属性 MaxButton属性为True,窗体右上角有最 大化按钮;为False时,无最大化按钮。

MinButton属性为True,窗体右上角有最 小化按钮;为False时,无最小化按钮。

7. BorderStyle 属性 决定窗体边框式样及窗体是否能调整大小。

取值为:

=0无边框; =1单边无最大最小按钮 可改变大小;= 2可改变窗体大小,默认;= 3 固定大小对话框无最大最小按钮;=4 固定工 具窗体风格不显示在任务栏;=5不固定工具 窗体风格不显示。 8. BackColor属性和 属性和ForeColor 属性 属性和 BackColor属性设置窗体的背景颜色, ForColor 属性设置窗体的前景颜色。窗体 的前景颜色是执行Print方法时所显示文本 的颜色。

9. Height属性和 属性和Width属性 属性和 属性 设置窗体的初始高度和宽度。其单位为 Twip。1Twip=1/20点=1/1440英寸=1/567cm。

10. Moveable属性 属性 属性值为True或False,设置是否可以移 动窗体。 11. Icon属性 属性 用于改变系统提供的默认窗体图标。可 以单击属性窗口中Icon项右边的“…”按钮, 选择一个存在的图标文件装入即可。

12. Picture属性 属性 设置在窗体中显示的图片。单击Picture属 性右边的按钮,弹出“加载图片”对话框, 用户可选择一个图片文件作为窗体的背景图 片。若在程序中设置该属性的值,需要使用 Load Picture函数。 13.WindowState属性 13.WindowState属性 设置窗体启动后的大小状态。

正常、 最小化 最小化、 最大化 最大化) (0-正常、1-最小化、2-最大化) 正常 14. StartUpPoition属性 属性(0-不指定 1-父窗体中心 2-屏幕中心 3-屏幕左上角 不指定;

父窗体中心 屏幕中心;

屏幕左上角) 不指定 父窗体中心;

屏幕中心 屏幕左上角在VB中,虽然不同的对象有不同的属性 集合,但有一些属性,如Name 、Enabled、 Visible、Height、Width、Left、Top等,其它 控件也有,且具有相似的作用。在后续的章 节中,主要介绍各种控件常用的特殊属性。 2.4.2 窗体的主要方法格式:[对象名称.]方法名称 [参数列表]1.Cls方法:清除运行产生的图形和文字,但对 背景图无效。

2.Hide方法:隐藏窗体。并将其Visable属性设 为False. 3.Move方法:移动窗体对象。格式:[对象名.] Move Left[,top[,width[,height]]]4.Print方法:输出表达式的值.格式:[对象名称.]Print {[tab(n)[;]][spc(n);|,][表达式[,|;;]]}5.Refresh方法 方法 重新显示窗体内容。 6.Show方法 方法 用指定的风格在指定的窗体中显示指定的窗 体。

[被显示对象名称.]Show [Style] Style(=0为非模态,=1为模态) 。

2.4.3 窗体的主要事件窗体加载事件:initialize 窗体加载事件 窗体卸载事件:deactivate 窗体卸载事件 terminate load activate 其它事件 unload queryunload其它常用事件: 其它常用事件 Click,Dblclick,Move,Change,KeyPress,LostFocus, GotFocus等。 1.Click事件 . 事件 程序运行后,单击窗体触 2.DbClick事件 . 事件 程序运行后,双击窗体触发该事件。3.Load事件 . 事件 Load事件是窗体被装入内存工作区时触 发的事件。如果这个事件过程存在,就 马上执行它。Load事件过程通常用于启 动程序时,对属性、变量的初始化以及 装载数据等。 窗体上无最大化、最小化按钮,程序运行后, 【例】窗体上无最大化、最小化按钮,程序运行后, 在窗体上装入一幅图片作为背景,当单击窗体时, 在窗体上装入一幅图片作为背景,当单击窗体时, 窗体变宽;当双击窗体时,则退出。

窗体变宽;当双击窗体时,则退出。程序运行界面 如图所示。

如图所示。对 象 属 性 Caption 设 置练习 窗口 事件 MaxButton FalseForm1MinButton False 事件过程如下:Private Sub Form_Load()

装入图片 End Sub Private Sub Form_click()

单击窗体 Form1.Height = Form1.Height + 200 Form1.Width = Form1.Width + 200 End Sub Private Sub Form_DblClick()

双击窗体 End End Sub 2.4.3 标签 (Label)用于显示动态或静态的说明性文本信息,不 能作为输入信息的界面。也有自己的属性, 方法和事件。

2.4.3.1属性 属性 ?Alignment(0,1,2,左右中) ?AutoSize(水平扩展)和WordWrap(自动换行) ?BackStyle(0透明,1不透明) ?BorderStyle(0默认,无边框,1单边框) 2.4.3.2方法 同窗体. 方法: 方法 2.4.3.3 事件 很少使用. 命令按钮(CommandButton) 2.4.4 命令按钮(CommandButton) 接受用户输入的命令。输入命令可以有三种方式:

鼠标单击、Tab键焦点到该按钮、快捷键。

1. 主要属性 ?Caption:命令按钮显示的内容,可设置快捷键, 例 &Ok,显示 Ok。

?Value:

检查该按钮是否按下。该属性在设计时 无效。

?Picture :按钮可显示图片文件(.bmp和.Ico),当 Style为1时有效。

?Style:确定显示的形式,0 只能显示文字,1 文 字、图形均可 。 ?ToolTipText :设置工具提示,和Picture结合 使用。

1.主要属性 1.主要属性 ? Text:正文内容。

? Maxlength:设置正文的最多字符个数。

? MultiLine:是否为多行,默认为一行,False。

? ScrollBars:MultiLine为True时,该属性才有效, 表示滚动条的形式。

?PassWordChar:口令字符; Text属性返回输入的数 据,屏幕显示该字符。

? SelStart、SelLength、SelText:选中文本的起始( 从零开始)、长度、内容。 2.方法 2.方法 ?Move方法 Move方法 ?Setfocus方法 将该命令按钮设为焦点. Setfocus方法 将该命令按钮设为焦点. Setfocus 3. 事件 ?Click事件 最常用的事件. 事件 最常用的事件. ?GotFocus事件 事件 ?LostFocus事件 事件 ?Keypress事件 事件 ?Change事件 事件 2.5 V B应用程序的结构和工作方式2.5.1 Visual Basic应用程序的结构 创建Visual Basic应用 程序的第一步即是创建一 个工程(Project),相应 的文件称为工程文件(扩 展名为.vbp),然后再在 该工程下可添加一些模块, 从而组成了完整的应用程 序,如图2-5-1所示。

图2-5-1 VB应用程序的组成 应用程序的组成 VB中的三种模块1.窗体模块窗体模块是最常用的模块。具有可视 化界面,且包含相应的代码。一个窗体就 是一个窗体模块,相应的文件类型为窗体 文件(.frm)。当窗体上(包括窗体自身和 内含的控件)含有图片、图标等二进制类 的信息时,保存该窗体时系统在产生.frm文 件的同时会产生文件主名称相同的窗体二 进制数据文件(.frx)。 2.标准模块 . 没有可视化界面,只包含用户自定义的变量、 没有可视化界面,只包含用户自定义的变量、 过程等代码的模块。相应的文件类型为标准模块文 过程等代码的模块。

件(.bas)。

)。

3.类模块 . 没有可视化界面, 没有可视化界面,只包含用于描述类结构 属性和方法)代码的模块。

(属性和方法)代码的模块。相应的文件类型为类 模块文件(.cls)。

模块文件( )。

可以说,一个Visual Basic应用程序=一个工程文 应用程序= 可以说,一个 应用程序 多个模块。其中, 件+多个模块。其中,工程文件只包含与应用程序 相关的所有模块的组织信息, 相关的所有模块的组织信息,而不涉及应用程序的 具体实现部分(具体实现部分存放在各模块中)。

具体实现部分(具体实现部分存放在各模块中)。 2.5.2 Visual Basic应用程序的工作方式启动模块的设置:[工程]菜单的属性对话框设置启 动模块2.6 工作环境的设置与程序调试2.6.1工作环境的设置通过工具菜单的选项命令打开对话框,建 立适当的运行环境。

常见的运行时错误有:除数为零、试图打开一个 不存在的文件、进行运算时类型不匹配等。 (3)逻辑错误 )所谓逻辑错误,就是程序能“正确”运行, 所谓逻辑错误,就是程序能“正确”运行, 但得到的结果并不是所期望的。这种错误往往是 但得到的结果并不是所期望的。

因为程序所体现的算法不对所导致的。例如,变 因为程序所体现的算法不对所导致的。例如, 量的初始值不对、循环方式不合适、某些语句的 量的初始值不对、循环方式不合适、 执行次序不正确等等。比如程序要进行阶乘运算, 执行次序不正确等等。比如程序要进行阶乘运算, 但对于保存阶乘结果的变量s没有赋初值(默认 没有赋初值( 为0),程序能运行,但结果肯定是不正确的。

),程序能运行,但结果肯定是不正确的。

程序能运行 可导致逻辑错误的可能性很多,不能枚举, 可导致逻辑错误的可能性很多,不能枚举, 要排除这种错误,就需要用户静下心来,仔细阅 要排除这种错误,就需要用户静下心来, 读并分析程序,彻底搞清楚算法才行。

读并分析程序,彻底搞清楚算法才行。 作 业第37~38页: 2-1~2-8 页 ~本章结束

《vb编程》出自:书业网范文大全

链接地址:


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-27726-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...