对象sql2000挂起

sql2000挂起  时间:2021-03-01  阅读:()

第3章VBA编程基础3.
1VBA简介VBA(VisualBasicforApplication)是MicrosoftOffice系列软件的内置编程语言,VBA的语法与独立运行的VisualBasic编程语言互相兼容.
它使得在MicrosoftOffice系列应用程序中快速开发应用程序更加容易,且可以完成特殊的、复杂的操作.
3.
1.
1什么是VBA相信大多数的读者对于VB都比较熟悉,至少应该是听说过.
VB就是微软公司推出的可视化BASIC语言,用它来编程非常简单.
因为它简单,而且功能强大,所以微软公司将它的一部分代码结合到Office中,形成我们今天所说的VBA.
它的很多语法都继承自"VB",所以可以像编写VB语言那样来编写VBA程序,以实现某个功能.
当这段程序编译通过以后,Office将这段程序保存在Access中的一个模块里,并通过类似在窗体中激发宏的操作那样来启动这个"模块",从而实现相应的功能.

VBA提供了一个编程环境和一门语言,应用它可以自行定义应用程序以扩展Office的性能,将Office与其他软件相集成,并使Office一体化为一系列商业处理的一环.
通过使用VBA构建定制程序会使你充分利用Office提供的功能和服务.

3.
1.
2VBA的编程环境在Office中提供的VBA开发界面称为VBE(VisualBasicEditor),在VBE中可编写VBA函数和过程.
Access的VBE界面与Word、Excel和PowerPoint的VBA开发界面基本一致.
1.
VBE界面在Access中,,可以有多种方式打开VBE窗口.
可以先单击"数据库"窗口的"模块"快捷键,然后双击所要显示的模块名称,就会打开VBE窗口并显示该模块的内容;也可以单击数据库窗口工具条上的"新建"按钮,就会在VBE中创建一个空白模块;还可以通过在"数据库"窗口中,选择"工具"菜单的"宏"子菜单的"VisualBasic编辑器"命令打开VBE.
用VBE打开一个已有的Northwind数据库中的"启动"模块时,窗口如图3-1所示.
在图3-1所示的VBE窗口中,VBE界面由主窗口、工程资源管理器窗口、属性窗口和代码窗口组成.
通过主窗口的"视图"菜单可以显示其他的窗口,这些窗口包括:对象窗口、对象浏览器窗口、立即窗口、本地窗口和监视窗口,通过这些窗口可以方便用户开发VBA应用程序.

图3-1在VBE中打开模块(1)菜单VBE的菜单共有文件、编辑、视图、插入、调试、运行、工具、外接程序、窗口和帮助10个菜单.
各个菜单的说明如表3-1所示表3-1菜单及其说明菜单说明文件文件的保存、导入、导出等基本操作编辑基本的编辑命令视图控制VBE的视图插入进行过程、模块、类或文件的插入调试调试程序的基本命令,包括监视、设置断点等运行运行程序的基本命令,如运行、中断等命令工具用来管理VB的类库等的引用、宏以及VBE编辑器的选项外接程序管理外接程序窗口设置各个窗口的显示方式帮助用来获得MicrosoftVisualBasic的链接帮助以及网络帮助资源(2)工具栏默认的情况下在VBE窗口中显示的是标准工具栏,用户可以通过"视图"菜单的"工具"子菜单来显示"编辑"、"调试"和"用户窗体"工具栏,甚至是自行定义工具栏的按钮.
标准工具条上包括了创建模块时常用的命令按钮,关于这些命令按钮及其功能的介绍如表3-2所示.

表3-2标准工具栏常用按钮功能按钮按钮名称功能视图MicrosoftAccess按钮切换Access2000窗口插入按钮单击该按钮右侧箭头,拉出列表,含有"模块"、"类模块"和"过程"过程三个选项,选一项即可插入新模块运行子过程/用户窗体按钮运行模块中的程序续表按钮按钮名称功能中断按钮中断正在运行的程序重新设置按钮结束正在运行的程序设置模式按钮在设计模式和非设计模式之间切换工程资源管理器按钮用于打开工程资源管理器属性窗口按钮用于打开属性窗口对象浏览器按钮用于打开对象浏览器(3)窗口在VBE窗口中,提供了工程资源管理器窗口、属性窗口、代码窗口、对象窗口、对象浏览器窗口、立即窗口、本地窗口、监视窗口等多个窗口,可以通过"视图"菜单控制这些窗口的显示.
下面对常用的工程资源管理器窗口、属性窗口、代码窗口做简单的介绍.

①工程资源管理器窗口"工程资源管理器"的列表框列出了在应用程序中用到的模块文件.
可单击"查看代码"按钮显示相应的代码窗口,或单击"查看对象"按钮,显示相应的对象窗口,也可单击"切换文件夹"按钮,隐藏或显示对象文件夹.

②属性窗口"属性窗口"列出了所选对象的各种属性,可"按字母序"和"按分类序"查看属性.
可以编辑这些对象的属性,这通常比在"设计窗口"中编辑对象的属性要方便和灵活.
为了在"属性窗口"显示Access类对象,应先在"设计视图"中打开对象.
双击"工程窗口"上的一个模块或类,相应的"代码窗口"就会显示相应的指令和声明,但只有类对象在"设计视图"中也打开时,对象才在"属性窗口"中被显示出来.

③代码窗口在"代码窗口"中可以输入和编辑VBA代码.
可以打开多个"代码窗口"来查看各个模块的代码,而且可以方便地在"代码窗口"之间进行复制和粘贴.
"代码窗口"对于代码中的关键字以及普通代码通过不同颜色加以区分,使之一目了然.

2.
在"代码窗口"中编程VBE的"代码窗口"包含了一个成熟的开发和调试系统.
在"代码窗口"的顶部是两个组合框,左边是对象组合框,右边是过程组合框.
对象组合框中列出的是所有可用的对象名称,选择某一对象后,在过程组合框中将列出该对象所有的事件过程.
在"工程资源管理器"窗口中双击任何Access类或模块对象都可以在"代码窗口"中打开相应的代码,然后就可以对它进行检查、编辑和复制.

进行过VB编程的用户,一定对于VB的方便友好的编程界面十分喜欢.
VBE继承了VB编辑器的众多功能,例如自动显示快速信息、快捷的上下文关联帮助以及快速访问子过程等功能.
如图3-2所示,在代码窗口中输入命令时,VBA编辑器自动显示关键字列表供用户参考和选择.

图3-2自动显示快速信息应用上述的"代码窗口"的优秀功能,用户可以轻松地进行VBA应用程序的代码编写.
正确地编写VBA应用程序的代码,首先要注意的就是程序的书写格式,下面做简要的介绍.
(1)注释语句通常,一个好的程序一般都有注释语句.
这对程序的维护以及代码的共享都有重要的意义.
在VBA程序中,注释可以通过使用Rem语句或用"'"号实现.
例如下面的代码中分别使用了这两种方式进行注释.

Rem声明两个变量DimMyStr1,MyStr2AsStringMyStr1="Hello":RemMyStr1赋值为"Hello"MyStr2="World"'MyStr2MyStr1赋值为"World"其中Rem注释在语句之后要用冒号隔开,因为注释在代码窗口中通常以绿色显示,因此可以避免写错.
(2)连写和换行通常情况下,程序语句为一句一行,但有时候对于十分短小的语句,可能需要在一行中写几句代码,这时需要用到":"来分开几个语句.
对于太长的代码可以用到空白加下划线"_"将其截断为多行.

3.
2VBA基础知识3.
2.
1数据类型VBA同其他的编程语言一样,都要对数据进行操作.
为此,VBA支持多种数据类型,为用户编程提供了方便.
表3-3列出了VBA程序中主要的数据类型,以及它们的存储要求和取值范围.
表3-3VBA支持的数据类型数据类型类型名称存储空间取值范围Byte字节型1字节0到255Boolean布尔型2字节True或FalseInteger整型2字节-32768到32767续表数据类型类型名称存储空间取值范围Long长整型4字节-2147483648到2147483647Single单精度浮点型4字节负数:-3.
402823E38到-1.
401298E-45;正数:1.
401298E-45到3.
402823E38Double双精度浮点型8字节负数:-1.
79769313486232E308~-4.
94065645841247E-324;正数:4.
94065645841247E-324~1.
79769313486232E308Currency货币型8字节-922337203685477.
5808~922337203685477.
5807Decimal十进制小数型14字节无小数点时:+/-79228162514264337593543950335有小数点时又有28位数时:+/-7.
9228162514264337593543950335;最小的非零值:+/-0.
0000000000000000000000000001Decimal数据类型只能在Variant中使用Date日期型8字节100年1月1日到9999年12月31日Object对象4字节任何对象引用String(fixed)定长字符串10字节+字符串长0到大约20亿String(variable)变长字符串字符串长1到大约65400Variant(数字)变体数字型16字节任何数字值,最大可达Double的范围Variant(字符)变体字符型22字节+字符串长与变长String有相同的范围Type自定义类型所有元素所需数目每个元素的范围与它本身的数据类型的范围相同.
其中Variant数据类型是所有没被显式声明为其他类型变量的数据类型.
Variant是一种特殊的数据类型,除了定长String数据及用户定义类型外,可以包含任何种类的数据.
Variant也可以包含Empty、Error、Nothing及Null等特殊值.
通常,数值Variant数据保持为其Variant中原来的数据类型.
可以用Variant数据类型来替换任何数据类型,这样会更有适应性.
Empty值用来标记尚未初始化的Variant变量.
内含Empty的Variant在数值的上下文中表示0,如果是用在字符串的上下文中则表示零长度的字符串("").
Null是表示Variant变量含有一个无效数据.
在Variant中,Error是用来指示在过程中出现错误时的特殊值.
这可以让程序员,或应用程序本身,根据此错误值采取另外的行动.

