资源预览内容
第1页 / 共302页
第2页 / 共302页
第3页 / 共302页
第4页 / 共302页
第5页 / 共302页
第6页 / 共302页
第7页 / 共302页
第8页 / 共302页
第9页 / 共302页
第10页 / 共302页
亲,该文档总共302页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Visual Basic程序设计教程 课件2011版参考文献Visual Basic程序设计教程 课件2011版博学之,审问之,慎思之,明辨之,笃行之。 礼记中庸博学之,审问之,慎思之,明辨之,笃行之。 礼记中庸目录主要参考文献 2罗朝盛,罗朝盛, Visual Basic 6.0程序设计教程(第二版),人民邮电出版社(程序设计教程(第二版),人民邮电出版社(2008.6)3陈佳丽,陈佳丽, Visual Basic程序设计基础与实训教程,清华大学出版社(程序设计基础与实训教程,清华大学出版社(2005.7)5刘志妩刘志妩等,基于等,基于VB和和SQL的数据库编程技术,清华大学出版社(的数据库编程技术,清华大学出版社(2008.4)1龚沛曾等,龚沛曾等,Visual Basic程序设计教程(第程序设计教程(第3版),高教出版社(版),高教出版社(2007.3)4徐安东等,徐安东等,Visual Basic数据库应用开发教程,清华大学出版社(数据库应用开发教程,清华大学出版社(2006.8)6刘炳文等,全国计算机等级考试二级教程刘炳文等,全国计算机等级考试二级教程-Visual Basic语言程序设计(语言程序设计(2010版),版),高等教育出版社(高等教育出版社(2009.7)7NCRE研究组,全国计算机等级考试考点解析、例题精解与实战练习研究组,全国计算机等级考试考点解析、例题精解与实战练习-二级语二级语言言Visual Basic程序设计,高等教育出版社(程序设计,高等教育出版社(2008.3)8NCRE研究组,全国计算机等级考试考点解析、例题精解与实战练习研究组,全国计算机等级考试考点解析、例题精解与实战练习-二级公二级公共基础知识共基础知识,高等教育出版社(,高等教育出版社(2008.3)目 录 2 程序设计入门3 数据类型、常量与变量4 运算符与表达式5 控制结构6 过程8 内部控件10 绘图11 多重窗体与多文档窗体7 数组与自定义数据类型12 文件操作1 引言9 内部函数13 数据库操作第1章 引言一、计算机编程语言的分类 当今,程序设计语言的种类繁多,其分类方法也有多种。根据程序设计语言的发展或按其与硬件的接近程度,通常可分为机器语言、汇编语言和高级语言三种类型,如下图所示。 计算机语言机器语言(第一代语言) 汇编语言(第二代语言) 高级语言 Fortran、Basic、Cobol、Pascal、C等(称为第三代语言) 高级语言 JAVA、C+、VB、.NET、ASP、SQL、PHP、XML、FoxBASE、FoxPro、Oracle 、Forth等(也称为第四代语言) Lisp、Prolog(人工智能语言, 人们也常称为第五代语言)。一般来说,人工智能语言应具备如下特点: 具有符号处理能力(即非数值处理能力); 适合于结构化程序设计,编程容易; 具有递归功能和回溯功能; 具有人机交互能力; 适合于推理; 既有把过程与说明式数据结构混合起来的能力,又有辨别数据、确定控制的模式匹配机制。 面向对象的语言(Object-Oriented Language) :上个世纪80年代中期提出的新思想,是一种以对象作为基本程序结构单位的程序设计语言,指用于描述的设计是以对象为核心,而对象是程序运行时刻的基本成分。语言中提供了类、继承、封闭和多态等成分,如Visual Basic、C+、Java、 C#、 Object Pascal(Delphi) 等。 “面向过程”是一种致力于用计算机能够理解的逻辑来描述需要解决的问题和解决问题的具体方法和步骤。编程时不仅要说明做什么,还要非常详细地告诉计算机如何做,程序需要详细描述解题的过程和细节。 “面向对象”是一种以事物为中心的编程思想。比如以公共汽车而言。“面向过程”就是汽车启动是一个事件,汽车到站是另一个事件。在编程序的时候我们关心的是某一个事件。而不是汽车本身。“面向对象”需要建立一个汽车的实体,由实体引发事件。我们关心的是由汽车抽象成的对象,这个对象有自己的属性,象轮胎,颜色等;有自己的方法,象启动,行驶等.方法也就是汽车的行为.而不是汽车的每个事件。面向过程的语言(高级语言)。高级语言,其语法和结构更类似普通英文,且由于远离对硬件的直接操作,使得一般人经过学习之后都可以编程,如:Fortran、C、Basic、Pascal等 。机器语言:计算机所能识别的语言,即由0和1构成的代码。但通常人们编程时,不采用机器语言,因为它非常难于记忆和识别。汇编语言(Assembly Language):也是面向机器的程序设计语言,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言(或称为符号语言)。使用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序。汇编程序把汇编语言翻译成机器语言的过程称为汇编。二、程序的执行方式和运行环境解释型。应用程序源程序必须在编程环境的支持下才能运行。执行方式类似于“同声翻译”,一边由相应语言的解释器“翻译”成目标代码(机器语言),一边执行,因此效率比较低,而且不能生成可独立执行的可执行文件,应用程序不能脱离其解释器,但这种方式比较灵活,可以动态地调整、修改应用程序。 编译型。编译是指在应用源程序执行之前,就将程序源代码“翻译”成目标代码(机器语言),因此其目标程序可以脱离其语言环境独立执行,即生成直接运行于操作系统之上的可执行文件.exe。使用比较方便、效率较高、保密性好。但应用程序一旦需要修改,必须先修改源代码,再重新编译生成新的目标文件( .OBJ)才能执行。例如VB、VC、VFP、Delphi等。三、面向对象的基本概念“对象”与“类” 的概念任何事物都可以被看作“对象”(Object),而“类”(Class)则是同种对象的总称。例如:“人”是一个类,每个具体的人是一个对象。在程序设计中,类和对象是事先定义好的。例如:“按钮”是一个类,每个具体的按钮是一个对象。属性名称 =XX 材料= XX直径 = XX颜色 = XX厚度 = XX方法飘浮上升下降膨胀缩小爆炸事件被释放被扎被打气被放气对象:一只气球面向对象的PME模型任何对象都可以从以下三个方面进行描述: “属性”(Property):对象所具有的特性。 “方法”(Method):对象可能执行的操作或行为。 “事件”(Event):对象可以识别并作出反应的外部刺激。 以下是两个生活事例。一个是一只气球,第二个是人。属性姓名 = 张三性别 = 男身高 = 1.7米国藉 = 中国年龄 = 19岁 方法跑步学习 笑 唱歌 事件遇到高兴的事情 下课了.对象:一个人不同对象之间的关系 一个“系统”是由多个相互联系的对象组成(对象的数目和种类由系统的复杂程度决定)。同一系统中的对象之间通过相互作用(方法与事件)来改变各自的属性,使整个系统保持运动和发展。 对于同一个对象,它的属性、方法和事件之间存在极为密切的关系:事件的发生方法的执行属性的改变。 Visual Basic的优点是语言简单易学,引入了“面向对象”和“事件驱动”等先进思想,支持ActiveX控件、VBS和VBA,对网络和数据库的编程有良好的支持,拥有完全的中文界面和帮助系统。缺点是可移植性不好,只适用于32位Windows。 本课程使用:VB 6中文企业版SP6WinXPMSDN帮助Visual Basic 的优点和缺点四、Visual Basic 简介Visual Basic 发展史VB 1.0 VB 3.0 VB 4.0 VB 5.0 VB 6.0 VB.NET 1.0 VB.NET 1.120世纪90年代初 1997年 1998年 2001年 2003年中文学习版中文专业版中文企业版VB 20052005年VB 20072007年Visual Basic 6的安装和启动方法(1)“开始”按钮(2)“开始”菜单(3)“程序”子菜单(4)“VB6”子菜单(5)此菜单项启动VB集成环境返回目录VB 6的安装方法,参见课堂安装演示操作。VB 6的启动方法,如下图所示。第2章 程序设计入门工具箱工程窗口属性窗口窗体布局窗口窗体对象对象窗口一、Visual Basic 6的集成开发环境代码窗口立即窗口本地窗口主菜单主工具栏PictureBox 控件TextBox 控件CommandButton 控件OptionButton 控件ListBox 控件VScrollBar 控件DriveListBox 控件FileListBox 控件Line 控件Data 控件Image 控件Shape 控件DirListBox 控件Timer 控件HScrollBar 控件ComboBox 控件CheckBox 控件Frame 控件Label 控件二、Visual Basic 工具箱窗口三、Visual Basic 集成环境的“工程”窗口(右上)和“属性”窗口(下)四、Visual Basic 集成环境的“对象”窗口向窗体上添加控件的方法单击图标,再拖动;双击图标;Ctrl键单击图标,再拖动;复制粘贴。选择控件的方法单击可选择一个控件按住Ctrl键,单击要选择的多个控件。按住Shift键,单击要选择的多个控件。在窗体上拖动鼠标,画出一个包含要选择控件的矩形。改变控件的大小和位置 在窗体的控件上单击,可使该控件成为“活动”的,“活动”控件的四周有8个小方块。改变控件大小的方法如下:将鼠标指针对准控件的小方块,出现双向箭头,拖动鼠标即可改变变控件的高度和宽度;按下Shift+“方向箭头”键也可改变控件的大小。改变控件的位置如下:将鼠标指针指向活动的控件,拖动控件到所需位置。按下Ctrl+“方向箭头”键也可改变控件的位置。 此外还可修改控件的Left、Top、Width、Height改变控件的大小和位置五、程序的设计、运行和中断状态(1)设计状态设置对象、编辑代码。(2)运行状态解释型地运行程序。(3)中断状态调试程序,进行排错。可以在三种状态之间进行切换。六、窗体(Form)对象 窗体是窗口的框架,是VB程序最基本的对象,是各类控件的容器。VB开发环境为每个窗体模块自动地创建了一个窗体对象。 【例题】如下图左所示,设计一个应用程序,以实现简单的加法运算的功能。Name:对象名。用于标识对象的字符串。对象名必须满足以下条件: 必须以字母开头 可以包含字母、数字和下划线,不能包括标点和空格 不能多于40个字符 不能与其它公共对象重名,可以与关键字相同,但应避免 在同一模块下,不能重名 建议为对象名加上类型前缀Caption:显示在窗体标题栏上的文字。BorderStyle:边框类型。决定窗体是否可缩放、标题栏是正常还是窄、是否在任务栏上出现等。该属性对MinButton、MaxButton属性的设置有影响。ControlBox:窗体是否有图标、系统菜单和最大化、最小化与关闭按钮。Icon:窗体图标。与一图标文件相联系。如为“无”则使用默认图标。MaxButton与MinButton:是否显示最大化与最小化按钮,值为True或False。只有二者均为False时才不显示,否则设为False者只以无效显示。Visible:窗体是否可见,True或 False。七、Form对象的常用属性Left、 Top属性:窗体相对于屏幕的位置。坐标值的默认单位是缇(twip),1缇等于1/567厘米。Width 、Height属性:窗体的宽度与高度。默认单位也是缇。Moveable属性 :True/False,False时窗体不能被鼠标拖动。Enabled属性: True/False,False时窗体及上面的控件不响应用户的操作。WindowState属性:取值为0、1、2,决定窗体还原、最小化、最大化状态。Picture属性: 指定一个图片文件,用为窗体的背景图。 对象的每个属性反映了该对象某个方面的特性。同一个对象的不同属性之间可能相互影响。程序设计阶段可以在属性窗口中对属性的值进行设置,(有些属性不能在设计时设置;有些属性的设置只有在运行时才反映出来)。在程序进行过程中,程序代码可以读取或重新设置属性的值。有一些属性的值只能在设计阶段设置,程序运行过程中这些属性是只读的。 在程序中对对象的属性进行存取要以如下格式: 对象名.属性名如:frmFirst.Height = 1200 表示窗体frmFirst的高度设置为1200单位(缇)八、属性的分类九、运行时对象属性的读写方法在设计和运行状态下都可设置的属性只能在设计时设置,不能在运行时设置的属性。如对象的Name属性。只能在运行时设置,不能在设计时设置的属性。在设计和运行状态下都可设置,但只有在运行时才能生成的属性。如Visible属性。访问对象属性的格式: 对象名.属性名如: Form1.Caption通过此格式可以读取属性的值,也可以设置属性的值。如: Form1.Caption 你好!Visual Basic 或: x = Form1.Left 此外,窗体的属性还有:BackColor、ForeClolor、Font、FontSize、 FontBold、FontItalic、FontUnderline、AutoRedraw等。Move方法,语法为: 对象名.Move Left, Top, Width, Height 该方法将 object 对象移动到以 left, top 定义的新位置。同时可以改变该对象的大小(以 width , height为新的宽与高)。其中 left 参数必须给定。但是,要给定任何其它的参数,必须先给定出现在语法中该参数前面的全部参数。例:设frmFirst为一窗体对象名。 frmFirst.Move 1000,1000,1200,2000 既移动位置,又改变大小 frmFirst.Move 1000,1000只移动 frmFirst.Move 1000只左右移动 frmFirst.Move 1000, ,1200错误,缺少参数Move方法同时改变了Left, Top, Width与Height属性的值。效果与分别设置这些属性的值等效。Hide方法,语法为: 对象名.Hide 此方法将object对象隐藏,并将其Visible属性设置为 False。窗体被隐藏之后,就不能响应用户的操作。该方法无参数。 某些方法的执行改变一些属性的值,有些方法的执行结果可能受一些属性的影响。方法的执行可能等效于对一些属性的修改。十、Form对象的常用方法Show方法:使窗体从隐藏状态变为显示状态。 对象名.Show Show方法有两个参考,将在第11章讲解。Print方法:在窗体表面上显示指的内容。 对象名. Print“,|;”分隔的输出项 Print支持以逗号或分号分隔的多个输出项的值,每个输出项可以是属性、变量、常量或表达式。其中:分中(;)光标定位在上一个显示的字符后,而逗号(,)光标定位在下一个打印区(每隔14列)的开始位置处。 默认情况下,每调用一次Print方法将在窗体上显示一行内容。 Print方法的详细用法见第10章。Cls方法:该方法用来清除窗体上显示的正文和和绘制的图形。Cls方法的一般格式如下: 窗体名.|Cls十一、窗体Form对象的常用事件 事件是对象能够识别的外部刺激并做出反映,该刺激既可能来自于用户,也可能来自于操作系统。常用的窗体事件有:Load、Activate、Click、DblClick、Resize、UnLoad等。 Load事件:窗体在加载显示时此发此事件,常用来对窗体或控件进行初始化。 Activate事件:在Load事件发生后,系统自动触发并执行该事件。 Load事件发生时窗体是不活动的,Activate事件发生时窗体已是活动的。在不活动的窗体上不能使用Print方法,在活动的窗体上能使用Print方法。Click事件:当用户在窗体上(除标题栏和边框)单击鼠标左键或右键时引发。Click事件过程:当对象接收到Click事件时所执行的代码。窗体的Click事件语法: Private Sub Form_Click() (语句组) End Sub用户可以把想让对象对该事件所做的反应以VB语句的形式写在事件过程中。在一个对象的事件过程中,可以设置其自身的或其它的对象的属性、执行其自身的或其它的对象的方法、甚至可以调用自身的或其它的对象的事件过程。DblClick事件:DblClick事件是当程序运行后,用鼠标双击窗体时触发的事件。 DblClick事件的形式如下: Private Sub Form_DblClick() (语句组) End SubDeactivate(活动、非活动)事件 取消活动窗体激活另一个窗体时该窗体发生Deactivate事件。 Paint(绘画)事件 重新绘制一个窗体时发生Paint事件。当移动、放大、缩小该对象或一个覆盖该对象的窗口移动后,该窗体暴露出来,就会发生此事件。 Resize事件:当窗体因任何原因大小发生变化时(或第一次显示窗体时)引发引事件。在拖动边框窗体改变大小时,会连续引发多个Resize事件。例如加入下面的代码,会在改变窗体大小的同时使窗体居中显示: Private Sub Form_Resize() Form1.Left = (Screen.Width - Form1.Width) / 2 Form1.Top = (Screen.Height - Form1.Height) / 2 End SubUnload事件:Unload事件是在窗体被卸载时触发的事件。该事件过程执行后,窗体从内存工作区被清除,用户在此可进行相关数据的保存。 Unload事件的形式如下: Private Sub Form_Unload(Cancel As Integer) (语句组) End Sub在关闭窗体时,如果Cancel 是一个非0值(True),则禁止关闭窗体;Cancel值是0时(False),则可进行卸载窗体。十二、“代码”窗口的使用打开【例2.2】 改变窗体大小。 打开【例2.1】 单击和双击事件的使用。Left、 Top:命令按钮在窗体上的位置。坐标值的默认单位是缇(1p/20)。Width 、Height :按钮的宽度与高度。默认单位也是缇。Caption:显示在按钮表面上的文字。可使用“&”字符与其后的字母组成快捷键。Visible: True 或False。该按钮是否可见。Enabled: True 或False。False时按钮变灰,不能被点击。Name:对象名。要符合VB对对象名的要求。建议为按钮对象名加上“cmd”前缀。Value:将该属性设为True可以触发按钮对象的Click事件。只能在运行时设置。Default:若该属性为True,则按钮对象为默认按钮。不管焦点在哪个控件上,用户按回车键,均触发按钮的Click事件。默认按钮有较粗的边框。一个窗体上只能有一个按钮的Default属性为True。Cancel:若该属性为True,则按钮对象为默认的“取消”按钮。不管焦点在哪个控件上,用户按“ESC”键,均触发按钮的Click事件。常用属性TopTopLeftLeftWidth十三、命令按钮(CommandButton)Picture:按钮装入图片文件(.bmp或.ico),但Style必须为1.Move方法,此方法在窗体上移动按钮对象,使用语法格式如下: object.Move Left, Top, Width, HeightClick事件:当用户在按钮表面上单击鼠标左键产生Click事件。另外下列方法也能触发按钮的Click事件: 用Tab键把焦点移动到该按钮上,然后按空格或回车键。按快捷键(Alt + 具有下划线的字母) 如为窗体的缺省按钮,按回车键。 如为窗体的默认“取消”按钮,按ESC键。在运行阶段设置属性:object.Value = TrueClick事件过程:当对象接收到Click事件时所执行的代码。按钮的Click事件语法:Private Sub object_Click()(语句组)End Sub命令按钮对象不支持鼠标双击事件,即无DblClick事件。双击操作被理解为两个单击操作。窗体与控件事件过程名的区别:对于窗体对象,其事件过程名为“Form_事件名”,与其对象名无关。对于控件对象,其事件过程名为“对象名_事件名”,用到了其对象。命令按钮对象的常用方法和事件打开【例2.3】 使用按钮移动窗体。Name、Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。Text:框中的文本内容(默认属性)。MaxLength:限制文本框中的文本的最大长度(字符个数)。如果为0,则长度只受系统限制。MultiLine:为True时,文本框中可以显示多行内容,最多可包含32K个字符。False时,忽略换行符,最多可包含2048。ScrollBars:设置文本框的滚动条,有03共4个取值。只有MultiLine属性为True时,此属性才有意义。SelLength、 SelStart和 SelText:分别为当前选定文本的长度、选定文本的起始位置(以0为起点)与选定文本的内容。这三属性只在运行时使用。Locked:为True时,框内的内容不能被编辑(与将Enabled设置为False不同) 。Alignment:文本框中文本相对与文本框的对齐方式。须将MultiLine设为True。PasswordChar:设置口令字符。须将MultiLine设为False。十四、文本框(TextBox)文本框的常用属性文本框是一个文本编辑区域,用户可以在该区域输入、编辑、修改和显示正文内容。Move方法:用法与窗体相同。SetFocus方法:该方法用于将光标移动到指定的文本框中。同样地,文本框支持Click、DblClick等常见事件。 Change事件:当文本框的内容发生改变时引发Change事件。Private Sub object_Change()(语句)End Sub文本框(TextBox)对象的事件与方法打开【例2.4】 用于文本原样输出,如图所示。KeyPress事件:当用户按下并且释放键盘上的一个键时,所触发的事件,此事件会返回一个键ASCII值。如: Private Sub Text1_KeyPress(KeyAscii As Integer) Print KeyAscii End SubGotFocus事件、LostFocus事件:GotFocus事件表示一个对象获得焦点时触发。反之,LostFocus事件表示丢失焦点时所触发的事件,常用用于对数据更新进行验证和确认。 Alignment 、Left、 Top、Width 、Height、Visible、Enabled 属性与文本框、命令按钮的意义相同。Name:对象名。AutoSize和WordWrap :这两个属性决定标签大小是否随显示的文本内容变化,以及变化时是垂直还是水平扩展。Caption:标签上显示的文字内容。可以使用“&”来为标签创建快捷键。标签本身并不能拥有输入焦点。当用户按快捷键时,会把焦点传递给Tab键次序中下一个可拥有焦点的控件。 与文本框的Text属性不同,标签控件Caption属性的值不能由用户直接修改,但可以由程序修改。BorderStyle:01。当此属性为1时,标签有边框。默认值为0,即无边框。标签可以用来对其它没有标题的控件(如文本框)进行说明,也可用来显示一些程序运行过程中的提示信息。标签对象显示的内容不能由用户直接修改,但由程序代码修改。常用属性十五、标签(Label)对象 标签控件支持:Move方法、Click事件、DblClick事件与Change事件。其中:当标签Caption属性值变化时,引发Change事件。 因为标签控件主要的作用是描述其他控件,显示的是形态文本。一般情况下,不必编写其事件过程。Label对象的常用事件和方法打开【例2.5】 显示作者姓名和年龄,如右下图所示。打开【例2.6】 综合示例,如左图所示。 字母的大小写问题,关键字 语句:程序以语句为单位,一般情况下,一条语句占一行。 续行:如果语句太长,可以分为连续的多行书写,这时,未完的行要以空格与下划线(称为“续行符”)结尾。注意分行时要避开关键字、对象名、过程名。如:lblMyFirst.Caption= lblMyFirst.Caption _+12313 一行中写多条语句:要在一行中写多条语句,可在多条语句之间插入冒号作为分隔。如:txtFirst.Text=“Hello” : frmOpen.Top=1000 : frmOpen.Left=1200 注释:可在程序中加入以单引号开头的解释性的文字,单引号为“注释符”,这些文字为注释内容。注释内容在程序执行时被忽略。注意:在续行符后不能写注释。如: 这是2009年2月16日编写的,整行注释也可使用Rem txtMy.Text = 您好! 在文本框中向用户问好 行号与标号 英文符号与中文符号 使用中文时要使用半角标点符号。 程序行的缩进,与源程序的美观十六、Visual Basic 语法规则十七、Visual Basic开发程序的主要步骤进入VB集成开发环境添加对象,编写代码保存打开源程序*.vbp、*.frm*.frx、*.bas文件解释性试运行编译可执行文件*.exe文件完成未完成或出错预备工作建立界面设置属性编写代码、进行调试编译十八、工程中的模块与文件 为编制一个应用程序而创建的所有源文件统称为一个“工程”(Project)。一个工程有一个工程文件(vbp,vbw),另外还有多个模块文件。窗体模块窗体模块包含窗体及其控件的定义、属性设置,以及代码窗口中的程序行。窗体文件的扩展名为 .frm ,如果设置了对象的ICO或Picture属性,会生成同名的.frx文件。标准模块 标准模块包含数据类型、常数、变量、外部过程和公共过程的公共的或模块级的定义。标准模块文件以 .bas为文件扩展名。 还可能用到其他类型的模块。保存工程时先提示保存各模块文件,最后提示保存工程文件。打开工程时,直接打开工程文件即可。应该将一个工程中的所有文件保存在同一个文件夹中,便于管理。不能在VB集成环境之外移动工程中的模块文件或对其进行重命名。这样会导致工程无法打开。十九、保存和打开工程二十、生成可执行文件通过“文件”菜单中的“生成”命令可执行文件.exe。可指定可执行文件名和保存位置。可执行文件可脱离源程序与VB环境单独运行。可执行文件需要一些中间文件的支持才能运行。显示作者姓名和年龄,如下图3所示。综合示例,如图4所示。用于文本原样输出,如图3中所示。验证课程例子,如图1所示。设计一个窗体,窗体上有“放大”、“加粗”、“下画线”、“还原”和“移动”5个命令按钮和一个显示“VB程序设计”的标签。单击命令按钮可实现标签文字的放大、加粗、下画线、还原和移动功能。单击按钮可移动窗体。返回目录二十一、实验补充题1234第3章 数据类型、常量与变量 数值型类型名中文名类型符字节表示范围精度Integer整型 2-3276832767精确Long长整型&4-2147483648 2147483647精确Single单精度浮点型!4-3.402823E 10-38 3.402823 10387位有效数字Double双精度浮点型#8-1.7976931348623210-308 1.79769313486232 10308 15位有效数字Currency货币型8-922337203685477.5808 922337203685477.580715位整数,4位小数Byte字节型10255精确一、基本数据类型 在计算机中,数据没有大小和类别,是用一定位数的二进制数码表示的一种符号编码,这类似18位的身份证或学生证号,占同样大小的存储空间。不加快计算机的处理速度和节省存储空间,VB中将数据分为不同类型。 字符串是指连续的字符序列。字符串数据类型是专门用来存放文字信息的。字符串型又分为“定长字符串型”和“变长字符串型”两大类。字符串类型所占的内存空间大小 与字符串长度有关。变长字符串型类型符号是“$”。String(字符串型)(字符串型) Boolean类型的数据只可能有两个值:True(逻辑“真”)和False(逻辑“假”),用来表示“是”与“否”、“开”与”关”、“对”与”错”这类只有两种取值的情况。一个逻辑型数据却要占2个字节的存储空间。 Date类型又称为日期型,这种类型的数据可以存放日期信息、时间信息或者同时存放日期与时间信息。Date类型数据用8个字节来表示日期和时间(公元100年1月1日9999年12月31日) 。Boolean(逻辑型、布尔型)(逻辑型、布尔型)Date(日期时间型)(日期时间型) Object(对象型)和Variant(变体类型),将分别在后面节中讲解。Object(对象型)(对象型)和和Variant(变体类型),(变体类型), 十进制:1、20、500、-101 、230594、12%、234& 八进制:&O11、&O123、&O321&错误:&081及&O88 十六进制:&H11、&HFF 以&结尾发长整型 错误:&HFR二、各种数据类型的直接常量 普通记法:1.2、-1.4、4.5!、-5.67# 科学记法:1.2E10、-1.23E-3错误:1.2E1.4、E4、12E 字节型、整型、长整型字节型、整型、长整型精度浮点型精度浮点型 只有两个取值:True、False 逻辑型逻辑型 使用“#”号作界定符: #1/1/2005#、#April 1, 2005#、#1:00:00PM#、#1-1-2005 13:30:45# 日期型日期型 使用双引号“” “”,将指定的字符串界定起来,如:“ Visual Basic ” 、 “你好!”。 特殊的字符串: “ ” “ ”表示一个双引号, “ ”表示空字符串。字符串常量中的双引号必须成对出现。字符串本身包括双引号时,必须用两个连续的双引号表示,如“V“”B”,则表示V”B,又如“”“Are You from chengDU?”,he asks.”。字符串型字符串型变量:在程序执行过程中存储临时数据的命名内存单元。变量名:程序是通过变量名来保存和访问相应内容单元中的值的。在VB中变量名有如下规则:(1) 以字母开始,可以包括字母、数字和下划线;(2) 不能包含标点符号;(3) 不能多于255个字符;(4) 不能与保留关键字重复(如:End、Private、Sub) ;(5) 在同一作用域中,变量名不能重复。变量的数据类型:数据类型决定变量占用内存的大小、数据处理的方式、表示值的范围。定义变量: Dim|Static|Private|Public 变量名 As 数据类型名如: Dim x1 As Integer 定义x1为整数型变量 Static C1 As Long Dim d As Date,f1 as Single,f2# 分别定义d、f1和f2为日期型、单精度和双精度变量 Private S1 As String (定义变长字符串变量) Private S2 As String *4 (定义定义长字符串变量)变量赋值:通过以下形式的语句为变量赋值。 Let 变量名= 表达式 赋值语句的作用是把一个表达式的值赋予一个变量,即保存到变量所占的内存空间。被赋值之后变量旧值被覆盖,变为新值。被赋的新值的类型和大小应与变量的数值类型相一致,否则会出错。 另外,在过程、函数调用过程时,可以通过参数传递的方式为被调用过程中的变量赋值。 三、变量 也称为“局部变量”,在过程中定义,作用域为所在的过程。定义过程级变量的方法有两种: Dim 变量名 AS 数据类型名动态局部变量 Static 变量名 AS 数据类型名静态局部变量如: Dim a As Integer 使用Dim关键字定义的局部变量只在定义它的过程执行时存在,过程执行完变量即消失。下一执行该过程时,会重新生成变量,重新初始化。 使用Static关键字定义的局部变量称为“静态变量”,它在整个程序的运行过程都存在,但是只能被定义它的过程所用。每次执行不重新进行初始化。可以在一个过程的多次执行之间保持其值。 注:不能在过程中声明公用变量,只能在模块(窗体给和标准模块)的声明段中声明公用变量。四、变量的作用域 变量的作用域决定一个变量在什么代码范围内可以被访问。定义变量时所使用的关键字以及定义变量的位置决定了变量的作用域。引用变量的值:将变量名写到表达式中、过程函数实参表中,实际上就是对变量的值进行引用。如下式中,是将变量b和c的值求和后赋给变量a。a 的值变为新值,b和c的值被引用,并未改变。 a=b+c 过程级变量 打开【例3.1】使用过程级变量,在中使用局部和静态变量。 在模块或模块顶部的“通用声明段”中定义,在该模块中的所有过程中可用。 定义的方法(两种方法等价) : Dim 变量名 As 类型名 Private 变量名 As 类型名如: Private d As Date Private S1 As String (定义变长字符串变量) Private S2 As String *4 (定义定义长字符串变量) 一个定长字符串变量所占的内存空间是一定的,当其中的字符信息没达到这个长度时,所剩的空间用户“空格“填充。如果给定长字符串变量赋一个超过其长度的字符串,会被截掉多余部分,不会出现“溢出”错误。模块级模块级(窗体级或模块级窗体级或模块级)变量变量 应用程序级变量应用程序级变量 定义:也称为“全局变量”或“公共变量” ,在标准模块顶部的“通用声明段”中使用Public(Global)关键字定义。全局变量在程序(即同一个工程中)的所有模块中皆可用。 Public 变量名 As 类型名如:Public p As Boolean 注:不能在窗体模块中定义全局定长字符串变量。打开【例3.2】使用模块级变量,模块(或窗体)级变量的定义和使用。 打开【例3.3】为模块级变量赋初值(可在Load事件中进行)。 引用 一个应用程序的结构如右图所示。访问另一个模块(窗体)中定义的全局变量,应在变量名前加模块名修饰。如 Form2.int1 = 2 在没有重名的情况下,访问标准模块中的全局变量,不必加模块名。 数值型变量的默认值为0; 逻辑型变量的默认值为False;日期时间型变量的默认值为#0:00:00#;变长字符串变量的默认值为空字符串;定长字符串变量的默认值是全部由空格组成的字符串,空格个数等于定长字符串的字符个数;对象型变量的默认值为Nothing;变体类型变量的默认值为Empty。四、变量的默认值 变量被定义之后,在第一次赋值之前,并不是没有值的,而是具有默认值。五、强制变量定义 默认情况下,所有未出现过程的标识符,都被VB当成变体类型的变量。这样,使得程序不容易调试,可以在模块声明段中加上: Option Explicit使得所有的变量必须定义才能使用。 对象型变量占用4个字节共32位的内存空间,保存的是某一个对象的引用(即内存中的地址),程序对对象型变量的操作等于对它所引用对象的操作。对对象型变量赋值要用Set语句。对象型变量在被定义但未被赋值时的值是一个特殊值:Nothing。 例如,右图所示: Private Sub Command1_Click() Dim a As Object Set a = Form1 a.Font = “楷体_gb2312”:a.FontSize = 16 a.Caption = 对象变量的使用 Print a.Caption End Sub Object类型的变量可以引用任何一种类型的对象。如果在使用中,一个变量只引用一种特定类型的对象时,就可以将该变量定义为此特定类的对象型变量。定义特定类型对象型变量,要使用对象的类型名,如已学习过的:Form、Textbox、CommandButton、Line、Shape等。例:Dim obj2 As CommandButtonSet obj2=cmdOK : obj2.Caption=Hello! 注:对象型变量没有默认值,定义之后未赋值之前不能使用。特定类型对象型变量只能引用同一类型的对象。例:Dim obj3 As Form:Set obj3 =cmdOK (错!)八、对象型数据类型(Object) 变体类型变量可以存贮几乎所有系统定义类型的数据(除定长字符串和用户自定义类型)。把其它类型的数据赋给变体变量,变体变量的类型会随之变化,适应新的值。变体变量在存放数值时,占16字节的内存;存放字符串时,占用22字节的内存(加字符串长度)。例:Dim vnt1 As Variant (定义)vnt1=“17” (为字符型“17”)vnt1=vnt1-15 (为数值型,值为 2) 变体变量类型是默认类型,在定义变量时可以省略“As Variant”。变体变量也可以引用对象,赋值时须使用Set语句。 例:Dim vnt2(定义)vnt2=1234(为数值型1234)Set vnt2=Command1 (对象型,对cmdOK的引用) Variant变量有二个的特殊的取值:Empty、Null。 Empty:一个变体变量可以在下列两种情况下具有Empty值:尚未赋值时;被赋予Empty值之后。把Empty值赋给一个数值型变量时被理解为0,赋给一个字符串时被理解为空字符“”。 Null:主要用于对数据库的操作,表示数据未知或数据不确定。Null值有如下特点:如表达式的任何一部分是Null,则整个表达式的值也为Null;把Null值作为参数传递给一个函数,则函数的返回值为Null。可给一个变体变量赋值 Null。Null与其本身不相等。九、变体类型(Variant) VB允许不同类型的变量之间相互赋值,也允许把不同类型的值赋予某种类型的变量,VB会自动将所赋予的值转换为被赋值的变量的类型。 数值型变量的赋值 数据型变量之间可以相互赋值。浮点数转换为整型数时,小数部分“四舍五入”为整数(其中0.5要向最近的偶数靠拢),如i=4.5,转换后为4。 字符串变量 字符串变量中存贮的是数值信息,则可以将其赋予数值型变量。包括非数值字符的字符串(如有字母、标点符号)不能赋值给数值型变量,否则出现“类型不匹配”错误。 逻辑型变量 逻辑变量的值赋给数值型变量,False转换为0,True转换为-1。数值型变量的值赋给逻辑变量,0转换为False,其它值转换为True。 日期时间型变量 期时间型变量赋给数值型变量时,日期部分转换为数值的整数部分,值为此日期距1899年12月30日的天数;时间部分转换为小数部分,从零时到该时间占一整天的比例,12:00:00转为0.5。 例:dtm3=#3/18/1999 6:00:00# : sng2!=dtm sng2的值为“36237.25” 问题:#0:00:00#表示是哪一天的时间? 所有的类型值均可以转换为字符串值 日期时间型变量转换为字符串时,按照日期的短格式字符串。可以使用类型转换函数进行显式转换。转换规则与上述默认转换相同。 以上是隐式转换,也可通过转换函数i3=Cint(123.5) ,结果为124,等函数进行显示转换。十、类型转换 符号常量是指使用一个名称代表在程序运行过程中其值一直保持不变的量。符号常量的作用有:便于记忆与识别,可使用一个具有描述性的名字替代一个抽象的值;便于修改,如果要改变常量所代表的值,只需在定义常量的地方修改即可。 常量的定义方法: 过程级常量:在过程中定义 Const 常量名 As 类型名=表达式 模块级常量:在模块的声明段中 Private Const 常量名 As 类型名=表达式 全局常量:在标准模块的声明段中 Public Const 常量名 As 类型名=表达式 符号常量的命名规则与变量相同,一般使用con前缀或大写字母加以区别。在程序运行过程中,不能再为符号常量赋值。例如,定义全局常量PI: Public Const PI As Double = 3.1415926则,在过程中可以引用符号常量的值: s = PI *r *r 注意:不能在窗体模块和类模块中定义全局常量,只能在标准模块中定义。十一、符号常量不允许同名的情况 一般情况下,在同一作用域内不能定义重名的变量。 同一个过程中不能定义同名过程级变量,既使类型不相同也不能同名。 同一个模块中不能定义同名的模块级变量。在窗体模块中,窗体的属性、控件、过程和模块级变量是同一层次的,故它们之间不能重名。 同一个模块中不能定义同名的模块级变量和全局变量。 十二、变量重名问题 多个标准模块中不能有重名的全局变量。允许同名的情况 不同的过程中可以定义同名的过程级变量;不同的模块中可以定义同名的模块级变量;过程中可以定义与模块级变量同名的过程级变量;过程中可以定义与全局变量同名的过程级变量;模块中可以定义与其他模块定义的全局变量同名的模块级变量;不同的模块中可以定义同名的全局变量。变量的使用 不同作用域的变量同名时,作用域小的变量会屏蔽作用域大的变量,即过程级变量屏蔽模块级和全局变量,模块级变量屏蔽全局变量。例如,在例3.2中,按钮事件过程中的变量i屏蔽模块级变量i,过程中被访问的i实际上是过程级变量。 如果不同模块中全局变量同名,访问其他模块中定义的全局变量时应添加模块名进行限定(形式为“模块名.变量名”)。访问本模块或标准模块中定义的全局变量时不必进行限定。如果本模块与标准模块中的全局变量同名,访问标准模块中的全局变量时也应加模块名进行限定。当全局变量与过程级变量同名时,在过程中直接使用这个变量名时,指的是过程级变量。如果使用定义全局变量的模块名来限定变量名,则可访问该全局变量。如果本模块中的模块级变量与其他模块中的全局变量同名,可以在变量名前加模块名来访问全局变量。 过程中的局部变量比过程低一级,所以,与控件同名的局部变量会屏蔽控件,如要访问该控件,要用窗体名来限定。 在窗体模块中,要用窗体名来限时,窗体名都可以用关键字“Me”来代替。在窗体模块中,如果没有重名,对窗体属性的修改、方法的调用可以省去窗体名或“Me”的限定。 如:在frmFirst模块中如无变量、控件与窗体重名,frmFirst.Top=0 等价于 Top=0定义变量要尽量避免重名;能定义小范围的变量就不要定义大范围的变量。十二、变量重名问题*1、简易计算器(左下图)。2、求圆的周长和面积(右下图)。3 3、打印如右图所示的图形。、打印如右图所示的图形。提示:提示:Private Sub Form_Click()Private Sub Form_Click() For i = 1 To 5 For i = 1 To 5 Print Tab(i);String(6- Print Tab(i);String(6-I,);Spc(6);String(I,)I,);Spc(6);String(I,) Next i Next iEnd SubEnd Sub考虑:若把考虑:若把Spc(6)Spc(6)换成换成Tab(6)Tab(6),效果如何?,效果如何?返回目录十三、实验补充题第4章 运算符与表达式 “运算符”(Operator)是代表某种运算的符号。用运算符把变量和常量连接起来形成“表达式”(Expression)。每一个表达式都有一个值,即计算结果,称为表达式的值。算术运算符对数值进行运算,计算结果也是数值。运算符 作用示例结果注指数运算238 -取负数-1-1 ? -24 显示-16 * 乘法运算2*36 /除法运算5/22.5 整除运算522只用于整数Mod求余运算 5 Mod 2 1只用于整数+加法运算2+35-减法运算2-3-1一、运算符算术运算符字符串运算符 字符串连接运算符和& :将两个字符串首尾相连为一个字符串。因为号又是算术运算符,所以使用号可能引发歧义。所以应使用&进行字符串连接。 崇尚科学、 & 追求真知。 运算结果为崇尚科学、追求真知。 团结献身 + 求是创新 运算结果为团结献身求是创新 30 & 15 运算结果为3015 30 + 15 运算结果为3015 30 & 15 运算结果为3015(先将整数转换为字符串) 30 & 15 运算结果为3015(先将整数转换为字符串)字符串比较:字符串的大小是按字符顺序按字符的内码(ASCII码和国标码)逐个进行比较。字符串的比较不是比较长度。例如: “ ab ” “ ac ” (False) “ ab ” “ abc ” (False) “ ab ” = “ ab ” (True) “ ab ” “ AB ” (True) “ 2000 ” “ 400 ” (False) 中 “Zhong” (True) 通用声明区中,用下面语句可设置可以决定英文比较时是否考虑大小写。 OptionCompareBinary|Text 其中:Text时不区分大小写,Binary(默认值)时区分大小写。运算符 意义例子结果=等于2=4False4=4True 不等于45True44False小于2.5大于35False35True =小于或等于3=5True4=大于或等于4=4True3=5False 比较运算符用来对两个数值的大小进行比较,如果满足运算符的定义,则结果为True,否则结果为False。比较运算符 字符串除了可以比较大小,还可以比较是否匹配(也是一种比较)。 strA Like strB strA和strB均为字符串表达式,其中strB为比较的“模板”。如果strA与strB定义的模板相匹配,运算的结果为True,否则为False。strB中可以包含任何字符,但是下列字符具有特殊含义:?代表任何一个字符*代表任意多个字符,(包含0个)#代表任意一个数字,(0-9)charlistcharlist中包含的任何一个字符!charlist不包含于charlist中的任何一个字符 要匹配字符:、?、#和*,要用方括号把它们括起来。可以作为一个单独的字符出现。如中的“-”出现在“!”号之后、最前或最后,则表示是一个可以匹配的字符,在其它位置上时表示字符范围。 Like操作符的执行结果与Option Compare 语句的设定有关。默认情况下,设定是Option Compare Binary,按照字符的表示的二进制数来比较的。如果在模块的声明段加入Option Compare Text语句,则比较结果对大小字不区分。字符串匹配运算符:Like例如:aBBBa Like a*aTrue“F” Like “A-Z”True 而 F Like !A-Z“Falsea2a Like a#aTrueaM5b Like aL-P#!c-eTrueBAT123khg Like B?T*TrueCAT123khg Like B?T*False*?# Like *?#True“a” Like “!abc”False 而 a Like a!bc True你 Like 你我他TrueABC Like AB!abTrue 当Option Compare Text时“ABC” Like “aB!ab”False 当Option Compare Binary时日期时间运算符1日期与数值的加减运算表示在日期上加上或减去若干天。如:#1/1/2010#+1.5(或-)2日期与日期的减法。如#3/1/2000#-#3/1/1999# 结果为366表示两个日期之间的天数差,不是整天则用小数表示。3日期的比较比较晚的日期比较早的日期。 对象变量的比较运算符为:Is。如果两个被比较的变量引用的是同一个对象,则得出True,否则为False。 例:Dim obj1 As Object (定义一对象型变量 obj1) Dim obj2 As TextBox (定义一对象型变量 obj2) Dim bln1 As Boolean (定义一逻辑型变量 bln1) Set obj1=txt1(为对象型变量赋值) Set obj2=txt1 (为对象型变量赋值) bln1=obj1 Is obj2 (对象型变量的比较,结果赋予对象型变量)bln1的值为True对象型比较运算符 Is逻辑运算符 对逻辑量进行运算的运算符称为逻辑运算符,包括: Not 、 And、Or、 Xor 、Eqv、 Imp共六个运算符。逻辑运算的结果也是逻辑值。 Not 逻辑“非”运算符: Not A Not 为单目运算符,如果A为True,则结果为False,如果A为False,则结果为True。 And 逻辑“与”运算符:A And B 如果A与B是逻辑表达式(True或False),只要有一个为False,则运算结果为False。二者全为True时,结果才为True。 Or 逻辑“或”运算符:A Or B 如果A与B是逻辑表达式(True或False),只要有一个为True,则运算结果为True。二者全为False时,结果才为False。 等价Eqv、蕴含Imp、异或Xor运算符的运算规则见下表。逻辑运算的应用【例4.1】使用下面程序代码验证逻辑运算符。 Private Sub Command1_Click() Dim A As Integer, B As Integer, C As Integer A = 10: B = 8: C = 6 给变量赋值 Print A B And B C, B A Or B C 结果为True 和True Print Not A B 结果为False Print B A Eqv B C;B A Imp C B;B A Xor C B 结果分别为False、True和False End Sub打开【例4.1】【例4.2】根据给定条件编写表达式。 假设a、b和c是三个变量。如果已知ac,要判断b的值是否在a与c之间,可以使用以下表达式: a b And b c 不能写成:a b c 如果不知道a和c哪个大,要判断b的值是否在a与c之间,可以使用表达式: (a b And b c) Or (c b And b 0 And y 0 判定(x,y)是否位于第一象限内单位圆中(单位圆是以坐标原点为圆心,半径为1的圆),可以使用表达式: x 0 And y 0 And x * x + y * y 0 And y 0 Text4.Text = x 0 And y 0 And x * x + y * y 1 Text5.Text = x = 0 Or y = 0End Sub打开【例4.3】如果逻辑运算的操作数(运算量)中有一个是数值型值。则VB会将所有的运算量转换为整数进行“按位逻辑运算”。运算规则是将整数以二进制形式按位进行逻辑运算,结果转换为十进行制整数。如:10 Or 8的值为10。 Not 10 的值为 -11。10D= 00001010B 10D= 00001010B 8D = 00001000B Or Not10D= 00001010B -11D=11110101B (补码取反加1)按位逻辑运算二、表达式表达式的求解顺序 在一个表达式中,先计算优先级高的运算符,再计算优先级低的运算符。优先级相同时,从左向右计算。 使用不括号,可以改变计算顺序,先计算括号内的。 如下表所示,在表达式中,先进行算术运算符,接着进行比较运算,然后才进行逻辑运算符。所有比较运算符的优先级都相同;也就是说,要按它们出现的顺序从左到右进行处理。运算符的优先级正确编写表达式将代数式转换为表达式应遵循计算机语言的代码书写规范,免受代数知识的影响。浮点数的精度问题无论是单精度还是双精度浮点数都有有效数字位数的限制,无法准确表示超过该精度的值。在编程时,应考虑这一点。打开【例4.5】运算的顺序问题有时,只要调整一下计算的先后顺序,结果就在不一样!运算过程中的溢出错误避免出错运算过程中的溢出错误。使用小括号在表达式中加一些不影响计算顺序的小括号,会使表达式的可读性增强。打开【例4.6】 判断变量x是否可以被3整除。 (1)已知变量a = 3、b = 4、c = 5,求下面表达式的值。表达式求值打开【例4.7】 求表达式的值。1、打开【例4.8】 验证三种除法运算符(/、Mod)的区别(右)。返回目录3、打开【例4.9】 在文本框(Text1)中输入一个三位数据,单击窗体体后,在窗体中打印输出该数的个位数、十位数和百位数(左)。4、打开【例4.10】 (选做题)单击窗体,在窗体随机位置上显示输出一个大写的英文字母。 提示:提示: 用以下语句进行随机定位:用以下语句进行随机定位: CurrentX = Me.Height * Rnd 定位光标定位光标 CurrentY = Me.Width * Rnd 用以下语句输出字母:用以下语句输出字母: Print Chr(Int(Rnd * 26) + 65)三、实验补充题2、判断坐标(x,y)所处的象限,如下图。第5章 控制结构Visual Basic提供的控制结构有以下四种: 顺序结构。 分支结构(也称为“选择结构”)。 语句有:If语句、Select Case语句。 循结结构。 DoLoop语句、ForNext语句、WhileWend语句等。 跳转结构。 GoTo语句、GoSub语句。控制结构流程图如下。一、控制结构概述 程序是人们事先编制好的语句序列,程序以文件的形式保存在指定的磁盘中称为程序文件。程序文件中未编译的按照一定的程序设计语言规范书写的文本文件称为源代码(也称源程序) 。计算机按照一定顺序执行这些语句,逐步完成整个工作。 程序类似于作文,是有一定的结构,即有“启、承、转、合”等部分。每一部分由一或几个自然段组成,我们说程序是有结构的,结构的顺序可以不同。为了描述语句的执行过程,VB语言提供了一套控制机制,它的作用是控制语句的执行过程,这种机制称为“控制结构” 。把“控制结构”所用的语句或命令称为结构控制语句。二、If 条件语句 这两种形式的If语句在执行流程方面是相同的。 如果“条件表达式”的值为 True ,则执行“语句块”,否则跳过“语句埠”,直接执行随后的语句。 “语句块”可以是一条语句,多条语句。对于单行形式,多条语句必须使用“:”隔开写在同一行上。 例:下面双种形式功能相同。 单行形式: If i Mod 2 = 0 Then Print 偶数 块形式: If i Mod 2 = 0 Then Print 偶数 语句块 End If单行形式的IfThen 语句条件语句块TrueFalse块形式的IfThen End If语句If 条件表达式 Then 语句块 If 条件表达式 Then 后面不能书写语句 语句块 End If If 条件表达式 Then语句组1 Else 语句组2 End If 如果“条件表达式”的值为 True ,则执行“语句块1”;否则,执行“语句块2”。“语句组1”与“语句组2”中至少有一组被执行,然后继续执行随后的语句。 例: If i Mod 2 = 0 Then Print 偶数 语句块1 Else Print 奇数 语句块2 End If单行形式的IfThenElse 语句条件语句块1TrueFalse语句块2 If 条件表达式 Then 语句块1 Else 语句块2 块形式的IfThenElseEnd If 语句打开【例5.1】 判断输入数的奇偶性,并根据判断的结果输出文字。在 If 语句的“If语句块”和“Else语句块”中还可以包含另一个 If 语句。如:.If 条件1 Then .If 条件2 Then .Else.End If.Else.If 条件3 Then .Else.End If.End IfIf 语句的嵌套【例5.2】判断输入数的奇偶性及所在的区间。Private Sub cmd1_Click( )Dim int1 As Integer, int2 As Integer : int1=Cint(txt1.Text)If int1100 Thentxt2.Text=这是一个大于100的偶数!Elsetxt2.Text=“这是一个不大于100的偶数!End IfElseIf int1 100 Thentxt2.Text=这是一个大于100的奇数!Elsetxt2.Text=这是一个小于100的奇数!End IfEnd IfEnd IfEnd Sub打开【例5.3】 三数求最大。打开【例5.4】 分数转换为等级。这是一种多重分支结构,比使用嵌套的If语句更容易理解。IfThenElseIfEnd If语句If 条件1 Then语句块1ElseIf 条件2 Then 语句块2ElseIf 条件3 Then 语句块3ElseIf 条件n Then 语句块nElse语句块n+1End If 从上到下,第几个条件表达式值为True,就执行相应的第几个语句块,然后执行End If下面的语句。如果有不只一个条件表达式的值为True,只有最上面的条件所对应的语句块被执行。如果所有条件表达式的值均不为True,则执行Else关键字下面的“语句块n+1”,然后执行End If下面的语句。其中Else和“语句块n+1”是可选部分。 注意:“ElseIf”关键字中间没有空格,不是“ElseIf”。打开【例5.5】 使用IfThenElseIfEnd If语句改写【例5.4】。 Select Case 测试表达式 Case 表达式1 语句块1 Case 表达式2 语句块2 . Case 表达式n 语句块n Case Else 语句块n+1 End Select Select Case语句中包含一个类型为数值或字符串的“测试表达式”,开始时计算一次此表达式的值,然后用这个值与各个Case语句之后的“表达式X”比较,如果二者匹配,则执行该Case之后的语句块,然后执行End Select之后的语句。如果“测试表达式”中的值与“表达式X”中的多个相匹配,则只执行第一个相匹配的Case之后的语句块。如果没有相匹配的,则执行Case Else之后的语句。没有Case Else语句,则直接执行End Select 之后的语句。三、Select Case 多重分支语句Select Case语句根据一个表达式的值来执行多个语句块中的一个,可以实现多分支结构。语句格式语句格式Select Case语句中的“匹配”包括“精确相等”和“在指定区间内”两种情况。具体使用的是哪种情况,由Case后面“表达式”的给定方式决定。Case后面“表达式”的形式可以是以下4种情况之一:单个常量、变量或表达式如:Case 90和Case Tom。这种情况下,如果测试表达式的值与给出的值相等就认为匹配。使用关键字“To”连接的两个值如:Case 1 To 5和Case A To C。这种情况下,关键字“To”连接两个值表示值的范围(闭区间),如果测试表达式的值属于这个区间则认为匹配。使用“Is”关键字、比较运算符和数值、字符串构成的表达式如:Case Is = 80和Case Is 。这种情况表示一个开区间,如果测试表达式的值属于该区间便认为匹配。以上三种的组合形式(使用逗号分隔)如:Case 6, 8 To 9, Is 12。这种情况下,只要由逗号分开的多项中有任何一项与测试表达式匹配,就认为匹配。关于“匹配”的定义打开【例5.6】 使用Select Case语句重写【例5.5】。打开【例5.7】 输入两个小于10的整数,判断两数之和落在的区域。该循环语句共有五种形式。“当循环”的第一种形式: Do While 条件表达式语句块 退出循环 Loop“当循环”的第二种形式: Do 语句块 Loop While 条件表达式两种循环共同的特点是:当每次计算“条件表达式”的值为True或非零数值时,循环执行“语句块”;当“条件表达式”值为False或零值时,跳出循环,执行Loop语句后别的语句。二者不同的是:第一种形式,如果条件表达式第一次计算“条件表达式”就为False,则“语句块”不会被执行;第二种形式中,条件测试在后,所以“语句块”至少被执行一次。条件语句块TrueFalseDo While Loop形式条件语句块TrueFalseDo While Loop形式四、Do Loop循环语句打开【例5.8】 使用Do While Loop计算123n的值。打开【例5.9】使用Do Loop While计算123n的值。“直到型循环”的第一种形式:Do Until 条件表达式 语句块 Loop“直到型循环”的第二种形式:Do 语句块 Loop Until 条件表达式 “直到型循环”与“当循环”不同点是:当每次计算“条件表达式”的值为False或零数值时,循环执行“语句块”;当“条件表达式”值为True或非零值时,跳出循环,执行Loop语句后别的语句。 “直到型循环”的两种不同形式的区别和“当循环”相同:第一种形式中的“语句块”有可能一次都不被执行到;第二种形式中的“语句块”至少被执行一次。打开【例5.10】 计算阶乘数n!。条件语句块FalseTrue条件语句块FalseTrueDo UntilLoop形式Do Loop Until形式Do Loop形式:Do 语句块 Loop 这种形式是一种“条件永远成立”的循环,需要使用Exit Do语句强制跳出循环。五、Exit Do 语句 Exit Do语句必须放置在DoLoop语句的循环体中。执行到Exit Do时,程序会立即结束循环,跳到Loop后面执行下面的语句。当有多个循环嵌套使用时,Exit Do语句只跳出所在的最内层的DoLoop循环。 Exit Do语句不只可以用来结束不使用While和Until关键字的DoLoop语句,也可以用在使用了While或Until关键字的“当型循环”或“直到型循环”中。 如果在运行时发生了“死循环”,可以使用Ctrl+Break组合键返回调试状态,再返回设计状态。打开【例5.11】 使用Exit Do语句计算阶乘数n!。 For 计数器变量 = 起始值 To 终止值 Step 增量语句块(循环体) 满足条件时可退出该循环 Next 计数器变量 For Next 循环语句使用一个“计数器”变量控制循环,这个变量不能是逻辑值或数组元素,此语句每次自动给计算器变量增加一个“增量”,如果变量的值超出给定的“终止值”,则退出循环,否则会重复执行“语句块”。第一次运行“语句块”时,只进行比较,不改变变量的值。 当“增量”是正值或零时,变量的值大于“终止值”时退出循环,当为负值时,变量量的值小于“终止值”时退出。如果 “Step 增量”省略,按增量为1处理。循环体TrueFalse给“计数器变量”赋以“初始值”“计数器变量”是否超过“终止值”?给“计数器变量”增加“增量”六、For Next 循环语句 一般地,当事先可以确定循环次数时,使用ForNext语句,否则应使用DoLoop循环。打开【例5.12】 使用For循环计算n!。语句格式Exit For 语句 就像使用Exit Do语句可以强制跳出DoLoop循环一样,对于ForNext循环,可以在循环体中使用Exit For语句,当程序执行到Exit For语句时立即终止循环,跳到Next下面的语句继续执行。与Exit Do类似,Exit For语句只能用在Exit For循环中,并且只能跳出所在的最内层ForNext循环。ForNext循环的“终止值”和“步长”问题 特别值得注意的是,对于ForNext语句来说,一旦进入循环,其“终止值”和“增量”便不会再改变了。例如,在下面的程序段中,循环的“终止值”和“增量”是由变量j和k的值决定的。虽然在循环体中改变了这两个变量的值,但是并不会影响循环次数(10次),“终止值”和“增量”仍然是进入循环时两个变量的值,分别是10和1。Dim i As Integer, j As Integer, k As Integerj = 10: k = 1For i = 1 To j Step k Print i j = j - 1 k = k + 1NextPrint j, k练习:分析下面程序段结束时窗体上显示的值是多少?(2)i2=0For i = 1 To -2 Step -1i2 = i2+1NextPrint i , i2(-3 4)(1)For i = 1 To 10 i2 = i2+1NextPrint i(11)(3)i2=0For i = 1 To 5 Step 2i2 = i2+1NextPrint i(7)(4)i2 = 1For i = 1 To 10i = i + 1i2 = i2 + 1NextPrint i, i2(11 6)(5) i2 = 1i3 = 10i = 10For i = 1 To i3i = i + 1i2 = i2 + 1i3 = i3 + 1NextPrint i, i2(11 6)(6)i2 = 0For i = 1 To 10 i2 = i2 + 1 If i 6 Then Exit ForNextPrint i, i2(7 7)(7) i2 = 0i = 10Do i2 = i2 + 1Loop While i = i2Print i2(1)嵌套的层数不限;内层控制结构必须完全位于外层的一个语句块中;多个ForNext语句嵌套时,不能重复使用同一个“循环计数器变量”;为了便于阅读与排错,内层的控制结构应向右缩进。正确的嵌套:七、循环的嵌套错误的嵌套: 循环嵌套时的格式 Exit Do语句用于强制结束Do循环,当有多个Do循环嵌套时,只跳出该语句所在的最内层循环并执行对应Loop之后的语句。同理,Exit For语句用于强制结束For循环,当有多个For循环嵌套时,只跳出该语句所在的最内层循环并执行对应Next之后的语句。 当Do循环与For循环嵌套使用时,如果Exit Do语句处于Do循环中的一个For循环中,Exit Do语句同时会跳出For循环。同理,如果Exit For处于一个For循环内的Do循环中,程序不但跳出当前的For循环,而且会跳出正在执行的处于For循环内部的Do循环。Exit Do和Exit For语句在循环嵌套时的作用 当程序中有控制结构的互相嵌套时,其执行流程仍严格按照每个控制结构既定的流程进行。下面以两重ForNext嵌套为例,演示循环嵌套时的执行流程。多重嵌套的道理是相同的。 循环嵌套的执行流程Private Sub Form_Click() Dim i As Integer, j As Integer For i = 1 To 3 Print i=; i For j = 1 To 3 Print Tab; j=; j Next NextEnd Sub 从这段程序的执行情况可见,外层循环执行一次(如i = 1),内层循环要从头循环一遍(如j = 1、j = 2、j = 3)。在同一对象或同一个用户定义类型变量上执行一系列的语句。 With 对象名或自定义类型变量名 语句块(可以省略其中的对象名或变量名) End WithWith 语句可以对某个对象执行一系列的操作(如设置属性值、调用方法),而不用重复指出对象的名称。例如:cmd1 .Height = 2000cmd1 .Width = 2000cmd1 .Caption = Hellocmd1 .Move 0,0With cmd1.Height = 2000.Width = 2000.Caption = Hello.Move 0,0End With注意: 一个With语句只能用于一个对象,如果一个对象属于另一个对象,可以使用嵌套的With 语句。不要跳入或跳出 With 块。如果在 With 块中的语句被执行,但是 With 或 End With 语句并没有执行,则会产生错误,或不可预知的结果。八、With 语句With语句的格式Private Sub cmd2_Click()Form1.Height = 2000Form1.Width = 2000Form1.Caption = HelloForm1 .Move 0, 0Form1.cmd1.Height=1000Form1.cmd1.Width=1000Form1.cmd1.Caption=OKForm1.cmd1.Move 0, 0End SubPrivate Sub cmd2_Click()With Form1 .Height = 2000 .Width = 2000 .Caption = Hello .Move 0, 0 With .cmd1.Height=1000.Width=1000.Caption=OK .Move 0, 0 End WithEnd WithEnd SubWith语句的嵌套【例5.15】求一元二次方程的根。一元二次方程的根有下列三种情况:(1)当a=0、b=0时,方程无解;(2)当a=0、b0时,方程只有一个实根;(3)当a0时,方程有两个根(两个实根或两个虚根)【例5.16】验证质数。 如果一个整数n只能被1和n整除,则n为质数。质数又称为素数,规定1不是质数,2是质数。本程序验证从文本框中输入的正整数是否为质数。在窗体上的文本框txtInput中输入任一大于3的正整数n,然后单击按钮cmdPrime,文本框txtOutput中显示出“n是质数”或“n不是质数”。 判断n是否为质数比较简单的方法是:用n逐个除以2n-1之间的每个整数,只要有一个可以整除,则说明n不是质数;如果全部不能整除,则说明n是质数。【例5.17】求水仙花数。 “水仙花数”是指一种三位整数,它各位数字的立方和等于该数本身。编程将所有的水仙花数显示在窗体上,并在文本框中显示个数(水仙花数共有4个:153、370、371和407)。九、控制结构的应用打开【例5.15】打开【例5.16】打开【例5.17】【例5.18】求Fibonacci(菲邦纳契)数列第n项的值。 已知Fibonacci数列为:1,1,2,3,5,8,。该数列第一项和第二项均为1,从第三项开始,每一项都是前面两项的和。 除了数列的前两项之外,其他项可用迭代法求得。打开【例5.18】【例5.19】使用级数求的值。 根据下式,计算圆周率的近似值,当计算到绝对值小于0.0001的通项时,认为满足精度要求,停止计算。 本例的两个重点是:(1)对于需要进行“无限次”计算的情况,如何利用给定的“精度”在适当的时刻结束计算。(2)如何使程序编制得代码简单,运行效率高。解法一:Private Sub cmdPi_Click() Dim a As Single Dim m As Single Dim n As Integer n = 1 Do m = 1 / (2 * n - 1) a = a + (-1) (n + 1) * m n = n + 1 Loop While m = 0.0001 Text1.Text = a * 4 End SubPrivate Sub cmdPi_Click() Dim a As Single Dim m As Single Dim s As Integer Dim i As Integer s = 1 : i = 1 Do m = 1 / i a = a + s * m i = i + 2 s = -s Loop While m = 0.0001 Text1.Text = a * 4 End Sub解法二:打开【例5.19】【例5.20】将一角钱换成零钱(可以包括含1分、2分、5分中的任意多个面值),共有多少种换法? 组成一角的零钱中,最多有10个1分、5个2分、2个5分。判断所有的组合中,总和正好是一角(10分)的情况有多少次即为所求。这类方法称为“穷举法”,也称为“列举法”。 Private Sub Command1_Click() Dim i As Integer, j As Integer, k As Integer Dim n As Integer Print 1分个数, 2分个数, 5分个数 For i = 0 To 10 For j = 0 To 5 For k = 0 To 2 If i + j * 2 + k * 5 = 10 Then n = n + 1 Print i, j, k End If Next Next Next Print 共有 & n & 种方法 End Sub打开【例5.20】设计“健康称”程序,界面设计如下图所示。具体要求如下: 将两个文本框的文字对齐方式均设置为右对齐,最多接受3个字符。 两个文本框均不接受非数字键; 单击“健康状况”按钮后,根据计算公式将信息通过标签显示在按钮下面。 计算公式为:标准体重身高-105 体重高于标准体重的1.1倍为偏胖,提示“偏胖,加强锻炼,注意节食”;体重低于标准体重的90为偏瘦,提示“偏瘦,增加营养”;其他为正常,提示“正常,继续保持”,如右图(上)所示。十、实验题计算 的值。计算 的值。计算 的值。设计如右图(中)所示的界面程序。设计如右图(下)所示的金字塔界面程序。返回目录第6章 过 程 “过程”(Procedure)是VB程序中相互独立的、可完成特定的操作任务的程序块。每个过程有一定的语法结构。 使用过程,可将大的模块细分 。这样既简化了程序的编制,也使用程序更易理解,便于调试。 VB的过程分为事件过程、通用过程和属性过程。事件过程由系统在一个事件发生时自动调用,而通用过程必须在程序中需要的地方进行“显式”地调用。 引例1:试执行下面的程序,观察结果。Private Sub Command1_Click() Call Command2_ClickEnd SubPrivate Sub Command2_Click() Print 调用了第二命令按钮End Sub 通用过程分为两类:Sub过程Function过程一、通用过程VB中的过程事件过程通用过程类的属性过程和事件过程Sub过程(子过程,自定义过程)Function过程(函数)(不在本课程范围内)引例2:求组合数。 Private | Public Static Sub 过程名 (形式参数) 语句块(过程体) Exit Sub End Sub 过程语法结构的第一行称为首部。 过程名:Sub过程的名称,与变量命名规则相同,在同一模块中不能重复。 Public|Private :决定过程的作用域(全局的或模块级的),即可访问性(默认值为Public)。 Static:使该过程中所定义的所有变量均成为静态变量,不管在定义变量时使用的是Dim或是Static。 形式参数:过程可以有零个或多个参数,多个参数由逗号隔开。 (参数名1 As 类型名,参数名2 As 类型名,. ) 形参的命名规则与变量相同。在通用过程中,形参被看作是过程级变量,所以不能在过程中定义与形参同名的变量。如果省略“As数据类型名”,则默认形式参数是变体类型的。 过程体:多行语句,用来实现过程的功能。可以是空过程,不执行任何操作。 “代码窗口”中过程的定义是平等的、并列的。二、Sub过程(子过程)定义Sub过程Call语句调用 Call过程名(实际参数值1 , 实际参数值2 , .) (如无参数,则不用括号)使用过程名直接调用 过程名参数值1 , 参数值2 , . (不能使用括号)调用Sub过程【例6.1】使用两种方法调用有参数的Sub过程。 Private Sub ChangeForm2(intTop As Integer, intLeft As Integer, _ strCaption As String) 定义通用过程 Me.Top = intTop Me.Left = intLeft Me.Caption = strCaption End Sub Private Sub cmd1_Click() Call ChangeForm2(0, 0, VB) 第一种调用方法 End Sub Private Sub cmd2_Click() ChangeForm2 1000, 1000, Visual Basic 第二种调用方法 End Sub打开【例6.1】过程调用时的执行流程 在程序的执行过程中,当一个过程(事件过程或通用过程)中有调用其他过程的语句时,先暂停当前过程的执行(保留过程级变量的值,记录执行到的位置),转到被调用的过程中继续执行。被调用过程执行完毕后(遇到End Sub语句或Exit Sub语句),返回调用它的过程从暂停位置继续向下执行。过程的嵌套调用调用时的参数传递 Private | Public Static Function 函数名 (形式参数) As 返回值数据类型 语句块(函数体) 函数名=表达式 Exit Function 函数名=表达式 End Function函数与Sub过程的主要区别在于有返回值,需要指定返回值的类型。指定函数的返回值:在函数体中为函数名赋值:函数名=表达式函数的返回: 当遇到End Function 语句或函数体中的Exit Function语句则结果函数的执行,返回到调用它的过程中继续向下执行。 Exit Function: 它的功能与Exit Sub(Exit Do)相似,用于强制跳出所在函数。 如果在函数返回之前未给函数名赋值,则返回一个函数类型的初始值,如0、#0:0:0# 或 False。 如果在返回之前多次为函数名赋值,则只返回最后的值。三、函数(Function 过程)定义函数调用函数因为Function过程包含了Sub过程的所有功能,所以调用Sub过程的方法也可以用来调用Function过程。Call语句调用 Call函数名(实际参数1, 实际参数2, )函数名直接调用函数名实际参数1, 实际参数2, 在表达式中调用前两种方法都忽略了函数的返回值,一般较少使用。大多数情况下,把函数用于赋值语句、表达式中或作为实际参数调用其他过程。这时使用函数名调用并且必须加括号把实参括起来。例如: a = f() 函数f返回值用于赋值 b = f() + a 函数f返回值用于表达式计算 c = sub1(f() + b 函数f返回值用于过程sub1的实际参数当程序执行到有函数调用的过程时,先暂停当前过程,转而去执行被调用的函数,函数执行完毕,将返回值返回,父过程使用返回值继续进行暂停的运算和操作。【例6.2】使用函数Factor计算10!-9!的值。参考程序: Private Sub Command1_Click() Text1.Text = Factor(10) - Factor(9) 两次调用函数FactorEnd SubPrivate Function Factor(n As Integer) As Long 计算阶乘的函数过程 Dim i As Integer, f As Long i = 1: f = 1 变量赋初值 Do 计算阶乘 f = f * i i = i + 1 Loop While i n + 1 Factor = f 为函数名赋值,返回值End Function练习:如右下图所示,输入某一天的年、月和日,计算出这一天是该年的第几天?打开【例6.4】计算分数数列前n项之和,如右上图所示。【例6.5】已知下式成立(其中x的单位为弧度):编制名为mySin的函数,要求它能够计算参数x(单位是“度”)的正弦值,精度为0.00001。Function mySin(x As Single) As Single Dim i As Integer, a As Single, s As Single x = x * 3.1415926 / 180 角度转换为弧度 i = 1: s = x: a = s Do s = -1 * s * x * x / (i + 1) / (i + 2) 计算通项 a = a + s i = i + 2 Loop Until Abs(s) = 0.00001 mySin = a 返回值End FunctionPrivate Sub Command1_Click() Dim x As Single x = Text1.Text Text2.Text = mySin(x) 调用mySin函数End Sub本程序利用了通项之间的关系,每个通项都是由前一项计算得到,避免了幂运算和求阶乘,使得算法比较优化。打开【例6.5】【例6.6】使用欧几里德法求两个非负整数m和n的最大公约数。欧几里德法被称为“辗转相除法”,用此方法求最大公约数的算法描述如下。首先使用变量u和v分别保存m和n的值。然后当v不为0时,反复执行下面的三个操作(其中r为一个辅助变量): ru Mod v uv vr直到v等于0时,变量u的值即为m和n的最大公约数。下面的函数使用了欧几里德法,计算参数m和n的最大公约数并返回。 Private Function gcd(m As Integer, n As Integer) As Integer Dim u As Integer, v As Integer, r As Integer u = m v = n Do While v 0 r = u Mod v u = v v = r Loop gcd = u End Function打开【例6.6】在调用具有参数的Sub过程或Function过程时,实际参数传递给形式参数的可以是值,也可能是其地址。四、过程的参数传递方式 按值传递参数(ByVal)如果在定义通用过程时,形式参数名前加上关键字“ByVal”,就规定了在调用此过程时,该参数是按值传递的。按值传递时,传递给形参的是父过程中调用语句中相应实际参数(可以是变量、常量或表达式)的值。如果在子过程中改变了形参变量的值(比如给形变量参赋值),不会影响父过程中实参的值。当子过程结束并返回父过程后,实参还是调用之前的值。如果通用过程中的形参设定为按值传递,不要求调用时相应实参的类型与其一致,只要实参的值能够转换为形参的类型即可。按地址传递参数(ByRef)如果形式参数前加上关键字“ByRef”(默认设置),则该参数是按地址传递的。调用时,传递给该形参的是父过程中调用语句中相应实参(可以是变量或数组元素)的地址。即,子过程的形参与父过程的相应实参共用了相同的内存单元。当在子过程中改变形参的值时,同时也改变了父过程中实参的值。当子过程结束并返回父过程后,实参变量的值已经发生了变化。 注意:按地址传递参数时,要求调用时使用的变量(或数组元素)的类型与子过程相应的形参类型一致,否则出错。例:用值传递的方式求组合数。例:用地址传递的方式求组合数。 如果实参是以下情况之一的,实际进行的是按值传递:实参是常量;实参是表达式;实参是函数的调用;实参是以括号括起的单个变量。在这四种情况下,实参的数据类型可以与形参不同。【例6.7】检验参数的按值和按地址传递。 【例6.8】以另一种方法求正弦值。【例6.9】按地址传递的副作用。打开【例6.7】打开【例6.8】打开【例6.9】定义过程时在参数前加上关键字“Optional”。如果一个过程有多个参数,当它的一个参数定为可选参数,那么它之后所有的参数都应用“Optional”定义为可选的。还可以为可选参数指定默认值。如果一个Sub或Function过程的某个参数定义为“可选参数”,则在调用此过程时可以不提供该参数相应的调用值。以提供的默认值或数据类型的默认值传递。可选参数(Optional)(大纲不要求)Sub|Function过程名(.,Optional可选参数As数据类型=默认值,.)打开【例6.10】打开【例6.10-1】编写一个用于计算两个实数的和以及平均值的子过程,该子过程具有一个可选参数,在调用子过程时,如果不提供与可选参数对应的实参,或实参的值为0,则在窗体上只打印两个数的和;如果提供了一个不为0实参,则在窗体上还将打印出两个数的平均值。 具有可选参数的子过程的代码如下:命名参数(大纲不要求)打开【例6.11】在调用通用过程时,如果使用以下方式在指定实参时同时指定形参名,则不要求严格地按顺序指定。形式参数名 : = 实际参数Private Sub Form_Click() Print 不提供与可选参数对应的实参 sum 6, 9 Print 提供与可选参数对应的实参,并且实参为0: sum 6, 9, 0 Print 空行 : Print 提供与可选参数对应的实参,并且实参不为0: sum 6, 9, 1End SubPrivate Sub sum(x As Single, y As Single, Optional n As Boolean = 0) Dim s As Single, A As Single s = x + y : A = s / 2 If n = False Then Print 总和为: & s Else Print 总和为: & s Print 平均值为: & A End IfEnd SubVB允许一个过程直接或间接地调用其自身,称为“递归”。递归是一种技巧,可以将程序设计的非常紧凑,甚至有些问题必须使用递归来实现。但是,如果程序设计得不好,递归调用的程序很容易出错。尽管函数调用的是自身,但是每调用一次自己都会在内存中复制一份,因此调用的次数越多,占用的空间越大。如果超过一定的限制,就会出错。【例6.12】编写递归函数求阶乘n!。五、过程的递归调用Private Function Fact(n As Integer) As Long If n 1 Then Fact = n * Fact(n - 1) Else Fact = 1 End IfEnd Function打开【例6.12】Sub fact(n As Integer) If n = 1 Thenfact = 1 Else fact = n * fact(n - 1) End IfEnd FunctionSub fact(n As Integer) If n = 1 Thenfact = 1 Else fact = n * fact(n - 1) End IfEnd FunctionSub fact(n As Integer) If n = 1 Thenfact = 1 Else fact = n * fact(n - 1) End IfEnd Function父过程中调用:i fact(3)传递3传递2传递1返回1返回2返回6n=3n=2n=1递归一般不能提高程序的执行性能,因为直接递归过程不断地调用其本身,而间接递归会调用两个或更多的过程,这样对内存占用是巨大的,所以,在递归过程中应尽量少用过程级变量和数组。下面使用递归计算Fibonacci数列的例子与使用循环计算相比,速度慢得多。【例6.13】编写递归函数计算Fibonacci数列第n项的值。Private Function Fibo(ByVal n As Integer) As Long If n y Then Swap X,y X1=y1 If Yz Then Swap Y,z Y1=temp If Xy Then Swap X,yEnd SubEnd Sub第7章 数组与自定义数据类型一、数组数组概述 在程序中,常有很多变量,如x1=301,x2=302,x3=303,x4=304,。为方便对各个变量进行统一管理,可将各同类变量定义一个集合,即数组,如下图所示: x1=301 x2=302x(4) x3=303y(3,4) x4=304z(2,3,4) 数组是变量的扩展,一个数组可以存储多个值,通过数组名和下标对这些值进行存取。与变量相比,数组有以下优点:数组能够保存多个值;数组可与循环语句配合实现复杂算法;数组可作通用过程的参数,传递大量的值;数组可作函数过程的返回值,可返回大量的值;数组常用来表示与一维、二维、三维空间分布相关的数据,非常直观;动态数组可根据需要开辟内存空间,优化程序、提高效率。下标:指成员个数。元素:组成的成员。维数数组名:变量集合名。引用数组各元素的方法:x(1)、x(2)、x(3)、x(4)。这里的“1”表示下界值,“4”表示上界值。下标的上界(Upper Boundary)和下界(Lower Boundary)。指定的上下标界,称为固定大小的数组(常规数组),否则是动态数组。组成数组的要素数组名(Array Name):变量集合名。元素(Element):组成的成员下标(Index):指成员个数。维数(Dimension):下标的上界(Upper Boundary)和下界(Lower Boundary)。指定的上下标界,称为固定大小的数组(常规数组),否则是动态数组。一维数组元素个数的计算公式是:元素个数下标上界下标下界1常规数组至少应该有一个元素,这时下标的上界与下界相等。二、常规数组常规数组,即固定大小的数组。由括号中的数值决定数组的维数和下标的上下界。定格格式如下: Public|Private|Dim|Static数组名(维数与下标界限)As数据类型名如: Dim x(5) as Integer,y(3,4) as Single,s(3,4,5) as String分别定义了一个一维数组x,一个二维数组y和一个三维数组s。数组x、y和z中的每个元素分别接受整型、单精度浮点数和字符串的数值。使用关键字To指定下标的下界和上界,形式如下:Dima(mTon)As.m为下标下界,n为下标上界。m和n必须为整型常量,可以是负值,并要求mn。M如果是负值,则引用数组元素的下标从负数开始,如: Dim x(-2 To 3) as Integer 表示数组x有6个元素,分别是x(-2)、 x(-1) 、x(0)、 x(1)、 x(2)、x(3)。 可以使用下列两种方式指定一维数组的下标界限: 只指定下标上界,而由Option Base语句指定下标下界:Dima(n)As. Dim x(3) as Integer在模块“代码”窗口顶部的声明段中使用以下语句定义下标下界是0或1:Option Base0|1使用“0”时,上界n必须是非负整数常量(不能使用变量),使用“1”时,上界n必须是正整数常量。如果没使用Option Base语句,默认为0。 例如,右图所示的语句不正确。错错误误信信息息正正确确指定下标界限 访问数组元素常规数组被定义之后,便具有了内存空间,可以通过以下方式访问数组指定下标的元素: 数组名(下标)访问数组元素时的“下标”可以是整型(或长整型)常量、变量或表达式。下标值不能小于数组下标的下界,不能大于下标的上界,否则会引发“下标越界”的运行时错误。数组元素的赋值 数组元素可以像普通变量一样被赋值、参与表达式计算、作为实参调用通用过程,也可以使用循环语句对多个元素进行“批量”操作。例子: Dim a(0 To 5) As Integer 定义数组a 方法1:为单个元素赋值 a(0) = 1 : a(1) = 3 : a(2) = 5 : a(3) = 7 : a(4) = 9 : a(5) = 11 方法2:通过循环语句为个元素赋值 For i = 0 To 5 a(i) = 2 * i +1 Next【例7.1】十进制数转换为二进制数。 分析: 对整数,将十进制转换成二进制的方法是“除2反序取余法”,即:把要转换的十进制数反复除以2取其余数(除尽为1,除不尽为0),直至商为0;再将余数反序排列即为对应的二进制数。程序中使用了数组b保存每次除以2所得的余数。 对十进制小数,将十进制转换成二进制的方法是“乘2正序取整法”,即:把要转换的十进制数反复乘以2取其整数,直至所需的小数位。 Option Base 0Private Sub Command1_Click()Dim i As Integer: Dim d As IntegerDim b(15) As Byte : Dim s As Stringd = Text1.Text 得到十进制数Do Until d = 0 b(i) = d Mod 2 除2取余 d = d 2 i = i + 1LoopDo While i 0 i = i - 1 s = s & b(i) 反序排列LoopText2.Text = s 显示二进制数 End Sub打开【例7.1】【例7.2】找出数组元素中的最大值、最小值并计算所有元素的平均值。Option Base 1Private Sub Command1_Click() Const N As Integer = 10 定义常量 Dim a(N) As Integer 定义数组 Dim i As Integer Dim sum As Integer 此变量保存总和 Dim max As Integer 此变量保存最大值 Dim min As Integer 此变量保存最小值 For i = 1 To N a(i) = Rnd * 100 为数组元素赋随机值 Print a(i) Next max = a(1) 注意!给变量赋初值 min = a(1) 注意!给变量赋初值 sum = a(1) 注意!给变量赋初值 For i = 2 To N If max a(i) Then min = a(i) sum = sum + a(i) Next Text1.Text = max 显示最大值 Text2.Text = min 显示最小值 Text3.Text = sum / N 显示平均值End Sub打开【例7.2】三、二维数组二维数组是指有两个下标的数组,每个下标对应一个二维数组是指有两个下标的数组,每个下标对应一个“维维”。定义二维数组的语法。定义二维数组的语法格式为:格式为: Dim数组名数组名(第一维的下标界限第一维的下标界限 , 第二维的下标界限第二维的下标界限)As数据类型数据类型二维数组中每一维下标界限的定义方式与一维数组相同。例子:二维数组中每一维下标界限的定义方式与一维数组相同。例子: Dim a(4 , 5) As Integer Public b(-5 To 5 , 10) As Double Private c(1 To 10 , 2 To 5) As Boolean 二维数组的元素个数是各维下标取值个数之积。二维数组的元素个数是各维下标取值个数之积。 二维数组可以被理解为二维表格。如右图二维数组可以被理解为二维表格。如右图(a)所示,这是一个记录学习成绩的表所示,这是一个记录学习成绩的表格,由行和列组成。可以使用以下语句定义一个二级数组(如图格,由行和列组成。可以使用以下语句定义一个二级数组(如图(b)所示)来表示此所示)来表示此表格:表格:Dim a(1 To 3 , 1 To 4) As Integer访问二维数组元素,使用下面格式:访问二维数组元素,使用下面格式: a(i,j) = k使用循环结构访问数组元素使用循环结构访问数组元素Sum=0For i=1 to 3 For j=1 to 4 Sum=sum+a(I,j) NextNext四、多维数组多维数组是指三维或三维以上的数组,是在一维和二维概念上的扩展。多维数组的定义、元素的访问方式与一维和二维数组类似。例如,下而定义的是2个多维数组。 Dim a(3,3,4) As Integer 3维数组 Dim b(1 To 10,-4 To 5, 10,20) As Single 4维数组如果将二维数组比作二维表格,那么,三维数组可看作是由多张二维表组成的三维表格。【例7.3】矩阵的转置。矩阵是由N行M列数值组成的特殊数据形式,本例涉及的是方阵(即N=M,N称为阶数)。矩阵的转置是指行列数据交换(即沿对角线反转,如图)。如图所示,矩阵A可以使用二维数组表示。打开【例7.3】【例7.4】生成杨辉三角。杨辉是我国南宋时期的数学家,它引用前人贾宪的研究成果提出了后人所说的“杨辉三角”。如图7.9所示,杨辉三角的两侧全部是1,中间的每个数是其左上方和右上方两个数之和。打开【例7.4】当在编程时不能预料应该为数组定义多少个元素时,可以使用Visual Basic提供的动态数组。动态数组的维数和下标上下界可以在程序运行过程中改变。定义动态数组的的语法结构与定义常规数组相似,只是括号是空的: Public|Private|Dim|Static动态数组名( )As数据类型名定义语句确定了动态数组的名称、作用域和数据类型。在使用ReDim语句重新定义之前,动态数组没有元素,不能使用。重定义是指定动态数组的维数和下标界限(不能再改变数据类型): ReDimPreserve动态数组名(m1 To n1, m2 To n2,)ReDim语句指定动态数组维数和下标界限的方法与Dim定义常规数组相同。对于同一个动态数组,重定义ReDim语句可以反复使用,即可以多次改变该动态数组的维数和下标界限。如果不加关键字Preserve,ReDim语句会清除重定义之前动态数组所有元素中的数据,使用默认值来填充。如果希望重新定义之后,保留那些原来就有的数组元素值,则必须使用Preserve关键字。五、动态数组定义动态数组重定义动态数组Preserve关键字【例】 下面例子说明了动态数组的用法,程序运行结果如图所示。Option Base 1Private Sub Command1_Click() Dim da() As Integer, k% ReDim da(3) For k = 1 To 3 da(k) = 2 * k - 1 每个元素赋予奇数值 Print da( & k & )= & da(k) Next Print 不使用Preserve时的显示结果如下: ReDim da(5) da(4) = 7 : da(5) = 9 For k = 1 To 5 Print da( & k & )= & da(k) Next 使用Preserve显示的结果如何? ReDim Preserve da(5) da(4) = 7 : da(5) = 9 For k = 1 To 5 Print da( & k & )= & da(k) NextEnd Sub动态数组示例在编应用程序编写过程中,可能用到一引起类型相同且功能相近的控件,这时可以将这些控件定义为控件数组。 使用控件数组类似于使用数组变量,其特点如下: 具有相同的名称(Name); 通过索引值(下标)来区别控件数组中的元素。控件数组的元素个数受系统资源的限制,并且最大的Index属性值不能超过32767。六、控件数组创建控件数组的方法给多个控件定论相同的控件名称;控件数组的使用如右图所示,用VB编写一个由命令按钮组成的控件数组的单击事件程序。 在窗体上复制并粘贴相同类型的控件,如在窗体上先创建一个标签Label1控件,然后通过复制和粘贴的方法即创建标签Label1控件数组Label1(),这时开发系统将出现如下对话框,如右图所示; 设置控件的索引属性Index的值为非Null数值。七、 For Each-Next 语句Option Base 1Dim a(10) As IntegerPrivate Sub Form_Load() Dim k% For k = 1 To 10 a(k) = k NextEnd SubPrivate Sub Command1_Click() Dim Sum As Long,m For Each m In a m是一个缺省声明的变体变量 If m Mod 2 = 1 Then Sum = Sum + m Next Print 奇数元素的和为: & SumEnd Sub For Each Next语句是专门用于操作数组和集合的语句。其语法格式为: For Each 成员 In 数组名 循环体 Next 说明:成员必须是一个变体变量。循环执行的次数取决于数组元素的个数,数组元素的个数就是循环执行的次数。每次执行循环之前,都把数组中的一个元素赋给成员,第一次是数组中的第一个元素,第二次是第二个,依此类推。可以使用Exit For语句退出循环。For Each Next语句不能用于用户定义数据类型的数组。 可以看出,在数组操作中有时使用For Each Next语句比用For循环遍历数组元素更加方便,因为它不需要指定循环条件。 【例1】 假设已经给出了一个一维数组a,里面存放的都是整数。求数组a里所有奇数的和。 代码如下: 【例2】 下面的程序在窗体上的列表框内打印出窗体上所有控件的名称。命令按钮Command1的caption属性是“列窗体上的控件名”,该命令按钮的单击事件过程如下: Private Sub Command1_Click() For Each Control In Form1.Controls List1.AddItem Control.Name Next Control End Sub 程序运行的效果如下:图 Form1在设计是的外观 说明:由图可知,窗体上的记时器控件在执行后不见了,说明记时器控件是不可见控件。执行程序后的外观如图4-12所示。图 执行程序后的外观1LBound函数、UBound函数LBound(ArrayName,Dimension)UBound(ArrayName,Dimension)参数ArrayName指定数组名,参数Dimension指定第几维,函数LBound返回指定数组指定维的下标下界,函数UBound返回指定数组指定维的下标上界。如果省略Dimension参数,则返回的是第一维的下界与上界。2IsArray函数IsArray(VarName)如果参数VarName是数组名,或是引用了数组的变体类型变量名,IsArray函数返回True;否则返回False。未重定义的动态数组返回的也是True。如果VarName是数组元素,返回False。3Array函数Array(ArgList)参数ArgList是由逗号分隔的多个值,Array函数将这些值组成一个一维变体类型的数组。数组元素的值依次为各参数值。例如,以下语句: Dim A As Variant A = Array(10,20,30) B = A(2) A(2)元素和变量B的值都是20 注意:使用 Array 函数创建的数组的下界受 Option Base 语句指定的下界的决定。八、数组函数与语句4Erase语句Erase数组名1, 数组名2,Erase语句对数组进行初始化操作。对于常规数组,Erase语句使其成为数据类型的默认值。对于动态数组,Erase语句释放动态数组的存储空间,要继续使用这个动态数组,则必须使用ReDim语句重新定义。【例题 】 分析以下程序(2004年9月二级VB语言试题第24题)。在窗体上画一个名称为Command1的命令按钮,然后编写如下事件过程:Option Base 1Private Sub Command1_Click()Dim aa= Array(1,2,3,4,5)For i=1 To UBound(A)a(i)= a(i)+i-1NextPrint a(3)End Sub 程序运行后,单击命令按钮,则在窗体上显示的内容是 A)4B)5 C)6 D)72004年9月二级VB语言试题第25题Option Base 1Private Sub Form_Click() Dim arr,Sum Sum = 0 arr = Array(1,3,5,7,9,11,13,15,17,19) For i=1 To 10 If arr(i)/3 = arr(i)3 Then Sum = Sum + arr(i) End If Next i Print SumEnd Sub程序运行后,单击窗体,输出结果为A)13B)14C)27D)15 在编写通用过程时,允许定义数组参数,这样便可以使用一个参数传递大量的值。(1)数组形参的定义 ByRef数组形参名()As数据类型名数组形参名后必须加空括号,并且不能使用ByVal关键字修饰,因为数组参数必须按地址传递。(2)调用时,相应的实参必须是与形参相同类型的数组名,可以带空括号。(3)一个通用过程可以定义多个数组参数。(4)作参数的数组可以是任意维的,由实参数组决定。因为是按地址传递,在通用过程中修改形参数组的元素值可以改变父过程中实参数组的元素值。如果实参是动态数组,则相应的形参也可以被看作为动态数组,在子过程中可以使用ReDim语句重新定义,改变数组维数、下标上下界以及元素值,同时也改变了父过程的数组。【例7.6】使用数组参数编写求和的函数sum。【例7.7】顺序查找。九、数组作参数打开【例7.6】打开【例7.7】【例7.8】折半查找。 “折半查找法”比顺序查找效率更高一些。折半查找的原理是:假设数组是递增的,并且被查找的数一定在数组中。如图所示,先拿被查找数(12)与数组中间的元素进行比较,如果被查找数大于元素值,则说明被查找数位于数组中的后面一半元素中。如果被查找数小于数组中间元素值,则说明被查找数位于数组中的前面一半元素中。接下来,只考虑数组中包括被查找数的那一半元素。拿剩下这些元素的中间元素与被查找数进行比较,然后根据二者的大小,再去掉那些不可能包含被查找值的一半元素。这样,不断地减小查找范围,直到最后只剩下一个数组元素,那么这个元素就是被查找的元素。当然,也不排除某次比较时,中间的元素正好是被查找元素。打开【例7.8】过程用Option关键字修饰的形参,称为选参数。可选参数,在过程调用时,的实参可提供,也可不提供。指定可选参数及默认值的语法格式如下: Sub|Function 过程名(,Optional 可选参数 As 数据=默认值,) 说明: 在过程的形参表中列入了Optional关键字,则可以指定过程的形式参数为可选参数,参数表中此参数后面的其他参数也必须是可选的,并要用Optional来声明。 调用具有多个可选参数的过程时,可以活力它的任意一个或多个可选参数对应的实参。如果被活力的不是最后一个参数,则它的位置必须用逗号保留和分隔。例如,定义了如下过程:Private Sub Command1_Click() Print f(1) 省略第2个和第3个参数,显示1 Print f(1, 2) 省略第3个参数,由于第3个参数提供了默认值10,因此显示21 Print f(1, , 3) 省略第2个参数,显示1 Print f(1, 2, 3) 不省略参数,显示7 Print f() 出错,第一个参数不能省略End Sub定义了一带有可选参数的函数fPrivate Function f(a%, Optional b%, Optional c As Integer = 10) As Integer f = a + b * cEnd Function 十、可选参数(Option)函数返回数组是返回大量值的好办法。如果在定义函数过程时,返回值类型后加上空的小括号,表示此函数过程的返回值是一个数组。Function函数过程名(形参列表)As数据类型名()1指定函数的返回值首先在函数体中定义一个与返回值类型相同的数组,把要返回的值赋给数组的各个元素。在返回之前,把这个数组名赋值给函数名,则这个数组会作为返回值返回。2调用返回数组的函数调用返回数组的函数之前,先定义一个与函数返回值类型相同的动态数组(不必重定义)或变体类型的变量;调用函数时,把返回值赋给定义好的动态数组名或变量。通过动态数组或变体变量即可访问返回数组的元素。十二、函数返回数组打开【例7.10】【例7.10】矩阵乘法。【例】 试分析下面程序的功能。Private Sub Command1_Click() Dim arr() As String arr = GetArray For n = LBound(arr) To UBound(arr) Print arr(n) NextEnd SubPrivate Function GetArray() As String() Dim arr(2) As String arr(0) = A arr(1) = B arr(2) = C GetArray = arrEnd Function可以使用Type关键字来定义自定义数据类型。自定义数据类型是由已存在的数据类型组合而成的。定义自定义数据类型,必须要在模块的声明段中进行。Public|PrivateType自定义数据类型名 成员名1As已有的数据类型名 成员名2As已有的数据类型名 成员名3As已有的数据类型名 EndType十三、自定义数据类型打开【例7.10-1】 代码如下面所示。Private Type student xh As Integer xm As String cj As IntegerEnd Type 在窗体模块中不能定义Public型Private Sub Form_click() Dim xs As student xs.xh = 1 xs.xm = 乔丹 xs.cj = 99 Print xs.xh, xs.xm, xs.cjEnd Sub例如:如下图所示,设计一个简单窗体的单击事件,使用自定义数据类型输入“乔丹”的个人信息。说明省略了Public和Private关键字,默认是应用程序级必须在标准模块的声明段中定义。窗体模块中只能定义Private,可在本模块中使用。自定义数据类型中的成员的定义方法类似于定义变量,只是省略了Public|Private|Dim|Static关键字。成员可以是任何已有的数据类型,包括定长和变长字符串以及已定义的其他自定义类型。如果是变体类型,必须使用“As Variant”显式定义。成员也可以是数组(包括常规数组和动态数组)。除非使用To关键字指定下标的上下界,否则成员数组的下标下界总是0,不受Option Base 0|1设置的影响。1定义自定义类型的变量和数组可以使用与基本数据类型一样的语法格式来定义自定义类型的变量和数组。例如: Dim student1 As Student, student2 As Student 定义两个Student类型的变量 Dim students(1 To 50) As Student 定义Student类型的常规数组students Dim mystudents() As Student 定义Student类型的动态数组mystudents Redim mystudents(50) 重定义动态数组自定义类型变量所占用的内存空间是各个成员占用内存空间之和。其中变长字符串和动态数组只占4字节,字符串和数组内容保存在内存的其他区域,成员中保存的是这个区域的地址。2访问自定义类型变量或数组元素的成员为自定义类型变量、数组元素赋值,或使用其值,应使用以下格式(类似于访问对象的属性):自定义类型变量名自定义类型变量名.成员名成员名自定义类型数组自定义类型数组(下标下标).成员名成员名3为自定义类型变量赋值为自定义类型变量赋值有两种方法:(1)逐一给各个成员赋值;(2)使用同类型的变量或数组元素为整个变量赋值,被赋值变量的每个成员的值与赋值变量每个成员的值相同。4为自定义类型数组赋值为自定义的数组赋值就是为其每个元素赋值,方法与为自定义类型的变量赋值相同。当一个变量具有有限个可能值,并且这些值有两个特点: 可以取整型值。 每个值可以有一个名字。这时,该变量的值就可以有枚举描述。 定义枚举类型的语法如下:Public | Private Enum namemembername =值表达式membername =值表达式. . .End Enum 说明:该语句只能在模块级别,Enum 类型的缺省情况是 Public。 例:Option ExplicitPrivate Enum WorkDays Saturday 0值,系统的定义 Sunday = 0 0值,自定义值 Monday 1值,在自定义值的基础上加1,如无自定义值,则在系统值的基础上加1 Tuesday 值为2。 Wednesday Thursday Friday Invalid = -1End Enum十四、枚举类型Private Sub Command1_Click() Dim MyDay As WorkDays MyDay = Saturday Saturday的数值为 0。 If MyDay Monday Then Monday的数值为 1, MsgBox 周末! End IfEnd SubCollection 集合对象可以将一组相关的项目视为单一对象来引用。集合的成员不一定都是同一种数据类型的。 建立集合的方法如下: Dim As New Collection 一旦建立集合之后,就可以用 Add 方法添加成员,用 Remove 方法删除成员。在用 For Each.Next 语句重复整个集合时,可以用 Item 方法从集合返回特定成员。用Count 属性测试包含集合中的对象数目。 为集合添加元素Add,方法如下: .Add ,Before:=,After:= 说明:采用Add方法为集合添加元素。用代表集合的元素,并为它赋一个。Before:=后面的表示位于该元素后的元素的主题词;After:=后面的表示位于该元素前的元素的主题词。如果Before:=缺省,但不缺省,那么前应出现两个逗号,以表示是属于After的。 移去集合中的元素Remove,方法如下: .Remove index 说明:Index 表达式,指定集合成员的位置。如果是数值表达式,则 index 必须是介于 1 和集合 Count 属性值之间的数。如果是字符串表达式,则在将被引用的成员添加到集合时,index 必须和 key 参数一致。 十五、Collection集合类型 指定集合中的成员Item 方法,语法如下: .Item(index) 其中:index表达式,指定集合中成员的位置。如果是数值表达式,则 index 必须是从 1 到集合 Count 属性值之间的数值。如果是字符串表达式,则当加入一被引用的成员到集合时,index 必须和 key 参数对应。 例如:下面语句是等价的:Print MyCollection(1)Print MyCollection.Item(1) Count 属性测试包含集合中的对象数目,语法如下: X=. Count【例1】 下面程序段可打印学生的年龄,如图所示:Private Sub Command1_Click() Dim stu As New Collection stu.Add 18, 张三 stu.Add 20, 王五, , after:=张三 在张三后添加 stu.Add 19, 李四, before:=王五 在王五前添加 stu.Add 21, 马六, , 王五 在王五后添加 For k = 1 To stu.Count Print 年龄:; stu.Item(k) NextEnd Sub【例2】 用以下的代码实现将项目中所有窗体上控件的字体的大小都设置成统一的格式,所有载入的窗体中的控件的字体都被指定为宋体,字号为16。 在项目中定义一标准模块定义两个全局变量Global CtrFont As Control, Aform As Form定义一FontAllSame子过程Sub FontAllSame()Dim i, j As IntegerFor i = 0 To Forms.Count - 1 Count属性是从0开始的整数Set Aform = Forms(i)For j = 0 To Aform.Controls.Count - 1Set Font1 = Aform.Controls(j)Font1.FontName = 宋体Font1.FontSize = 16Next jNext iEnd Sub 在项目中的所有窗体的Activate事件中加入以下语句:FontAllSame程序运行效果如图所示。求数组的最大元素及下标,设数组元素的取值为0100之间的整数十六、实验补充题编写程序,实现矩阵转置,即将一个nm的矩阵的行和列互换,如a矩阵为: 转置后的矩阵b为:打印杨辉三角形。输入一串字符,统计各字母出现的次数,大小写字母不区,运行界面:简单加密和解密。加密和解密。简单加密的思想是: 将每个字母C加一序数K,式子 c=chr(Asc(c)+k), 例如序数k为5,这时 “A”“F”, “a”“f”,“B”“G” 当加序数后的字母超过“Z”或“z”则 c=hr(Asc(c)+k -26)。 解密为加密的逆过程。 随机产生个10100的随机整数,并按由小到大的顺序打印出来。设某一个班共有60个学生,期末考试门课程,请编一程序评定学生的奖学金我,要求打印输出一、二等奖学金学生的学号和各门课程成绩。(奖学金评定标准是:总成绩超过全班总平均成绩20发给一等奖学金,超过全班总平均成绩10发给二等奖学金。)返回目录第8章 内部控件Name:对象名。X1,Y1,X2,Y2:直线控件的两个端点的坐标。Visible:直线控件的可见性,True或False。BorderStyle:直线的样式(06):透明、实线、虚线、点划线 .BorderWidth:直线的宽度(单位为像素),设置了此项,BorderStyle不起作用。Line控件无Move方法,要移动它,可以改变它的四个端点坐标属性的值。要隐藏直线控件,可以把其BorderWidth属性定为0(透明)或把Visible属性设为Fasle,而不能设它的BorderWidth属性为0。要应用除“实线“与“透明“之外的直线样式,线的宽度一定要设为1。直线控件不能响应用户操作,无事件过程和Enabled属性。一、直线(Line)控件常用属性Name:对象名。Shape :该属性决定图形控件以什么形状显示(05)。矩形、正方形、椭圆、圆、圆角矩形、圆角正方形。Left、 Top、Width 、Height、Visible 属性与其它控件的意义相同。BorderStyle:图形的边框样式(06):与直线控件一样为:透明、实线、虚线、点划线 BorderWidth:图形边框的宽度,单位为象素。FillStyle:图形内部的填充样式(07):实心、透明、水平线、方格线 .形状控件有Move方法,用法与其它控件一样。与直线控件一样,形状控件不能响应用户动作,无事件过程。二、形状(Shape)控件打开【例8.1】 形状和填充样式的改变。常用属性Name、Enabled 、Left、 Top、Width 、Height、Visible、 属性与命令按钮的意义相同。Name:对象名。Picture属性:此属性决定图象控件中所显示的图象来源。图象控件支持扩展名为:BMP、WMF、ICO、JPG、GIF为扩展名的图象文件。在设计时可以通过属性窗口来指定图象控件所显示的图象文件。在程序中可以使用VB定义的LoadPicture方法来打开一个图象文件赋予此属性。如: Image1.Picture=LoadPicture(c:bm.bmp)三 、图像(Image)控件常用属性Image控件有Move方法,用法与其它控件一样。Image控件有Click、DblClick事件,用法与其它控件一样。常用方法和事件 也可以使用不带参数的此方法使用图象控件不显示任何图象,如: Image1.Picture=LoadPictureBorderStyle属性:0:无边框(默认);1:有边框。Stretch属性:此属性为True时,当控件大小与图象的原始大小不同时,会缩放图象来填充整个控件。注:当图象缩放过度时,会造成失真。Name、Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。Picture属性:属性的意义与用法和Image控件的Picture属性一样。BorderStyle属性:0-无边框;1-有边框(默认)。AutoSize属性:此属性为True时,当控件大小与图象的大小不同时,会自动改变控件的大小来显示整个图片,当为False时,不会自动调整控件大小。这一点与图象控件不同。四、图片框控件(PictureBox)打开【例8.1_1】 生成一个随机的5行5列的2维数组,数组元素的值为单个正整数,并显示在图片框中,如图所示。计算该矩阵的位于主对角线上方的所有元素的和与位于主对角线下方的所有元素的和,并计算二者的差。图片框具有图像控件的所有功能,还有如下功能 :可作控件的容器;支持绘图方法,可绘图;通过Align属性定位于窗体的一侧。常用方法和事件常用属性PictureBox控件有Cls、Print等方法,用法与其它控件一样。PictureBox 控件支持Click、DblClick等事件,用法与其它控件一样。Change事件:当图片框的Picture属性变化时产生此事件。【例】图片框中LoadPicture函数的应用。在窗体上画一个图片框和2个命令按钮,编写如下代码。 Private Sub Command1_Click() Picture1.Picture = _ LoadPicture(“D:zhumlm.jpg”) 加载图片 End Sub Private Sub Command2_Click() Picture1.Picture = LoadPicture(“”) 删片 End Sub Name、Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。Value属性:滚动条的当前值,改变滚动块的位置会改变此属性。Min、Max属性: 分别表示当滚动条的滚动框处于顶部(或最左)位置时,和处于底部(或最右)位置时,滚动条代表的当前值。Max的值可以比Min小,但是实际工作中,仍是向右向上为增。二者也可以相等。SmallChange、LargeChange属性:分别是用户单击滚动箭头和空白区域时,滚动条控件的 Value 属性值的改变量。五、滚动条(HScrollBar、VScrollBar)控件打开【例8.2】 开合图片。常用属性和方法常用属性和方法Change事件:当滚动条的Value属性值发生变化时,激发此事件。可以是由于单击滚动箭头、拖动滚动框,或是用程序设置属性值等原因引起的。Scroll事件:当滚动条的滚动框被拖动时激发此事件。Caption属性:框架左上角的说明性文字。可以使用“&”号建立一个快捷键。BorderStyle属性:0:无边框与文字,1 正常样式。Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。Name:对象名。框架控件也可作控件的容器。框架用来把窗体上的控件进行分组,使窗体在外观上更有条理。框架有两种方法来对控件进行分组,六、框架控件(Frame)常用属性常用方法Move方法:移动控件、改变大小。Click、DblClick事件:用法与其它控件一样。但它不接受用户输入,不能显示文本和图形,也不能与图形相连。 柜架控件Name:对象名。Enabled属性:True,打开计时器,False,关闭计时器。Interval属性:以毫秒为单位的时间间隔。如果定时器打开,它就会每隔此属性指定的时间间隔激发一次Timer事件。当此属性为0时(缺省值),使 Timer 控件无效。1 到 65535 设置的时间间隔,因此时间间隔最多1 分钟多一些。计时器的时间间隔并不精确,特别是时间间隔太小时,会影响系统性能。七、定时器控件(Timer)打开【例8.3】常用属性常用事件定时器控件无方法。Timer事件:当时间间隔到时激发的事件。例如下面程序段的功能是:通过定时器控制标签的移动(移动字幕)。【例8.3】窗体上自动移动的按钮。Private Sub Timer1_Timer() If Label1.Left = Form1.Width Then Label1.Left = -Label1.Width Else Label1.Left = Label1.Left + 50 End IfEnd Sub思考一下:如何自动改变字体大小 程序代码如下:Private Sub Command1_Click() Static f As Boolean If f = False Then Timer1.Enabled = True Timer2.Enabled = True Label1.Visible = True Label2.Visible = True Command1.Caption = 停止 f = True Else Timer1.Enabled = False Timer2.Enabled = False Label1.Visible = False Label2.Visible = False Command1.Caption = 开始 f = False End IfEnd Sub【例题】如右图所示,使用双定时器的控制程序,其功能是:标签Label12的长度不断地以30个单位变长,当其变化到3000个单位时,长度改变为0。然后,再不断地变长;标签label1的背景和前景颜色不断地变化,标签Label2上显示的文字前景色跟随变化。Private Sub Form_Load() Label1.Width = 0 Label2.Width = 0 Label1.BackColor = vbRed Label2.ForeColor = vbRed Label1.Visible = False Label2.Visible = False RandomizeEnd SubPrivate Sub Timer1_Timer() If Label1.Width =1):n列,条目多时自动加水平滚动条。ListCount属性:此属性返回列表框中的条目数(只读属性)。List属性:此属性实质上是一个字符串数组,每一个元素对应列表框中的一个条目,元素的值就是此条目显示的文字。List属性数组下标从0ListCount-1。可以利用此属性在程序运行时给列表框中添加条目或改变指定条目所显示的文字。List1.List(m)= 新值也可在设计时通过属性窗口设置List属性,是个列表(条目之间使用Ctrl+Enter换行)。ListIndex属性:当前被选择的条目的序号( 0ListCount-1之间)。此属性只能在运行时用。通过此属性可访问当前被选择条目。列表框的常用属性MultiSelect属性:此属性决定列表框是否允许多选(运行时只读)。0:不允许多选;1:允许多选,使用鼠标左键单击或空格键选择,方向键移动光标。2:允许多选,使用Ctrl与Shift键来配合多选。(默认值为0)注:如果Style属性为1,则无论MultiSelect属性为何值,列表框均能多选。SelCount属性:返回列表框中被选中的条目数,如无条目被选中,则为0。Selected属性:此属性实质上是一个逻辑型数组,数组元素个数与列表框中条目个数相同,每一个元素对应一个条目。数组元素值为True表示相应的条目被选中,False表示未被选中。可以利用这个属性,在程序中检测具体一条目是否被选中;或使用此属性在程序中选择列表框中的条目。TopIndex属性:此属性返回或设置列表框当前可见的最上端一条的索引值。Text属性:此属性保存列表框当前所选条目的文字。此属性的值与List(ListIndex)一样。如无条目被选中,此属性为空字符串。(此属性只读) 另外,还有下面4个常用属性Style 属性:返回或设置一个值,该值用来指示控件的显示类型和行为。0 (缺省值),列表框控件是一个简单文本项的列表;1 , 每一个文本项的边上都有一个复选框。 Sorted属性:列表框中的条目是否排序,True:排序。False:不排序(默认)。NewIndex属性:返回最新添加到列表框中条目的序号。此属性为只读,对于排序列表框特别有用。往列表框中添加一条目之后,使用此属性可以获得它的序号,可以使用此序号来为它赋ItemData属性值,或进行其它操作。如果在列表中没有项或在新项被加入之后一个项被删除,那么 NewIndex 属性将返回 -1。ItemData属性:此属性是一个长整型数组,数组中每个元素(下标以0开始)对应列表框中的一个条目,所以此数组中元素的个数与列表框中条目数相同,也与List属性元素个数相同。此属性中的元素用来保存一个与列表框中相应条目有关的一个数据。AddItem方法:使用此方法往列表框中添加新条目。语法: 对象名.AddItem Item ,IndexItem参数指定要添加新条目的字符串表达式。Index参数指定新条目插入的位置(以0为基准)。如果语句中省略index参数,新条目将按Sorted的值插入列表框中:Sorted为True(排序)时,新条目会自动插入到恰当的位置。 Sorted为False(不排序)时,新条目会被插入为最后一条。如果指定index参数值,会把新条目插入到相应位置,但如果Sorted为True,可能出现错乱。RemoveItem方法:在列表框内删除指定条目。 列表框对象名.RemoveItemIndexClear方法:清除列表框中所有条目。 列表框对象名.Clear列表框的常用方法Click、DblClick事件:列表框控件支持Click和DblClick事件。应该注意的是,只有使用鼠标在列表框控件中的条目上单击或双击时才引发这两个事件。如果在列表框中没有条目的空白区域中操作鼠标,不会引发这两个事件。另外,如果通过程序可改变了列表框的ListIndex属性值,也会引发Click事件。Scroll事件:当列表框的滚到框被拖动时,激发此事件。ItemCheck事件:当 ListBox 控件的 Style 属性设置为 1(复选框),并且 ListBox 控件中一个项目的复选框被选定或者被清除时该事件发生。 Private Sub lstObjectName_ItemCheck(Item As Integer)Item参数反映被操作条目的序号。ItemCheck 事件出现在 Click 事件之前。列表框的常用事件【例8.5】“城市与人口”程序。本程序具备以下功能(如图所示):(1)在“城市”和“人口”文本框中输入信息之后,单击“添加”按钮,城市名被添加到“已有城市”列表框中,相应的人口数量也被保存;(2)单击列表框中任意一个城市名,在两个文本框中显示出这个城市的名称与相应的人口数量;(3)单击“删除”按钮,删除列表框中当前选定的城市名;(4)当单击“全部删除”按钮,消除列表框中的所有城市名。【例8.6】移动列表框条目。如图8.12所示,窗体上有两个列表框,在左边的“源列表框”中选择多个条目,单击“-”按钮后,选中的条目被移动到“目标列表框”中。【例8.6_1】 从提供的选择中,选择相应的字体类型、字体大小、是否黑体、是否加下划线,确定后使文本框中的字符串按选定的字体属性显示。打开【例8.5】打开【例8.6】打开【例8.6_1】 0:“下拉式组合框”的列表框可以打开或关闭,文本框的中内容可以进行编辑。 1:“简单组合框”的列表框一直保持显示,文本框内容可以编辑。 2:“下拉式列表框”的列表框部分可以打开或关闭;文本框的内容不能编辑,只是反映列表框中的选中项的内容。因为组合框可以看作是文本框与列表框的组合体,因此它具有二者的事件与方法。但组合框不支持多选,所以没有MultiSelect、SelCount和Selected三个与多选有关的属性。Name、Left、 Top、Width 、Height、Visible、Enabled 属性同其他控件的使用相同。 组合框支持列表框与文本框的大多数常用属性。如:SelLength属性、SelStart属性、SelText属性和Text属性;ListIndex属性、NewIndex属性、Sorted属性、ItemData属性、TopIndex属性、List属性和ListCount属性。有些属性会受Style属性设置的影响,比如,对于下拉式列表框来说,Text属性是只读的。 Style属性:组合框是由一个列表框与一个文本框组合形成。组合框有三类,由Style属性决定。十一、组合框(ComboBox)控件组合框的常用属性组合框可以看作是文本框与列表框的组合体。AddItem、Clear、RemoveItem、Move方法与列表框相同。Change事件与文本框相同;Click、DblClick、Scroll事件与列表框相同。组合框不支持复选框,因此无ItemCheck事件。组合框控件的常用方法和事件打开【例8.6_2】 使用组合框修改例8.6_1,如右图所示。打开【例8.6_3】 设计一个选购计算机配置的应用程序,如图所示。当用户选定了基本配置并且单击“确定”按钮后,在右边的列表框中显示所选择的信息。 打开【例8.6_4】 编写一个如图所示的程序。用户能从饭店菜单把选定的菜添加到下面的列表框中。要求:饭店菜单列表框支持多项选择。 十六、控件数组的使用正如使用数组可以简化编程,使用控件数组可以替代同一个窗体上功能类似的多个同类控件。因此,使用控件数组可以很大程度上简化编程。编写事件过程 控件数组的所有元素共用同一事件过程。控件数组的事件过程比单独控件的事件过程多一个参数“Index As Integer”,并且,这个参数总是事件过程的第一个参数。通过处理Index参数,便可知道是控件数组中的哪个元素引发的事件。例如:SubcmdNumber_Click(IndexAsInteger)SubcmdNumber_KeyPress(IndexAsInteger, KeyAsciiAsInteger)动态添加、删除控件数组元素运行时添加新的元素:Load动态控件数组名(下标)新添加的元素是不可见的。运行时删除元素:Unload动态控件数组名(下标)不能使用Unload删除设计时添加的元素。打开【例8.9】 计算器。十七、菜单菜单形式 如下图右所示。使用菜单编辑器进行菜单设计,如下图左所示。创建菜单 快捷键热键分隔线菜单列表框菜单编辑器的使用菜单编辑器的使用 菜单项属性常用属性:1. 标题(Caption) 热键:前面加&2. 名称(Name)文本框 分隔符也应有名称。3. 快捷键(Shortcut) 菜单名没有快捷键4. 复选(Checked)检查框 TRUE 有5. 有效(Enabled)检查框6. 可见(Visible)检查框7. Index属性:用于控件数组的创建。操作按钮【例】 建立一个有菜单功能的文本编辑器。操作方法:单击“工具菜单编辑器”(CTRL+E)命令,打开菜单编辑器窗口。窗体上快显菜单菜单编辑器 菜单项增减菜单项增减 在程序运行时,菜单随时增减,如“文件”菜单能保留最近打开的文件数。这同控件数组一样,使用菜单数组。步骤如下:在菜单设计时,加入一个菜单项,其Index为0(菜单数组),Visible为False。在程序运行时,通过Load方法向菜单数组增加新的菜单项。同样,要删除所建立的菜单项,使用UnLoad方法向菜单数组减少菜单项。【例8.14】在上例中的文件菜单中保留最近打开的文件清单。Dim menucounter As IntegerDim msg, Temp As StringPrivate Sub AddAp_Click() With CommonDialog1 CommonDialog1为添加的通用对话框控件 .DialogTitle = 打开“ : .CancelError = False .InitDir = d: 打开D盘。 .ShowOpen End With menucounter = menucounter + 1 Load AppName(menucounter) AppName(menucounter).Caption _ = CommonDialog1.FileName AppName(menucounter).Visible = TrueEnd SubPrivate Sub DelAp_Click() Dim n, i As Integer msg = Enter number to delete: n = InputBox(msg, Delete Application) 输入要删除的应用程序的编号。 If n menucounter Or n 1 Then MsgBox 超出范围! Exit Sub End If For i = n To menucounter - 1 AppName(i).Caption = AppName(i + 1).Caption Next i Unload AppName(menucounter) menucounter = menucounter - 1End Sub 弹出菜单弹出菜单( (快捷菜单快捷菜单) )例例Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = 2 Then PopupMenu EditMenu, vbPopupMenuCenterAlign End IfEnd Sub显示在窗体的浮动菜单,操作时使用右键,菜单与鼠标位置有关。设计与普通菜单,仅该菜单名不可显示;要显示时使用PopupMenu方法弹出菜单。PopupMenu方法的命令格式: 对象.PopupMenu 菜单名, 标志, x, y其中:X,Y,表示弹出的位置和触发的键位置,默认为鼠标坐标;标志:进一步定义菜单的性能,如下表所示: 位置标志 0:X 位置确定弹出菜单的左边界0:只能用鼠标左键触发弹出菜单; 4:弹出菜单以X为中心2:能用鼠标右键键触发弹出菜单; 8: X 位置确定弹出菜单的右边界 说明:位置与性能是加的关系。 工具栏以其直观、快捷的特点出现在各种应用程序中,事实上工具栏已经成为Windows应用程序的标准功能。它使用户不必在一级一级的菜单中去搜寻需要的命令,给用户带来比菜单更为快速的操作。十八、工具栏和状态栏手工制作工具栏 用手工制作的工具栏,实际上是一个放置了一些工具按钮的图片框。通过设置图片框的Align属性,可以控制工具栏(图片框)在窗体中的位置,当改变窗体的大小时,Align属性值非0的图片框会自动地改变大小,以适应窗体的宽度或高度。 图片框上各种工具按钮,如命令按钮、图形方式的选项和复选框、下拉列表控件等,可以通过不同的图像来表示对应的功能,还可以设置按钮的ToolTipText属性为工具按钮添加工具提示。对于有些按钮如复选框等,需在其上放置两个图像,分别代表按钮弹起及按下时的外观。 例如,通过在窗体上添加一个图片框Picture1和文本框Text1,并在图片框中增加一个命令按钮数组Command1(0) Command1(2)。 然 后 将 命 令 按 钮 的Caption属性值设为空白,Style属性设为1,Graphical,Picture属性分别设为New.bmp,Open.bmp 和Save.bmp。建立好的用户界面如图所示。 由于工具按钮通常用于提供对其他(菜单)命令的快捷访问,所以一般都是在其Click事件代码中调用对应的菜单命令。 要在工具栏中放置一系列图片按钮,最直接的方法是在窗体上添加工具栏(Toolbar)控件和图像列表(ImageList)控件。Toolbar控件和ImageList控件是ActiveX控件的一部分,在使用前必须加载“Microsoft Windows Common Controls 6.0”,然后才能使用工具箱中新添加的ImageList控件和Toolbar控件。 Toolbar控件与控件与ImageList控件控件 ImageList控件的ListImage属性是对象的集合,每个对象可以存放图片文件。图片文件类型有.bmp,.cur,.ico,.jpg和.gif等,并可通过索引(Index)或关键字(Key)来引用每个对象。控件具有标准的集合方法:Add,Remove和Clear。利用这些方法,用户可以在运行时添加、删除图像。一旦ImageList关联到其他控件,就不能再删除或插入图像了。 1创建ImageList控件 ImageList控件的作用像图像的储藏室,ImageList控件不能独立使用,它需要Toolbar控件(或ListView,TabStrip,TreeView控件等)来显示所储存的图像。ImageList控件可以包含任意大小的所有图片文件,但是图片的显示大小都相同。通常,加入该控件的第一幅图像决定了随后加入图像的显示大小。 在设计时,可以在ImageList属性页中添加图像,按照顺序将需要的图像插入到ImageList中。例如,在窗体上创建ImageList1后,用鼠标右键单击ImageList1控件,出现弹出式菜单,选择“属性”命令,或者选中窗体上的ImageList1后在属性窗口选择“(自定义)”右边的三点按钮,都可以打开“属性页”对话框。选择“图像”选项卡,在“图像”选择卡中就可以插入图片了,如图所示。 2设置工具栏的属性 将属性页切换到“按钮”选项卡,创建按钮(Button)对象,如右图所示。其中各项功能说明如下: 插入按钮、删除按钮。在Button集合中添加或删除元素。通过Button集合可以访问工具栏中的各个按钮。 索引、关键字。工具栏中的按钮通过Button集合进行访问,集合中的每个按钮都有唯一的标识,Index属性和Key属性就是这个标识。Index为整型,Key为字符串型,访问按钮时可以引用二者之一。 标题(Caption)、描述。标题是显示在按钮上的文字;描述是按钮的说明信息。 值(Value)。Value属性决定按钮的状态,0-tbrUnpressed为弹起状态,1-tbrPressed为按下状态。 用鼠标双击Toolbar控件,它将加入窗体并出现在窗体的顶部(也可单击控件后在窗体中画出控件)。通过设置Toolbar1的Align属性可以控制工具栏在窗体中的位置。当改变窗体的大小时,Align属性值为非0的工具栏会自动改变大小以适应窗体的宽度或高度。 用鼠标右键单击窗体上的Toolbar1,在弹出的快捷菜单中选择“属性”,将打开“属性页”对话框,如左图所示。“通用”选项卡中的“图像列表”属性将被用来与ImageList控件建立关联。样式(Style)。Style属性决定按钮的行为特点。与按钮相关联的功能可能受到按钮样式的影响。Button对象Style属性设置值如下: 常 数值说 明 tbrDefault0 默认值。按钮是一个规则的下压按钮,如保存文件。 tbrCheck 1 复选按钮。具有下压、放开两种状态。当按钮代表的功能是某种开关类型时,可用复选样式,如加粗、倾斜、下划线等。 tbrButtonGroup2选项按钮。当一组按钮功能相互排斥时,可使用选项按钮组样式。同一时刻只能有一个按钮被按下,但可同时处于抬起状态,如两端对齐、居中、右对齐。 3编写ButtonClick事件代码 工具栏控件的常用事件有ButtonClick事件和Change事件。当用户单击按钮(占位符和分隔符样式的按钮除外)时,将激发ButtonClick事件。此时可以用按钮的Index属性或Key属性标识被单击的按钮。 【例】 利用工具栏来实现字体变化。 分析:为了能够输入更多的文字,这里使用文本框Text1,并将文本框的MultiLine属性值设为True,ScrollBars属性值设为2-Vertical。 利用添加部件将ImageList和Toolbar控件放入工具箱。 在窗体上添加ImageList1控件,通过其属性窗口,依次将Graphic Bitmaps Tlbr_w95目录中的图片文件Bld.bmp,Itl.bmp,Undrln.bmp加入到图像框内。 双击工具箱中的Toolbar控件, 在窗体的顶部添加一个工具栏Toolbar1。打开Toolbar1属性对话框,在“通用”选项卡中将图像列表的属性值改为ImageList1,建立与图像列表控件的关联。还可以将样式属性值改为1(tbrFlat式样)。在“按钮”选项卡中依次插入按钮:1,2,3,并同时注意修改它们的图像属性值(这里依次为1,2,。由于加粗、倾斜、下划线为复选按钮,还应将三个按钮的样式属性值设为1。编写程序代码Private Sub Form_Resize()With Text1.Top = Toolbar1.Height.Left = 0.Height = Form1.ScaleHeight - Toolbar1.Height.Width = Form1.ScaleWidthEnd WithEnd SubPrivate Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)n = Button.IndexSelect Case nCase 1 : Text1.FontBold = Not Text1.FontBoldCase 2 :Text1.FontItalic = Not Text1.FontItalicCase 3 :Text1.FontUnderline = Not Text1.FontUnderlineEnd SelectEnd Sub运行程序,显示界面如图所示。 可以用ToolTipText属性设置提示文本。设计时,在Toolbar1控件属性页中的“工具提示文本”框中输入需要的文本,即可为按钮加入提示文本。运行时,可通过设置Button对象的ToolTipText属性动态地改变提示文本。 工具栏控件提供的另一功能是用户定制工具栏。如果将工具栏控件的AllowCustomize属性设置为True,则当用户双击工具栏时,即可显示出“自定义工具栏”对话框。在代码中可以通过调用Customize方法显示对话框。“自定义工具栏”的对话框如图所示。图7.24 “自定义工具栏”对话框当用户利用“自定义工具栏“对话框定制了自己的工具条时,Change事件被激活。通常,在该事件中保存用户的定制。 若允许用户重新配置工具栏控件,那么需要用SaveToolbar和RestoreToolbar方法保存和恢复该工具栏。例如,如果多个用户同时使用同一个应用程序,但他们的使用习惯不同,则可以用SaveToolbar方法使用户能够创建自己的定制工具栏。然后创建一个登录过程,用来标识每个用户,并通过RestoreToolbar方法,根据登录信息恢复用户个人的工具栏。 状态栏通常位于窗口的底部,主要用于显示应用程序的各种状态的信息。StatusBar控件是ActiveX控件,添加的方法与ImageList相同,添加后在控件工具箱中出现StatusBar控件的图标 。创建状态栏创建状态栏 在运行时,可以通过Text,Picture和Width等属性动态地改变窗格对象。要在设计时更改窗格对象的属性或添加窗格对象,可以用鼠标右键单击控件,然后选择“属性”来显示“属性页”对话框,如图所示。 在状态栏控件的“属性页”对话框中,“通用”标签上的为状态栏的通用属性,包括Style,MousePointer,SimpleText,OLEDropMode,Enabled和ShowTips属性。“窗格”标签上的是窗格的属性,其中索引(Index)是一个从1开始的数值,用它来唯一标识集合中的对象。“插入窗格”按钮创建一个新的窗格,“删除窗格”按钮删除当前索引号所指的窗格。文本(Text)属性设置窗格对象的标签。图片(Picture)属性设置窗格上显示的图片,其与文本属性显示相对位置要根据对齐方式的设置。工具提示文本(ToolTipText)设置当用户将鼠标放在窗格上时显示的提示信息。关键字(Key)属性设置一个唯一标识集合中对象的字符串,它的作用和索引类似。对齐(Alignment)属性设置窗格对象上文本的对齐方式,有左对齐、居中对齐、右对齐。 状态栏控件是由面板(Panels)集合构成的,在集合中最多可包含16个窗格对象,每个对象可以显示图像和文本。如下图所示,显示了一个具有三个窗格的状态栏。 样式(Style)属性设置窗格的样式,这也是状态栏控件最有用的部分,能够用最少的代码显示键盘状态、时间和日期。下面列出了Style属性的设置值。 常 数值说 明 sbrText0默认值。显示文本和图片。 sbrCaps1显示Caps Lock键状态。当Caps Lock处于激活状态时,显示粗体字母CAPS,反之则显示灰色字母CAPS,可以通过设置文本属性更改显示的字符串。 sbrNum2显示Num Lock键状态。意义同上。 sbrIns3显示Insert键状态。意义同上。 sbrScrl4显示Scroll Lock键状态。意义同上 sbrTime5显示系统时间。此时忽略该窗格的文本属性。 sbrDate6显示系统日期。此时忽略该窗格的文本属性。 sbrKana7显示Kana Lock键状态(仅在日文操作系统中有效)。窗格对象的最小宽度、实际宽度和自动调整大小属性是和它的显示宽度有关的。斜面属性决定窗格的外观,是凹的、凸的或平面的。 状态栏控件的事件包括PanelClick事件和PanelDblClick事件等。需要获得相应状态栏的单击事件,可以在PanelClick事件过程中使用Select Case语句。该事件包含的参数能够指出发生单击的窗格对象。相应的代码可如下:Private Sub StatusBar1_PanelClick(ByVal Panel As MSComctlLib.Panel)Select Case Panel.IndexCase 1 : 相应处理程序段1Case 2 : 相应处理程序段2Case Else : 处理其他情况End SelectEnd Sub 通过剪贴板(Clipboard)对象,用户能够复制、剪切和粘贴应用程序中的文本和图形。剪贴板对象没有属性和事件,但具有一些方法,其中最为常用的方法是处理文本的GetText和SetText方法。GetText用于从剪贴板中返回文本,也可将它作为函数使用。SetText将文本复制到剪贴板上,替换先前存储在那里的文本,可将它作为一条语句使用。 GetText和SetText方法的格式为: 对象.GetText (格式) Clipboard.SetText 字符串数据,格式 其中,格式用于指定数据格式,默认为文本格式(vbCFText),还可设置DDE(Dynamic Data Exchange)对话信息(vbCFLink)、RTF(Rich Text Format)格式(vbCFRTF)等。剪贴板的使用剪贴板的使用 例如,在上例的工具栏中加入剪切、复制、粘贴按钮,如图所示。 其中,将文本框中所选定的文字复制到剪贴板中的代码为: Clipboard.SetText Text1.SelText 要实现剪切功能,还必须将该数据从文本框中清除掉,即: Clipboard.SetText Text1.SelText Text1.SelText = 粘贴的动作则恰好是将复制过程逆向操作,将剪贴板的文本数据复制到插入点所在位置,如: Text1.SelText = Clipboard.GetText 除了处理文本数据,Clipboard对象还用GetData和SetData方法处理图形,其语法格式与GetText和SetText相同。 另外,可以用Clear方法清除剪贴板中的内容,在复制任何信息到剪贴板之前,应使用Clear方法清除剪贴板中的内容。还可以用GetFormat方法判断Clipboard中存放的数据格式。 进度指示器可以用图形的方式来显示任务的进程,它的方框在任务进行过程中逐渐被充满。使用进度指示器来给用户提供良好的可视反馈信息。 进度指示器控件(ProgressBar)是ActiveX控件之一。 进度指示器控件比较简单,其常用的属性如下: 属 性说 明 Align设置或返回对象在窗体时显示的位置。 Appearance设置或返回对象在窗体上是否以3D效果显示。1,以3D效果显示;2,以平面效果显示。 Enabled设置或返回对象是否有效。默认值是True。 Max/Min设置或返回控件的最大/小值。默认值是100/0。 Orientation决定进度栏是水平还是垂直显示。默认值0,水平显示;1,垂直显示。 Scrolling决定控件显示进度的样式。默认值0,使用标准的分段进度栏。设为1,使用平滑的进度栏。 Value设置进度时。要显示某个操作的进展情况,该属性将持续增长,直到达到了由Max属性定义的最大值。 Visible决定对象是否可见。 【例】 创建一个安装软件进度器,如图所示。 在一个新窗体上,添加一个标签Label1,一个命令按钮Command1,一个定时器Timer1,以及一个进度栏ProgressBar1。将标签的标题设置为“准备开始”,并根据需要设置它的字体大小。将定时器控件的Enabled属性设置为False,将Interval属性设置为1000。使进度栏控件的属性保持缺省值。进度指示器进度指示器首先,在通用代码中定义StartTime变量,然后编写命令按钮和定时器的代码:Private Sub Command1_Click()ProgressBar1.Value = 0StartTime = 0Timer1.Enabled = TrueCommand1.Enabled = FalseEnd SubPrivate Sub Timer1_Timer()Dim PercentIf StartTime! = 0 ThenStartTime = TimerEnd IfPercent = 100 * (Timer - StartTime) / 90If Percent 0返回1,当number0返回-1,当number=0返回0; Int(number)、Fix(number):返回number的整数部分。当number0时,Int返回小于或等于number的最大整数;Fix函数返回大于或等于number的最小整数。如:Int(-8.4)=-9、Fix(-8.4)=-8。Int(-5)=-5、Fix(-5)=-5。 Rnd (number):当无参数或参数大于零时,产生一个Single类型、小于1并大于等于0的随机数。当参数是其它值时,情况有所不同。Rnd返回的随机数序列还受Randomize语句的影响。【例9.1】为数组元素随机赋值。一、数学函数打开【例9.1】Space(number) 、String(number,character) :前者返回number个空格组成的字符串;后者返回由number个重复字符组成的字符串,这个字符为字符character的首字符。如果character是整数,则被理解为Ascii码,返回相应的字符。Str(number):把数值表达式number的值转换为字符串,如为正数,则返回的字符串第一个字符为空格。Val(String):把字符串String转换为数值。遇到不能转换的字符就停止转换。转换时忽略空格、制表符与换行符。如:Val(-161.5 198th Street N. E.) 返回数值:-161.5198。Len(String):返回指定的字符串表达式中字符个数。InStr(start, String1, String2):此函数在字符中String1中从第start个字符开始搜索字符串String2第一次出现的位置。如无start参数,则从开头搜索。InStr(2, fasfasfa, fa) 返回值为4Mid(String, start, length):返回字符串str中从第start个字符开始的length个字符。如果start大于str长度,返回空字符串;省略length参数,返回从start以后的全部字符。Left(String, number)、Right(String, number):返回字符串String前面或后面的的expN个字符组成的子串。当number大于String长度时,返回整个字符串。LTrim(String)、 RTrim(String)、 Trim(String):去掉字符串String前面、后面或前后的空格。二、字符串函数LCase(String)、UCase(String):把字符串转换为小写或大写,不影响其它字符。Asc(String):返回字符串String的第一个字符的编码。如果是单字节字符,返回值在0与255之间(ASCII码);如为双字节字符,返回值在-32768和32767之间。Chr(charcode):这个函数与前个函数正相反,它们把字符编码charcode转换为相应的字符。可以使用Chr函数返回一些无法直接输入到字符串中的控制符,或无法用字符表示的特殊字符。如Chr(10)返回一个换行符、 Chr(13)返回一个回车符。Text1.Text = “safaf” + Chr(13) + Chr(10) + “fasf” 文本框应支持多行。Hex(number)、 Oct(number) :以字符串形式返回整数number的十六进制和八进制表示形式。LSet、RSet语句LSet varS=expSRSet varS=expS在不改变varS字符串变量长度的情况下,将expS字符串变量的内容放置在varS变量的的左边(或右边),剩下部分用空格填充。另:Mid也可以当语句使用。Mid(expS1,expN1,expN2) = expS2用expS2字符串来替换expS1字符串变量从expN1个字符起的expN2个字符。Format(expr , format, firstdayofweek, firstweekofyear:将任意类型的表达式的值,按指定格式format 转换为字符串。如果只有参数exp1,则按默认的方式转换。format参数是一个字符串,指定具体的转换方式。用format指定的转换方式可以是预定义的或是自定义的。例:MyStr = Format(Time, Long Time) 以预定义的长时间格式返回当前系统时间。MyStr = Format(Date, Long Date) 以预定义的长日期格式返回当前系统日期。MyStr = Format(#17:04:23# , h:m:s) 返回 17:4:23。MyStr = Format(#17:04:23# , hh:mm:ss AMPM) 返回 05:04:23 PM。MyStr = Format(#January 27, 1993#, dddd, mmm d yyyy) 返回 Wednesday, Jan 27 1993。MyStr = Format(5459.4, #,#0.00) 返回 5,459.40。MyStr = Format(334.9, #0.00) 返回 334.90。MyStr = Format(5, 0.00%) 返回 500.00%。MyStr = Format(HELLO, ”) 返回 “THIS IS IT”。Replace(c,c1,c2,N1,N2):在C字符串中从N1开始用C2字符串替代C1字符串N2次,无N1表示从1开始。例:Replace(“ABCDABCD”,“CD”,“123”) 显示: “AB123AB123”Date、Time、Now:这三个函数无参数,分别返回当前系统的日期、时间、日期与时间。Text1.Text = Now要重新设置系统的日期与时间可以通过以下方法:Date= #05/01/99# :Time=#12:12:00#DateAdd(interval, number, date):此函数得到在date指定的日期时间上增加一定时间后日期时间。Interval是一字符串,指定增加的时间种类,取值列于下面。“yyyy”:年;“q”:季;“m”:月;“y”:一年中的日数;“d”:日;“w”:一周的日数;“ww”:周;“h”:时;“n”:分钟;“s”:秒。( “y”、 “d”和 “w” 等效)例:DateAdd(“h”, 26, #1/1/99#) 返回#1/2/99 02:00:00#。DateDiff(interval, date1, date2, firstdayofweek, firstweekofyear) :此函数计算两个日期时间date1、date2之间的间隔,单位由interval指定,取值与DateAdd函数相同。Firstdayofweek参数指定一周是从星期几开始的,默认为星期日,1代表星期日,2代表星期一,以此类推。参数firstweekofyear指定一年中的第一个星期是如何确定的,1:为1月1日所在的星期(默认值);2:大半在新年的那一个星期;3:全部在新年的哪一个星期。使用w与ww比较的结果不同。在计算 12 月 31 日和来年的 1 月 1 日的年份差时,DateDiff 返回 1 年,虽然实际上只相差一天而已。DatePart(interval, date,firstdayofweek, firstweekofyear):此函数计算给定的日期时间date的年、月、日、时、分、秒等信息。参数意义与上个函数相同。三、日期与时间函数DateSerial(year, month, day):此函数按给定的年月日产生一个日期值,允许month与day超出有的意义范围。如DateSerial(1999, 2, -3)产生的日期为1999年1月28日。TimeSerial(hour,minute,second):此函数产生一个时间值,用法同上一个函数。Year(date)、Month(date)、Day(date)、WeekDay(date,firstdayofweek):返回给定日期date的年、月、日以及星期几。返回的星期值是指从星期的第一天到给定日期经历的天数,并非星期几。TimeValue(date):返回给定日期值的时间部分。Hour(time)、Minute(time)、Second(time):返回给定时间的时、分、秒的值。Timer:此函数无参数,返回从午夜到当前的经历的秒数。IIf(expr, truepart, falsepart)此函数共有三个参数。第一个参数应是一个逻辑表达式,当这个表达式的值为TRUE时IIF函数返回第二个参数,当表达式的值为FALSE时,返回第三个参数的值。如:int1=10 : int2=11IIF(int1int2,1,10)返回值为10,而IIF(int1sng2, sng1,sng2)四、分支函数Choose函数Choose的形式如下:Choose(整数表达式,选项列表)说明:Choose根据整数表达式的值来决定返回选项列表中的某个值。如果整数表达式值是1,则Choose会返回列表中的第1个选项。如果整数表达式值是2,则会返回列表中的第2个选项,以此类推。若整数表达式的值小于 1 或大于列出的选项数目时,Choose函数返回Null。例如:根据Nop是14的值,转换成+、-、运算符,语句代码如下:Op= Choose(Nop,+,-,)当值为1时,返回字符串“+”,然后放入Op变量中,当值为2时,返回字符串“-”,依此类推;当Nop是14的非整数时,系统会自动使用取Nop的整数进行再判断;若Nop不在14之间,函数返回Null值。Switch函数Switch函数的形式是: Switch(条件表达式1,条件表达式1为True时的值,条件表达式2,条件表达式2为True时的值)说明:返回表达式N为真时的值。例: print Switch(35,1,45,2,35,3) 结果为3五、测试函数TypeName(VarName) 返回一个 String,用于测试变量的类型名称。TypeName() 所返回的字符串可以是下面列举的任何一个字符串: 说明:如果 varname 是一个数组,则返回的字符串可以是任何一个后面添加了空括号的可能的返回字符串(或 Variant)。如,如果 varname 是一个整数数组,则 TypeName 返回 Integer()。返回字符串返回字符串变量量类型代码返回字符串返回字符串变量量Byte位值String字符串Integer整数Boolean Boolean 值Long长整数Error错误值Single单精度浮点数Empty未初始化Double双精度浮点数Null无效数据Currency货币Object对象Decimal十进制值Unknown类型未知的对象Date日期Nothing不再引用对象的对象变量常数常数值描述描述常数常数值描述描述vbEmpty0Empty(未初始化)vbObject9对象vbNull1Null(无有效数据)vbError10错误值vbInteger2整数vbBoolean11Boolean 值vbLong3长整数vbVariant12Variant(只与变体中的数组一起使用)vbSingle4单精度浮点数vbDataObject13数据访问对象vbDouble5双精度浮点数vbDecimal14十进制值vbCurrency6货币值vbByte17位值vbDate7日期vbUserDefinedType36包含用户定义类型的变量vbString8字符串vbArray8192数组VarType(varname) 返回一个 Integer,用于测试变量的类型代码。VarName() 所返回的数值可以是下面列举的一个: 说明:VarType 函数自身从不对 vbArray 有返回值。VarType 可以总是要加上一些其他值来指出一个具体类型的数组。例如,对一个整数数组的返回值是 vbInteger + vbArray,或 8194。如果一个对象有缺省属性,则 VarType (object) 返回对象缺省属性的类型。IsNumeric(expression) 结果:Boolean 值,测试表达式的运算结果是否为数。 说明:如果expression是日期表达式,则 IsNumeric()返回 False。如: Dim Var1, Check1 Var1 = 459.95“ : Check1 = IsNumeric(Var1) 返回 True Var1 = 45 Help“ : Check1 = IsNumeric(Var1) 返回 False。 IsDate(expression) 结果:Boolean 值,如果表达式是一个日期,或可以作为有效日期识别,则 IsDate 返回 True;否则返回 False。IsArray(varname) 测试变量是否为一个数组,结果是一个Boolean 值。,IsNull(expression) 如果表达式不包含任何有效数据 (Null),则IsNull返回 True;否则IsNull返回 False。如果expression由多个变量组成,则表达式的任何作为变量组成成分的Null都会使整个表达式返回 True。IsObject(identifier) 测试一个变量是否表示对象变量。 说明:IsObject 只用于确定Variant 是否属于 VarType vbObject。如果 Variant 实际引用(或曾经引用过)一个对象,或者如果 Variant 包含 Nothing,则可能出现这种情况。如果 identifier 是 Object类型或任何有效的类类型,或者,如果 identifier 是 VarType vbObject 的 Variant 或用户自定义的对象,则 IsObject 返回 True;否则返回 False。即使变量已设置成 Nothing,IsObject 也仍返回 True。使用错误捕获方法可以确认对象引用是否有效。六、强制转换函数可以强制将一个表达式转换成某种特定数据类型。常用的一类型转换函数如下:函数函数返回返回类型型expression参数范参数范围 CBool(expression)Boolean任何有效的字符串或数任何有效的字符串或数值表达式。表达式。 CByte(expression)Byte0 至至 255。 CCur(expression)Currency-922,337,203,685,477.5808922,337,203,685,477.5807CDate(expression)Date任何有效的日期表达式。任何有效的日期表达式。 CDbl(expression)Double负数数-1.79769313486232E308 至至 -4.94065645841247E-324;正数从;正数从 4.94065645841247E-324 至至 1.79769313486232E308。 CDec(expression)Decimal无小数位数无小数位数值,为+/-79,228,162,514,264,337,593,543,950,335。 对于于 28 位小数的数位小数的数值,范,范围则为+/-7.9228162514264337593543950335;最小的可能非零;最小的可能非零值是是 0.0000000000000000000000000001。CInt(expression)Integer-32,768 至至 32,767,小数部分四舍五入。,小数部分四舍五入。 CLng(expression)Long-2,147,483,648 至至 2,147,483,647,小数部分四舍五入。,小数部分四舍五入。 函数函数返回返回类型型expression参数范参数范围 CSng(expression)Single负数数为 -3.402823E38 至至 -1.401298E-45;正数;正数为 1.401298E-45 至至 3.402823E38。 CStr(expression)String依据依据 expression 参数返回参数返回 Cstr。CVar(expression)Variant若若为数数值,则范范围与与 Double 相同;若不相同;若不为数数值,则范范围与与 String 相同。相同。 说明: 如果传递给函数的 expression 超过转换目标数据类型的范围,将发生错误。 通常,在编码时可以使用数据类型转换函数,来体现某些操作的结果应该表示为特定的数据类型,而不是缺省的数据类型。例如,当单精度、双精度或整数运算发生的情况下,使用 CCur 来强制执行货币运算。 当小数部分恰好为 0.5 时,Cint 和 CLng 函数会将它转换为最接近的偶数值。例如,0.5 转换为 0、1.5 转换为 2。Cint 和 CLng 函数不同于 Fix 和 Int 函数,Fix 和 Int 函数会将小数部分截断而不是四舍五入。并且 Fix 和 Int 函数总是返回与传入的数据类型相同的值。 例如:使用 CByte 函数将一表达式转成 Byte。 Dim MyDouble, MyByte , MyInt MyDouble = 125.5678 MyDouble 为Double(双精度)。 MyByte = CByte(MyDouble) MyByte 值为 126。 MyInt = CInt(MyDouble) MyInt 的值为126。消息框函数MsgBox暂停程序、显示信息并让用户在多种情况中选择。MsgBox(prompt, buttons , title , helpfile, context)Prompt参数:字符串表达式,作为显示在消息对话框中的消息。如果要使用消息内容换行 则可以用回车符 Chr(13)与换行符 Chr(10) 将各行分隔开来。buttons参数:数值表达式,指定显示按钮的数目及形式、图标样式、缺省按钮等。见后面表格。title参数:在消息对话框标题栏中显示的字符串。七、自定义对话框函数buttons 参数有下列设置值:系统常量值说明(第一组:定义按钮)vbOKOnly0只显示 OK 按钮。VbOKCancel1显示 OK 及 Cancel 按钮。VbAbortRetryIgnore2显示 Abort 、Retry 及 Ignore 按钮。VbYesNoCancel3显示 Yes 、No 及 Cancel 按钮。VbYesNo4显示 Yes 及 No 按钮。VbRetryCancel5显示 Retry 及 Cancel 按钮。(第二组:定义图标)VbCritical16显示 图标。VbQuestion32显示 图标。VbExclamation48显示 图标。VbInformation64显示 图标。(第三组:定义默认按钮)VbDefaultButton10第一个按钮是缺省值。VbDefaultButton2256第二个按钮 是缺省值。VbDefaultButton3512第三个按钮是缺省值。VbDefaultButton4768第四个按钮是缺省值。(第四组:定义模态性)VbApplicationModal0应用程序模态。VbSystemModal4096系统模态。使用时,每一组取一个值,相加后作为button参数。函数的返回值:返回值说明了用户对消息框的反应。常数值描述常数值描述 vbOK1OKvbCancel2CancelvbAbort3AbortvbRetry4RetryvbIgnore5IgnorevbYes6YesvbNo7 No int1 = MsgBox(口令错误,不能进入!, 16, 错误)int1 = MsgBox(数据尚未保存,退出之前是否保存?, 51, 注意) 51=3 + 48提示用户输入所需内容。InputBox(prompt, title , default , xpos , ypos , helpfile, context)prompt:显示在输入对话框中的提示信息(字符串表达式)。如果要显示多行信息,则可在各行之间用回车符 (Chr(13)和换行符 (Chr(10) 来分隔。title:输入对话框标题栏中的文字(字符串表达式)。如果省略 title,则把应用程序名放入标题栏中。default:显示在输入对话框中的文本框中的默认内容,在没有其它输入时作为缺省值。如果省略 default,则文本框为空。xpos、ypos:指定对话框显示在屏幕上的位置。如果省略 xpos,则对话框会屏幕中间。Helpfile、context:与帮助有关。输入对话框有一个文本框与两个按钮,如果用户选择 “确定”按钮 ,则 InputBox 函数返回文本框中的内容。如果用户选择了“取消”,则此函数返回一个长度为零的字符串 (“”)。例:str1 = InputBox(请输入完整学号(10位数)) 输入框函数InputBox打开【例9.3】 在VB中,不但可以调用内部函数,还可以调用各种应用程序。也就是说,凡是能在DOS下或Windows运行的应用程序,都可以在Visual Basic中调用。 Shell函数的格式如下: Shell(命令字符串,窗口类型) 其中: 命令字符串:要执行的应用程序名,包括路径,它必须是可执行的文件(扩展名为.com、.exe、.bat或者.pif)。 窗口类型:表示执行应用程序的窗口大小,为整型数值,见下表。 八、Shell函数窗口类型 内部常数 意 义0 vbHide 窗口不显示1 Visual BasicNormalFocus 正常窗口,有指针2 VbMinimizedFocus 最小窗口,有指针3 vbMaximizedFocus 最大窗口,有指针4 vbNormalNoFocus 正常窗口,无指针6 vbMinimizedNoFocus 最小窗口,无指针 例如,如果程序在运行时要切换到DOS界面,则调用Shell函数如下: I=Shell(“c:COMMAND.COM”,1) 程序执行该语句即可切换到DOS界面。说明:如果成功的话,代表这个程序的任务 ID,若不成功,则会返回 0。 例如,把标签表现为超链接的样子(用鼠标移上时改变其颜色及字体)。用鼠标单击时,调用Shell语句执行一个外部命令,运行结果如下所示图。 程序如下: Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Label1.FontUnderline = False : Label1.FontBold = False Label1.ForeColor = vbBlack : Label1.MousePointer = vbDefault End Sub Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Label1.FontUnderline = True : Label1.FontBold = True Label1.ForeColor = vbBlue : Label1.MousePointer = 14 End Sub Private Sub Label1_Click() ShellC:Program FilesInternet ExplorerIEXPLORE.exe&_ http:/www.cernet.edu.cn, vbNormalFocus Me.MousePointer = vbHourglass End Sub 标签表现为超链接调用shell函数 九、实验补充题返回目录1InputBox函数和MsgBox函数。在窗体的Load事件中两次调用InputBox函数,由用户分别输入学号和姓名存入两个变量,然后调用MsgBox函数分两行显示输入的学号和姓名。MsgBox对话框关闭后卸载窗体,即在程序运行期间始终不显示窗体,仅显示三个对话框,如图1所示。2用InputBox函数输入数据三角形3条边的边长a、b和c,求三角形的面积。三角形面积的计算公式是:,其中:,设计界面并编程。3从键盘输入任意一个大写字母,要求改用小写字母输出。Lcase(x)可以将大写字母转换成小写字母。图1 InputBox函数和MsgBox函数的使用4生成指定范围的随机整数,程序运行结果如图2所示。提示:生成指定范围随机整数的表达式为:Int(Rnd * (上界 下界 + 1) + 下界)。5建立如图3所示的应用程序。完成功能:在起始文本框中输入起始位置,长度文本框中输入截取长度,单击“确认”按钮后,截取的内容放入下面的文本框中。图3 第5题运行效果图图2 生成指定范围的随机数第10章 绘 图在计算机中,任何一种颜色都被认为是红(R)、绿(G)、蓝(B)三种颜色的混合结果。因此设定任何一种颜色,只要指定其红绿蓝分量即可,VB中颜色的表示就是基于此概念。给一个颜色属性赋值或用颜色调用方法或函数有以下六种方法。使用整数在VB中任何一个颜色都可以用四个字节的整数来表示,第一个字节为0,第二个字节表示的是蓝色(B)分量的大小,第三个字节表示的是绿色(G)分量的大小,第四个字表示的是红色(R)分量的大小。 每个分量的值十六进制为从&H00到&HFF,十进制为从0到255。因此常用十六进制数表示一个颜色值。如 &H00BBGGRR& 其中最高一个字节(两位十六进制数)未使用,后边的三个字节(每个字节对应两位十六进制数),分别表示此颜色的蓝绿红分量。哪一个分量数值大,则它对应的颜色成分越大。当三个分量数值相等时,相应的颜色为灰色。这种方法共能表示16M种颜色。 例:&H00000000&(黑色) &H00FFFFFF&(白色) &H00FF0000& (浅蓝) &H00800000&(深蓝) &H00FFFF&(浅黄) &H008080&(深黄)如:Form1.PSet (1000,1000), &H000000FF& 在窗体上绘制一个红色的点一、颜色使用系统颜色 如果一个表示颜色的整数的最高位为1,也就是第一字节值为&H80,则不表示一个RGB颜色值,而是一个系统颜色。系统颜色由用户在控制面板的显示器属性中设定,如:菜单颜色、按钮表面颜色、桌面颜色等。同一个系统颜色有可能不同用户的设置不同。系统颜色目前有25个,从&H80000000&到&H80000018。 Form1.Line (1000,1000)-(2000,2000),&H80000001&,B该语句的功能是使用当前桌面颜色来绘制一个矩形。使用RGB函数 可以使用RGB函数返回一个颜色值,此函数要求三个参数,分别表示红(R)、绿(G)、蓝(B)分量的大小。如:RGB(0,0,0)返回黑色, RGB(255,0,0)返回浅红,RGB(255,255,0)返回黄色。 Picture1. Circle (1000,1000), 1000, RGB(255,255,0)该语句的功能是在图片框内绘制一黄色的圆。使用VB定义的颜色常量 常数值描述常数值描述 vbBlack&H0&黑色vbRed&HFF&红色 vbGreen&HFF00&绿色vbYellow&HFFFF&黄色 vbBlue&HFF0000&蓝色vbMagenta&HFF00FF&紫红 vbCyan&HFFFF00&青色vbWhite&HFFFFFF&白色QBColor函数 QBColor函数采用Quick Basic所使用的16种颜色,其语法格式为: QBColor(color) 其中: color 参数是一个界于 0 到 15 的整型,如右表所示。值颜色值颜色值颜色值颜色0黑色4红色8灰色12亮红色1兰色5洋红色9亮兰色13亮洋红色2绿色6黄色10亮绿色14亮黄色3青色7白色11亮青色15亮白色使用“颜色”通用对话框 ,如: CommonDialog1.Action=3 Label1.BackColor=CommonDialog1.Color 设置标签的背景色。【例题】 演示颜色的渐变过程,程序如下:Private Sub Form_click() Dim j%, x!, y! x = Form1.ScaleWidth y = Form1.ScaleHeight sp = 255 / y For j = 0 To y Line (0, j)-(x, j), RGB(j * sp, j * sp, j * sp) NextEnd Sub 如下列语句: Label1.BackColor=QBColor(4) 设置标签的背景色为红色。窗体与图片框支持几个文字输出和绘图方法和属性,可以使用它们的这些方法,在窗体或图片框的表面上输出文字或进行绘图。 Print方法:此方法用于在窗体和图片框表面上输出文字。语法为: 对象名.Print 用“,”或“;”分隔开的输出项对象名可以是窗体名或图片框控件名,输出项可以是任何类型的常量、变量、表达式、属性等,输出时会自动转换为文本。如以“,“分隔输出项,则每一项输出到不同的制表列,项与项之间有一定的间隙;如以“;”分隔输出项,则项与项之间会紧挨着。如果Print方法使用时,在最后一个输出项后加“,”或“;”,则下一条Print方法的输出会接在此行后边,否则会另起一行输出。不接任何参数的Print产生一个空行。 CurrentX,CurrentY属性:只有窗体与图片框有这两个属性,用来控制文本或图形的输出坐标位置。在最开始时,它们均为0,即左上角。在输出文本或图形之后,会自动调整它们的值。如,使用Print方法输出一行后,这两个属性会自动移动下一行的坐标位置。如果要在特定位置输出文本或图形,可以在程序中设置这两个属性的值,然后使用文本或绘图方法。如 Picture1.CurrentX=1000: Picture1.CurrentY=1000 Picture1.Print Hello! Picture1.Print Good Morning!二、绘制文字和图像Private Sub Command1_Click() Dim int1 As Integer, int2 As Integer CurrentX = 0: CurrentY = 500 使第一行离标题栏使第一行离标题栏100单位单位 For int1 = 1 To 9 每次循环生成一行每次循环生成一行 For int2 = 1 To int1 每次循环生成一项每次循环生成一项 Print Spc(3); CStr(int2); ; CStr(int1); =; CStr(int1 * int2); Next Print 另起一行另起一行 Print 两行之间隔一空行两行之间隔一空行 NextEnd Sub打开【例10.1】500单位 PSet方法: 此方法可以在窗体或图片框上的指定位置上画一个点。语法: 对象名.PSet Step (x, y), color Step(x,y)指定画点的坐标,如无Step则(x,y)是绝对坐标,如果有Step,则(x,y)表示的是与(CurrentX,CurrentY)的相对坐标。还可以同时指定颜色。执行完此方法后,对象CurrentX,CurrentY属性的值会等于此点的坐标。 Line方法: 此方法可以在窗体或图片框上画一条直线或一个矩形。语法: 对象名.Line Step (x1, y1)- Step (x2, y2), color,BF Step(x1,y1)指定起始坐标,Step(x2,y2)指定终止坐标。如果有参数“B”,则绘制以给定点为对角的矩形,否则为给定点为端点的直线。如果有参数“F”,则用边框颜色填充矩形,无“B”参数,不能使用“F”参数。执行完此方法后,对象CurrentX,CurrentY属性的值会等于终点的坐标。例,下面语句可画线和矩形: Line (0, 0)-(1000, 1000), vbRed CurrentX = 1500: CurrentY = 200 Line Step(300, 300)-Step(1000, 1000), &HFF0000, BF Form1.ForeColor = vbRed Print 当前X和Y坐标点是:(; CurrentX; ,; CurrentY; )显示结果如右图所示。【例】 单击窗体,在图片框中产生300根爆炸的射线。 Circle方法: 此方法可以在窗体或图片框上的指定位置上画圆、椭圆或弧。语法: 对象名. Circle Step (x, y), radius, color, start, end, aspect 对象名为窗体或图片框对象名。Step(x,y)指定圆心坐标,radius指定半径,color,指定颜色,start与end指定弧的起止角度(弧度表示)。当 start与end为负值时,画出一个扇形 。Aspect指定圆度(即长短轴比),当它为1.0时,是一个圆,其它值为椭圆。执行完此方法后,对象CurrentX,CurrentY属性的值会等于圆点的坐标。例:下面语句分别画出一个圆、一个椭圆、一个圆弧和一个扇形。 Circle (800, 800), 500, &HFF Circle (1800, 800), 500, vbBlue, , , 2 Circle (800, 2200), 500, vbRed, 0, 3.14, 0.7 Circle (1800, 2200), 500, vbBlack, -0.1, -2.5显示结果如右图所示。【例题】 在窗体Form1上不建立任何控件,只编写适当程序,当程序运行时,单击鼠标右键,在窗体上以鼠标位置为圆心,以100800Twip之间的随机数为半径事圆,如下图所示。程序如下:Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) Dim r% r = Int(Rnd * 700 + 100) If Button = 1 Then Circle (X, Y), rEnd Sub Point方法:此方法用来返回窗体或图片框上指定点的颜色,返回的颜色以长整数表示,如在对象外面,则Point方法返回值-1(True)。此方法的语法为: 窗体或图片框名.Point (x, y) 例:IngColor=Picture1.Point (100, 100)【例】 用Point方法描绘文字。程序代码如下:Private Sub Form_click() Dim i%, j%, mcolor As Long Form1.DrawWidth = 2 Form1.Scale (0, 0)-(150, 150) Picture1.Scale (0, 0)-(150, 150) Picture1.Print 用Point方法仿真 For i = 1 To 150 按行扫描 For j = 1 To 150 mcolor = Picture1.Point(i, j) If mcolor = False Then PSet (i, j), mcolor Next NextEnd Sub注:使用窗体和图片框的绘图方法绘制的图形与图象与VB的图形控件、图象控件、直线控件有本质的不同。 Cls方法:此方法用来清除窗体或图片框上由以上方法所输出的文字、图形。清除之后CurrentX,CurrentY属性被设为0。打开【例10.2】 逐渐变大的圆。【例】 放大图形。 PaintPicture方法: 此方法在窗体或图片框上绘制图象,在绘制时可以只绘制图象的一部分,对进行反转和缩放。语法为:对象名.PaintPicture picture, x1, y1, width1, height1, x2, y2, width2, height2, opcode 对象名:为窗体或图片框对象名。picture:要绘制的图像,可以使用LoadPicture函数调入硬盘上的图象文件;x1,y1:绘制的起始坐标;width1,height1:绘制成的大小,负值可以使用图象翻转;x2,y2,width2,height2,表示被绘制图像的哪一个矩形区域;opcode:绘制的方法,决定位图中的每一个点是如何绘制到窗体或图片框上的,默认是按本来的颜色进行绘制。ForeColor属性、BackColor属性 对象的前景色和背景颜色。前景色是在对象里绘图的默认边框颜色或文本的前景颜色。当绘图方法中指定了颜色,则不受此属性值的影响。DrawWidth、DrawStyle属性 这两个属性用于窗体和图片框。DrawWidth可以返回或设置绘图方法产生图形的线宽。 DrawStyle可以返回或设置绘图方法产生图形的线型。 此属性的取值为0-6,默认值为0,实线。FillColor、FileStyle属性 用于窗体、图片框与图形控件。 FillColor返回或设置用于填充图形的颜色, 也可以用来填充由 Circle 和 Line 绘图方法生成的圆和方框。 FillStyle 属性设置图形控件、绘图方法产生的封闭图形的内部填充样式。此属性的取值为0-7。默认值为1,表示透明,此时,FillColor属性的值就被忽略。Picture属性 窗体也有此属性,指定窗体的背景图象。窗体的Cls方法不能清除窗体的背景图象。ScaleLeft、ScaleTop、ScaleWidth、ScaleHeight属性 窗体与图片框对象有这些属性,分别是对象在其当前的坐标系统下,左上角的位置坐标和宽度与高度。三、与绘图有关的属性、事件和方法打开【例10.3】 绘制Sin一个周期的函数曲线。 DrawMode:此属性用于窗体和图片框。决定绘制直线、矩形等线条及其填充时所使用的颜色,此颜色由“画笔色”和“背景色”经运算得到。 默认情况下DrawMode的值为13,即使用画笔色(由ForeColor、FillColor决定),但如果使用其他取值,可以实现特殊效果。如下面画出的圆是绿色的。 Me.BackColor = vbRed DrawMode = 10 Circle (1500, 1500), 600, vbBlue 经运算“Not(画笔色 Xor 背景色)”得到新画笔色 Not(vbBlue Xor vbRed)=vbGreen又如:Private Sub Form_Load() DrawWidth = 10 设置DrawWidth.End SubPrivate Sub Form_Click() Static M As Integer 当前 DrawMode 的设置值. ForeColor = QBColor(Int(Rnd * 15) 选择一种颜色. M = (M + 1) Mod 16) + 1 使 DrawMode 小于或等于 16 DrawMode = M 设置 DrawMode.End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button Then PSet (X, Y) 当按钮被按下时,画一个大点End Sub程序运行结果如图所示。AutoRedraw属性: 此属性用于窗体和图片框控件。当此属性为True时,使用绘图方法绘制的图形会被保存在内存中,当窗体或图片框被其它窗体遮盖后又显示出来,图形会自动显示;当此属性为False时,窗体或图片框重新显示出来时,图形不会被重画。此属性为True时,窗体和图片框的Cls方法不能清除已绘制的图形。窗体与图片框的Paint事件 在窗体或图片框被遮盖后又显示出来或窗体被放大时,窗体或图片框上显示的图形应被重新绘制。这时,VB发送Paint事件,允许程序进行绘制。写在Paint事件过程中的代码在每次窗体或图片框要重绘时会被自动地调用。所以Paint事件过程中适合绘制永久显示的内容。 注:当窗体或图片框的AutoRedraw属性设为True时,不激活Paint事件,即不执行Paint事件过程中的代码。ClipControls属性: 此属性用于窗体和图片框。当此属性为True时,在Paint事件过程外的绘图方法产生的图形会绘制在窗体或图片框上其它控件的后面;当此属性与AutoRedraw属性均为False时,图形会覆盖控件。Font属性: 此属性指定在窗体或图片框上输出文字、在控件上显示标题或文本时使用的字体的名称、样式、大小、下划线等方面特征。在设计时,可以使用属性窗口中Font属性栏中的按钮所弹出的对话框设置。也可以在程序中设置。 Font属性本身也是一个对象,它也有属性,分别是:Name:字体型,字体名。Size:字体大小,单位是磅,最大为2048。Bold:这是个逻辑型值,字体是否为粗体。Italic :逻辑型,字体是否为斜体。Underline:逻辑型,表明字体是否有下划线。StrikeThrough :逻辑型,表明字体是有中删除线。Weight:字体的粗细度,0到900。 例:Form1.Font.Size = 40 此外,还有窗体与控件还有FontName、 FontSize、 FontItalic、 FontBold、 FontUnderline、 FontStrikeThrou等属性,意义与上述Font属性的具体属性相同。FontTransparent属性: 透明属性,如此属性为True,则文本输出不会遮住窗体或图片框的背景。该属性用于窗体和图片框。TextHeight、 TextWidth方法。方法格式: object.TextHeight(str)与 object.TextHeight(str) object为窗体或图片框名。这两个方法计算并返回使用当前字体输出str所指定的字符串的文本高度与宽度。四、与文字输出有关的属性窗体或图片框的有关属性对绘图方法的影响,如下图所示。窗体或图片框的有关属性对绘图方法的影响,如下图所示。BackColorForeColorDrawWidthDrawStyleFillColorFillStyle文字输出ForeColor、Font(Font.Name、Font.Size、Font.Italic .)FontName、FontSize 、FontItalic、FontUnderline 五、绘图坐标系统 坐标系统包括原点位置和坐标单位,影响图形方法的输出和控件的定位。 ScaleMode属性:窗体与图片框的这个属性决定使用何种坐标系统。 Object.ScaleMode = value Object为窗体或图片框对象名。 value 的设置值为:常数设置值 描述vbUser0自定义坐标系统。VbTwips1(缺省值)缇(每厘米为 567 个缇)。VbPoints2磅(每英寸为 72 个磅)。VbPixels3像素(监视器或打印机分辨率的最小单位)。vbCharacters4字符(水平和垂直每个单位分别=120 缇、240 缇。)VbInches5英寸。VbMillimeters6毫米。VbCentimeters7厘米。 说明:当ScaleMode值为1到7时,是VB已定义好的标准坐标系统。这7种坐标的原点都在对象的左上角,x的正方向为向右,y的正方向为向下。其中系统3以像素为度量单位,在不同分辨率的显示器上显示的大小不同。其它几种标准坐标系统都是设备无关的。系统4的水平与垂直度量不同,应注意。在1024x768或800x600等标准的分辨率下:1毫米 约等于 3.78像素。 当窗体与图片框的ScaleMode属性为0时,使用自定义坐标系统,如下图所示。六、自定义坐标系统 使用ScaleHeight、ScaleWidth、ScaleLeft 和 ScaleTop确定自定义坐标系统(0,1)(360,0) 自定义坐标系统的原点位置和坐标单位受其它四个属性: ScaleHeight、ScaleWidth、ScaleLeft 和 ScaleTop 的值决定。 ScaleLeft 、ScaleTop属性:这两个属性分别指定在自定义坐标系统下对象左上角的坐标。 ScaleHeight、ScaleWidth属性:两个属性指定在自定义坐标下,当前窗体或图片框对象的高与宽。当这两个属性取负值时,会改变坐标的正方向。 在自定义坐标系统下,坐标的实际单位是由对象的实际大小和这两个属性联合决定的。以下是自定义坐标系统,或定义坐标的的四个角的坐标 Picture1.ScaleLeft = 0 X轴方向左侧以0值开始 Picture1.ScaleTop = 1 Y轴方向上方最大值为1 Picture1.ScaleHeight = -2 坐标的Y轴方向以上为正方向, Y轴方向下方最小值为-1 Picture1.ScaleWidth = 360 在使用标准的坐标系统时,上述四个属性分别反映出在当前坐标系统下,ScaleLeft、ScaleTop的值为0 ,ScaleHeight、 ScaleWidth 值为以当前单位的对象高度与宽度。如果在标准坐标系统下,改变了这四个属性之一的值,会自动使用自定义坐标。ScaleMode 自动地设置为 0。 更改坐标系统,不会影响窗体或图片框上已有的图形或控件的位置,CurrentX 和 CurrentY属性值将发生改变以反映当前点的新坐标。使用Scale方法确定自定义坐标系统打开【例10.6】 使用自定义坐标系统绘制Sin函数曲线。打开【例10.7】 使用Pset方法绘制Sin函数曲线。 使用Scale方法:此方法也可以设置一个自定义坐标系统:object.Scale (x1, y1) - (x2, y2) 其中:(x1,y1)确定对象左上角在自定义坐标系统下的坐标;(x2,y2)确定对象右下角在自定义坐标系统下的坐标。 如下面语句所确定的坐标和上面所用语句功能等同。 Picture1.Scale (0, 1)-(360, -1) 以下语句可以画Sin(x)函数曲线 Picture1.Line (0, 0)-(360, 0) 画横轴坐标 Picture1.Line (0, -1)-(0, 1) 画纵轴坐标 For d = 0 To 360 Step 0.5 Picture1.Line -(d, Sin(d / 180 * 3.14) Next绘制李萨如曲线,其函数如下:七、上机实验补充题用Circle方法在窗体上绘制由圆环构成的艺术图案,如右图所示。 提示:本题的算法如下:等分半径为r的圆周为n份,以等分点为圆心,半径r1绘制n个圆。为此,首先要确定圆心坐标(x0,y0),然后在确定圆周上一点 (x1,y1),如右下图所示,所示有以下公式: x1=x0+x=x0+r*cos() 其中:0 2 y1=y0+y=y0+r*sin()xy主要程序代码如下:Private Sub Form_Click() Const PI = 3.1415926 Dim r, x, y, x0, y0 r = Form1.ScaleHeight / 4 指定圆的半径 x0 = Form1.ScaleWidth / 2 y0 = Form1.ScaleHeight / 2 定圆心 st = PI / 20 等分圆周20份 For i = 0 To 2 * PI Step st x = x0 + r * Cos(i) y = y0 + r * Sin(i) Circle (x, y), r * 0.8 NextEnd Sub 返回目录用Line方法绘制函数f(x)=x2在区间a,b之间积分面积图,如图下图左一所示。 提示:为了能绘制任意区间a,b上函数f(x) 积分面积图,可在窗体上放置一个图形框和两个文本框。文本框用于指定积分上下限的值,图形框用于绘图。根据区间a,b的值设置图形框的左上角坐标为(a-1,bb+1),右下角坐标为(b+1,-1)。将区间a,b等分为n 份,在每一等分点i上,用Line方法连线到(i,i*i)。用Circle方法绘制如上图左二所示图形。 提示:要绘制的圆由小到大,只需要在循环中改变圆心坐标x和半径r,圆心的另一坐标y可保持不变,例如,取窗体高度的1/2,半径r取x/2。使用自定义坐标:Scale (-4, 4)-(4, -8)。然后,按照阿基米德螺线x=cos(),y= sin(),绘制02之间的展开直线,如上图右三所示。设计一个时钟程序,要求以钟表刻度的形式显示时间,如上图右四所示。第11章 多重窗体和多文档窗体一、多重窗体前面的应用程序都是只有一个窗体的简单程序。在实际应用中,单一窗体往往不能满足需要,须通过多个窗体来实现,这就是多重窗体。在多重窗体中,每个窗体可以有自己的界面和程序代码,分别完成不同的功能。新建 现存添加窗体添加窗体操作方法:“工程|添加窗体” 添加添加“现存现存”窗体时要注意:窗体时要注意: 防止多个窗体的name相同而不能添加; 添加的窗体实际是将其它工程中已有的窗体加入,多个工程共享窗体; 通过“另存为”命令以不同的窗体文件名保存,断开共享。 一个工程中有多个窗体,应分别取不同的文件名保存在磁盘上,VBP工程文件中记录了该工程的所有窗体文件名。 保存窗体保存窗体“启动对象”是程序启动时被VB自动装载的对象,可通过“工程”菜单的“工程属性”所激活的“工程属性”对话框中选择“启动对象”。可以用作启动对象的只有两种对象之一: 工程中的一个窗体; 标准模块中的Sub Main过程。默认的启动对象是第一个窗体。设置启动对象例如,在标准模块中的一个典型的Main()过程,代码如下:Sub main() Dim d As Date If Weekday(d) = 1 Or Weekday(d) = 7 Then 判断是否为周末 Load Form2 加载窗体Form2 Form2.Show 显示窗体Form2 Else Form1.Show End IfEnd Sub窗体的加载、显示、隐藏与卸载加载: 窗体在显示之前要先加载到内存:使用语句: Load 窗体名显示:显示一个窗体可以使用窗体的Show方法。 窗体名.Show 0 | 1, Me 0:窗体是无模式的(或非模态的),即窗体的出现不会影响用户对其它窗体的操作。1:窗体是模式的(或模态的),即窗体显示之后,用户就不能对本程序的其它窗体进行操作,直到关闭此窗体为止。如果在使用此方法之前,窗体未加载到内存,VB会自动加载。隐藏:隐藏一个窗体,使用其Hide方法。 窗体名.Hide此方法把窗体的Visible属性设为False。但并不卸载窗体。 程序仍可以对窗体及其控件进行操作,甚至窗体的Timer也在工作。如果在执行此方法之前窗体尚未加载,则加载之。卸载: 把窗体从内存中清除。 Unload 窗体名卸载掉的只是窗体的显示部件,它的代码,如过程与函数仍可用。打开【例11.1】 使用启动对象。创建工程,添加窗体Form1、Form2和标准模块Module1,定义和启用Main()过程。窗体加载与卸载时的相关事件Initialize事件:窗体的初始化事件,在加载一个窗体时,此事件最先被激活。Load事件:当窗体被装载入内存时,激活此事件。在以在窗体的此事件中加入启动代码,例如:指定控件缺省属性值,在列表框中加入被始条目, ComboBox 或 ListBox 控件的内容,以及初始窗体级变量等。Activate事件:当一个窗体第一次被显示或成为当前活动窗体之前,激活此事件。可以在此事件过程中,设置拥有焦点的控件等工作。 Deactivate 事件:当一个窗体不再成为活动窗体时,激活此事件。QueryUnload事件:当窗体要被卸载之前,先激活此事件。此事件有两个参数:Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)在事件过程中为第一个参数cancel赋一个非零值,会阻止窗体的卸载。第二个参数UnloadMode,说明引起窗体卸载的原因,0:选择窗口菜单中的“关闭”命令或点击了“关闭”按钮;1:在程序中使用了Unload语句;2:操作系统关闭;3:在Windows的任务管理器中关闭此程序;4:在MDI窗体关闭引起MDI子窗体的关闭。程序处理此事件,对未保存的工作进行保存,或中止关闭窗体。Unload事件:当窗体被卸载,从显示上消失时,激活此事件。此事件过程的格式是:Private Sub Form_Unload(cancel As Integer),其中有一参数cancel,在事件过程中把参数cancel的值设为非零值,则会阻止窗体的卸载。Terminate事件:窗体从内存中卸载过程中的最后的一个事件。打开【例11.3】 使用QueryUnload事件过程提示用户保存数据。不同窗体间数据的存取不同窗体间数据的存取存取控件的属性,方法如下: 另一窗体名另一窗体名.控件名控件名.属性属性存取变量的值 另一窗体名另一窗体名.全局变量名全局变量名Unload语句End语句Stop语句 在高度程序时,向代码中加入Stop语句,每次执行到这条语句时,会轶并处于中断状态,按F5键继续执行。程序的终止Unload语句End语句Stop语句 在高度程序时,向代码中加入Stop语句,每次执行到这条语句时,会轶并处于中断状态,按F5键继续执行。模块:模块:Public MATH As SinglePublic PHYSICS As SinglePublic CHEMISTRY As SinglePublic CHINESE As SinglePublic ENGLISH As Single打开【例11.7】输入和计算学习成绩。二、多文档界面(MDI)多文档界面(Multiple Document Interface,简称MDI)由一个父窗体和多个子窗体组成。MDI窗体作为子窗体的容器,子窗体包含在父窗体之内,用来显示各自的文档。父窗体和子窗体中都 可以使用菜单和工具栏,它们的命令处理只能在自己的模块中执行。MDI窗体MDI子窗体 创建和设计MDI窗体及其子窗体,本部分的内容已超出授课内容,感兴趣的同学请参考列出的教材。三、上机补充题 如图右所示,单击“电影目录”中的一条项目,可弹出该电影的简介窗口;同样地,单击“电视目录”中的一条项目,可弹出该电视的简介窗口。 完成如下图所示的程序。返回目录第12章 文件操作保存在外部存储介质上的一批有内在相关联系的数据集合,我们称之为文件。区别一个文件的方法是文件名。是指磁盘文件是永久存储信息的重要方式。应用程序在以下的情况下需要进行磁盘文件操作:大量的数据需要以文件的形式传递给程序进行处理,而不是通过鼠标和键盘的输入;程序计算的结果、得到的大量数据需要以文件的形式保存,以供其他程序处理,而不仅仅是显示在屏幕上;程序的运行参数,用户的设置需要以文件形式保存,供以后本程序再次使用。总之,除非功能极其简单的程序,几乎所有的程序都需要进行文件操作。Visual Basic支持文件的操作,提供了大量的语句和函数,根据文件读写方式和保存格式的不同,把文件分为三类:顺序访问文件;随机访问文件;二进制文件。一、文件操作的必要性二、文件的标识方法文件名;文件路径,如:c:windowssystem32command.com;用App.Path方法可测试应用程序所在目录,但结果没有最后的“”。当前驱动器和当前文件夹;应用程序的路径;文件号。三、文件系统控件 为了方便与磁盘文件操作有关的编程,Visual Basic提供了三个文件系统控件,它们是:驱动器列表框、目录列表框和文件列表框。驱动器列表框、目录列表框与文件列表框一般是配合起来使用,供用户选择一个文件。要使用三者联动起来就必在一个发生改变之后立刻刷新其它的。驱动器列表框控件DriveListBox驱动器列表框控件包含了所有的驱动器(包括软盘驱动器、硬盘驱动器与光驱),允许用户从中选择一个驱动器。主要属性、方法与事件有: Drive属性,返回当前所选驱动器或设置要选择的驱动器。可以给该属性赋一个字母(大小写均可)来选定相应的驱动器。如: Driver1.Drive = C可以赋给此属性一个字符串,但只有第一个字符才有意义。如果当前计算机上无所指定的驱动器,则会出错。 另有List、ListIndex和ListCount属性,和列表框控件的属性相同。 Change事件,当所选驱动器发生改变时(用户使用鼠标或通过程序设置)激活此事件。如:Dir1.Path = Drive1.Drive 让驱动器与目录联动目录列表框控件DirListBox目录列表框显示指定目录下的所有子目录,并允许用户选择目录。目录列表框的主要属性、方法与事件有: Path属性:设置或返回在目录列表框中打开的当前目录。List属性:每一个显示出来的子目录名(带全部路径)。ListIndex属性:当前所选定的目录的序号。由Path所指定的目录的序号为-1。它的上一级目录的序号为:-2,依此类推。它的第一个子目录序号为0,第二个子目录的序号为1,依此类推。 Click事件。 Change事件。在当前子目录被改变时激活此事件。 如:File1.Path = Dir1.Path 让目录和文件联动,双击某目录可在文件列表框显示文件列表框控件FileListBox文件列表框控件用于显示给定子目录下所有的文件供用户选择。主要的属性、方法与事件有:Path属性:文件列表框中所显示的文件所在的路径名。FileName属性:返回或设置所选择的文件名。打开【例8.7】 图片查看程序。ListIndex-4-3-2-1012345 Pattern属性:设置文件列表框中显示文件的类型,如:*.bmp;*.jpg。 Click,DblClick,KeyPres,Scroll,PatternChange等常见事件。PathChange 事件:当文件列表框所列的文件的所在目录发生变化时,触此事件。四、对话框自定义对话框 对话框(Dialog Box)是一种用于实现用户和应用程序进行交互的特殊窗体。 对话框的大小一般不可改变,也没有“最小化”和“最大化”按钮,它只有一个“关闭”按钮(有时还包含一个“帮助”按钮)。 对话框分为模式和无模式两种类型。无模式用于显示频繁使用的命令与信息。 VB提供了三种解决方案:系统预定义的对话框,即:InputBox和MsgBox。用户自定义对话框。通用对话框控件。 由普通窗体创建自定义对话框,在窗体上放置常用控件,如命令按钮、单/复选按钮、文本框等。 对话框窗体与一般窗体在外观上是有区别的,需要设置窗体及控件的属性值来自定义窗体外观,如下图所示。通用对话框(Common Dialog Box) 通用对话框(Common Dialog Box)是一种可以添加到应用程序中的特殊控件,它可以产生6种不同的可用于应用程序的标准对话框。用它可以方便地定义较为复杂的对话框。可以用来进行打开或保存文件、选择字体、选择颜色、设置打印选项等操作。另外还可以调用Windows帮助引擎来显示应用程序的帮助。在编制程序时,可以直接调用通用对话框控件完成上述功能,既减少了工作量,又使程序更加符合Windows用户的使用习惯。 通用对话框是一种ActiveX控件,在一般情况下,启动Visual Basic后,在工具箱中并没有通用对话框控件。要使用通用对话框控件,必须首先把“通用对话框”控件添加到工具箱中,具体步骤如下:使用对话框模板窗体创建对话框 Visual Basic6.0系统提供了多种不同类的“对话框”模板窗体,通过“工程”菜单中的“添加窗体”命令,即可打开“添加窗体”对话框。 用户可以选择的对话框有“关于”对话框、对话框、登录对话框、日积月累、ODBC登录、选项对话框6类等。 选择“工程”菜单中的“部件”命令,打开“部件”对话框。 在控件选项卡中选中“Microsoft Common Dialog Control6.0”,如右图所示。 选择“确定”按钮,即可把通用对话框加到工具箱中。 通用对话框控件时,可以放置在窗体的任何位置,程序运行时通用对话框控件并不显示,只有在程序运行时通过代码使用不同的方法才能显示相应的对话框。打开和保存对话框 用通用对话框工具在窗体上可以创建以下对话框窗口,分别为打开(Open)、另存为(Save As)、颜色(Color)、字体(Font)、打印(Print)及帮助(Help)窗口。设计时,将通用对话框添加到窗体上,通过在代码中设置其属性调用所需的对话框。 对话框的类型即可通过Action属性设置,也可用相应的方法设置,如下表所示: 对话框类型方法 Action属性值对话框类型方法Action属性值 打开文件 ShowOpen 1选择字体ShowFont4 保存文件ShowSave 2打印ShowPrinter5 选择颜色ShowColor 3显示帮助文件ShowHelp6 下面介绍如何使用通用对话框控件提供的几种标准对话框。文件“打开”(Open)与“另存为”(Save As)对话框 文件对话框包括打开(Open)文件对话框和保存文件(Save As)对话框,如图所示,主要用来获取用户指定的文件信息供程序使用。 打开和保存文件对话框的主要属性如下: 1DefaultExt属性 设置对话框缺省的文件扩展名。 2DialogTitle属性 设置对话框的标题。在缺省情况下,“打开”对话框的标题是“打开”;“保存”对话框的标题是“另存为”。 3FileName属性 设置或返回要打开或保存文件的路径及文件名。可以设置默认打开或保存的文件名和返回用户在对话框中所选文件的路径和文件名。 4FileTitle属性 返回用户所选文件的文件名(不包含路径)。该属性与FileName属性的主要区别是:FileName属性返回包含路径的文件名,例如“d:vbproform1.frm”;FileTitle只返回文件名称。 5Filter属性 设置对话框的文件列表框中显示的文件的类型。例如,选择过滤器为 *.txt,在对话框的文件列表框中只显示文本文件。Filter属性由一对或多对字符串组成,每对字符串包括文字说明和过滤器两部分,两部分之间用管道符“|”隔开,各字符串之间也用管道符隔开。文字说明部分用来说明过滤器的用途;过滤器部分用来设置显示的文件类型(一般由通配符和文件扩展名组成,如:*.txt),如果在一个过滤器中要显示多种文件类型则用分号“;”把多种类型隔开。其格式如下: 通用对话框控件名称.Filter =“文字描述1|过滤器1|文字描述2|过滤器2” 例如: CommonDialog1.Filter=”图形文件|*.BMP;*.JPG;*.GIF|WORD文档|*.DOC” 6FilterIndex属性 设置默认的过滤器。用Filter属性设置好过滤器后,每个过滤器都有一个值,第一个过滤器的值为1,第二个过滤器的值为2,依此类推。FilterIndex属性用来设置默认的过滤器。例如:CommonDialog1.FilterIndex2 把第二个过滤器设为默认过滤器。对于上面的例子来说,打开对话框后,在文件类型下拉列表框中显示的是“Word文档”,文件列表框中只显示扩展名为.doc的文件。其他过滤器可以通过在文件类型下拉列表框中选择切换。 7Flags属性 用于设置对话框的一些选项,如值为2时,文件在保存时,提示用户是否覆盖。 8InitDir属性 设置并返回对话框的初始目录。如果没有设置InitDir属性,对话框则显示当前目录下的文件。例如:CommonDialog1.InitDir=”E:Visual Basic”,则打开文件对话框后显示“E:Visual Basic”目录下的文件。 9MaxFileSize属性 设置文件名的最大长度,以字节为单位。取值范围132k,缺省值是256。 10CancelError属性 控制当在对话框中单击“取消”按钮时,是否显示错误信息。如果设为True,则显示错误信息,如果设为False(缺省设置),则不显示错误信息。 【例】 编写程序,建立“打开”和“另存为”对话框,如图所示。 设计步骤如下:打开【例8.11】 文件“打开”与“另存”对话框。 设计步骤如下: 在窗体上画一个通用对话框控件,其Name属性为Commondialog1(默认值);再画两个命令按钮,其Name属性分别为Command1和Command2;然后,编写两个事件过程。建立打开对话框的事件过程如下:Private Sub Command1_Click()CommonDialog1.FileName=CommonDialog1.Flags = 4 取消只读检查CommonDialog1.Filter =All Files|*.*|(*.txt)|*.txt |(*.exe) |*.exeCommonDialog1.FilterIndex = 1CommonDialog1.DialogTitle = 打开CommonDialog1.Action = 1如果=2则为另存对话框如果没有选择任何文件则FileName返回值为空If CommonDialog1.FileName = ThenMsgBox 您没有选择任何文件ElseCls 清除当前窗体显示内容Form1.Print CommonDialog1.FileNameEnd IfEnd Sub 该事件过程用来建立一个“打开”对话框。 在这个对话框中可以选择要打开的文件,然后单击“打开”按钮,所选择的文件名即作为对话框的FileName属性值。过程中的“CommonDialog1.Action = 1”用来建立“打开”对话框,它与语句:CommonDialog1.ShowOpen 等价。 “打开”对话框其实并不真正打开文件,而是仅仅用来选择一个文件,至于选择后的处理,包括打开、显示等,由代码中的相关语句来处理,“打开”对话框已无能为力了。有关文件处理的内容,请参阅第12章。 颜色(Color)对话框允许在调色板中选择颜色,或生成和选择自定义颜色。颜色对话框具有和文件对话框相同的一些属性,包括CancelError、DialogTitle、Help-Command、HelpContext、Help-File和HelpKey等,此外,还有两个属性: Color属性。设置对话框的初始颜色,并可返回用户所选择的颜色给应用程序。该属性是一个长整型数。 Flags属性。Flags属性用来设置颜色对话框的一些选项。属性值见如下: 常 数十六进制 十进制作 用 vbCCRGBInit&H1 1为对话框设置颜色初始值 vbCCFullOpen&H2 2显示全部的对话框 vbCCPreventFullOpen&H4 4 使自定义颜色命令按钮无效 vbCCShowHelp&H8 8显示帮助按钮 【例】 为一按钮的Click事件编写程序,显示颜色对话框,并把窗体的背景色设置为选择的颜色。Private Sub Command1_Click()CommonDialog1.ShowColorForm1.BackColor = CommonDialog1.ColorEnd Sub“颜色”(Color)对话框 执行上面的过程,将显示如图所示的一个颜色对话框,在该对话框的“基本颜色”部分选择一种颜色(单击某个色块),然后单击“确定”按钮,即可把窗体(Form的背景色设置为所选的颜色。打开【例8.12】 “颜色”对话框。 在VB中,字体通过字体(Font)对话框或者字体属性进行设置。 字体对话框除了有和其他对话框相同的CancelError、DialogTitle、HelpCommand、HelpContext、HelpFile和HelpKey等属性外,还有以下主要属性。FontBold、FontItalic、FontName、FontSize、FontUnderline、FontStikeThru、Color分别设置选择粗体,斜体,字体名称,字体大、小,设置下划线,删除线效果,选择文字的颜色。如果要使用这些属性,必须先将Flags属性设为cdlCFEffects或256。Flags的属性。主要取值如下:符号常量值描述cdlCFScreenFonts1使对话框只列出系统支持的屏幕字体。cdlCFPrinterFonts2使对话框只列出打印机支持的字体。cdlCFBoth3使对话框列出可用的打印机和屏幕字体。cdlCFEffects256指定对话框允许删除线,下划线,以及颜色效果。cdlCFLmitSize8192只能在Min和Max属性规定的范围内选择字体大小。 【例】 用字体对话框设置文本框中显示的字体,如图所示。 Private Sub Command1_Click()CommonDialog1.Flags = 3CommonDialog1.ShowFontText1.FontName = CommonDialog1.FontNameText1.FontSize = CommonDialog1.FontSizeText1.FontBold = CommonDialog1.FontBoldText1.FontItalic = CommonDialog1.FontItalicText1.FontUnderline = CommonDialog1.FontUnderlineText1.FontStrikethru = CommonDialog1.FontStrikethru End Sub“字体”(Font)对话框 打印(Print)对话框可以用于选择打印机,设置打印份数、页码范围等打印选项。但选择完打印选项后并不能启动打印作业,要完成打印功能必须编写处理打印作业的代码。 打印对话框和其他对话框一样,除具有CancelError、Dialog-Title、HelpCommand、HelpCon-text、HelpFile和HelpKey等属性外,还具有以下主要属性: Copies属性。设置要打印的份数。如果把Flags的属性值设为262144,则Copies属性值总为1。 Flags属性。设置字体对话框的一些选项。 FromPage和ToPage属性。设置打印文档的页码范围,要使用这两个属性,必须把Flags属性设置为2。 Max和Min。用来限制FromPage和ToPage的范围。 【例】 建立打印对话框。在窗体上画一个通用对话框和一个命令按钮,给命令按钮Click事件编写如下代码:Private Sub Command1_Click()firstp = 1lastp = 100CommonDialog1.Flags = 8CommonDialog1.ShowPrinterCommonDialog1.Min = firstpCommonDialog1.Max = lastpFor i=1 to CommonDialog1.copiesPrinter.print text1.textNextEnd Sub 运行程序,单击命令按钮,结果如图7.18所示。“打印”(Printer)对话框五、顺序文件顺序文件实际上是文本文件。写入顺序文件的任何类型的数值,都被转换成字符形式。因此,顺序文件可以使用任何的文本编辑软件打开查看(如记事本) 。文本文件中的信息往往是以行为单位的,行与行之间是以不可见的回车符与换行符分隔。一行中又可分为多个数据项。【格式】Open Filename For Input | Output | Append As #FileNo Len=reclength【说明】Filename参数:是文件全名(包括路径);Input|Output|Append 参数决定对文件的操作方式,其中:Input:从文件读到程序中;Output:从程序写到文件中,覆盖文件中现有内容;Append:追加到文件的末尾。如果文件尚未建立,则Input方式会出错,其它两种方式会创建新文件。FileNo参数指定是文件号,它的值应在1511,打开文件后对文件的操作均要使用此文件号,每一个打开的文件都应使用不同的文件号。 reclength 可选。小于或等于 32,767(字节)的一个数。对于用随机访问方式打开的文件,该值就是记录长度。对于顺序文件,该值就是缓冲字符数。 打开顺序文件关闭文件【格式】 Close #FileNo1,#FileNo2,【说明】这个命令可以关闭任何一种以Open语句打开的文件。不带任何参数的Close语句可以关闭所有当前以Open语句打开的文件。写顺序文件之前,应该以Output或Append模式打开文件。可以使用下列语句把变量、常量、属性或表达式的值写入顺序文件。Print # 语句 Print# 文件号,一个或多个参数,|; Print# 语句可以向“文件号”参数指定的文件中写入多个数据项,用法与窗体的Print方法很相似。多个参数可以用逗号分隔也可以用分号分隔。用逗号分隔时,写入文件中的数据项之间的有较多的空格分隔;用分号分隔时,写入文件中的数据项只间隔最多一个空格。如果Print#语句以一个逗号或分号结尾,则下一条写文件语句的输出不另起一行,否则换行。Print#语句也支持Spc(n)和Tab(n)函数把参数输出到特定位置上。Write# 语句Write# 文件号,一个或多个参数,|; Write# 语句与Print# 语句的语法完全相同,但是输出到文件中的结果不一样。主要表现在:Write# 输出到文件中的各数据项之间用逗号分隔。Write#写到文件中的内容会加上“界定符”:字符串加双引号,日期型、逻辑型加“#”,数值类型无特殊处理。不论使用逗号还是分号来分隔参数,Write#语句都会把数据一个挨一个地写入文件中,并用逗号隔开。Print# 语句适合于为其他软件生成数据文件,而Write# 更适合于为Visual Basic程序读入而生成文件。另外,Print#和Write#语句不能将整个数组或自定义类型变量的值写入文件中,只能一个元素(成员)一个元素(成员)地写。写顺序文件打开【例12.1】 向文件输出文字。要从顺序文件中读入数据到变量中以供后续处理,必须以Input方式打开文件;读顺序文件,可以使用下面的语句。Line Input# 语句LineInput# 文件号,字符串变量名Line Input# 语句是整行读入语句,可以把“文件号”所代表文件中当前读写位置上的一整行数据作为一个字符串读入,赋予指定的字符串变量。这个语句把一行中所有界定符、分隔符都当成字符串的组成部分。读入的内容中不包含行末的回车符与换行符。Input # 语句Input# 文件号,一个或多个变量名Input # 语句一次可以读入一项或多项内容,读入的值依次赋给相应的变量。如果文件中的数据项与对应的变量类型不同,会作一些默认的转换,无法转换时产生“类型不匹配”错误。此语句读入数据时,将逗号、空格、回车符、换行符等当作数据的分隔符。因为Write# 语句写文件时产生的数据项具有明显的分隔符(逗号、双引号和井号),所以应该用Input #语句来读Write# 语句产生的数据。在实际应用中,Input#和Write#语句使用的数据类型应一致。如果使用Input# 语句读取由Print#语句产生的数据(尤其是字符串数据),可能会出现数据项定位不准的情况。例如,本想读入10个字符,却读入了多个20个字符。读顺序文件打开【例12.2】 课程管理程序,实现课程的添删。 EOF(文件号) 此函数测试当前是否位于指文件号文件的末尾。是,返回True;否,则返回False。有的语句或函数在执行如果超出文件末尾,则会出错,应的使用前用本函数或LOF函数检测。 EOF()函数也适合于随机文件和二进制文件。对于随机文件和二进制文件,当最近一次执行的Get()无法读到一个完整记录时,EOF()返回回True,否则返回False。LOF(文件号) 返回指定文件号文件号所代表文件的长度,以字节为单位,如一个文件的内容为“1949年中华人民共和国成立”,LOF()的值为24。FreeFile函数 使用FreeFile 提供一个尚未使用的文件号,返回一个 Integer。语法格式如下: FreeFile(0|1) 指定 0(缺省值)则返回一个介于 1 255 之间的文件号。指定 1 则返回一个介于 256 511 之间的文件号。 例如: FileNo = FreeFile 取得未使用的文件号。 Open “d:Test.dat For Output As #FileNo 创建文件名。 Write #FileNo, “姓名:丁俊晖 输出文本至文件中。 Close #FileNo 关闭文件。与顺序文件操作有关的函数和语句【例12.1 _1】分别用Line Input和Input语句读从【例12.1】所建立文件中的数据。顺序文件操作示例保存文本框的内容保存文本框的内容 假定文本框的名称为txtTest,文件名为TEST.DAT。 方法1:把整个文本框的内容一次性地写入文件。 Open TEST.DAT For Output As #1 Print #1, txtTest.Text Close #1 方法2:把整个文本框的内容一个字符一个字符地写入文件。 Open TEST.DAT For Output As #1 For i=1 To len(txtTest.Text) Print #1,Mid(txtTest.Text,i,1); Next i Close #1读文本文件到文本框读文本文件到文本框 假定文本框名称为txtTest,文件名为MYFILE.TXT。 方法1:一行一行读 txtTest.Text Open MYFILE.TXT For Input As #1Do While Not EOF(1) Line Input #1, InputData txtTest.Text txtTest.Text + InputData+vbCrLfLoopClose #1方法2:一次性读 txtTest.Text Open MYFILE.TXT For Input As #1 txtTest.Text = Input( LOF(1),1) 使用了Input(number, #filenumber )函数 Close #1方法3:一个个字符读 Dim InputData as String*1 txtTest.Text Open MYFILE.TXT For Input As #1 Do While Not EOF(1)InputData= Input(1,#1) txtTest.Text txtTest.Text + InputData Loop Close #1对文件内容进行加密,方法是:“A”“D”,“a”“d”,“B”“E”,“Z”“C”,如右图所示。顺序文件的特点无论是读操作还是写操作,顺序文件都是一个数据项一个数据项地从文件头向文件尾依次进行,不会跳跃也不会返回。Visual Basic为每个打开的文件维护了一个文件读写指针,指针指向的位置就是下一次读写操作时的开始位置,读写之后,指针会自动作相应的移动并指向下一个位置。刚打开文件时,指针停留在文件的开头。在读顺序文件时,读入一个数据项后,下一条读文件的语句就从下一个数据项读入数据。如已到文件尾,继续读文件会产生错误,写文件的操作则不会出错,它会把文件扩大。文件号的有效性从作用域的概念上讲,文件号是具有全局性质的。一个文件使用Open语句以某一文件号打开之后,在用Close语句关闭之前,文件号总是有效的,可以用来进行读写。也就是说,只要在时间上保证“打开读写关闭”这个顺序即可,打开、读写和关闭的语句可以分别位于不同的事件过程,甚至不同的模块中。比如,对于频繁读写的文件,频繁地进行打开和关闭的操作会浪费大量的时间,应该在窗体的Load事件过程中打开,在UnLoad事件过程中关闭,窗体工作过程中进行读写。对于偶尔读写的文件,可以在单个过程中完成整个打开、关闭和读写的全套操作。文件的扩展名使用Open语句打开新文件时,可以指定任意的扩展名。不过,为了检验生成数据的正确性,建议在编程练习时使用“.txt”为扩展名。这样,所生成的文件可以很方便地在Windows资源管理器中通过鼠标双击的方法用“记事本”打开查看其内容。顺序文件的的几点说明与顺序文件不同,随机文件有特殊的格式要求: 文件的数据分为一个个等长的单元,称为记录(Record); 每条记录中包含一个或多个数据项,称为字段(Field),每条记录中字段数目相等,对应字段类型相同; 记录(Record)和字段(Field)的概念如下图所示。六、随机文件在随机文件中,除字符串之外,其他类型的数据不转换成字符形式,而是直接以与内存中相同的二进制形式存放。记录之间、字段之间没有分隔符进行分隔。一条记录一个字段记录指针或记录号随机文件的“随机”体现在,无论是从文件中读数据,还是向文件中写数据,都可以任意指定记录,不必像顺序文件那样只能从文件头向文件尾进行。 为将一条记录(行)的信息保存到文件中,必须将记录中各字段的信息打包,即形成一个等长的单元,就要用到讲解数组时介绍的自定义数据类型。 一条记录对应一个自定义类型值,一个字段对应自定义数据类型的一个成员。自定义一个数据类型,如。 Private Type Student xh As String * 9 xm As String * 12 xb As Boolean csrq As Date End Type打开随机文件 Open文件名ForRandomAs#文件号Len = 记录长度 关键字For Random :指定文件是以随机方式打开,因为Random是默认方式,所以可以省略。以随机方式打开的文件既可以读也可以写。如果文件不存在,则新建文件。“记录长度”参数指定读写操作时一条记录的长度(以字节为单位),如果使用自定义数据类型,可以使用Len函数计算自定义类型变量所占用的内存字节数,当作记录长度。使用Put语句写随机文件。语法为:Put#文件号, 记录号,表达式“文件号”参数应该是已打开的随机文件的文件号。“记录号”参数应是正整数,指定数据将写在文件中的第几条记录上。如果省略这个参数,则写在当前记录上。如果尚未进行读写,则写在第一条记录上。“表达式”是指要写入文件中的数据来源。Put语句把“表达式”的值写入文件中指定的一条记录上。当表达式的值所占的存储空间大于打开文件时指定的“记录长度”时,会出错。一般情况下,“表达式”是自定义类型变量名,变量的各个成员对应这条记录的各个字段。写随机文件使用Get语句读随机文件,语法为:Get#文件号, 记录号, 变量名“文件号”参数指定要读取的随机文件。“记录号”参数指定要读入随机文件中的第几条记录。如省略此参数,则读当前记录。如果尚未进行读写,则为第一条记录。“变量名”参数确定读入的数据存入哪个变量中。此变量的类型应与写文件时使用的变量类型相匹配,否则读出的数据可能没有意义。完成操作之后,Get语句将下一条记录设为当前记录。读随机文件随机文件使用示例【例12.3】如图所示为一学生信息管理程序,功能如下:追加记录(Command1):将一个学生的信息作为一条记录添加到随机文件末尾。显示记录(cmdDisplay):显示在右边文本框(text4)中指定的记录。 部分代码如下:部分代码如下:Module1.bas代码,定义了一个数据类型代码,定义了一个数据类型Type studtype ino As Integer strname As String * 10 strsex As String * 1 smark As SingleEnd TypeForm1.frm模块模块Dim student As studtypeDim record_no As IntegerPrivate Sub Command1_Click() With student .ino = Val(Text1.Text) .strname = Text2.Text .strsex = IIf(Option1.Value, 1, 0) .smark = Val(Text3.Text) End With Open d:student.dat For Random As #1 Len = Len(student) record_no = LOF(1) / Len(student) + 1 Label6.Caption = record_no Put #1, record_no, student Close #1End Sub转下页Private Sub Form_Load() Open d:student.dat For Random As #1 Len = Len(student) Label6.Caption = LOF(1) / Len(student) Close #1End SubPrivate Sub Command2_Click() Open d:student.dat For Random As #1 Len = Len(student) record_no = Val(Text4.Text) Get #1, record_no, student Text1.Text = student.ino Text2.Text = student.strname If student.strsex = 1 Then Option1.Value = True Else Option2.Value = True End If Text3.Text = student.smark record_no = LOF(1) / Len(student) Close #1End Sub使用For Binary关键字来打开二进制文件。语法为:Open文件名ForBinaryAs# 文件号 以二进制方式打开的文件既可以读也可以写。如果文件不存在,则创建新文件。打开二进制文件使用Put语句来写二进制文件。Put#文件号, 写位置, 表达式“文件号”代表一个以二进制方式打开的文件。“写位置”参数为长整型数,指定数据要写到文件中的位置(从文件开头以字节为单位计算),如省略此参数,则写入当前位置。如果尚未进行过读写操作,则为文件头的位置。如果指定位置上本来有数据,则会被新写入的数据覆盖。当指定位置超出文件末尾时,会使用文件扩大。“表达式”是要写入文件中数据的来源,表达式的值可以是任意类型。如果“表达式”处是一个数组名,则会把数组所有元素的值依次写入文件中。写入数据成功后,Put语句将下一个字节位置设为下一次读写的当前位置。写二进制文件七、二进制文件使用Get语句来读二进制文件。Get#文件号, 读位置, 变量名 “文件号”代表一个以二进制方式打开的文件。“读位置”参数指定要读入的数据在文件中的位置(从文件开头以字节为单位)。如省略此参数,则从当前位置开始读。如果尚未进行过读写操作,从文件头开始读入。如果指定位置超出文件长度,并不会出错,读入的是变量类型的默认值。“变量名”参数指定从文件中读出的数据要存入的变量,变量的数据类型决定从文件中读入的字节数。如果“变量名”为字符串变量,则读入的字符数与字符串变量当前字符数相同。如果“变量名”参数是一个数组名,则会从文件中读入多个值并依次赋给数组元素,读入值的个数与数组元素个数相等。读数据成功后,Put语句将下一个字节位置设为下一次读写的当前位置。读二进制文件将【例12.3】建立的文件进行备份,程序如下: Dim Char As Byte Open D:student.Dat For Binary As #1 Filenum2 = Freefile Open D:student.Bak For Binary As #2 Do While Not EOF(1) Get #1, , Char Put #2, , Char Loop Close #1,#21Seek语句:Seek #filenumber, positionSeek语句将指定文件号的文件的下一个读写位置position(长整型)。随机文件的单位是记录号,二进制文件的单位是字节。2 Seek(filenumber)函数此函数返回filenumber指定文件的当前读写位置。返回值为长整型。3 Input(number, #filenumber)函数此函数从filenumber文件中从当前位置读入number指定的个数的字节,并作为字符串返回。这个函数只适合以顺序输入或二进制方式打开的文件。此函数读入的内容包括逗号、回车符、空白列、换行符、引号和前导空格等一起读入。4 EOF(filenumber)此函数测试当前是否位于指文件号文件的末尾。是,返回True;否,则返回False。有的语句或函数在执行如果超出文件末尾,则会出错,应的使用前用本函数或LOF函数检测。5 LOF(filenumber)返回指定文件号filenumber所代表文件的长度,以字节为单位。6 FileLen(filename)此函数返回指定文件名的文件长度(字节为单位),文件不要求打开。如果文件打开,则返回的是打开前的文件长度。与随机(二进制)文件操作有关的函数与语句7 Freefile函数FreeFile(0|1)使用 FreeFile 提供一个尚未使用的文件号。参数指定文件号范围,FreeFile或FreeFile(0)返回1255之间未使用的文件号; FreeFile(1)返回256511之间未使用的文件号。8 Dir函数Dir函数用来测试指定文件或文件夹是否存在。被测试的文件和文件夹名可以包含通配符“*”(代表任意多个字符)和“?”(代表任意一个字符)。除了文件和文件夹的名称之外,还可以指定其属性。Dir(PathName,Attributes)其中字符串参数PathName指定文件或文件夹名,参数Attributes指定文件和文件夹的属性。Dir函数返回的是一个字符串类型值:如果PathName参数中没有使用通配符,当指定的文件或文件夹存在,则返回文件或文件夹的名称(不包括驱动号和目录结构),否则返回空字符串。如果PathName参数中使用了通配符,返回第一个符合条件的文件名或文件夹名(不包括驱动号和目录结构);如果下一次使用不带任何参数的Dir函数,则返回第二个符合条件的文件或文件夹名。这样连续使用不带参数的Dir可以返回所有符合条件的文件和文件夹名。当Dir返回空字符串时,表明所有符合通配符的文件和文件夹全部返回,这时,如果再使用不带任何参数的Dir函数就会导致出错。第一次调用Dir函数时必须指定PathName参数。打开【例12.5】9 Shell函数Shell(pathname,windowstyle)此函数执行filename指定的可执行文件。Windowstyle指定该运行时的窗口状态,如省略此参数,则以最小化方式启动。10 Kill 语句Kill filename 此语句从磁盘上删除filename指定的文件。Filename可使用* ?通配符。如果文件已打开,则不能删除。11 Filecopy 语句FileCopy source, destination把源文件source复制为目标文件destination。不能复制打开的文件。12 Name语句 Name oldpathname As newpathname 重命名。oldfilename与newfilename可以是文件也可以是文件夹。如果它们的路径不同,则可以移动文件或文件夹。13ChDrive 语句 ChDrive drive 改变当前驱动器。如果drive为“”,则当前驱动器将不会改变;如果drive中有多个字符,则ChDrive只会使用首字母。14MkDir 语句 MkDir path 创建一个新的目录。15ChDir 语句 ChDir path 改变当前目录。例如:ChDir D:TMP 16RmDir 语句 RmDir path 删除一个空目录。17CurDir函数 CurDir(drive) 利用CurDir函数可以确定任何一个驱动器的当前目录。如果drive为“”,则CurDir返回当前驱动器的当前目录。 如:某File1_DblClick()事件过程。 Sub File1_DblClick() ChDrive Drive1.Drive 设置缺省驱动器 ChDir File1.Path 设置缺省目录 RetVal = Shell(File1.FileName, 1) End Sub 又如事件过程File1_MouseDown(),使之支持Del键,即按下Del键删除选定的文件。 Sub File1_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyDelete ThenChDrive Drive1.DriveChDir File1.PathKill File1.FileNameFile1.Refresh 文件删除后更新文件列表框 End If End Sub八、上机补充题 建立一个具有3个学生三项内容的文本文件。三项内容为姓名、专业和年龄,前2项为字符串,最后一项为整型。分别利用Print #和Write #语句同时建立两个文件,文件名分别为C:T1.txt和C:T2.txt。文件创建后,单击“显示”按钮,以行读方式分别读入刚建立的两个文件,并显示在两个文本框中。运行结果如左图上所示。 设计如左图下所示的应用程序。要求如下: 选择打开打开某个文本文件。 选择保存保存文件。 选择“统计”分类统计出文件中数字字符、英文字符和汉字的个数。统计结果显示另一个窗体上。 提示:可以根据字符的ASC()函数值判断属于哪类字符,其中汉字字符的ASC()函数值为负的。 返回目录设计如下图所示的文件复制程序。选择复制命令,将在左边任意选定的文件复制到右边文件系统目录列表框指定的当前文件夹中。 设计如下图所示的应用程序,用于输入学生成绩,存放在随机文件C:S.dat中。如果选择“添加”,则把当前窗体上的数据作为一条记录添加到文件中。各数据项的长度由读者自己确定。第13章 数据库技术数据库表一、数据库概念 数据库就是一组排列成易于处理和读取的相关信息的集合。 关系模型已经成为数据库设计事实上的标准。数据库基本参考文献:1王珊,数据库系统概论(第四版) M。北京:高等教育出版社,2006.5。2杨海霞,数据库原理与设计 M。北京:高等教育出版社,2007.9。3李春葆,曾平,数据库原理与应用基于Access 2003(第2版)M。北京:清华大学出版社,2008.4 。4章立民,SQL Server 2000 中文版完全实战(入门篇) M。北京:中国铁道出版社,2001.7。5王小玲,刘卫国,数据库应用基础教程,M。北京:中国铁道出版社,2008.3。6匡松,何振林,数据库程序设计教程(修订版),科学出版社,2007.8关系数据库模型表间联系 一个数据库可以由多个表组成,表与表之间可以用不同的方式相互关联。若第一个表中的一条记录内容与第二个表中多条记录的数据相符,但第二个表中的一条记录只能与第一个表的一条记录的数据相符,这样的表间关系类型叫做一对多关系。 若第一个表的一条记录的数据内容可与第二个表的多条记录的数据相符,反之亦然,这样的表间关系类型叫做多对多关系。一对多关系主键按学号索引字段记录 可以将一个或几个表中的数据构成记录集Recordset对象(视图),记录集也由行和列构成,它与表类似。记录集数据库记录集VB与数据库的关系 在VB中数据库内的表格不允许直接访问,而只能通过记录集对象进行记录的操作和浏览,因此,记录集是一种浏览数据库的工具。数据库记录集建立和查询数据库的方法 可以利用Access、FoxPro、Microsoft SQL Server、Oracle、Sybase等数据库系统工具建立所需要的数据库。方法请见参考文献36,这里不再叙述。 结构化查询语言SQL是操作数据库的标准语言。在SQL语言中,指定要做什么而不是怎么做。不需要告诉SQL如何访问数据库,只要告诉SQL需要数据库做什么。 利用SQL,可以确切指定想要检索的记录以及按什么顺序检索。可以在设计或运行时对数据控件使用SQL语句。用户提出一个查询,数据库返回所有与该查询匹配的记录。使用SQL进行数据查询请见参考文献1、35。二、使用ADO访问数据库 ADO是Microsoft处理数据库信息的最新技术,它是一种ActiveX对象,采用了被称为OLE DB的数据访问模式。它是数据访问对象DAO、远程数据对象RDO和开放数据库互连ODBC三种方式的扩展。ADO对象模型更为简化,不论是存取本地的还是远程的数据,都提供了统一的接口。 ADO Data控件是可视的ADO对象,由三个对象成员(Connection、Command和Recordset)和几个集合对象(Errors、Parameters和Fields)组成,可以快速建立数据绑定的控件和数据提供者之间的连接。 ADO data控件使用灵活、适应性强,建议用户在开发新的数据库应用程序时使用ADO Data控件来替代内嵌的Data控件。 ADO对象模型 【例13.1】 编写一个简单的数据库浏览界面,以网格形式浏览xsgl.mdb数据库中xsqk表的数据,如图1所示。 操作方法与步骤如下: 添加ADO数据控件与DataGrid控件 在使用ADO数据控件前,必须先通过“工程/部件”菜单命令选择“Microsoft ADO Data Control 6.0(OLE DB)”和“Microsoft DataGrid Control 6.0(OLE DB)”选项,将ADO数据控件添加到工具箱,如图2所示。 ADO数据控件与Visual Basic的内部数据控件很相似,它允许使用ADO数据控件的基本属性快速地创建与数据库的连接。 将ADO数据控件与DataGrid控件添加到窗体中,ADO控件默认名为Adodc1,DataGrid控件的默认名为DataGrid1,如图3所示。使用ADO数据控件 要使用ADO控制访问数据库,通常需要进行以下三步操作,以与某个数据库连接。 设置ConnectionString属性,即通过什么方式连接数据库; 设置RecorfSource属性,确定具体可访问的据库,构成记录集对象Recordset; 设置ADO绑定控件及其属性,具体显示数据。 在使用ADO数据控件前,必须先通过“工程/部件”菜单命令选择“Microsoft ADO Data Control 6.0(OLE DB)”选项,将ADO数据控件添加到工具箱。ADO数据控件与Visual Basic的内部数据控件很相似,它允许使用ADO数据控件的基本属性快速地创建与数据库的连接。图2图3 数据源连接 选择数据源连接方式。右击Adodc1控件,选择菜单中的“ADODC”属性命令,打开控件“属性页”对话框,如图4所示。在这里能够利用三种记录集对象访问数据库中的数据,这里使用“使用连接字符串”方式。 单击“生成”按钮,打开“数据链接属性”对话框,如图5所示。图1图4 由于是第一次链接数据源,必须先选择一个数据源驱动程序,这里使用“Microsoft Jet 4.0 OLE DB Provider”方式,如图5所示。 单击“下一步”按钮,打开“数据链接属性连接”选项卡,如图6所示。图5图6在“1.选择或输入数据库名称”处,输入一个已知数据库名称(*/mdb),或单击“”按钮,打开“选择Access数据库”对话框,如图7所示。图7 选择一个Access数据库后,单击“打开”按钮,回到图6对话框,如图8所示。图8图9 单击“测试连接”按钮,可进行测试,如测试不成功,须重新设置数据库。 单击“确定”按钮,回到图4所示的“属性页通用”对话框,如图9所示。 完成数据源的连接数据源连接设置完成后,生成的连接字符串是: Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:MyDOCVB课件例子accessxsgl.mdb; Persist Security Info=False 单击“属性页”对话框中的“记录源”选项卡,如图10所示。选择“命令类型”为:2-adCmdTable(表);“表或存储过程名称”为:xsqk。 单击“确定”按钮,设置RecorfSource属性完成。 利用DataGrid控件来显示数据 选定DataGrid控件,将DataSource属性设置为Adodc1控件,即将网格产生的记录集。运行该程序,将看到结果,如图1所示。图10使用ADO数据控件访问数据库过程 VB应用程序访问数据库的过程为:首先使用ADO数据控件建立与数据库的连接;使用命令对象对数据库发出SQL命令,从数据库中选择数据构成记录集;应用程序对记录集进行操作。 数据库应用程序、ADO数据控件与数据库之间的关系如下图所示。 思考题:如果按下图所示,将“命令类型”为:2-adCmdText;“表或存储过程名称”为SQ命令: select xsqk.学号,xsqk.姓名,xsqk.性别,xscj.高等数学,xscj.大学英语,xscj.计算机基础 from xsqk,xscj where xsqk.学号=xscj.学号 显示结果如何? 应用程序ADO数据控件的其他属性、事件和方法 ADO数据控件的其他属性、事件和方法 EOFAction和BOFAction属性当记录指针指向Recordset对象的开始(第一个记录前)或结束(最后一个记录后)时,数据控件的EOFAction和BOFAction属性的设置或返回值决定了数据控件要采取的操作。当设置EOFAction为2(AdoAddNew)时,可向记录集加入新的空记录,在输入数据后,只要移动记录指针就可将新记录写入数据库。 Recordset属性产生ADO数据控件实际可操作的记录集对象。ADO产生的Recordset是一个象电子表格的集合。记录集对象中的每个字段值用Recordset.Fields(字段名)获得。 Refresh方法Refresh方法用于刷新ADO数据控件的连接属性,并能重建控件的Recordset对象。当在运行状态改变ADO数据控件的数据源连接属性后,必须使用Refresh方法激活这些变化。例如,在程序中执行了Adodc1.RecordSource= “xscj”,必须再执行Adodc1.Refresh命令,才能使记录集的内容从“xsqk”改变为“xscj”ge 。如果不使用Refresh方法,记录集的内容还是来源于“xsqk”表中的数据。 WillMove事件与MoveComplete事件当用某种方法改变记录集的指针使其从一条记录移到另一条记录,会产生WillMove事件。 MoveComplete事件发生在一条记录成为当前记录后,它出现在WillMove事件之后。三、绑定控件与应用在Visual Basic中,ADO控件本身不能直接显示记录集中的数据,必须通过能与它绑定的控件来实现。所谓绑定控件是指任何具有DataSource属性的控件。在绑定控件中,有些控件一次只能显示一条记录中的一个字段值,例如TextBox和Label控件;而另外一些控件可以同时显示多条记录,例如DataGrid、DBList和DBCombo控件。 要使绑定控件能被数据库约束,必须在设计或运行时对这些控件的两个属性进行设置: DataSource属性:通过指定一个有效的数据控件(Adodc)将绑定控件连接到一个数据源上。 DataField属性:设置数据源中有效的字段使绑定控件与其建立联系。绑定控件 绑定控件、数据控件和数据库三者的关系如下图所示,ADO数据控件建立数据绑定控件和数据提供者之间的连接。绑定控件、数据控件和数据库三者的关系并非所有的绑定控件能被ADO数据控件使用,只有具有OLE DB特性的控件才能被ADO数据控件绑定。可被ADO数据控件使用的绑定控件对象有文本框、标签、图像框、图形框、复选框、DB列表框、DB组合框、DB网格、MsChart和OLE容器等。当上述控件与数据控件绑定后,Visual Basic将当前记录的字段值赋予该控件。 绑定控件的简单应用简单数据绑定指所使用的绑定控件一次只能处理一条记录中的一个字段的内容。在窗体上要显示n项数据,就需要使用n个绑定控件。下面通过建立浏览“xsqk”窗口来说明数据绑定的操作过程,如下图所示。 【例13.2】 设计一个窗体,用以浏览“xsgl.mdb”数据库中“xsqk”表的内容,并具有编辑和添加新记录的功能,如图1所示。 在窗体上放置1个ADO数据控件、2个下拉列表框、4个文本框和6个标签控件。6个标签控件分别给出相关的提示说明。 建立连接和产生记录集 参照【例13.1】 中ADO数据控件数据源连接设置过程,建立与数据库“xsgl.mdb”的连接,设置ADO控件的EofAction属性为2(aDoAddNew),使窗体界面具有添加新记录的功能,如图2所示。 并指定记录源的命令类型为:“2-adCmdTable”,在表或存储过程名称为:“xsqk”表。图图1图图2图图3 下拉列表框和6个文本框控件Text1Text6的DataSource属性都设置成Adodc1。通过单击这些绑定控件的DataField属性上的“”按钮,将下拉出“xsqk”表所含的全部字段。分别选择与其对应的字段,使之建立约束关系。 为了能控制绑定控件数据显示格式,可对绑定控件的DataFormat属性进行设置,例如指定数值的小数位、日期格式等,如图3所示。 运行结果:运行该工程即可出现图1所示效果。使用数据控件对象的4个箭头按钮可遍历整个记录集中的记录。 当记录指在最后一条记录上时,再单击下一条记录的按钮,即可进入增加记录的状态。数据控件可以浏览Recordset对象中的记录外,同时具有编辑功能。如果改变了某个字段的值,只要移动记录,即可将修改后的数据存入数据库中。复杂数据与绑定控件的应用利用被ADO控件绑定的网格控件DataGrid、MSHFlexGrid、数据列表框DataList和数据组合DataCombo等,可以几乎不用编写代码就可以实现多条记录数据显示。DataGrid控件可显示文本内容,并具有编辑操作功能。MSHFlexGrid控件有图形功能,网格的单元格中可以同时存放文本和图片,对于具有相同内容的相邻单元格可实现单元格合并操作,但显示在MSHFlexGrid网格内的数据不能直接进行编辑操作。当把数据网格控件的DataSource属性设置为一个ADO控件时,网格控件会被自动地填充,并且网格的列标题会用ADO控件记录集内的字段名自动填充。下面通过例子来说明网格控件的使用。 【例13.3】 设计一个窗体,通过单击不同的命令按钮,在数据网格显示xsgl.mdb数据库中“xsqk”、“xscj”和“zymc”表的内容,产生右图所示的效果。 DataGrid控件不是VB工具箱内的默认控件,需要在开发环境中选择工程工程|部部件件菜单命令,并在随即出现的对话框中选择MicroSoft DataGrid Control 6.0(OLE DB)选项,将其添加到工具箱中。根据图1所示,在窗体上放置1个ADO数据控件、1个DataGrid控件和三个命令按钮Command13,完成ADO控件与数据源的连接,设置ADO控件的RecordSource为:xsqk。设置DataGrid控件的DataSource属性为Adodc1即可在网格上显示全部字段的数据。分别为Command13的Click事件编写代码:Private Sub Command1_Click() Adodc1.RecordSource = xsqk Adodc1.RefreshEnd Sub图图 数据库网格控件的效果 设计步骤如下: 【例13.4】 设计一个窗体,用数据网格显示“xsqk”表中的学生的学号、姓名、性别和出生年月,如图1所示效果。根据图1所示,在窗体上放置1个ADO数据控件、1个DataGrid控件,完成ADO控件与数据源的连接。 设置ADO控件命令类型为:1-adCmdText, 设置ADO控件的数据源RecordSource为: select xsqk.学号,xsqk.姓名,xsqk.性别,xsqk.出生日期,xsqk.入学总分 from xsqk where 性别=男 设置DataGrid控件的DataSource属性为Adodc1即可在网格上显示全部字段的数据。 程序分析和设计步骤如下:图图 1图图 2 显示在DataGrid网格内的记录集,可以通过DataGrid控件的AllowAddNew、AllowDelete和AllowUpdate属性设置控制增、删、改操作。也可在图2所示的DataGrid控件属性页内进行设置。如果要对网格显示的数据进行控制,可用鼠标右击DataGrid控件,在弹出的快捷菜单中选择“编辑”选项,进入数据网格字段布局的编辑状态。右击DataGrid控件,在弹出如图3所示的菜单中,选择“追加”命令,可增加一列。然后使用图2的“属性页列”选项卡,对列进行编辑,如图4所示。图图 4图图 3 最后,运行该工程。 AbsoloutPostion属性AbsolutePosition返回当前记录指针值,从1到Recordset对象所含记录数。例如:Adodc1.Caption = Adodc1.Recordset.AbsolutePosition数据控件的标题区会显示记录的序号。 BOF和EOF的属性BOF判定记录指针是否在首记录之前,若BOF为True,则当前位置位于记录集的第1条记录之前。与此类似,EOF判定记录指针是否在末记录之后。 注意:如果BOF和EOF的属性值都为True,则记录集为空。 BOF和EOF属性与AbsoloutPostion属性存在相关性。如果当前记录指针位于BOF,AbsoloutPostion属性返回AdPosBOF(-2);当前记录指针位于EOF,AbsoloutPostion属性返回adPosEOF(-3);记录集为空,AbsoloutPostion属性返回AdPosUnknown(-1)。四、记录集RecordSet的属性和方法记录集Recordset的常用属性 在VB中,数据库内的表格不允许直接访问,而是通过记录集Recordset对记录进行浏览和操作,并最终修改原始表记录。因此记录集是一种操作数据库的工具,下面按照对记录操作分类介绍记录集常用的属性和方法。 Bookmark属性系统为当前记录生成一个称为书签的标识值,包含在Recordset对象的Bookmark属性中,每个记录都有唯一的书签(用户无法查看书签的值)。要保存当前记录的书签,可将Bookmark属性的值赋给一个变体类型的变量。反之,通过设置Bookmark属性,可将Recordset对象的当前记录快速移动到设置为由有效书签所标识的记录上。RecordCount属性RecordCount属性对Recordset对象中的记录计数,该属性为只读属性。在多用户环境下,RecordCount属性值可能不准确,为了获得准确值,在读取RecordCount属性值之前,可使用MoveLast方法将记录指针移至最后一条记录上。记录集Recordset的常用方法Find方法使用Find方法可在Recordset对象中查找与指定条件相符的一条记录,并使之成为当前记录。如果条件不符合,则记录集指针将设置在记录集的末尾。Recordset.Find 搜索条件搜索条件 ,位移位移 , 搜索方向搜索方向, 开始位置开始位置 说明: 1搜索条件是一个字符串,包含用于搜索的字段名、比较运算符和数据。例如,语句Adodc1.Recordset.Find “学号 = s0801101 ”,表示在由Adodc1数据控件所连接的数据库xsgl.mdb的记录集内查找学号为s0801101的一条记录。这里,学号为记录集中的字段名。如果条件部分的数据来自变量,例如,xh=“s0801101,则必须使用字符串连接运算符&组合条件,&两侧必须加空格。例如: xh=“s0801101 Adodc1.Recordset.Find 学号= & & xh & 如果搜索的字段类型为数值型,则变量两侧不要加单引号。 当使用Like运算符时,常量值可以包含*,*代表任意字符。例如: Adodc1.Recordset.Find “学号Like s080110* ”,将在记录集内查找以“s080110”开始的所有学号,这样就可产生模糊查询的功能。2位移是可选项,其默认值为零。它指定从开始位置位移n条记录后开始搜索。3搜索方向是可选项,其值可为adSearchForward(向前)或adSearchBackward(向后)。 4开始位置是可选项,变体型书签,用作搜索的开始位置。 Move方法组 使用Move方法可代替对数据控件对象的4个箭头按钮的操作遍历整个记录集。5种Move方法是: 1MoveFirst方法移至第1条记录;2MoveLast方法移至最后一条记录;3MoveNext方法移至下一条记录;4MovePrevious方法移至上一条记录;5Move n 方法向前或向后移n条记录,n为指定的数值。如果n大于零,则当前记录位置将向前移动(向记录集的末尾)。如果n小于零,则向后移动(记录集的开始方向)。 【例13.5】 设计如下图所示的窗体,用命令按钮代替数据控件对象的4个箭头按钮的功能;增加一个“查找”按钮,通过inputBox()输入学号,使用Find方法查找记录。 程序设计步骤如下:在【例13.2】的基础上,增加5个命令按钮(本例用控件数组,按钮数组名为Command1),将ADO数据控件的Visible属性设置为False。通过对命令按钮的编程,使用Move方法就可使按钮具备移动记录的功能(本例不考虑记录集为空的情况)。 编写命令按钮组控件Click事件代码。(略) 注意:在使用Move方法将记录向前或向后移动时,需要考虑Recordset对象的边界,如果越出边界,就会引起一个错误。可在程序中使用BOF和EOF属性检测记录集的首尾边界,如果记录指针位于边界(BOF或EOF为真),则用MoveFirst方法定位到第1条记录或用MoveLast方法定位到最后一条记录。 对记录集中数据的增、删、改涉及到如下4个方法: AddNew方法:AddNew方法在记录集中增加入一个新行。 Delete方法:删除记录集中的当前记录。 Update方法:确定所做的修改并保存到数据源中。 CancelUpdate方法:取消未调用Update方法前对记录所做的所有修改。五、记录集RecordSet的编辑增加新记录 增加一条新记录通常要经过以下三步:调用AddNew方法,在数据表内增加一条空记录。给新记录各字段赋值。可以通过绑定控件直接输入,也可使用程序代码给字段赋值,用代码给字段赋值的格式为:Recordset.Fields.Item(字段名字段名) = 值值调用Update方法,确定所做的添加,将缓冲区内的数据写入数据库。 注意: 如果使用AddNew方法添加了新的记录,但是没有使用Update方法而移动到其他记录,或者关闭了记录集,那么所做的输入将全部丢失,而且没有任何警告。 从记录集中删除记录通常要经过以下三步:定位被删除的记录使之成为当前记录。调用Delete方法。移动记录指针。注意:在使用Delete方法时,当前记录立即删除,不加任何的警告或者提示。删除一条记录后,被数据库所约束的绑定控件仍旧显示该记录的内容。因此,必须移动记录指针刷新绑定控件,一般采用移至下一记录的处理方法。在移动记录指针后,应该检查EOF属性。 删除记录ADO有较高的智能,当改变数据项的的内容时,ADO自动进入编辑状态,在对数据编辑后,只要改变记录集的指针或调用Update方法,即可确定所做的修改。 注意:如果要放弃对数据的所有修改,必须在Update前使用CancelUpdate方法。 修改记录 【例13.6】 在【例13.5】的基础上加入新增、删除、更新和放弃4个按钮,通过对4个按钮的编程建立增、删、改功能,如图3所示。 程序设计步骤如下:本例使用控件数组加入4个按钮(按钮数组名为Command2),新增按钮的Click事件调用AddNew方法在记录集中增加入一个新行;更新按钮的Click事件调用Update方法,将新增记录或修改后的数据写入数据库;删除按钮的Click事件调用Delete方法删除当前记录;放弃按钮的Click事件调用CancelUpdate方法,取消未调用Update方法前对记录所做的所有修改。 编写命令按钮组控件Click事件代码。(略) 【例13.7】 利用“xsqk”和“zymc”表查找指定专业的学生信息,如图所示。 二进制大型对象(Binary Large Object,BLOB)是指任何需要存入数据库的随机大块字节流数据,如图形、声音、或是一个Word文档。数据库中存放BLOB数据的字段需要使用二进制类型,在数据库中对BLOB数据的写入与读出操作通过ADO的AppendChunk方法和GetChunk方法。六、BLOG数据处理把BLOB数据写入数据库 ADO的AppendChunk方法用于将BLOB数据追加到数据库的二进制字段中。其语法格式是: ADO对象.Recordset.Fields(字段).AppendChunk data其中,参数Data包含追加到数据库中的BLOB数据。 通常的处理步骤如下: 用二进制访问方式打开BLOB数据文件。定义一个字节类型的数组,数组大小为文件长度。将文件保存到数组。使用ADO对象的AppendChunk方法写入数据库。从数据库中读出BLOB数据 ADO的GetChunk方法用于取出数据库中的BLOB数据。其语法格式是: 变量=ADO对象.Recordset.Fields(字段).GetChunk(size)其中,参数Size为长整型表达式,读取字段内的数据的字节数。如果Size大于数据实际的长度,则GetChunk方法仅返回数据,而不填充空白。如果字段为空,则GetChunk 方法返回Null。每个后续的GetChunk 方法调用将检索从前一次GetChunk 调用停止处开始的数据。 【例13.8】 设计一个程序,实现功能:在浏览记录时显示照片;单击“图片输入”按钮,打开通用对话框,选择指定图形文件将数据写入到数据库。 程序设计步骤如下:根据图中所示,在窗体上放置1个ADO数据控件、5个标签L5、5个文本框Text15、1个图像控件Image1、1个通用对话CommonDialog1和1个命令按钮Command1,完成ADO控件与数据源的连接。 在Form_Load事件代码设置ADO控件的ConnectionString属性和CommandType属性。 设置Image1控件的DataSource属性为Adodc1。并设置Stretch属性为True,使图形能适应图像控件的大小。 编写命令按钮组控件Click事件代码。(略)在VB6.0中,Microsoft在系统中集成了数据报表设计器(Data Report Designer),从而使报表的制作变的更加方便。数据报表设计器属于ActiveX Designer组中的一个成员,在使用前需要执行“工程工程|添加添加Data Report”命令,将报表设计器加入到当前工程中,产生一个DataReport1对象,并在工具箱内产生一个“数据报表数据报表”标签,如下图所示。七、数据报表设计器标签控件在报表上放置静态文本文本控件在报表上连接并显示字段的数据图形控件可在报表上添加图片 线条控件在报表上绘制直线形状控件在报表上绘制各种各样的图形外形函数控件在报表上建立公式报表设计器的画面由若干区域组成,报表标头区包含整个报表最开头的信息,一个报表只有一个报表头,可使用标签控件建立报表名;报表注脚区包含整个报表尾部的信息,一个报表也只有一个注脚区;页标头区设置报表每一页顶部的标题信息;页注脚区包含每一页底部的信息;细节区包含报表的具体数据,细节区的高度将决定报表的行高。使用报表设计器处理的数据需要利用数据环境设计器创建与数据库的连接,然后产生Command对象连接数据库内的表。【例13.9】 使用xsgl.mdb数据库“xsqk”表,建立如下图1所示的报表。 建立报表的步骤如下: 建立新工程,在窗体上放置两个命令按钮,分别设置标题为“显示显示”和“打印打印”,如图2所示。图1图2执行“工程工程| Data Environent”命令,在当前工程内加入一个DataEnvironent1对象,如图3所示。用鼠标右击Connection1,选择快捷菜单中的“属性属性”选项,打开数据链接属性对话框,在“提供者提供者”选项卡内选择“Microsoft Jet 4.0 OLE DB Provider”,在“连接连接”选项卡内选择指定的数据库文件,完成与指定数据库的连接。 再次用鼠标右击Connection1,选择快捷菜单中的添加命令添加命令选项,在Connection1下创建Command1对象。 标右单击Command1,选择快捷菜单中的“属性属性”选项,打开Command1属性对话框,如图4所示,设置Command1对象连接的数据源为需要打印的数据表,产生图5所示结果。如果Command1对象不显示记录集的字段名,鼠标右单击DataEnvironent1,勾选快捷菜单中的“显示字段显示字段”选项,见图6所示。图3图5图4 执行“工程工程|添加添加Data Report”命令,将报表设计器加入到当前工程中,产生一个DataReport1对象,如图7所示。设置DataReport1的DataSource属性为数据环境DataEnvironent1对象,DataMember属性为Command1对象,使DataReport1从Command1对象获取数据源。 在页表头处,添加5个标签控件RptLabel15,调整好各控件的位置,并调整页表头和细节的高度。 在细节处添加5个文本框RptTextBox15,调整好各控件的位置。将5个文本控件的Datamember属性设置为:Command1;DataFields属性分别置为:学号、姓名、性别、出生日期和入学总分。图6图7 使用标签标签控件,通过标签的Caption属性在报表标头区插入报表名,页标头区设置报表每一页顶部的标题信息等,使用标签的Font属性设置字体大小。使用线条控件在报表内加入直线,使用图形控件和形状控件加入图案或图形。 要显示报表,可使用DataReport1对象的Show方法。在主控窗体的“显示”命令按钮或菜单的Click事件内加入代码: DataReport1.Show。 报表打印可直接使用预览窗口左上角打印按钮来控制,也可以使用DataReport1对象的PrintReport方法,使用PrintReport方法时可以配合一个Boolean值来控制是否显示打印对话框。在主控窗体的“打印”命令按钮或菜单的Click事件内加入代码: DataReport1. PrintReport True功能是为用户提供让用户选取打印机、打印范围、份数等操作。 使用预览窗口工具栏上导出导出按钮可将报表内容输出成文本文件或HTML文件,也可以使用DataReport1对象的ExportReport方法将报表内容输出成文本文件或HTML文件。 在Access或SQL Server下创建数据库,该数据库有xsqk表、xscj表和zymc表,如下图左所示。设计一个VB界面中实现学生信息的显示、添加、删除等功能,如下图右所示。八、上机补充题 在上题的基础上,增加一个登录窗体,当用户合法时,显示主窗体,否则退出运行程序。想一想,应该如何添加窗体及代码? 设计一个界面,实现浏览记录,插入记录,修改记录,删除记录等功能,如下图左所示。 输入姓名查询成绩信息,如左图上和左图下所示。 如右上图所示,单击左边的数据表名,右边就会显示相应记录 。返回目录
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号