《《数据库原理与应用(Access)》第9章VBA编程.ppt》由会员分享,可在线阅读,更多相关《《数据库原理与应用(Access)》第9章VBA编程.ppt(76页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第9 9章章 VBA编程编程【本章要点】通过本章的学习,可以了解到什么是VBA,并掌握Access2003的VBA编程环境VBE的操作,学会使用基础VBA语法,并用它来编写短小实用的模块,帮助我们更方便有效的使用Access。知识要点1、理解 VBA 概念2、掌握 VBA 编程环境 VBE的操作3、使用基础 VBA 语法本章学习内容本章学习内容n9.1 VBA编程环境n9.2 VBA语法n9.3 面向对象的程序设计基础9.1 VBA9.1 VBA编程环境编程环境9.1.1 VBA9.1.1 VBA简介简介虽然宏有很多功能,但是其运行速度比较慢,也不能直接运行Windows的程序,不能自定义函
2、数,如果要对数据进行特殊的分析或操作时,宏的能力就有限了。因此,微软创建了一种新的语言VBA(Visual Basic for Application),使用VBA可以创建“模块”,在其中包含执行相关操作的语句,它可以使Access自动化,可以创建自定义的解决方案。VBA是VB的子集,VB是微软公司推出的可视化Basic语言,用它来编程非常简单。它简单,而且功能强大,所以微软公司将它的一部分代码结合到Office中,形成今天所说的VBA。它的很多语法继承了“VB”,所以可以像编写VB语言那样来编写VBA程序,以实现某个功能。当这段程序编译通过以后,将这段程序保存在Access中的一个模块里,并
3、通过类似在窗体中激发宏的操作那样来启动这个“模块”,从而实现相应的功能。不单单是Access,其它的Office应用程序,如Excel,PowerPoint等都可以通过VBA来辅助设计各种功能。VBA是事件驱动的,简单来说,它等待能激活它的事件发生,比如说当鼠标被点击,一个键被按下或者一个表单被打开,等等。当事件发生时,VBA调用Windows操作系统的功能去实现“模块”中设定好的语句。这样看来,“模块”和“宏”的使用是差不多的。其实Access中的“宏”也可以存成“模块”,这样运行起来的速度还会更快。“宏”的每个基本操作在VBA中都有相应的等效语句,使用这些语句就可以实现所有单独“宏”命令。
4、模块是书写和存放VBA代码的地方。它是一个代码容器,可以将一段具备特殊功能的代码放入模块中,当指定的事件激活模块时,其中包含的代码对应的操作就会被执行。模块有两种形态:1标准模块标准模块简称“模块”,或称为“一般模块”。大多数模块都是标准模块,其中包含的代码和特定的数据库对象并无关联,当数据库中对象被移动时,模块还在原数据库中不动。标准模块包含与任何其他对象都无关的常规过程,以及可以从数据库任何位置运行的经常使用的过程。标准模块和与某个特定对象无关的类模块的主要区别在于其范围和生命周期。在没有相关对象的类模块中,声明或存在的任何变量、常量的值都仅在该代码运行时、仅在该对象中是可用的。2类模块类
5、模块可以包含新对象定义的模块。一个类的每个实例都新建一个对象。在模块中定义的过程成为该对象的属性和方法。类模块可以单独存在,也可以与窗体和报表一起存在。和窗体、报表相关联的分别称为窗口(form)模块和报表(report)模块,这种模块中的代码和特定的报表或窗口相关联。当对应的窗口或报表被移动到另一个数据库时,模块和其中代码通常也会跟着被移动。窗体模块(窗体模块:该模块中包含在指定的窗体或其控件上事件发生时触发的所有事件过程的代码。)和报表模块(报表模块:该模块中包含在指定报表或其控件上事件触发时的所有事件过程的代码。)都是类模块,它们各自与某一特定窗体或报表相关联。窗体模块和报表模块通常都含
6、有事件过程(事件过程:自动执行的过程,以响应用户或程序代码启动的事件或系统触发的事件。),过程的运行用于响应窗体或报表上的事件。可以使用事件过程来控制窗体或报表的行为,以及对它们操作的响应,如单击命令按钮。9.1 VBA9.1 VBA编程环境编程环境9.1.2 VBA代码编辑器代码编辑器(VBE)VBE就是VBA的代码编辑器,在Office的每个应用程序中都存在。可以在其中编辑VBA代码,创建各种功能模块。1.开启开启VBE有多种方式来打开VBE:在Access应用程序中,在菜单栏里单击【工具】|【宏】|VisualBasic编译器,打开VBE,如图9-1所示。在Access应用程序中,在菜单
7、栏里单击【插入】|【模块】或者【类模块】,打开VBE,并且直接在其中创建一个模块或类模块,如图9-2所示。图图9-1 打开打开VBE方法一方法一 图图9-2 打开打开VBE方法二方法二 刚打开数据库时,在对象栏中选中【模块】,然后选择【新建】,打开VBA,并在其中生成一个新的空标准模块。2.VBE窗口组成窗口组成如图9-3所示的VBE窗口。其中不包含任何代码。图图9-3 不包含代码的不包含代码的VBE窗口窗口VBE窗口可大体分为如图9-3中所标的六部分:(1)菜单栏:VBE中所有的功能都可以在菜单栏中实现。(2)帮助搜索:在图9-3中标号为2的位置,可以输入你所要查询的知识点,就会激活Visu
8、alBasic帮助,如图9-4中,就是在搜索栏中输入“属性”,按回车后,激活了VisualBasic帮助窗口,并把搜索到的相关条目列出,你再点击感兴趣的条目,就会打开MiscrosoftVisualBasic帮助文档,示条目的具体内容。图图9-4 帮助搜索和帮助文档帮助搜索和帮助文档 (3)工具栏:工具栏中包含各种快捷工具按钮,根据功能类型的不同各属于不同分组。比如:和代码编辑相关的工具按钮就属于“编辑”工具,和调试相关的工具按钮属于“调试”工具。(4)工程资源管理器:用来显示和管理当前数据库中包含的工程。刚打开VBE时,会自动产生一个与当前Access数据库同名的空工程,可以在其中插入模块。
9、一个数据库可以对应多个工程,一个工程可以包含多个模块。工程资源管理器窗口标题下面有三个按钮,分别为:“查看代码”,显示代码窗口,以编写或编辑所选工程目标代码;“查看对象”,显示选取的工程,可以是文档或是 UserForm 的对象窗口;“切换文件夹”,当正在显示包含在对象文件夹中的个别工程时可以隐藏或显示它们。(5)属性窗口:用来显示所选定对象的属性,同时可以更改对象的属性。“对象下拉列表框”是用来列出当前所选的对象,只能列出现用窗体中的对象。如果选取了好几个对象,则以第一个对象为准。“属性列表”:“按字母序”选项卡 按字母顺序列出所选对象的所有属性。“按分类序”选项卡 根据性质列出所选对象的所
10、有属性。可以折叠这个列表,这样将只看到分类;也可以扩充一个分类,并可以看到其所有的属性。当扩充或折叠列表时,可在分类名称的左边看到一个加号(+)或减号(-)图标。(6)主显示区域:用来显示当前操作所对应的主窗体。一般情况显示的是“代码窗口”,在其中可以编辑模块代码,如图9-5所示。9-5代码窗口代码窗口如果在【视图】菜单中,选择【对象浏览器】,在主显示区域中显示如图9-6中所示的对象浏览器窗口。如果选择【立即窗口】、【本地窗口】、【监视窗口】,在主显示区域的下端,显示出对应的窗口。9-6 对象浏览器对象浏览器立即窗口:在此窗中键入或粘贴一行代码,然后按下ENTER键立即执行该代码。立即窗口中的
11、代码是不能存储的。本地窗口:可自动显示出所有在当前过程中的变量声明及变量值。若本地窗口为可见的,则每当从执行方式切换到中断模式或是操纵堆栈中的变量时,它就会自动的重建显示。监视窗口:当工程中有定义监视表达式定义时,就会自动出现。也可以将选取的变量拖动到立即窗口或监视窗口中。提示提示:在VBE中的窗口都是可以移动的,你可以随意拖动窗口,设置出最适合自己编程习惯的窗口布局。9.2 VBA语法语法 和学习任何一门语言一样,想要使用VBA进行编程,必须先熟练掌握VBA的语法,它是VBA编程的工具。9.2.1 9.2.1 过程与函数过程与函数模块是VBA程序功能的基本单位,其中包含用VBA代码编写的操作
12、语句。模块又是由一个一个过程组成的,多个过程按一定的关系组成完整的模块。1.过程的概念:过程的概念:过程(Procedure),是有明显开始和结束标识的代码段,用来实现一个程序逻辑。它是有名字的语句序列,可作为单元来执行。例如,Function、Property和Sub都是过程类型。总是在模块级别定义过程的名称,所有可执行的代码必须包含在过程内,一过程不能套在其它过程中。在模块内的代码会被组织成过程,而过程会告诉应用程序如何去执行一个特定的任务。利用过程可将复杂的代码细分成许多部分,以便管理。过程按照其功能的不同分为3类,就是我们上面提到到Function过程、Property过程和Sub过程
13、。下面我们分别来介绍。2.Function2.Function过程:过程:Function过程的概念:FunctionFunction 过程通常被称为“函数”,是一系列由 Function Function 和 End End Function Function 语句所包含起来的 Visual Basic 语句。Function Function 过程可以返回一个值。FunctionFunction过程可经由调用者过程通过传递参数,例如常数、变量、或是表达式等来调用它。如果一个 FunctionFunction 过程没有参数,它的 FunctionFunction 语句必须包含一个空的圆括号。
14、函数会在过程中的一个或多个语句中指定一个值给函数名称来返回值。Function过程的用途:FunctionFunction程序会返回一个数据值,常用来返回计算的结果。VBA拥有许多内置函数,例如,Now()Now()函数会返回目前的日期和时间。除了这些内置函数外,用户还可以建立自己的函数(也就是所谓的用户自定义函数)。由于函数会返回值,因此可以在表达式中使用它们。在Access中的许多地方都可以在表达式中使用函数,包括在VBA表达式或方法中、在许多属性设置值之中或在筛选或查询中的准则表达式中。FunctionFunction过程的定义语法:声明 FunctionFunction 过程的名称,参
15、数以及构成其主体的代码。语法:Public|Private|Friend Function name (arglist)As typestatementsname=expressionEnd FunctionFunction语句的语法包含下面部分:部分描述Public可选的。表示所有模块的所有其它过程都可访问这个 Function 过程。如果是在包含 Option Private 的模块中使用,则这个过程在该工程外是不可使用的。Private可选的。表示只有包含其声明的模块的其它过程可以访问该 Function 过程。Friend可选的。只能在类模块中使用。表示该 Function 过程在整个
16、工程中都是可见的,但对于对象实例的控制者是不可见的。Function必需的。关键字,标示当前定义的是函数过程。name必需的。Function 的名称;遵循标准的变量命名约定。arglist可选的。代表在调用时要传递给 Function 过程的参数变量列表。多个变量应用逗号隔开。As type可选的。Function 过程的返回值的数据类型,可以是 Byte、Boolean、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(除定长)、Object、Variant或任何用户定义类型。如果不加,则函数没有返回值。stat
17、ements可选的。在 Function 过程中执行的任何语句组。name=expression可选的。设定Function过程的返回值。End Function必需的。关键字,标示函数过程的结束。Function过程的调用:在需要使用Function的过程中,可以直接用函数名(参数列表)来调用函数,也可以使用Call语句调用,Call函数名(参数列表)。如果函数有返回值,还可将函数放入表达式中使用。【例91】使用Function过程计算10的平方根。在本例中,要建立一个标准模块,然后在其中声明一个Function过程,用来开平方,再定义一个主过程,在其中调用Function过程计算10的平方
18、根,然后调用系统MsgBox,弹出对话框,显示计算结果。具体操作步骤如下:打开本书配套例子数据库tushu,在数据库对象管理窗口中,单击左侧【对象】组中的【模板】,再点击【新建】按钮,会自动打开VBE,并且新建一个只包含一个声明语句的空模块。块如图9.7,9.8所示。在代码窗口中添加如下代码:SubMain()MsgBox10的平方根是&CalculateSquareRoot(10)EndSubFunctionCalculateSquareRoot(NumberArgAsDouble)AsDoubleIfNumberArg10ThenA=A+1:B=B+A:C=C+B在块形式中,If语句必须是
19、第一行语句。其中的Else、ElseIf,和EndIf部分可以只在之前加上行号或行标签。If块必须以一个EndIf语句结束。要决定某个语句是否为一个If块,可检查Then关键字之后是什么。如果在Then同一行之后,还有其它非注释的内容,则此语句就是单行形式的If语句。Else和ElseIf子句都是可选的。在If块中,可以放置任意多个ElseIf子句,但是都必须在Else子句之前。If块也可以是嵌套的。当程序运行到一个If块(第二种)时,condition将被测试。如果condition为True,则在Then之后的语句会被执行。如果condition为False,则每个ElseIf部分的条件式
20、(如果有的话)会依次计算并加以测试。如果找到某个为True的条件时,则其紧接在相关的Then之后的语句会被执行。如果没有一个ElseIf条件式为True(或是根本就没有ElseIf子句),则程序会执行Else部分的语句。而在执行完Then或Else之后的语句后,会从EndIf之后的语句继续执行。【例93】使用IFELSE语句计算两个数的最大值。先来建立一个标准模块,然后在其中声明一个包含IFELSE条件分支Function过程,用来计算两个数的最大值,再定义一个主过程,用来获取要比较的两个数,然后调用Function过程计算最大值,最后调用系统函数MsgBox,弹出对话框,显示计算结果。具体操
21、作步骤如下:打开数据库tushu,在数据库对象管理窗口中,单击左侧【对象】组中的【模板】,再点击上面的【新建】按钮,会自动打开VBE,并且新建一个空模块。在代码窗口中添加如下代码:SubMain()DimintNumber1AsIntegerDimintNumber2AsIntegerintNumber1=InputBox(请输入要比较的第一个整数)intNumber2=InputBox(请输入要比较的第一个整数)DimstrMaxAsStringstrMax=CStr(MyMax(intNumber1,intNumber2)MsgBox最大值为:+strMaxEndSubFunctionMy
22、Max(aAsInteger,bAsInteger)AsIntegerIfabThenMyMax=aElseMyMax=bEndIfEndFunction单击F5或者点击VBE工具栏中的【运行按钮】,在弹出的“宏窗口”中单击【运行】按钮,就会运行项目中的模块,弹出输入窗口,如图9-12所示,在其中输入第一个要比较的数,单击确定;然后弹出第二个输入窗口,在其中输入第二个要比较的数,单击【确定】,模块会计算出最大值,并显示在对话框中。如图9-13所示图图9-12 输入窗口输入窗口图图9-13 弹出对话框弹出对话框 程序分析:在实例9.3中,定义了一个Function过程MyMax来比较两个整型数的
23、最大值,其中使用了IFELSE条件分支结构,当参数a大于参数b时,函数的返回值等于a;否则,函数的返回值等于b。Sub过程主过程调用了系统过程InputBox,用来获取用户输入的数值,将输入的两个整数作为参数传递给MyMax来进行比较。CStr函数用于将其他数据类型转换为字符串型。部分 描述Testexpression条件表达式必要参数。任何数值表达式或字符串表达式。expressionlist-n分支表达式如果有 Case 出现,则为必要参数。其形式为 expression,expression To expression,Is comparisonoperator expression的一
24、个或多个组成的分界列表。To 关键字可用来指定一个数值范围。如果使用 To 关键字,则较小的数值要出现在 To 之前。使用 Is 关键字时,则可以配合比较运算符(除 Is 和 Like 之外)来指定一个数值范围。如果没有提供,则 Is 关键字会被自动插入。statements-n表达式分支语句可选参数。一条或多条语句,当 testexpression 匹配expressionlist-n中的任何部分时执行。ElsestatementsElse分支语句可选参数。一条或多条语句,当 testexpression 不匹配 Case 子句的任何部分时执行。SelectCase语句使用单一表达式来作为分
25、支的条件,根据表达式的不同结果来执行多种可能的动作时,Select Case 更为有用。它的语法如下:SelectCasetestexpressionCaseexpressionlist-nstatements-n.CaseElseelsestatementsEndSelect Select Case语句的语法具有以下几个部分:如果testexpression匹配某个Caseexpressionlist表达式,则在Case子句之后,直到下一个Case子句的statements会被执行;如果是最后一个子句,则会执行到EndSelect。然后控制权会转移到EndSelect之后的语句。如果test
26、expression匹配一个以上的Case子句中的expressionlist表达式,则只有第一个匹配后面的语句会被执行。CaseElse子句用于指明elsestatements,当testexpression和所有的Case子句中的expressionlist都不匹配时,则会执行这些语句。虽然不是必须的,但是在SelectCase区块中,最好还是加上CaseElse语句来处理不可预见的testexpression值。如果没有Caseexpressionlist匹配testexpression,而且也没有CaseElse语句,则程序会从EndSelect之后的语句继续执行。可以在每个Case子
27、句中使用多重表达式或使用范围,例如,下面的语句是正确的:Case1To4,7To9,11,13,IsMaxNumberSelectCase语句也可以是嵌套的。但每个嵌套的SelectCase语句必须要有相应的EndSelect语句。【例94】使用SelectCase语句换算成绩建立一个标准模块,然后在其中声明一个包含SelecCase条件分支Function过程,用来将数字成绩换算为汉字表示的成绩,再定义一个主过程,用来获取当前要换算的成绩,然后调用Function过程进行换算,最后调用系统MsgBox,弹出对话框,显示结果。具体操作步骤如下:打开本书配套例子数据库tushu,在数据库对象管理
28、窗口中,单击左侧【对象】组中的【模板】,再点击上面的【新建】按钮,会自动打开VBE,并且新建一个空模块。在代码窗口中添加如下代码:SubMain()DimintNumber1AsIntegerintNumber1=InputBox(请输入好换算的成绩)MsgBox成绩等级为:+Grade(intNumber1)EndSubFunctionGrade(intGradeAsInteger)AsStringSelectCaseintGradeCase0To59Grade=不及格Case60To69Grade=差Case70To79Grade=中Case80To89Grade=良Case90To100
29、Grade=优CaseElseGrade=你所输入的成绩不在1-100之间EndSelectEndFunction如图9-14所示,在其中输入一个数值,单击【确定】;运行该模块,弹出如图9-15所示的对话框。如果输入个不在0-100范围内,弹出对话框,提示输入出错。图图9-14 输入窗口输入窗口图图9-15 弹出对话框弹出对话框程序分析:在实例9.4中,定义了一个Function过程Grade来换算成绩格式,其中使用了SelectCase条件分支结构,当参数intGrade的值在0-59间时,函数的返回值等于“不及格”,如此类推,将百分制成绩换算为中文的等级格式。当前面的值都不满足条件表达式时
30、,执行CaseElse后的语句。在本例中,就是当输入的值不在1-100之间时,将Grade的返回值设为你所输入的成绩不在1-100之间。主过程调用了系统过程InputBox,用来获取用户输入的成绩值,将输入的整数作为参数传递给Grade来进行格式转换。最终,在弹出窗口里显示执行结果。2 循环结构循环结构循环允许重复执行一组语句。某些循环重复执行语句直到条件为False;而有些循环重复执行语句直到条件为True。也有某些循环执行一指定次数的语句或是集合中的每一个对象。循环结构在VBA中有三种语法结构,Do.Loop:循环重复执行语句直到或当条件为True时For.Next:使用一个计数器来运行一
31、指定次数的语句ForEach.Next:在集合中对每个对象的一组的语句重复(1)Do.Loop语句:DoLoop语句根据循环逻辑的不同,可分“当循环”和“直到循环”两种,分别对应While关键字和Until关键字。在条件表达式之前使用While的“当循环”,当条件为True时才执行循环,如果条件为False,就结束循环。它有两种使用方法。可以在进入循环之前检查条件式,也可以在循环至少运行一次之后才检查条件式。在下面的ChkFirstWhile过程中,在进入循环之前检查条件。如果将myNum的值由20替换成9,则循环中的语句将永远不会运行。在ChkLastWhile过程中,在条件变成False之
32、前循环中的语句只执行一次。SubChkFirstWhile()counter=0myNum=20DoWhilemyNum10myNum=myNum-1counter=counter+1LoopMsgBoxTheloopmade&counter&repetitions.EndSubSubChkLastWhile()counter=0myNum=9DomyNum=myNum-1counter=counter+1LoopWhilemyNum10MsgBoxTheloopmade&counter&repetitions.EndSub在条件表达式之前使用Until的“直到循环”,在条件表达式的值为Fal
33、se时执行循环,直到条件表达式为True时,结束循环。当使用Until关键字去检查Do.Loop语句中的条件时,也可以使用两种方法。可以在进入循环之前检查条件(如同ChkFirstUntil过程所示),也可以在循环至少运行一次之后才检查条件(如同ChkLastUntil过程所示)。当条件仍然为False时,循环继续。SubChkFirstUntil()counter=0myNum=20DoUntilmyNum=10myNum=myNum-1counter=counter+1LoopMsgBoxTheloopmade&counter&repetitions.EndSubSubChkLastUnt
34、il()counter=0myNum=1DomyNum=myNum+1counter=counter+1LoopUntilmyNum=10MsgBoxTheloopmade&counter&repetitions.EndSub(2)ForNext语句:可以使用For.Next语句去重复一个语句块,而它运行的次数是指定的。For循环使用一个计数变量,当重复每个循环时它的值会增加或减少。下面的过程会让计算机发出响声50次。For语句会指定计数变量x的开始与结束值。Next语句会将计数变量的值加1。SubBeeps()Forx=1To50BeepNextxEndSubForEachNext语句:这个
35、循环语句用于遍历数组或者集合。依次从指定的数组或者集合读出一个值用于操作。当循环执行一次则VisualBasic会自动设置一个变量用来获取数组或集合的值。面的代码会在数组的每个元素中循环,并且将每个值设置成它的索引变量I的值。DimTestArray(10)AsInteger,IAsVariantForEachIInTestArrayTestArray(I)=INextI【例95】使用登录系统访问数据库窗口。先建立一个登录窗口,来验证用户名和密码,在建立一窗口来查看数据。建立一个标准模块,然后在其中编写登录逻辑,供登录窗口调用。最终效果是:当用户打开数据库,只能看到登录窗口,只有输入正确的用户
36、名和密码,才能查看显示数据的窗口。使用条件分支和循环语句,设置了验证次数限制,如果输入错误的用户名或密码超过一定数目,将自动关闭Access。具体操作步骤如下:打开数据库tushu,在数据库对象管理窗口中,单击左侧【对象】组中的【模板】,再点击上面的【新建】按钮,会自动打开VBE,并且新建一个空模块。在代码窗口中添加如下代码:OptionCompareDatabaseDimcountAsInteger定义模块级变量作为计数器PublicFunctionlogin(str1AsString,str2AsString)AsBooleanDimconAsadodb.ConnectionDimrecS
37、etAsadodb.RecordsetDimsqlAsStringDimfrmAsFormSetfrm=Forms!login获取对登录窗口的引用SetrecSet=Newadodb.RecordsetSetcon=Newadodb.Connectioncon.OpenProvider=Microsoft.Jet.OLEDB.4.0;Data_Source=C:tushu.mdb;按照自己存放数据库的位置填写Source属性DoWhilecount=2ThenMsgBox你已经无效登录4次!DoCmd.QuitEndIfEndFunction使用设计视图创建一登录窗体,更改其中一些窗体属性值,
38、如下:标题=登录,滚动条=两者皆无,记录选择器=否,导航按钮=否,分割线=否。如图9.16所示。然后在窗体中加入两个文本框,和两个按钮,其外观设计如图9.17所示。将两个标签标题分别改为“用户名”和“密码”,将两个文本框的名称分别改为“txtUser”和“txtPwd”。两个按钮标题分别设置为“登录”和“退出”。使得最终登录窗体的运行效果如图9.18所示。使用设计向导创建一显示数据的窗体,和数据库中的图书表相关联,用于显示图书表中数据,显示效果如图9.19所示为登录按钮设置单击事件过程,用来调用模块中的函数过程,判断用户输入的用户名和密码是否正确,代码如下。PrivateSubcmdLogin
39、_Click()Dimstr1AsString,str2AsStringDimbAsBooleantxtUser.SetFocusstr1=txtUser.TexttxtPwd.SetFocusstr2=txtPwd.Textb=login(str1,str2)IfbThenUnloadMeEndIfEndSub图图9.16 设置登录窗体属性设置登录窗体属性 图图9.17 登录窗体外观设计登录窗体外观设计 为退出按钮添加单击事件过程,用于退出Access程序PrivateSubcmdCancel_Click()DoCmd.QuitEndSub最后保存登陆窗体,将其命名为login点击菜单【工具
40、】|【启动】,弹出Access程序的启动设置窗口。设置login为启动窗体,并且不显示数据库其他部分,设置如图9.20所示,这样设置之后,只有通过登录窗体验证,才能访问图书窗体,而且保护了数据库内部信息。打开“工作人员”表,在“xm”列中输入想要设置的用户名;在“kl”列中输入想要设置的密码口令,在登录时,用作用户名和密码。关闭数据库,保存所有设置,再双击数据库,将其打开。这次看到的就只有登录窗体了,如果在限定的4次中没有输入正确的用户名或密码,Access程序就会自动关闭;如果输入正确,就会显示图书窗体,以供查看数据。图图9.18 登录窗体外观登录窗体外观9.19 图书窗体外观图书窗体外观9
41、.20 设置数据库启动项设置数据库启动项 程序分析:在实例9.5中,创建了两个窗体,login用于登录,图书用于查看图书表中数据。并且设定了登录窗体为Access程序的启动窗体,不通过登录验证,就不能访问数据库;通过验证后可以查看图书窗体。登录逻辑通过登录窗体中的登录命令按钮激活,在登录按钮的单击事件中被调用,书写在模块1里,即Public Function login。在模块1中,login函数过程之外,还定义了一个计数器count,用来记录错误登录次数,在DoWhile循环中,判断用户输入和数据库“工作人员”表中存放的用户名和密码是否相同,相同则登录,显示图书窗体;不同时,每错一次,cou
42、nt加一,如果错误超过4次,就退出Access程序。9.2.8 9.2.8 错误处理错误处理错误处理错误处理再好的程序员也避免不了出错。有两个原因会导致应用程序中出错。第一,在运行应用程序时某些条件可能会使原本正确的代码产生错误。例如,如果代码尝试打开一个已被删除的表,就会出错。第二,代码可能包含不正确的逻辑,导致不能运行所需的操作。例如,如果在代码中试图将数值被0除,就会出现错误。如果没有做任何错误处理,则在代码出错时VisualBasic将停止运行并显示一条出错消息,还会在代码窗口中定位到编译器认为有错误代码的语句,高亮显示。可是编译器提示的错误代码位置并不十分准确,还需要手动去查找。可以
43、使用VBE自带调试功能来观测程序每一步的执行,以便查找错误。一般的做法是:首先为可能出错的代码语句添加“断点”,用左键单击选定语句的【代码窗口】最左边即可,如图9-21所示。然后打开“本地窗口”,运行程序。这时,没当程序运行到设置断点的语句之前就会停下,就可以在“本地窗口”(图9-22)中查看当前代码中的对象,变量等。接着根据自身需要,选择菜单【调试】下的【逐语句】,【逐过程】或者【跳出】来继续程序的运行。图图9-21 设置了断点的代码语句设置了断点的代码语句图图9-22 本地窗口本地窗口VBA还有一套错误处理程序语句,将其包含在代码中来处理可能产生的所有错误,可以预防许多问题。有兴趣的读者可
44、以查看VBE中的帮助或相关资料来了解详细信息,在此不作详述。9.3面向对象的程序设计基础VBA不仅支持结构化的编程技术,更能很好的使用于面向对象的编程技术(ObjectOrientedProgramming,OOP)。面向对象的程序设计以对象为核心,以事件作为驱动,可以大提高程序的设计效率。9.3.19.3.1对象和类的概念对象和类的概念对象和类的概念对象和类的概念客观世界里的任何实体都可以看作是对象。对象可以是具体的物,也可以指某些概念。例如一台计算机、一个相机、一个窗体、一个命令按钮等都可以作为对象。每个对象都有一定的状态,对一个窗体的大小、颜色、边框、背景、名称等。每一个对象也有自己的行
45、为,如一个命令按钮的可以进行单击、双击等。使用面向对象的方法解决问题的首要任务是从客观世界里识别出相应的对象,并抽象出为解决问题所需要的对象属性和对象方法。属性用来表示对象的状态,方法用来描述对象的行为。类是客观对象的抽象和归纳,是对一类相似对象的性质描述,这些对象具有相同的性质:相同种类的属性以及方法。类好比是一类对象的模板,有了类定义后,基于类就可以生成这类对象中任何一个对象。9.3.29.3.2属性和方法属性和方法属性和方法属性和方法属性是对象所具有的物理性质及其特性的描述,通过设置对象的属性,可以定义对象的特征或某一方面的状态。如一个命令按钮的大小、标题、标题字号的大小、按钮的位置等就
46、是这个命令按钮的属性。方法用来描述一个对象的行为,对象的方法就是对象可以执行的操作。如命令按钮的单击事件,双击事件,按下鼠标和释放鼠标等事件。在VBA代码中引用对象的属性和方法的格式为:对象名属性名对象名方法名(参数1,参数2)例如将文本框Text1的值赋给变Name。Name=MeText1Value如将Command1的标题设置为“确定”。Command1Caption=“确定”9.3.3 9.3.3 事件和事件过程事件和事件过程事件和事件过程事件和事件过程 1事件事件事件是Access预先定义好的,能被对象识别的动作。事件作用于对象,对象识别事件并作出相应的反应,如单击事件(Click)
47、、双击事件(DblClick)、移动鼠标事件(MouseMove)等都能引起对象作出操作。事件是固定的,由系统定义好的,用户不能定义新的事件,只能引用。2事件过程事件过程事件过程是为事件的响应编写的一段程序,又称为事件响应代码。当对象的某一个事件被触发时,就会自动执行事件过程中的程序代码,完成相应的操作。事件的处理遵循独立性原则,即处个对象识别并处理属于自己的事件。例如,当单击窗体中的一个命令按钮时,将引发命令按钮的“单击(Click)”事件,而不会引发窗体的单击事件,也不会引发别的命令按钮的单击事件。如果没有指定命令按钮“单击(Click)”事件代码,该事件将不会有任何反应。3窗体事件的触发
48、顺序窗体事件的触发顺序Access窗体本身内置了许多事件,这些事件会被用户的动作所触发,且用户的一个动作可能触发窗体的多个事件。事件被触发是有先后顺序的,1)窗体第一次打开时依次触发的事件打开(Open)加载(Load)调整大小(Resize)激活(Activate)成为当前(Current)。打开(Open):在窗体已经打开,但第一条记录尚未显示时,“打开(Open)”事件发生。对于报表,事件发生在报表被预览或被打印之前。加载(Load):窗体打开并且显示其中记录时,“加载(Load)”事件发生。调整大小(Resize):在窗体打开后,只要窗体大小有变化,“调整大小(Resize)事件”就发
49、生。激活(Activate):“激活(Activate)”在窗体或报表获得焦点并成为活动窗口时发生。成为当前(Current):当把焦点移动到一条记录,使之成为当前记录时触发“成为当前(Current)”事件。2)关闭窗体时依次触发的事件卸载(Unload)停用(Deactivate)关闭(Close)卸载(Unload):“卸载(Unload)”事件发生在窗体被关闭之后,从屏幕上删除之前。当窗体重新加载时,Access将重新显示窗体并重新初始化其中所有控件的内容。对于报表,事件发生在报表被预览或被打印之前。停用(Deactivate):当焦点从窗体或报表移到“表”、“查询”、其它“窗体”等对
50、象时,“停用(Deactivate)”事件发生。关闭(Close):当窗体或报表被关闭并从屏幕删除时,“关闭(Close)”事件发生。窗体中有两个与获得焦点有关的事件“获得焦点(GotFocus)”事件与“失去焦点(LostFocus)事件,“激活”事件发性在“获得焦点”事件之前,“停用”事件发生在“失去焦点”事件之后。如果在两个已经打开的窗体之间进行切换,切换的窗体将发生“停用”事件,而切换到的窗体发生“激活”事件3)插入数据时依次触发的事件插入前(BeforeInsert)更新前(BeforeUpdate)更新后(AfterUpdate)插入后(AfterInsert)插入前(Before