和其他的语言类似,VBA可以自定义数据类型,使用Type语句就可以实现这个功能.
用户自定义类型可包含一个或多个某种数据类型的数据元素、数组或一个先前定义的用户自定义类型.
Type语句的语法为:TypeTypeName定义语句EndType例如下面的Type语句,定义了MyType数据类型,它由MyFirstName、MyLastName、MyBirthDate和MySex组成.
TypeMyTypeMyFirstNameAsString'定义字符串变量存储一个名字.
MyLastNameAsString'定义字符串变量存储姓.
MyBirthDateAsDate'定义日期变量存储一个生日.
MySexAsInteger'定义整型变量存储性别EndType3.
2.
2变量、常量、数组和表达式VBA代码中声明和使用指定的常量或变量来临时存储数值、计算结果或操作数据库中的任意对象.
1.
变量的声明声明变量有两个作用,一是指定变量的数据类型,二是指定变量的适用范围.
VBA应用程序并不要求在过程中使用变量以前明确地进行声明.
如果使用一个没有明确声明的变量,VisualBasic会默认地将它声明为Variant数据类型.
虽然默认的声明很方便,但可能会在程序代码中导致严重的错误.
因此使用前声明变量是一个很好的编程习惯.
在VBA中可以强制要求在过程中使用变量前必须进行声明,方法是在模块通用节中包含一个OptionExplicit语句.
它要求在模块级别中强制对模块中的所有变量进行显式声明.
使用Dim语句来声明变量,该语句的功能是:声明变量并为其分配存储空间.
Dim语句的语法如下:DimVariable_NameAsDataType其中变量名称可以像命名字段名一样,但是变量名不能包括空格键或其他字符(除了下划线"_").
另外变量不能使用VBA关键字作为名字,因为关键字也称为保留字.
例如下面声明了字符串变量MyName.

DimMyNameAsString声明之后,就可以通过表达式给它赋值.
可以在同一行内声明多个变量.
例如,DimVar1,Var2AsInteger,Var3AsString其中Var1的类型为Variant,因为声明时没有指定它的类型.
在变量声明时,对于用户自定义的数据类型与常规的数据类型没有区别,只要在使用之前定义了该数据类型即可.
2.
常量的声明常量可以看作是一种特殊的变量,它的值经设置后就不能够更改或赋予新值.
对于程序中经常出现的常数值,以及难以记忆且无明确意义的数值.
使用声明常量可使代码更容易读取与维护.
使用Const语句来声明常数并设置其值,Const语句的语法为:ConstConst_Name=expression例如,下面的语句声明了一个常数PI.
ConstPI=3.
1415926同样的可以在同一行里声明多个常量.
3.
变量和常量的作用域变量和常量的作用域决定变量在VBA代码中的作用范围.
变量在第一次声明时开始有效,用户可以指定变量在其有效范围可以反复出现.
一个变量有效,被称为是可见的,意味着可为其赋值,并可在表达式中使用它.
否则变量是不可见的.
当变量不可见时使用这个变量,实际是创建一个同名的新变量.
对于常量也是一样.

可以在声明变量和常量的时候,对它的作用域作相应的声明,如果希望一个变量能被数据库中所有过程所访问,需要在声明时加上Public关键字.
可以用Private语句显式地将一个变量的适用范围声明为在模块内,但这不是必须的,因为Dim和Static所声明的变量默认为在模块内私有.

下面的语句使用Public关键字声明Var1可以在整个程序中引用,而第二句所声明的变量Var2只能被变量所在的模块使用.
对于常量情况完全一样.
PublicDimVar1AsStringDimVar2AsString4.
静态变量和非静态变量使用Dim语句声明的变量,在过程结束之前,一直保存着它的值,但如果在过程之间调用时就会丢失数据,这种变量称为非静态变量,与之对应的是静态变量.
可以使用Static语句声明静态变量,使用Static声明的变量在模块内一直保留其值,直到模块被复位或重新启动.
即便是在非静态过程中,用Static语句来显式声明只在过程中可见的变量,其存活期也与定义了该过程的模块的存活期一样长.

Static语句的语法与Dim相同,只是将Dim关键字换为Static而已.
下面的语句声明了一个静态变量MySex.
StaticMySexAsBoolean清除过程中的静态变量的方法是:选择"运行"菜单的"重新设置"命令.
也可以用Static关键字来声明函数和子程序,以便在模块的生存期内保留函数和子程序内的所有局部变量.
5.
数组可以用一个数组来表示一组具有相同数据类型的值.
数组是单一类型的变量,可以存储很多值,而常规的变量只能存储一个值.
定义了数组之后,可以引用整个数组,也可以只引用数组的个别元素.
数组的声明方式和其它的变量是一样的,它可以使用Dim、Static、Private或Public语句来声明.
标量变量(非数组)与数组变量的不同在于通常必须指定数组的大小.
若数组的大小被指定的话,则它是个固定大小数组.
若程序运行时数组的大小可以被改变,则它是个动态数组.
数组是否从0或1开始索引可以根据OptionBase语句的设置,如果OptionBase没有指定为1,则数组索引从0开始.
也可以使用To子句进行设定.
若声明为动态数组,则可以在执行代码时去改变数组大小.
可以利用Static、Dim、Private或Public语句来声明数组,并使括号内为空.
下面的语句声明了三个数组,其中Array1是大小为11的数组,Array2是一个10*20的二维数组,而Array3则是动态数组.
DimArray1(10)AsStringDimArray2(1To10,1To20)AsStringDimArray3()AsString在使用数组变量的某个值时,只需引用该数组名并在其后的括号中赋以相应的索引即可.
6.
表达式表达式用来求取一定运算的结果,由变量、常量、函数、运算符和圆括号构成,VBA中的包含丰富的运算符.
算术运算符、关系运算符、逻辑运算符和连接运算符,可以完成各种运算.
各种运算符及其描述依次如表3-4~3-7所示,具体的每个运算符的功能和用法这里就不作介绍.

表3-4算术运算符符号描述^求幂-负号*乘/除\整除Mod求余+加-减3-5比较运算符符号描述=等于不等于大于=大于等于Is对象引用比较表3-6逻辑运算符符号描述Not逻辑非And逻辑与Or逻辑或Xor逻辑异或Eqv逻辑等价Imp逻辑隐含表3-7连接运算符符号描述+或&字符串连接表达式就是由各种运算符将变量、常量和函数连接起来构成的.
但是在表达式的书写过程中要注意运算符不能相邻,乘号不能省略,括号必须成对出现.
对于包含多种运算符的表达式在计算时,将按预定顺序计算每一部分,这个顺序被称为运算符优先级.
各种运算符的优先级顺序为从函数运算符、算术运输符、连接运算符、关系运算符到逻辑运算符逐渐降低.
如果在运算表达式中出现了括号,则先执行括号内的运算,在括号内部,仍按运算符的优先顺序计算.

3.
2.
3程序控制语句VBA中的程序,按其语句代码执行的先后顺序,可以分为顺序程序结构、条件判断结构和循环程序结构.
对于不同的程序结构要采用不同的控制语句方能达到预定的效果.
下面介绍VBA中的这些控制语句.

1.
If条件句If语句利用应用程序根据测试条件的结果对不同的情况作出反应.
If条件语句有三种语形式,简单地介绍如下:(1)If…Then在程序需要作出"或者"的选择时,应该使用该语句.
该语句又有两种形式,分别为单行形式和多行形式.
单行形式的语法为:If条件Then语句其中,"条件"是一个数值或一个字符串表达式.
若"条件"为True(真),则执行Then后面的语句.
"语句"可以是多个语句,但多个语句要写在一行.
例如,IfI>10ThenA=A+II=0B=2*A多行形式的语法为:If条件Then语句EndIf可以看出,与单行形式相比,只是要执行的语句通过EndIf来标志结束,对于执行多条不方便写在同一行的语句时,使用这种形式会使代码整齐美观.
例如上面的那个条件句可以写成:IfI>10ThenA=A+II=0B=2*AEndIf(2)If.
.
.
Then.
.
.
Else如果程序必须在两种条件中选择一种,则使用If.
.
.
Then.
.
.
Else.
语法格式为:If条件Then语句Else语句EndIf若"条件"为True,则执行Then后面的语句;否则,执行Else后面的语句.
例如下面的代码,判断如果UpdateFlag的值为True则显示一条消息"UpdateSuccessfully",否则显示一条信息"Failed!
".
IfUpdateFlagThenMsgBox"UpdateSuccessfully"ElseMsgBox"Failed"EndIf(3)If…Then…ElseIf…Else如果要从三种或三种以上的条件中选择一种,则要使用If…Then…ElseIf…Else.
语法格式为:IF条件1Then语句ElseIf条件2Then语句[ElseIf条件2Then语句]…Else语句EndIf若"条件1"为True,则执行Then后的语句;否则,再判"条件2",为True时,执行随后的语句,依次类推,当所有的条件都不满足时,执行Else块的语句.
例如,下面的语句通过对销售额进行判断,给出雇员的评价和佣金.
IfSales>15000ThenCommission=Sales*0.
08Rating="Excellent"ElseIfSalses>12000AndSalses8000AndSalses表达式"几种形式.
每个Case后的语句都可包含一条或多条语句.
在程序执行时,如果有一个以上的Case子句与"检验表达式"匹配,则VBA只执行第一个匹配的Case后面的"语句".
如果前面的Case子句与都不匹配,则执行CaseElse子句中的"语句".
例如,下面改写上文If语句的雇员佣金的例子.
SelectCaseSalesCaseIs>15000Commission=Sales*0.
08Rating="Excellent"Case12000To15000Commission=Sales*0.
06Rating="Good"Case8000To12000Commission=Sales*0.
05Rating="Adequate"CaseElseCommission=Sales*0.
04Rating="NeedImprovement"EndSelect3.
Do…Loop语句在许多实例中,用户需要重复一个操作直到满足给定条件才终止操作.
例如,用户希望检查单词、句子或文档中的每一个字符,或对有许多元素的数组赋值.
循环就可用于这种情况下,一个较为通用的循环结构的形式是Do…Loop语句,它的语法如下:Do[{While|Until}条件][语句][ExitDo][语句]Loop或Do[语句][ExitDo][语句]Loop[{While|Until}条件]其中,"条件"是可选参数,是数值表达式或字符串表达式,其值为True或False.
如果条件为Null(无条件),则被当作False.
While子句和Until子句的作用正好相反,如果指定了前者,则当是真时继续执行,如果指定了后者,则当为真时循环结束.
如果把While或Until子句放在Do子句中,则必须满足条件才执行循环中的语句;如果把While或Until子句放在Loop子句中,则在检测条件前先执行循环中的语句.

在Do.
.
.
Loop中可以在任何位置放置任意个数的ExitDo语句,随时跳出Do.
.
.
Loop循环.
ExitDo通常用于条件判断之后,例如If.
.
.
Then,在这种情况下,ExitDo语句将控制权转移到紧接在Loop命令之后的语句.
如果ExitDo使用在嵌套的Do.
.
.
Loop语句中,则ExitDo会将控制权转移到ExitDo所在位置的外层循环.
例如下面的代码,通过循环为一个数组赋值.
DimMyArray(10)AsIntegerDimiAsIntegeri=0DoWhilei<=10MyArray(i)=ii=i+1Loop4.
While…Wend语句在VBA中支持While…Wend循环,它与DoWhile…Loop结构相似,但不能在循环的中途退出.
它的语法为:While条件语句Wend如果条件为True,则所有的语句都会执行,一直执行到Wend语句.
然后再回到While语句,并再一次检查条件,如果条件还是为True,则重复执行,如果不为True,则程序会从Wend语句之后的语句继续执行.
While.
.
.
Wend循环也可以是多层的嵌套结构.
每个Wend匹配最近的While语句.
例如上面的Do…loop的代码,可以用While…Wend来实现,如下.
DimMyArray(10)AsIntegerDimiAsIntegeri=0Whilei<=10MyArray(i)=ii=i+1Wend在VBA中提供While…Wend结构是为了与BASIC的早期版本兼容,用户应该逐渐抛弃这种使用法,而使用Do.
.
.
Loop语句这种结构化与适应性更强的方法来执行循环.
5.
For…Next语句For循环可以将一段程序重复执行指定的次数,循环中使用一个计数变量,每执行一次循环,其值都会增加(或减少).
语法格式如下:For计数器=初值To末值[步长]语句[ExitFor]语句Next[计数器]其中,"计数器"是一个数值变量.
若未指定"步长",则默认为1.
如果"步长"是正数或0,则"初值"应大于等于"末值";否则,"初值"应小于等于"末值".
VBA在开始时,将"计数器"的值设为"初值".
在执行到相应的Next语句时,就把步长加(减)到计数器上.

在循环中可以在任何位置放置任意个ExitFor语句,随时退出循环.
ExitFor经常在条件判断之后使用(例如If.
.
.
Then),并将控制权转移到紧接在Next之后的语句.
可以将一个For.
.
.
Next循环放置在另一个For.
.
.
Next循环中,组成嵌套循环.
不过在每个循环中的计数器要使用不同的变量名.
下面的代码使用For…Next循环为MyArray数组赋值.
DimMyArray(10)AsIntegerDimiAsIntegerFori=0To10MyArray(i)=iNexti6.
ForEach…Next语句ForEach…Next语句针对一个数组或集合中的每个元素,重复执行一组语句.
语法格式为:ForEach元素In组或集合语句[ExitFor]语句Next元素For.
.
.
Each.
.
.
Next语句中的元素用来遍历集合或数组中所有元素的变量.
对于集合来说,这个元素可能是一个Variant变量、一个通用对象变量或任何特殊对象变量.
对于数组而言,这个元素只能是一个Variant变量.
组或集合是数组或对象集合的名称.

如果集合中至少有一个元素,就会进入For.
.
.
Each块执行.
一旦进入循环,便先针对组或集合中第一个元素执行循环中的所有语句.
如果在该组中还有其它的元素,则会针对它们执行循环中的语句,当组中的所有元素都执行完了,便会退出循环,然后从Next语句之后的语句继续执行.

可以在循环中任何位置放置任意个ExitFor语句,以便随时退出循环.
ExitFor经常在条件判断之后使用(例如If.
.
.
Then),并将控制权转移到紧接在Next之后的语句.
可以将一个For.
.
.
Each.
.
.
Next循环放在另一个之中来组成嵌套式For.
.
.
Each.
.
.
Next循环,但是每个循环的元素必须是唯一的.
下面的代码,定义一个数组并赋值,然后使用For.
.
.
Each.
.
.
Next循环在Debug窗口中打印数组中每一项的值.
Subdemo()DimMyArray(10)AsIntegerDimiAsIntegerDimxAsVariantFori=0To10'数组赋值MyArray(i)=iNextiForEachxInMyArray'For.
.
.
Each.
.
.
Next循环Debug.
Printx'打印数组中的每一项NextxEndSub运行时在Debug窗口中的输出如图3-3所示.
图3-3运行结果7.
With…EndWith语句With语句可以对某个对象执行一系列的语句,而不用重复指出对象的名称.
例如,要改变一个对象的多个属性,可以在With控制结构中加上属性的赋值语句,这时候只是引用对象一次而不是在每个属性赋值时都要引用它.
它的语法格式如下:With对象语句EndWith下面的例子显示了如何使用With语句来给同一个对象的几个属性赋值.
WithMyLabel.
Height=2000.
Width=2000.
Caption="ThisisMyLabel"EndWith当程序一旦进入With块,对象就不能改变.
因此不能用一个With语句来设置多个不同的对象.
可以将一个With块放在另一个之中,而产生嵌套的With语句.
但是,由于外层With块成员会在内层的With块中被屏蔽住,所以必须在内层的With块中,使用完整的对象引用来指出在外层的With块中的对象成员.

8.
Exit语句Exit语句用于退出Do.
.
.
Loop、For.
.
.
Next、Function、Sub或Property代码块.
它包含ExitDo、ExitFor、ExitFunction、ExitProperty和ExitSub几个语句.
下面的示例使用Exit语句退出For.
.
.
Next循环、Do.
.
.
Loop循环及子过程.
SubExitStatementDemo()DimI,MyNumDo'建立无穷循环.
ForI=1To1000'循环1000次.
MyNum=Int(Rnd*1000)'生成一随机数.
SelectCaseMyNum'检查随机数.
Case7:ExitFor'如果是7,退出For.
.
.
Next循环.
Case29:ExitDo'如果是29,退出Do.
.
.
Loop循环.
Case54:ExitSub'如果是54,退出子过程.
EndSelectNextILoopEndSub9.
GoTo语句无条件地转移到过程中指定的行,它的语法为:GoTo行标签其中行标签用来指示一行代码.
行标签可以是任何字符的组合,以字母开头,以冒号(:)结尾.
行标签与大小写无关,必须从第一列开始标注行标签.
GoTo语句将用户代码转移到行标签的位置,并从该点继续执行.

下面的示例使用GoTo语句在一个过程内的不同程序段间作流程控制,不同程序段用不同的行标签来区分.
SubGotoStatementDemo()DimNumber,MyStringNumber=1'设置变量初始值.
'判断Number的值以决定要完成那一个程序区段(以"行标签"来表式).
IfNumber=1ThenGoToLine1ElseGoToLine2Line1:行标签MyString="Numberequals1"GoToLastLine'完成最后一行.
Line2:行标签'下列的语句根本不会被完成.
MyString="Numberequals2"LastLine:'行标签Debug.
PrintMyString'将""Numberequals1""显示在"立即"窗口.
EndSub太多的GoTo语句,会使程序代码不容易阅读及调试.
在VBA中使用GoTo语句只有一个目的,就是用OnErrorGoToLabel语句处理错误.
3.
2.
4过程和模块过程是VBA代码的容器.
在VBA中有三种过程,分别是子过程、函数过程和属性过程.
虽然在某些情况下,三者的功能会有所重合,但是每种过程都有其独特的、唯一的用途.
而模块则是过程的容器.
模块有两种基本类型:类模块和标准模块.
模块中的每一个过程都可以是一个函数过程或一个子程序.

1.
子过程子过程是一系列由Sub和EndSub语句所包含起来的VBA语句,它们会执行动作却不能返回一个值.
使用子过程可以执行动作、计算数值以及更新并修改内置的属性设置.
Sub语句必须声明一个子过程名.
对于事件除了过程有非常程式化的名称,过程命名通常要遵循标准的变量命名约定,必须以字母开头,长度不能超过255个字符,不能包含空格和标点,不能是VBA的关键字、函数和操作符名称.
子过程可有参数,例如常数、变量、或是表达式等来调用它.
如果一个子过程没有参数,则它的子语句必须包含一个空的圆括号.

可以在VBE的代码窗口中直接输入代码编写子过程,例如下面的代码实现了两个简单的子过程.
其中Int_Add子过程求两个整数的和,并将其输出到立即窗口中,Demo子过程则调用Int_Add子过程求1和2的和.

SubDemo()CallInt_Add(1,2)'调用Int_Add子过程求1和2的和EndSubSubInt_Add(aAsInteger,bAsInteger)DimResultAsIntegerResult=a+bDebug.
PrintResultEndSub将这段代码粘贴到一个新建的模块中,单击工具栏上的"运行"命令按钮,在弹出的如图3-4所示的"宏"对话框中选择运行"Demo"子过程.
运行结果如图3-5所示.
图3-4"宏"对话框图3-5运行结果在Access的窗口设计视图中,使用工具栏的"控件向导"命令,在往窗体中添加控件的同时,会有向导提示自动生成30多个功能的VBA代码.
可以在窗体的设计视图中,将工具栏上的"控件向导"命令按钮激活.
例如,这时候选择按钮控件在窗体上绘制,然后出现如图3-6所示的"命令按钮向导",可以在其中选择不同的操作,则会依据所选的操作生成相应的子过程.

图3-6"命令按钮向导"这里选择了关闭窗口的操作,则生成了如下的关闭窗口的子过程代码.
PrivateSubClose_Cmd_Click()OnErrorGoToErr_Close_Cmd_ClickDoCmd.
CloseExit_Close_Cmd_Click:ExitSubErr_Close_Cmd_Click:MsgBoxErr.
DescriptionResumeExit_Close_Cmd_ClickEndSub2.
函数过程函数过程是一系列由Function和EndFunction语句所包含起来的VBA语句.
函数过程和子过程有两点不同,首先,函数可以返回一个值,所以在表达式中可以将其当作变量一样使用;其次,函数不能作为事件处理过程.
其他方面二者很类似,例如,Function过程可经由调用者过程通过传递参数,常数、变量、或是表达式等都可以来调用它.
函数要在过程的一个或多个语句中指定一个值给函数名称来返回值.

下面这个函数过程求两个整数的和,将这段代码粘贴在代码窗口中,可以通过在立即窗口中数据一个问号后接函数名来激活函数,如图3-7所示,激活这个函数求3与4的和为7.
FunctionInt_Sum(aAsInteger,bAsInteger)DimResultAsIntegerInt_Sum=a+bEndFunction图3-7在"立即窗口"中激活函数3.
属性过程Property过程是一系列的VisualBasic语句,它允许程序员去创建并操作自定义的属性.
Property过程可以用来为窗体、标准模块以及类模块创建只读属性.
声明Property过程的语法如下所示:[Public|Private][Static]Property{Get|Let|Set}属性名[(参数)][As类型]语句EndPropertyProperty过程通常是成对使用的:PropertyLet与PropertyGet一组,而PropertySet与PropertyGet一组,这样声明的属性既可读又可写.
单独使用一个PropertyGet过程声明一个属性,那么这个属性是只读的.
PropertySet与PropertyLet功能类似,都可以设置属性.
不同的是PropertyLet将属性设置为等于一个数据类型,而PropertySet则将属性设置等于一个对象的引用.
例如,下面的代码使用PropertyLet语句,定义给属性赋值的过程,使用PropertyGet语句,定义获取属性值的Property过程.
该属性用来标识画笔的当前颜色.
DimCurrentColorAsIntegerConstBLACK=0,RED=1,GREEN=2,BLUE=3'设置绘图盒的画笔颜色属性.
'模块级变量CurrentColor设为用于绘图的颜色值.
PropertyLetPenColor(ColorNameAsString)SelectCaseColorName'检查颜色名称字符串.
Case"Red"CurrentColor=RED'设为Red.
Case"Green"CurrentColor=GREEN'设为Green.
Case"Blue"CurrentColor=BLUE'设为Blue.
CaseElseCurrentColor=BLACK'设为缺省值.
EndSelectEndProperty'用一个字符串返回画笔的当前颜色.
PropertyGetPenColor()AsStringSelectCaseCurrentColorCaseREDPenColor="Red"CaseGREENPenColor="Green"CaseBLUEPenColor="Blue"EndSelectEndProperty'下面的代码通过调用Propertylet过程'来设置绘图盒的PenColor属性.
PenColor="Red"'下面的代码通过调用PropertyGet过程'来获取画笔的颜色.
ColorName=PenColor4.
类模块类模块包含新对象的定义的模块.
当创建类的新实例时,即创建新对象.
模块中定义的过程成为该对象的属性和方法.
类模块又三种基本变形:窗体类模块、报表类模块和自定义类模块.
窗体模块中包含了在指定的窗体或其控件的事件所触发的所有事件过程的代码.
这些过程用于响应窗体中的事件.
可以使用事件过程来控制窗体的行为,以及它们对用户操作的响应.
报表模块与窗体模块类似,不同之处是工程响应和控制的是报表的行为.

数据库的每一个窗体/报表都有内置的窗体/报表模块,这些模块包含事件过程模板.
可以向其中添加程序代码,使得当窗体/报表或其上的控件中发生相应的事件时,运行这些程序代码.
自定义类模块不与窗体和报表相关联,允许用户定义自己的对象、属性和方法.
5.
标准模块在标准模块,放置希望供整个数据库的其他过程使用的过程,这些过程不与任何对象相关联.
单击"数据库"窗口中的"模块"选项卡,可以查看数据库中标准模块的列表.
类模块和标准模块的不同点在于存储数据方法的不同.
标准模块的数据只有一个备份.
这意味着标准模块中一个公共变量的值改变以后,在后面的程序中再读取该变量时,它将得到改变后的值.
而类模块的数据,是相对于类实例(也就是,由类创建的每一对象)而独立存在的.

同样的,标准模块中的数据在程序作用域内存在,也就是说,它存在于程序的存活期中;而类模块实例中的数据只存在于对象的存活期,它随对象的创建而创建,随对象的撤消而消失.
最后,当变量在标准模块中声明为Public时,则它在工程中任何地方都是可见的;而类模块中的Public变量,只有当对象变量含有对某一类模块实例的引用时才能访问.
3.
3VBA的对象3.
3.
1理解对象、属性、方法和事件VBA是一种面向对象的语言,因此进行VBA的开发,必须理解对象、属性、方法和事件这几个概念.
学好VB的诀窍之一就是要以"对象"的眼光去看待整个程序设计,而这个诀窍对于VBA的学习来说也同样适用.
"对象"是面向对象程序设计的核心,明确这个概念对理解面向对象程序设计来说至关重要.
对象的概念来源自在生活之中.
对象就是一个事物,对象可以是任何东西:一座房子、一张桌子、一部电脑、一次旅行等等.
所以在现实生活中,我们随时随地都在和对象打交道.

如果把问题抽象一下,会发现这些现实生活中的对象有两个共同的特点:第一,它们都有自己的状态,例如一个球有自己的质地、颜色、大小;第二、它们都具有自己的行为,比如一个球可以滚动、停止或旋转.
在面向对象的程序设计中,对象的概念就是对现实世界中对象的模型化,它是代码和数据的组合,同样具有自己的状态和行为.
只不过在这里对象的状态用数据来表示,称为对象的属性;而对象的行为用对象中的代码来实现,称为对象的方法.
不同的对象有不同的方法,当然也不排除有部分重叠.

对于VBA来说,最重要VBA应用程序对象就是用户所创建的窗体中出现的控件,所有的窗体、控件和报表等都是对象.
而窗体的大小、控件的位置等都是对象的属性.
这些对象可以执行的内置操作就是该对象的方法,通过使用这些方法可以控制对象的行为.

在Access的"窗体设计视图"中,可以通过"属性"窗口查看和设置对象的各个属性,如图3-8所示,通过上面的列表框可以选择不同的对象进行查看.
图3-8查看对象的属性对象的事件是一种特定的操作,它在某个对象上发生或对某个对象发生.
例如发生在窗体上的鼠标单击、数据更改、窗体打开或关闭及许多其他类型的操作,都是事件.
通常情况下,事件的发生是用户操作的结果.
VBA是基于事件驱动编程模型的,事件驱动编程是应用程序中的对象响应用户操作.
在事件驱动的应用程序中,并不是按照预订的顺序执行,而是通过响应各种事件来运行不同的代码过程.
这些事件可以是由用户操作引起的,也可是来自系统、其他应用程序和应用程序的内部消息触发.
通过使用事件过程,可以为在窗体、报表或控件上发生的事件添加自定义的事件响应.

用户不必关心所使用的对象需要响应的事件类型,因为在Access中的每一个窗体和控件都有一个预定义的事件集,它们能够自动识别属于事件集中的事件.
对象所识别的事件类型多种多样,但多数类型为大多数控件所共有.
例如一个命令按钮和窗体都有可以对Click,Dblick这样的事件做出响应.
某些事件只可能发生在某些对象上.
相同事件发生在不同对象上所得到的反应是不一样的,造成这种差异是因为这些事件的事件过程不同.

类包含新对象的定义,通过创建类的新实例,可以创建新对象,而类中定义的过程就成为该对象的属性和方法.
可以通过"对象浏览器"窗口查看各个库中的类,从而可以了解使用这些类创建的对象的属性、方法和事件.
"对象浏览器"窗口如图3-9所示.
在窗口中可以查看各个库中的类的列表,在列表右侧的窗格中显示在类中定义的对象的属性、方法和事件.
其中以标志的是属性,标志的是方法,而标志的则是事件.
对于选中的属性、方法和事件,在窗口的最下方会有简单的说明.

图3-9"对象浏览器"窗口3.
3.
2VBA的对象句法前面介绍了对象和对象的属性、方法等概念,在编程的过程中需要引用对象、属性和方法.
属性和方法不能够单独使用,它们必须和对应的对象一起使用.
用于分隔对象和属性以及方法的操作符是".
",称作点操作符.

引用属性的语法为:对象.
属性名一般的属性都是可读写的,这样就可以通过上面的语法读取或是为属性赋值.
例如下面的代码读取MyForm对象的Width属性,设置MyForm对象的Caption属性.
Width=MyFrom.
WidthMyForm.
Caption="MyForm"引用方法的语法为:对象.
方法名(参数1,参数2…)如果引用的方法没有参数,则可以省略括号.
例如下面的代码引用MyForm对象的Refresh方法.
Form.
Refresh在Access中,要确定一个对象可能需要通过多重对象来实现.
例如要确定在MyForm窗体对象上的一个命令按钮控件Cmd_Button1.
需要使用加重运算符"!
"来逐级确定对象.
MyForm!
Cmd_Button13.
3.
4创建对象和类模块1.
创建对象创建对象的最简单方法是在窗体的"设计视图"中通过工具栏创建各种控件对象.
但是对这种方法可以创建的对象十分少,所以对于大多数对象需要通过用对象变量创建对象引用.
除了存储值以外,变量可引用对象.
如同给变量赋值一样,可把对象赋给变量.
且引用包含对象的变量比反复引用对象本身有更高的效率.
用对象变量创建对象引用,首先要声明变量.
声明对象变量的方法和声明其它变量一样,要用Dim、ReDim、Static、Private和Public.
语法如下:Dim|ReDim|Static|Private|Public对象变量As[New]类其中可选的New关键字可隐式地创建对象.
如果使用New来声明对象变量,则在第一次引用该变量时将新建该对象的实例,因此不必使用Set语句来给该对象引用赋值.
如果在对象变量的声明时,没有使用New关键字,则要使用Set语句将对象赋予变量.
Set对象变量=[New]对象表达式通常使用Set将一个对象引用赋给变量时,并不是为该变量创建该对象的一份副本,而是创建该对象的一个引用.
可以有多个对象变量引用同一个对象.
因为这些变量只是该对象的引用,而不是对象的副本,因此对该对象的任何改动都会反应到所有引用该对象的变量.
不过,如果在Set语句中使用New关键字,那么实际上就会新建一个该对象的实例.

例如下面的代码声明一个对象变量anyForm并使用New关键字隐式的创建对象,它可以引用应用程序中的任何窗体,声明了一个能够引用应用程序中的任何文本框anyText对象变量,然后用Set语句为anyText赋值.

DimanyFormAsNewFormDimanyTextAsTextBoxSetanyText=NewTextBox还可以利用CreateObject或GetObject函数,初始化对象变量.
CreateObject创建一个ActiveX对象并返回该对象,这样就可以将CreateObject返回的对象赋给一个对象变量实现变量的初始化.
如果要使用当前实例,或要启动该应用程序并加载一个文件,可以使用GetObject函数.

CreateObject函数的语法为:CreateObject(类名称)例如下面的代码创建一个到Word的引用.
DimWordAppAsObject'定义存放引用对象的变量.
SetWordApp=CreateObject("word.
application")GetObject返回文件中的ActiveX对象的引用,函数的语法为:GetObject(路径,类名称)其中"路径"用来指定包含对象的文件的路径和文件名.
例如下面的代码使用GetObject函数可以访问C:\CAD\SCHEMA.
CAD文件中的FIGMENT.
DRAWING对象,并将该对象赋给对象变量.
DimCADObjectAsObjectSetCADObject=GetObject("C:\CAD\SCHEMA.
CAD","FIGMENT.
DRAWING")虽然过程结束时,过程中声明的变量被取消了,但下面的做法仍不失为一个良好的编程习惯:使用对象变量显式地退出已经自动化的应用程序,并通过将对象变量设置为Nothing关键字来取消这个对象变量.
下面的示例过程示例了如何声明对象变量并赋值使用,在过程结束后取消对象变量.
SubSendDataToWord()'定义对象变量.
DimwdAppAsWord.
ApplicationDimwdDocAsWord.
Document'实例化对象变量.
SetwdApp=NewWord.
ApplicationSetwdDoc=wdApp.
Documents.
Add'在新文档中添加文本然后保存.
WithwdDoc.
Range.
Text="Automationiscool!
".
SaveAs"C:\AutomateWord.
doc".
CloseEndWith'取消对象变量.
SetwdDoc=NothingwdApp.
QuitSetwdApp=NothingEndSub要运行该过程,可以将以上代码复制到任意Access的代码模块中,然后在菜单中选择"工具"菜单的"引用"命令,在弹出的如图3-10所示的"引用"对话框中设置对Word对象库的引用,即可运行该段代码.
图3-10"引用"对话框2.
创建类模块用户可以自己编写类模块,以创建自定义的对象、属性和方法.
单击"插入"菜单中的"类模块"命令,可以新建一个类模块,这时可以在属性窗口中为类设置名称和Instancing属性.
类模块的属性窗口如图3-11所示.
其中名称属性用来指定类的名称,因为类模块是对象的构架,因此在为类命名时,最好用一个能够表达该类的功能的名称.
Instancing属性用来设置当用户设置了一个到该类的引用时,这个类在其他工程中是否可见.
这个属性有两个值:Private和PublicNonCreatable.
如果Instancing属性的值设置为Private,引用用户工程的工程在对象浏览器中不能够看到这个类模块,它也不能够使用这个类的实例进行工作.
如果设置为PublicNonCreatable,则引用工程可以在对象浏览器中看到这个类模块.
引用工程可以使用类模块的一个实例进行工作,但是被引用的用户工程要先创建这个实例.
引用工程本身不能够真正的创建实例.

可以通过"插入"菜单的"过程"命令向类模块中插入子过程、函数或属性.
"添加过程"对话框如图3-12所示,用户可以在通过该对话框选择添加的过程的种类,以及范围.
图3-11类模块的属性窗口图3-12"添加过程"对话框由于一个类模块代表了一个在运行时可按需要创建的对象,因此非常希望客户程序在开始使用对象或是退出它之后能够完成某些处理.
这就可以由Class_Initialize和Class_Terminate子过程来完成.
一旦对象被调入内存,在此对象的引用还没有返回到创建此对象的客户程序之前,他的Class_Initialize子过程就被调用.
当对象引用被设置为Nothing时,Class_Terminate子过程被调用.

下面是一个简单的类模块的例子,创建了一个名为"MyClass"的类.
在类模块中声明了一个模块级变量MyName,在对象初始化时,将MyName的值赋为"MyClass",用户可以通过Name属性来读取或是设置MyName变量的值.
在对象退出时将MyName变量赋为空字符串,代码如下.

OptionCompareDatabaseOptionExplicitDimMyNameAsString'声明模块级变量用来存储Name属性的值'返回属性值PublicPropertyGetName()AsVariantName=MyNameEndProperty'设置属性值PublicPropertyLetName(ByValvNewValueAsVariant)MyName=vNewValueEndProperty'对象初始化处理PrivateSubClass_Initialize()MyName="MyClass"EndSub'对象退出时处理PrivateSubClass_Terminate()MyName=""EndSub在下面的代码中,创建MyClass类的实例MyFirstClass对象,读取和设置该对象的Name属性,并通过立即窗口查看.
代码如下:PublicSubMyClass_Test()DimMyFirstClassAsMyClass'声明MyFirstClass对象SetMyFirstClass=NewMyClass'使用New关键字为MyFirstClass对象赋值Debug.
PrintMyFirstClass.
Name'在立即窗口中输出MyFirstClass对象Name属性值MyFirstClass.
Name="MyClassNewName"'为MyFirstClass对象Name属性赋新值Debug.
PrintMyFirstClass.
Name'在立即窗口中输出MyFirstClass对象Name属性值SetMyFirstClass=Nothing'退出MyFirstClass对象EndSub在立即窗口中的运行结果如图3-13所示.
图3-13运行结果3.
3.
5使用Access的对象模型Access对象是由Access定义的一种对象,它与Access界面或应用程序的窗体、报表和数据访问页相关,而且,可以用来对输入和显示数据所采用的界面的元素进行编程.
VBA通过使用Access的集合和对象可以操纵Access中的窗体、报表、页以及它们所包含的控件.
可以利用这些功能强调的存取对象来格式化和显示数据,并使得用户向数据库中添加数据成为可能.
另外,Access还提供了许多可以用来与Access应用程序一起工作的其他对象,例如CurrentProject、CurrentData、CodeProject、CodeData、Screen、DoCmd对象等.
可以利用"对象浏览器"和VBA的帮助来获得个别对象、属性、过程和事件的信息.
下面介绍一些常用的Access对象的使用.

1.
Application对象Application对象引用活动的MicrosoftAccess应用程序.
使用Application对象,可以将方法或属性设置应用于整个MicrosoftAccess应用程序.
在VBA中使用Application对象时,首先确认VBA对MicrosoftAccess10.
0对象库的引用,然后创建Application类的新实例并为其指定一个对象变量,如以下示例所示:DimappAccessAsNewAccess.
Application也可以通过用CreateObject函数来创建Application类的新实例:DimappAccessAsObjectSetappAccess=CreateObject("Access.
Application")创建Application类的新实例之后,可以使用Application对象提供的属性和功能创建和使用其他Access对象.
例如,可以使用OpenCurrentDatabase或NewCurrentDatabase方法打开或新建数据库;可以通过用Application对象的CommandBars属性返回对CommandBars对象的引用,可以使用该引用来访问所有的MicrosoftOfficeXP命令栏对象和集合.
还可以通过Application对象处理其他MicrosoftAccess对象.
下面的这段代码创建一个Application对象,使用Application对象的OpenCurrentDatabase方法打开NorthWind数据库,再使用它的子对象DoCmd的OpenForm方法打开"订单"窗体.
其中Application对象的OpenCurrentDatabase方法可以打开一个已有MicrosoftAccess数据库(.
mdb)作为当前的数据库.
OptionCompareDatabase'声明Application对象DimappAccessAsAccess.
ApplicationSubDisplayForm()'将字符串初始化为数据库路径.
ConststrConPathToSamples="C:\ProgramFiles\MicrosoftOffice\Office10\Samples\"strDB=strConPathToSamples&"Northwind.
mdb"'新建MicrosoftAccess实例.
SetappAccess=CreateObject("Access.
Application")'使用OpenCurrentDatabase方法在MicrosoftAccess窗口中打开数据库.
appAccess.
OpenCurrentDatabasestrDB'打开"订单"窗体.
appAccess.
DoCmd.
OpenForm"订单"EndSub2.
Form对象、Forms集合和Controls集合、Control对象Form对象引用一个特定的MicrosoftAccess窗体.
Form对象是Forms集合的成员,该集合是所有当前打开窗体的集合.
在Forms集合中,每个窗体都从0开始编排索引.
通过按名称或按其在集合中的索引引用窗体,可以引用Forms集合中的单个Form对象.
如果要引用Forms集合中指定的窗体,最好是按名称引用窗体,因为窗体的集合索引可能会变动.
如果窗体名称包含空格,那么名称必须用方括号([])括起来.
引用Forms集合中的单个Form对象的语法如表3-8所示.
表3-8引用Forms中Form的语法语法示例Forms!
formnameForms!
OrderFormForms!
[formname]Forms!
[OrderForm]Forms("formname")Forms("OrderForm")Forms(index)Forms(0)每个Form对象都有一个Controls集合,其中包含该窗体上的所有控件.
要引用窗体上的控件,可以显式或隐式地引用Controls集合.
例如下面的代码引用OrderForm窗体上名为NewData的控件:'隐式引用Forms!
OrderForm!
NewData'显式引用Forms!
OrderForm.
Controls!
NewData3.
Modules集合和Module对象Modules集合包含MicrosoftAccess数据库中所有打开的标准模块和类模块.
所有打开的模块都包含在Modules集合中,不论模块是未经编译的、已经编译的、处于中断模式还是包含正在运行的代码.
Module对象引用标准模块或类模块.
可以返回对Modules集合中特定的标准或类Module对象的引用.
下面的代码返回一个对Modules集合中指定窗体Module对象的引用并将其赋予一个模块对象变量.
DimMyModuleAsModuleSetMyModule=Modules!
Form_Employees4.
DoCmd对象使用DoCmd对象的方法,可以从VisualBasic运行MicrosoftAccess操作.
这些操作可以包括执行诸如关闭窗口、打开窗体和设置控件值等任务.
例如,可以使用DoCmd对象的OpenForm方法来打开一个窗体,或使用Hourglass方法将鼠标指针改为沙漏图标.
DoCmd对象的大多数方法都有参数,某些参数是必需的,其他一些是可选的.
如果省略可选参数,这些参数将被假定为特定方法的默认值.
下面的代码在"窗体"视图中打开一个窗体并移到一条新记录.
SubShowNewRecord()DoCmd.
OpenForm"Employees",acNormalDoCmd.
GoToRecord,,acNewRecEndSub3.
4VBA中数据库操作基本手段在VBA中可以使用传统的数据访问对象(DAO)和ActiveX数据对象(ADO)两种数据访问模型访问Access2002数据库.
3.
4.
1DAODAO使得用户可以通过编程操作本地或远程的数据库中的数据和对象.
DAO依赖于工作区对象模型来进行不同类型的数据访问.
有两种不同的工作区:MicrosoftJet工作区和ODBCDirect工作区.
1.
MicrosoftJet工作区MicrosoftJet工作区是为针对Jet、Jet连接的ODBC和可安装的ISAM数据源而设计的.
它使用微软的Jet数据库引擎连接数据库.
这种工作区的最大特点式可以连接不同的数据源的表到通用记录集.

2.
ODBCDirect工作区ODBCDirect工作区提供了对远程数据源(如SQLServer)的快速直接的访问,并且可以绕过Jet.
使用该工作区可以进行异步查询,实现更好的访问远程数据库.
3.
工作区的对象模型在MicrosoftJet工作区和ODBCDirect工作区中,DAO对象都符合同一种继承关系,不同的是二者的对象的种类有所差别.
图3-14是MicrosoftJet工作区中DAO对象模型示意图.
图3-15是ODBCDirect工作区中DAO对象模型示意图.
图3-14MicrosoftJet工作区中DAO对象模型示意图图3-15ODBCDirect工作区中DAO对象模型示意图在上面的图中,灰色的代表集合,白色的代表对象,将两个示意图相互对照可以看出两种工作区中对象的继承关系是一致的.
在VBA中通过创建这些对象,利用其方法和属性实现数据库中数据的访问.
3.
4.
2ADOADO使得程序员能够编写应用程序通过OLEDB提供者访问和操作数据库服务器中的数据.
它的主要优点是易于使用、速度快、内存支出低、占用磁盘空间少.
ADO定义了"编程模型",即访问和更新数据源所必需的一系列活动.
编程模型概括了ADO的完整功能.
编程模型提出"对象模型"(即"对象"集)来表达和实现编程模型.
对象具有"方法"和"属性",方法用于操作数据,属性用于表示数据属性或控制某些对象方法的行为.
与对象关联的是"事件",事件用于通知某些操作已经发生或即将发生.

ADO提供执行以下操作的方法:连接数据源.
可以确保对数据源的更改全部成功或全部失败.
指定访问数据源的命令,可选择带变量参数或优化执行.
执行命令.
如果命令导致数据按表中行的格式返回,则将这些行存储在易于检查、操作和更改的缓存中.
适当情况下,可使用缓存行中的更改内容来更新数据源.
提供检测错误(通常由建立连接或执行命令造成)的常规方法.
通常情况下,需要在编程模型中采用所有这些步骤.
但是,因为ADO具有很强的灵活性,所以只需要执行模型的一部分就能完成有用的工作.
1.
ADO编程模型的关键元素ADO编程模型的关键元素有连接、命令、参数、记录集、字段、错误、属性、记录、流、集合、事件.
下面依次对它们进行简单的介绍.
(1)连接通过"连接"可从应用程序访问数据源,连接是交换数据所必需的环境.
对象模型用Connection对象来体现连接的概念.
"事务"用于分隔在连接过程中发生的一系列数据访问操作的开始和结束.
ADO确保由事务中的操作造成的对数据源的更改全部成功或者全部失败.
如果事务被取消或它的一个操作失败,最终的结果是事务中的操作都不会发生.
数据源将保持事务开始前的状态.
对象模型没有明确体现出事务的概念,而是用一组Connection对象方法来表示.
ADO访问来自OLEDB提供者的数据和服务,Connection对象用于指定特定提供者和任意参数,作为连接目标的数据源可以通过连接字符串或统一资源定位符(URL)来指定.
(2)命令"命令"通过已建立的连接发出,它能以某种方式操作数据源.
命令通常可以在数据源中添加、删除或更新数据,或者以表中行的格式检索数据.
对象模型用Command对象来体现命令的概念,Command对象使得ADO能够优化执行命令.

(3)参数通常,命令需要的变量部分(即"参数")可以在命令发出之前进行更改.
例如,可重复发出相同的数据检索命令,但每一次都指定检索不同的信息.
参数对执行其行为类似函数的命令尤其有用.
在这种情况下,只需知道命令是做什么的,而不必知道它如何工作.
对象模型用Parameter对象来体现参数的概念.

(4)记录集如果命令是按表中的信息行返回数据的查询,这些行将存储在本地.
对象模型用Recordset对象来体现存储.
Recordset是在行中检查和修改数据的主要方法.
Recordset对象主要用于指定可以检查的行、遍历行、指定遍历行的顺序、添加、更改或删除行、用更改的行更新数据源、管理Recordset的总体状态等操作.

(5)字段Recordset的一行由一个或多个"字段"组成.
如果把Recordset看作二维网格,排成行的字段将构成"列".
每一字段(列)都分别具有名称、数据类型和值等属性.
正是在这个值中包含了来自数据源的实际数据.
对象模型用Field对象来体现字段.
要修改数据源中的数据,只需修改Recordset行中Field对象的值.
最终,对Recordset的更改被传播到数据源.

(6)错误错误随时会在应用程序中发生,通常是由于无法建立连接、无法执行命令或无法对处于某种状态的对象进行操作而引起的.
对象模型用Error对象来体现错误.
任何给定的错误都会生成一个或多个Error对象,随后发生的错误将放弃先前的Error对象集合.

(7)属性每个ADO对象都有一组唯一的"属性"来描述或控制该对象的行为.
有两种类型的属性:内置属性和动态属性.
内置属性是ADO对象的一部分并且随时可用.
动态属性由基本的数据提供者或服务提供者添加到ADO对象的Properties集合中,并且仅在使用该提供者时才存在.
对象模型用Property对象来体现属性.

(8)记录并非所有的数据源都以数据库表的形式存在.
文件和电子邮件系统等信息存储系统由"容器"和"内容"组件组成.
容器可以包含内容及其他从属容器.
在文件系统中,容器和内容分别是"目录"和"文件",而在电子邮件系统中,它们分别是"文件夹"和"邮件".
对象模型用Record对象来体现容器和内容.
另外,Recordset行也可以用Record对象来体现.

(9)流信息存储系统的"内容"(如文件系统中的"文件")由字节流组成.
"内存"中的缓冲区也是由字节流组成的.
对象模型用Stream对象来体现字节流.
Stream对象提供执行读取或写入一系列字节或文本行、从文件中自动预置,或持久保留到文件中等操作的方法(10)集合ADO提供"集合",它是一种对象,可方便地包含其他特定类型的对象.
使用集合属性可按名称(文本字符串)或序号(整数)对集合中的对象进行检索.
ADO提供了4种集合,分别是:Connection对象的Errors集合、Command对象的Parameters集合、Recordset和Record对象的Fields集合以及Connection、Command、Recordset和Field对象都具有的Properties集合.
每种集合对象都包含存储和检索适合该集合的其他对象的方法.
(11)事件"事件"是有关某些操作即将发生或已经发生的通知.
可以用事件有效地改写包含几个异步任务的应用程序.
对象模型不直接体现事件,而是通过调用事件处理程序例程来表示.
2.
ADO对象模型在ADO对象库中有Connection、Command、Recordset、Field、Error、Property、Paremeter和Stream8个对象,其中Connection、Command、Recordset、Field4个对象具有集合.
它们的关系如图3-16所示,其中灰色图例表示对象,白色表示集合.
图3-16ADO对象模型3.
ADO编程基本步骤在VBA中使用ADO模型对数据库编程的基本步骤是:首先连接到数据源;然后有选择地创建表示SQL查询命令的对象,并在SQL命令中将值指定为变量参数;接下来执行命令,查询或更新数据,并对返回的结果进行处理;最后结束事务,关闭连接.

下面的这个例子基本按照上面的步骤进行ADO编程,对于Northwind中的一个新建的较为简单的表"商品简表"中的数据进行操作.
代码如下:OptionCompareDatabasePublicSubMain()DimcnnAsNewADODB.
ConnectionDimcmdAsNewADODB.
CommandDimrstAsNewADODB.
Recordset'打开连接cnn.
Open"Provider=Microsoft.
Jet.
OLEDB.
4.
0;DataSource=C:\ProgramFiles\MicrosoftOffice\Office10\Samples\Northwind.
mdb;"'创建命令Setcmd.
ActiveConnection=cnn'用ActiveConnection属性确定Connection对象cmd.
CommandText="SELECT*from商品简表"'设置Command对象要执行的命令文本.
'执行命令rst.
CursorLocation=adUseClient'使用本地游标库提供的客户端的游标rst.
Opencmd,,adOpenStatic,adLockBatchOptimistic'打开表示记录的游标'处理数据rst!
id.
Properties("Optimize")=True'设置属性rst.
Sort="id"'排序rst.
Filter="供应商='佳佳乐'"'指定数据的过滤器rst.
MoveFirstDoWhileNotrst.
EOFDebug.
Print"id=";rst!
id;"";rst!
商品名;",供应商=";rst!
供应商'在立即窗口中输出rst!
供应商="美食佳佳乐"rst.
MoveNextLooprst.
Filter=adFilterNone'删除当前过滤器'更新数据cnn.
BeginTrans'开始新事务OnErrorGoToConflictHandler'出错则转到错误处理rst.
UpdateBatch'将所有挂起的批更新写入磁盘'更新成功则结束事务cnn.
CommitTrans'保存更改并结束当前事务ExitTutorial:OnErrorGoTo0rst.
Closecnn.
CloseExitSub'更新失败则事务回滚ConflictHandler:rst.
Filter=adFilterConflictingRecords'设置过滤器用于查看使最后一次批更新失败的记录rst.
MoveFirstDoWhileNotrst.
EOFDebug.
Print"Conflict:id=";rst!
id;";";rst!
商品名;供应商=";rst!
供应商rst.
MoveNextLoopcnn.
RollbackTransResumeExitTutorialEndSub这里要操作的"商品简表"是通过Northwind中的"产品"的"产品ID"、"产品名称"和"供应商"三个字段的数据创建的一个新表,如图3-17所示.
上面的代码连接到Northwind数据库,通过SQL命令从"商品简表"中查询所有记录,并通过筛选选择"供应商"为"佳佳乐"的记录并通过"立即窗口"显示出来,再对该记录的"供应商"字段进行更新,将"佳佳乐"更新为"美食佳佳乐".
运行时在立即窗口中的输出结果如图3-18所示.
最后再查看"商品简表"可以发现,"供应商"字段的某些记录已经更新,如图3-19所示.

图3-17商品简表图3-18"立即窗口"的输出图3-19更新后的"商品简表"3.
5VBA程序调试调试是查找和解决VBA程序代码错误的过程.
当程序代码执行时,会产生两种类型的错误:(1)开发错误开发错误是语法错误和逻辑错误.
语法错误可能由输入错误、标点丢失或是不适当的使用某些关键字等产生的.
例如,遗漏了配对的语句(例如,If和EndIf或For和Next)、程序设计上违反了VBA的规则(例如,拼写错误、少一个分隔点或类型不匹配等).
逻辑错误是指应用程序未按设计执行,或生成了无效的结果.
这种错误是由于程序代码中不恰当的逻辑设计而引起的.
这种程序在运行时并未进行非法操作,只是运行结果不符合要求.

(2)运行时错误运行时错误是在程序运行的过程中发生的.
有运行时错误的代码在一般情况下运行正常,但是遇到非法数据或是系统条件禁止代码运行时(例如,磁盘空间不足等)就会发生错误.
编写容易理解、可维护的代码和使用有效的调试工具可以减少和排除上述的错误.
3.
5.
1良好的编程风格为了避免不必要的错误,应该保持良好的编程风格.
通常应遵循以下几条原则:①模块化除了一些定义全局变量的语句以及其他的说明性语句之外,具有独立作用的非说明性语句和其他代码,都要尽量地放在Sub过程或Function过程中,以保持程序的简洁性,并清晰明了地按功能来划分模块.

②多注释编写代码时要加上必要的注释,以便以后或其他用户能够清楚的了解程序的功能.
③变量显式声明在每个模块中加入OptionExplicit语句,强制对模块中的所有变量进行显式声明.
④良好的命名格式为了方便地使用变量,变量的命名应采用统一的格式,尽量做到能够"顾名思义".
⑤少用变体类型在声明对象变量或其他变量时,应尽量使用确定的对象类型或数据类型.
少用Object和Variant.
这样可加快代码的运行,且可避免出现错误.
3.
5.
2"调试"工具栏及功能VBE提供了"调试"菜单和"调试"工具栏,工具栏如图3-20所示.
选择"视图"菜单的"工具栏"子菜单的"调试"命令,即可弹出"调试"工具栏.
图3-20"调试"工具栏"调试"工具栏上各个按钮的功能说明如表3-9所示.
表3-9"调试"工具栏命令按钮说明命令按钮按钮名称功能说明设计模式按钮打开或关闭设计模式.
行子窗体/用户窗体按钮如果光标在过程中则运行当前过程,如果用户窗体处于激活状态,则运行用户窗体.
否则将运行宏.
中断按钮终止程序的执行,并切换到中断模式.
重新设置按钮清除执行堆栈和模块级变量并重新设置工程.
切换断点按钮在当前行设置或清除断点.
逐语句按钮一次执行一句代码.
逐过程按钮在代码窗口中一次执行一个过程或一条句代码.
跳出按钮执行当前执行点处的过程的其余行.
本地窗口按钮显示"本地窗口".
立即窗口按钮显示"立即窗口".
监视窗口按钮显示"监视窗口".
快速监视按钮显示所选表达式的当前值的"快速监视"对话框.
调用堆栈按钮显示"调用堆栈"对话框,列出当前活动过程调用.
3.
5.
3调试方法及技巧1.
执行代码VBE提供了多种程序运行方式,通过不同的运行方式运行程序,可以对代码进行各种调试工作.
(1)逐语句执行代码逐语句执行是调试程序时十分有效的工具.
通过单步执行每一行程序代码,包括被调用过程中的程序代码可以及时、准确地跟踪变量的值,从而发现错误.
如果要逐语句执行代码,可单击工具条上的"逐语句"按钮,在执行该命令后,VBE运行当前语句,并自动转到下一条语句,同时将程序挂起.

对于在一行中有多条语句用冒号隔开的情况,在使用"逐语句"命令时,将逐个执行该行中的每条语句.
(2)逐过程执行代码如果希望执行每一行程序代码,不关心在代码中调用的子过程的运行,并将其作为一个单位执行,可单击工具条上的"逐过程"按钮.
逐过程执行与逐语句执行的不同之处在于执行代码调用其他过程时,逐语句是从当前行转移到该过程中,在此过程中一行一行地执行,而逐过程执行则将调用其他过程的语句当作一个语句,将该过程执行完毕,然后进入下一语句.

(3)跳出执行代码如果希望执行当前过程中的剩余代码,可单击工具条上的"跳出"按钮.
在执行跳出命令时,VBE会将该过程未执行的语句全部执行完,包括在过程中调用的其他过程.
执行完过程后,程序返回到调用该过程的过程,"跳出"命令执行完毕.

(4)运行到光标处选择"调用"菜单的"运行到光标处"命令,VBE就会运行到当前光标处.
当用户可确定某一范围的语句正确,而对后面语句的正确性不能保证时,可用该命令运行程序到某条语句,再在该语句后逐步调试.
这种调试方式通过光标来确定程序运行的位置,十分方便.

(5)设置下一语句在VBE中,用户可自由设置下一步要执行的语句.
当程序已经挂起时,可在程序中选择要执行的下一条语句,单击鼠标右键,并在弹出菜单中选择"设置下一条语句"命令.
2.
暂停代码运行VBE提供的大部分调试工具,都要在程序处于挂起状态才能有效,这时就需要暂停VBA程序的运行.
在这种情况下,程序仍处于执行状态,只是暂停的正在执行的语句之间,变量和对象的属性仍然保持,当前运行的代码在模块窗口中被显示出来.

如果要将语句设为挂起状态,可采用以下几种方法:(1)断点挂起如果VBA程序在运行时遇到了断点,系统就会在运行到该断点处时将程序挂起.
可在任何可执行语句和赋值语句处设置断点,但不能在声明语句和注释行处设置断点.
不能在程序运行时设置断点,只有在编写程序代码或程序处于挂起状态才可设置断点.

可以在模块窗口中,将光标移到要设置断点的行,按F9键,或单击工具条上的"切换断点"按钮设置断点,也可以在模块窗口中,单击要设置断点行的左侧边缘部分,即可设置断点.
如果要消除断点,可将插入点移到设置了断点的程序代码行,然后单击工具条上的"切换断点"按钮,或在断点代码行的左侧边缘单击.
(2)Stop语句挂起给过程中添加Stop语句,或在程序执行时按Ctrl+Break键,也可将程序挂起.
Stop语句是添加在程序中的,当程序执行到该语句时将被挂起.
它的作用与断点类似.
但当用户关闭数据库后,所有断点都会自动消失,而Stop语句却还在代码中.
如果不再需要断点,则可选择"调试"菜单的"清除所有断点"命令将所有断点清除,但Stop语句须逐行清除,比较麻烦.

3.
查看变量值VBE提供了多种查看变量值的方法,下面简单介绍各种查看变量值的方式.
(1)在"代码窗口"中查看数据在调试程序时,希望随时查看程序中的变量和常量的值,这时候只要鼠标指向要查看的变量和常量,就会直接在屏幕上显示当前值.
这种方式最简单,但是只能查看一个变量或常量.
如果要查看几个变量或一个表达式的值,或需要查看对象以及对象的属性,就不能直接通过鼠标指向该对象或表达式在"代码窗口"中查看了.

(2)在"本地窗口"中查看数据可单击工具条上的"本地窗口"按钮打开"本地窗口".
本地窗口有三个列表,分别显示"表达式"、表达式的"值"和表达式的"类型".
有些变量,如用户自定义类型、数组和对象等,可包含级别信息.
这些变量的名称左边有一个加号按钮,可通过它控制级别信息的显示.

列表中的第一个变量是一个特殊的模块变量.
对于类模块,它的系统定义变量为Me.
Me是对当前模块定义的当前类实例的引用.
因为它是对象引用,所以能够展开显示当前类实例的全部属性和数据成员.
对于标准模块,它是当前模块的名称,并且也能展开显示当前模块中所有模块级变量.
在"本地窗口"中,可通过选择现存值,并输入新值来更改变量的值.
在"本地窗口"中查看变量如图3-21所示.

(3)在"监视窗口"查看变量和表达式程序执行过程中,可利用"监视窗口"查看表达式或变量的值.
可选择"调试"菜单的"添加监视"命令,设置监视表达式.
通过"监视窗口"可展开或折叠级别信息、调整列标题大小以及就地编辑值等.
在"监视窗口"中查看变量如图3-22所示.

图3-21"本地窗口"查看变量图3-22"监视窗口"查看变量(4)使用"立即窗口"查看结果使用"立即窗口"可检查一行VBA代码的结果.
可以键入或粘贴一行代码,然后按下ENTER键来执行该代码.
可使用"立即窗口"检查控件、字段或属性的值,显示表达式的值,或者为变量、字段或属性赋予一个新值.
"立即窗口"是一种中间结果暂存器窗口,在这里可以立即求出语句、方法和Sub过程的结果.

可以将Debug对象的Print方法加到VBA代码中,以便在运行代码过程中,在立即窗口显示表达式的值或结果,这在前面的众多的示例中都有应用.
(5)跟踪VBA代码的调用在调试代码过程中,当暂停VBA代码执行时,可使用"调用堆栈"窗口查看那些已经开始执行但还未完成的过程列表.
如果持续在"调试"工具条上单击"调用堆栈"按钮,Access会在列表的最上方显示最近被调用的过程,接着是早些被调用的过程,依次类推.
在"调用堆栈"窗口中查看过程如图3-23所示.

CloudCone(20美元/年)大硬盘VPS云服务器,KVM虚拟架构,1核心1G内存1Gbps带宽

近日CloudCone商家对旗下的大硬盘VPS云服务器进行了少量库存补货,也是悄悄推送了一批便宜VPS云服务器产品,此前较受欢迎的特价20美元/年、1核心1G内存1Gbps带宽的VPS云服务器也有少量库存,有需要美国便宜大硬盘VPS云服务器的朋友可以关注一下。CloudCone怎么样?CloudCone服务器好不好?CloudCone值不值得购买?CloudCone是一家成立于2017年的美国服务...

UCloud云服务器低至年59元

最近我们是不是在讨论较多的是关于K12教育的问题,培训机构由于资本的介入确实让家长更为焦虑,对于这样的整改我们还是很支持的。实际上,在云服务器市场中,我们也看到内卷和资本的力量,各大云服务商竞争也是相当激烈,更不用说个人和小公司服务商日子确实不好过。今天有看到UCloud发布的夏季促销活动,直接提前和双十一保价挂钩。这就是说,人家直接在暑假的时候就上线双十一的活动。早年的双十一活动会提前一周到十天...

台湾云服务器整理推荐UCloud/易探云!

台湾云服务器去哪里买?国内有没有哪里的台湾云服务器这块做的比较好的?有很多用户想用台湾云服务器,那么判断哪家台湾云服务器好,不是按照最便宜或最贵的选择,而是根据您的实际使用目的选择服务器,只有最适合您的才是最好的。总体而言,台湾云服务器的稳定性确实要好于大陆。今天,云服务器网(yuntue.com)小编来介绍一下台湾云服务器哪里买和一年需要多少钱!一、UCloud台湾云服务器UCloud上市云商,...

sql2000挂起为你推荐
邮箱怎么写正确的邮箱格式怎么写会声会影12下载哪里有会声会影12好看视频素材下载优酷路由宝怎么赚钱优酷路由宝整的可以赚钱吗?可以赚多少?站长故事科学家的故事200字网站运营网络运营主管的主要工作职责是什么?网店推广网站怎么免费推广淘宝店铺?iphone越狱后怎么恢复苹果手机越狱后怎么恢复天天酷跑刷金币如何使用八门神器给天天酷跑刷钻刷金币硬盘人500G的硬盘容量是多少啊?免费免费建站我想建一个自己的免费网站,但不知道那里有..
网站空间申请 北京主机租用 香港机房 wavecom 哈喽图床 512au 商家促销 全能主机 cpanel空间 域名和空间 cdn加速是什么 电信虚拟主机 上海电信测速网站 云营销系统 vul 什么是web服务器 全能空间 阿里云个人邮箱 北京主机托管 新疆服务器 更多