精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● VB和Basic>>● VB和Basic(1)>>文章连载>>VB邮件>>VB邮件(6.7)

主题:VB邮件(6.7)
发信人: aaaaaaaaa()
整理人: cobe(2000-02-12 23:52:56), 站内信件
                      编者的话
====================================================================
大家好!
    这是关于VB和ASP的免费邮件列表。
    如果您有问题或想回答别人的问题,请给我写信。
    如果您有好的作品或您发现了好的作品,不要忘
了让大家共享。
    热情欢迎您的参与!!!
                                版主   冯德平
                                [email protected]
=============================================
            VB邮件(6.7)
a Visual Basic也存在2000年问题

李海

    Visual Basic以其灵活易学的特点成为目前Windows开发的主要工具,可你想
到没有,当世纪钟声敲响之时,你的VB程序会怎样呢?

    笔者研究的结果说明Visual Basic的2000年问题比较复杂,因版本而异。

    为了考察Visual Basic的2000年问题,我编写了如下这段程序: 

      Dim sDate As String

      Dim vDate As Variant

      sDate = "Jan 1 01"

      vDate = CVDate(sDate)

      Debug.Print "Now = " & Now

      Debug.Print "sDate = " & Format$(sDate, "dd/mm/yyyy")

      Debug.Print "vDate = " & Format$(vDate, "dd/mm/yyyy")

    把这段程序在每个版本的Visual Basic运行两次,第一次运行系统时间采用
本世纪的时间1997年8月9日,另一次使用下世纪的时间2000年8月9日。完成整个
测试之后,我得出下面的结果。

    在Visual Basic 3.0中,两次的结果如下:

      Now=97/08/09 3:06:48 PM

      sDate = 01/01/1901

      vDate = 01/01/1901

      Now = 2000/08/09 3:08:11 PM

      sDate = 01/01/1901

      vDate = 01/01/1901

    从结果中我们可以看出,由于Visual Basic 3.0发行得比较早,当时2000年
问题还没有引起人们的注意,所以Visual Basic 3.0把任何年份都看成本世纪的
。也就是说,可能会出现这样的情况:你的程序在下世纪会突然使时光倒流100年
。在测试中,我还发现Format函数和Year函数返回的结果是一样的,这说明在Vi
sual Basic 3.0中只存在一种计算世纪的方法。Visual Basic 4.0中的情况比3.
0版复杂多了。首先看看16位版本。下面是测试的结果:

      Now = 97/08/09 3:06:48 PM

      sDate = 01/01/1901

      vDate = 01/01/1901

      Now = 2000/08/09 3:08:11 PM

      sDate = 01/01/2001

      vDate = 01/01/2001

   Visual Basic 4.0的16位是根据当前系统日期来判断世纪的。当前年份为199
7,得到的日期为20世纪的,若当前年份为2000年,得到的日期为21世纪的。这也
可能会出现问题,当你在2000年处理1999年的帐目时,Visual Basic会认为那是
2099年的。

    如果你使用的是Visual Basic4.0的32位版本,你可能得到与16位版本相同的
结果,也可能不同。这是因为Visual Basic 4.0的32位版本的日期函数(除DateS
erial函数以外)是从OleAut32.dll得到世纪数据的。Visual Basic 4.0的32位版
本自身带的是2.10版本,它采用的方法同Visual Basic 4.0 的16位版本一样。而
在Visual Basic 4.0发行后,微软也意识到它处理世纪的方法不够合理,所以在
随后发行的2.20版和此后的版本中采用了新的方法。新方法认为如果年份的后两
位在30至99之间,则认为是20世纪,而若在00至29之间,就认为是21世纪。这可
以比较好地解决世纪末过渡时期的世纪问题,至于2030年怎么办,只能到时候再
说了。微软96年以后推出的软件中包括的OleAut32.dll都是采用此方法,这些软
件包括Internet Explorer 3.0、Windows NT 3.51 Service Pack 5、Windows N
T 4.0、Windows 95 OSR 2( 俗称Windows 96)、Office 97 和Visual Studio 97
 等 等。Visual Basic 5.0也采用此方法。如果你在VisualBasic4.0的32位版本
中运行前面的测试程序得到的结果同16位版本相同,说明你的OleAut32.dll是老
版本,否则为新版本。可见,Visual Basic 4.0的32位版本得到的结果取决于Ol
eAut32.dll的版本。需要说明的是,DateSerial函数不是从OleAut32.dll得到世
纪数据的,它在Visual Basic的16位和32位采用的方法是一样的。以上是Visual
 Basic各个版本对世纪问题的处理方法。如果你的程序不会因此发生问题,可以
照常调用各日期函数。但如果会因此出问题,我建议采用自定义函数来确定世纪
。比如,我有一个程序认为80年至99年的日期都是本世纪,而00年至79年为下世
纪。可以编写如下的程序来返回四位年份。 

 

      Sub MyYear( vDate As Variant) As String

      Dim s As String

      If Format$( vDate, "yy") < "80" Then

s = "20"

Else

s = "19"

End If

MyYear = s + Format$( vDate, "yy")

End Sub

 

现在,你应该逐个审核你的程序,不要让它们在2000年元旦的节日里给你找
麻烦。

b 用VB和RDO访问SQL SERVER
作者:武浪辉雄

远程数据对象 (Remote Data Object ,简称RDO) 是位于 ODBC API 之上的一个对
象模型薄层,它依赖 ODBC API、选定的 ODBC 驱动程序以及后端数据库引擎实现
大部分的智能和功能,因此短小(大约 250 K)、快速、强健。 RDO具备基本的
ODBC 处理方法,所以可以直接执行大多数 ODBC API 函数。RDO包含在VB4.0/V
B5.0企业版中,由一个动态连接库MS RDO32.DLL实现。 当VB版本还只是2.0时,
从VB访问MS SQL Server的手段只有API函数集(VBSQL/DBLib或 ODBC API)。VB
发展到3.0时,其DAO/Jet (Microsoft Access的数据库引擎)功能非凡,具备面向
对象的程序接口,但处理速度尚不尽如人意。另一方面,尽管VBSQL/DBLib、ODB
C AP I在速度方面性能很好,但它需要花费很大的精力进行繁琐的编程工作。 当
MS SQL Server发展到6.0、VB发展到4.0时,开发了新的对象模块,由此产生了R
DO,可以访问SQL Server、Oracle;RDO2.0则是由VB5.0提供的。值得一提的是,
它实现了“事件驱动型数据库访问的编程方式”。 要讨论RDO,就必然要谈到DA
O。DAO/Jet是为了实现从VB访问Access数据库而开发的程序接口(对象)。RDO是
从DAO派生出来的,但两者很大的不同在于其数据库模式。DAO是针对[记录(Reco
rds)]和[字段(Fields)],而RDO是作为[行(Rows)]和[列(Columns)]来处理。也就
是说DAO 是ISAM模式,RDO是关系模式。此外DAO是访问Access的Jet引擎(Jet是I
SAM)的接口,而RDO则是访问ODBC的接口。 可见,RDO是综合了DAO/Jet、VBSQL/
DBLib以及ODBC的优点的对象(Object)。需要强调的是,RDO是包裹着ODBC API的
一层薄薄的外壳,被设计成在后台(服务器端)有数据库存在的前提下运行,同
时也是针对SQL Server和Oracle而特别设计的。 RDO的优势在于它完全被集成在
VB之中。此外,直接访问SQL Server存储过程、完全支持T-SQL、T-SQL调试集
成在开发环境中、Visual Database Tools的集成化等,也是RDO的长处。

RDO之后是ADO
Microsoft公司已经明确宣布今后不会对VBSQL/DBLib进行升级,而ODBC API函数
一级的编程方式也不为人们所喜爱。RDO自身今后将被以ActiveX技术为基础的AD
O(ActiveX Data O bjects)所替代。Visual Basic下一个版本中由哪一个作为标
准配置还不很明确,但这一发展趋势已经很清楚。 为什么需要ADO呢?RDO是以O
DBC为基础,而ADO则是基于全新的OLE DB技术。ODBC本身是以SQL Server、Orac
le等关系数据库作为访问对象;OLE DB则不仅限于此,而将是可以对电子邮件、
文本文件、复合文件、数据表等各种各样的数据通过统一的接口进行存取的技术
。DAO、RDO当然不会一下子消失,但随着新技术的利用,它们的作用将逐步淡化


RDO的对象模块图
要正确地使用RDO,有必要对其对象模块结构加以理解。在RDO的对象和集合中,
有很多对数据库的状态和设定进行操作的属性(Property),以及对数据库进行
操作的方法(Method)。利用这些,从RDO2.0起就可以开发事件驱动的数据库应
用程序。 RDO对象与VB中其他对象的概念相同。与VB用的ActiveX控件(以往称为
Custom Control 或OCX、VBX)相似的是,RDO也带有属性和方法;但同Spread、
InputMan等普遍应用的Activ eX控件不同的是,RDO没有自己的用户界面,因而可
以和VB标准的Timer控件归为同一类。当然也可以将RDO看作调用ODBC API函数,
进而对后台数据库操作加以控制的对象。在RDO的属性和方法中,包含了对单个的
ODBC API函数以及一连串API函数的调用。

1. rdoEngine对象 最初调用RDO对象以及RDC(远程数据控件)时,自动生成rdo
Engine对象的附带事件(i ncident)。rdoEngine用于对RDO全局属性的参数、选
项进行设置,是在RDO的阶层结构内处于最上层的对象,包含了所有的其他对象。
rdoEngine对象与DAO/Jet不同,虽然被多个应用程序共享,但体现rdoEngine对
象的设定值的属性却并不共用,而是在各自的应用程序的程序界面中对其分别加
以设定。这些设定值对其他使用RDO以及RDC的应用程序没有任何影响。rdoEngin
e不是集合的要素,而是重新定义的对象,rdoEngine对象不能被追加作成。

2. rdoEnvironment对象 RDO对象在自动创建rdoEngine对象时,将rdoEnviromen
t对象的初始值生成并保存为rdo Enviroments(0)。一般情况下,应用程序中不必
追加rdoEnvironment对象,大多只需对已有的rdoEnviroments(0)进行操作就可以
了。只有在支持一个以上事务(Transaction),需要将用户名和口令信息分别处理
的情况下,利用rdoCreateEnvironment方法将特定的用户名和口令值作成新的rd
oEnvironment对象。在这个方法中可以指定固有名、用户名和口令,如果所指定
的值与rdoEnvironments集合的已经存在的成员名称相同,会产生错误。新建的r
doEnvi ronment对象自动追加在rdoEnvironments集合的最后。调用rdoCreateEn
vironment方法时,其name参数可以是长度为0的文字列,这时新的rdoEnvironme
nt对象将不会被追加在rdoEnvi ronments集合之中。 3.rdoConnection对象 rdo
Connection对象用于同SQL Server的连接管理,下面是与SQL Server连接的例子
。 第一步用New关键字声明一个rdoConnection对象: Dim Cn as New rdoConne
ction 由此生成独立的连接对象,这时它还不是rdoConnection集合的成员。在具
体连接到SQL Server等之前,有必要设定rdoConnection集合的属性。对此,使用
With关键字编程效率会更好。
With CN
.Connect = “Uid = ; Pwd = ; Database = Pubs; DSN = MyPubsDSN; ”
' 设定Cursor类型
.CursorDriver = rdUseNone
'设定登录超时
.LoginTimeOut = 10 End With
用RDO与SQL Server连接和断开
RDO接口没有自动管理同SQL Server的连接和断开的功能,需由程序员自己加以判
断。这里需要注意的是对连接和断开时机的管理,因为同时有过多的连接将会造
成服务器负载过重。而且,对SQL Server而言,一个连接只能同时支持一个操作
,当同时进行记录的读出和更新时,需要分别对其各自的连接加以确认。在一定
条件下需要保持连接;反之,当操作完成以后,又需要立即将连接断开。如果能
正确地设计好连接和断开的时刻,就有可能确保扩展更多的用户数(客户/服务器
开发环境中,与数据库项的可扩展性一样,客户数扩张的可能性也非常重要)。
由于RDO是基于ODBC,它通过ODBC的数据源名(DSN: Data Source Name)与SQL S
erver相连。DSN的信息可以基于文件,也可以在连接时通过传递的参数指定。不
过,一般来说,不推荐基于文件的DSN,因为一旦DSN文件被破坏,或者被误删除
,设定起来就非常麻烦。通过 DSN对SQL Server的连接方式一般有以下几种: 


查询ODBC的登录信息中是否存在有效的DSN:可以通过ODBC API的SQLDataSource
s函数取得DSN条目的列表,不过这种办法实用性不大。 

用rdoRegisterDataSource函数生成新的DSN:虽然多少有一些麻烦,但比查询OD
BC 登录信息要好一些。 

与已有的DSN相连:需要手工设置DSN,而且安装应用程序之后还需个别地设定DS
N,对用户来说不是很友好的解决方法。 

从应用程序中自动启动控制面板的ODBC管理applet,向用户说明DSN的设定方法:
有的应用程序就是用这种方法进行设定,但仍不是很实用的办法。 

将SQL Server名保存在Windows Registry或INI文件,在连接时对rdoConnectio
ns对象的属性作如下设置:在初次运行应用程序,或者找不到指定的SQL Server
名的情况下,要求用户进行输入,并设置在Windows Registry或INI文件中。通
常,SQL Server名不会改变;当连接出现错误时,可以像初次运行应用程序时那
样,为用户提供指定SQL Server 名的对话框,这种做法最为理想。 

利用ODBC3.0驱动支持的功能在连接时实际指定DSN文件:作安装程序时包含这个
DS N信息的文件,随同程序一起安装。

此外还有其他一些DSN的连接方法,这里不作一一描述。 这些方法中具体哪一个
最实用,需根据各种应用程序的安全性要求、安装方法等进行考虑加以选择,一
般是组合上述方法的其中几种来编程。也就是说,用DSN文件的方式来作实际上的
连接,而同时采用对DSN文件是否存在进行检查、不存在时要求用户输入SQLServ
er 名、用户名、口令并即时自动生成的方法。 实际的连接除了RDO 1.0的OpenC
onnection方法以外,也可以用RDO 2.0中新增加的Esta blishConnection方法,
我们将在下期中介绍这些方法。此外,下面我们还将通过实际代码向大家继续介
绍经DSN对SQL Server的连接方式、数据的读取、追加、更新、删除等内容。

实例
在本系列文章的上篇刊文中,我们介绍了RDO的发展、优势、对象模块、趋势,以
及通过RDO与SQL Server的连接和断开等内容,本期将通过实例来介绍RDO的应用


OpenConnection方法的调用方式如下:
[调用方式:OpenConnection(dsName, Prompt, ReadOnly, Connect)]
其中参数说明如下:
 dsName,指定登录在系统中的DSN条目。当用Connect参数指定DSN值时,dsNa
me必须为“”(长度为0的文字列)。
 Prompt,当设置为rdDriverPrompt常数时,可以在不能与SQL Server连接的情
况下,激活ODBC设置对话框来设定DSN。只是最好不要让一般用户随意更改这个设
定。通常情况下,正确的处理方法是设定为rdDriverNoPrompt,利用Error处理程
序编程进行处理。
 ReadOnly,若需要通过连接对数据进行更新时设定为False。若没有数据更新
的必要则设为True,这时因为ODBC驱动没有对数据更新进行管理的需要,可以提
高程序效率。
 Connect,向ODBC驱动管理器传递所有的ODBC连接参数。可以省略dsName,只
通过Co nnect参数进行包括用户名、口令、缺省数据库、DSN(此时dsName参数的
值无效)等全部参数值的传递。
下面是OpenConnection方法的一个实例。
设定的DSN为MyDSN:
Dim Cn As rdoConnection
Dim En As rdoEnvironment
Dim Conn As String
Conn = “DSN = MyDSN; UID = Jacob;” & “PWD = 123456; DATABASE = MyD
b;”
Set Cn = En.OpenConnection(“”, rdDriverPrompt, False, Conn)
在这个例子中,dsName是空 “”(长度为0的文字列)。DSN情报从Conn参数中所含
的DSN = MyDSN取得。
OpenConnection方法中也可以通过变量来进行参数传递:
[变量名:=值]
Set Cn = En.OpenConnection(Prompt := rdDriverPrompt, ReadOnly := False
, Conn ect := Cnn)
虽然这多少有一些多余的代码,但毫无疑问会使程序维护工作容易得多。
EstablishConnection方法
EstablishConnection方法的调用方式如下:
调用方式:EstablishConnection(Prompt, ReadOnly, Connect)
本文前面对独立(stand alone)的连接对象(rdoConnection)作了说明,Establ
ishCon nection方法可以用于这种情况。EstablishConnection方法同OpenConne
ction方法很相似,被用于停止状态或独立的rdoConnection对象。
这里以独立的rdoConnection对象为例说明与SQL Server的连接。
Public WithEvents Eng As rdoEngine
Public WithEvents Cn As rdoConnection
 
Private Sub Form_Load()
Set Eng = New rdoEngine
Set Cn = New rdoConnection
With Cn
.Connect = “UID = ; PWD = ;” & “DATABASE = pubs; DSN = biblio”
.LoginTimeout = 5
.EstablishConnection rdoDriverNoPromt, True, rdAsyncEnable
End With
End Sub
在这个例子中,Form_Load函数对rdoEngine和rdoConnection对象进行初始化。这
里有一点需要注意,rdoConnection对象是处于独立的状态之下,即使是处于未连
接状态也可以设置属性的值。
接下来是rdoConnect对象的事件处理程序。从RDO 2.0起可以实现异步方式(rdA
syncEn able),EstablishConnection就设定为该值。在异步状态下,不必等待
与数据库的连接,程序可以迅速从Form_Load函数中退出。
然后是BeforeConnect事件,该处理在与数据库的连接开始以前被激发,此时不能
进行有关终止连接的操作:
Private Sub Cn_BeforeConnect(ConnetString As String, Prompt As Variant
)
MsgBox “正在连接” & ConnectString, vbOKOnly, “连接前”
End Sub
连接完成之后的事件处理:
Private Sub Cn_Connect(ByVal ErrorOccurred As Boolean)
Dim M As String
If ErrorOccurred Then
For Each er In rdoErrors
M = M & er & vbCrLf & M
Next
MsgBox “连接失败” & vbCrLf & M
Else
MsgBox “连接成功”
'这是确认连接状态的测试代码
Cn.Excute “use pubs”
End Sub
RDO连接处理结束后,在该事件中确认连接成功与否。连接成功的情况下ErrorOc
curred 返回False,失败时为True,由此可以对rdoErrors集合进行检测:
Private Sub Eng_InfoMessage()
For Each er In rdoErrors
Debug.Print er
Next
RdoErrors.Clear
End Sub
不能与SQL Server连接的原因多种多样,有可能是由于对数据库的访问权限、网
络连接问题、数据库表的信息错误、SQL Server同时连接的许可数、资源不足等
等,具体情况需要与网络管理员商量。
断开连接的操作非常简单,但又很重要,因为RDO不提供自动断开的功能。
Cn.Close
Set Cn = Nothing '释放对象所占的内存资源
En.Close
Set En = Nothing '释放对象所占的内存资源
VB是对象语言,Form、ActiveX控件也都是对象。使用对象后必须养成将对象设为
Nothi ng把它从内存中释放的编程习惯。这样可以预防很多不可预测错误,往往
程序中发生意义不明的错误时,其原因就在于此。
数据的取得
与数据库连接成功之后,接下来就是取得数据。一般用OpenResultset方法取得数
据,这里首先需理解数据库中与此有关的[游标]概念。

 

一言以蔽之,游标[cursor]就是指向依据一定的条件从数据库中抽取的数据的多
个指针。也就是说游标是用作指向由数据库返回的数据的方法。
RDO 支持几种不同的游标库,其中每一种都有其特定的作用:向前滚动型的结果
集(rdOpenForwardOnly-缺省值)、静态滚动型结果集(rdOpenStatic)、可滚
动的查询结果集(rdOpenKeyset)和动态可滚动的查询结果集(rdoOpenDynamic
)。在使用RDC的情况下,游标的值设定为ResultsetType属性;在使用RDO的情况
下,通过OpenResultset方法的Type参数进行设定。游标又分为[服务器端游标]和
[客户端游标],这需要根据程序的性质、处理内容的不同来选择适当的方式。也
有不使用游标的情况,比如当只进行数据读取时,使用rdUseNone选项更为合适。

关于是否使用游标、使用何种游标,需考虑下面一些情况:
 
* 需要读取多少行数据?要读取全部或只是几行数据?
* 是否等待游标的创建完成?对于用户来说等待时间是否在允许范围之内?
* 用来保存已创建游标的系统资源(内存容量),在用户端或服务器端是否充足

* 从服务器端返回的结果怎样读取?有必要从当前行随意移动,还是从最初到最
后顺序读取为好?
* 游标的成员关系怎样定义?
* 数据如何更新?数据有没有更新的必要?是通过Execute方法将游标的数据进行
更新,或是由存储过程更新?
关于游标的详细介绍,请参照Visual Basic Books Online以及SQL Server用户手
册。这里介绍从RDO对象读取数据的几种方法:
* rdoResultset对象,这是RDO的基本游标对象。与DAO的Recordset对象相似,可
应用于各种游标以及无游标的场合。可以通过rdoConnect对象或rdoQuery对象的
OpenResultset方法创建rdoResultset对象。
* rdoQuery对象,与DAO的QueryDef相似,在进行一次性查询时使用,用于取代已
经过时的由rdoConnection对象的CreatePreparedStatement方法创建的rdoPrepa
redStatement对象。rdoQuery对象直接调用ODBC的SQLPrepare。
* UserConnection对象,在VB5.0以及RDO 2.0中新增加的对象,这里不作详细阐
述。它是一个非常优秀的对象,使RDO使用起来更加容易。
* rdoTable对象,是rdoTables集合的成员,用来显示SQL Sever上的一个表的内
容。
编程中通常运用前3种方法中的某一种,而第4种一般不太用。
不论使用哪一种方法,都有必要给出SQL语句。在绝大多数的情况下,SQL语句是
针对SQL Server,从哪个表以何种条件读取哪一行的数据,如(SELECT * FROM
table1 WHERE field1 = “condition”)。运行存储过程时用Name参数指定存储
过程,程序能自动判别是RDO 2.0的还是存储过程的SQL语句。在以存储过程为核
心的情况下,利用UserConnection将存储过程作为方法来处理最为妥当。
 
下面给出一个运行rdoConnection对象Cn的OpenResultset方法的例子。
Dim Rs As Resultset
Set Rs = Cn.OpenResultset(name:=“SELECT * FROM Authors WHERE Year_Bo
rn=1966”)
If Rs.RowCount > 0 Then
MsgBox Rs.RowCount & “条记录取得完毕。”
Else
MsgBox “没有取得任何记录。”
End If
这个例子中用了name:=,OpenResultset方法,除了name参数以外,也可以使用l
ock、 locktype、option等。下面是从Resultset中将数据读取到ListBox中的方
法:
Do Until Rs.EOF
List1.AddItem Rs(“au_lname”)
Rs.MoveNext
Loop
存储过程虽然不在本文讨论的范围内,这里也简单地介绍一下。存储过程基本上
有以下4种类型:
{call myStoreProcedure} ' 没有参数的存储过程
{call myStoreProcedure(?)} ' 单一的输入或输出参数
{? = call myStoreProcedure(?)} ' 单一参数、有返回值
{? = call myStoreProcedure(?, ?)} ' 多个参数、有返回值
下面演示一个运行存储过程的例子:
sp_GetVendorCount参数是名称的条件,其返回值为符合该条件的记录数。
Dim CPw As rdoQuery
Dim sSQL As String
SSQl = “{? = call sp_GetVendorCount(?)}”
这里“名称的条件”是输入参数,由ODBC驱动器进行自动识别。使用rdoParamet
ers(n).Direction可以对返回值(rdParamReturnValue)、输入参数 (rdParamInp
ut) 、输出参数(rdParamOutput)和输入输出参数(rdParamInputOutput)加以控制
。但通常ODBC都会读入存储过程的定义式,并加以正确识别,所以绝大多数的情
况下不必使用这个参数。
Dim CPw = Cn.CreateQuery(“GetVendorCount”, sSQL)
代码生成名为GetVendorCount的rdoQuery对象,并将rdoQuery对象自动增加到rd
oQueries集合中,以后可以重复使用。
现在将CPw对象的第一个参数指定为返回值:
CPw.rdoParameters(0).Direction = rdParamReturnValue
最后由Execute方法运行:
CPw.Execute
返回行的查询(存储过程中包含一个以上的SELECT)时,可使用OpenResultset方
法。运行后,可通过rdoParameters集合取得返回值:
If CPw.rdoParameters(0) > 0 Then
MsgBox CPw.rdoParameters & “数据取得成功”
Else
MsgBox “数据读取失败”
End If
数据的追加、更新、删除
对SQL语句已经有一定了解的读者,应该比较熟悉INSERT、UPDATE、DELETE等语句
。对于rdoConnection对象,虽然可以在OpenResultset的Name参数中直接代入SQ
L语句,用Execute方法运行,但没有充分利用RDO对象的长处。在rdoResultset中
有AddNew、Edit、Update、Delete、MoveNext、MovePrevious、MoveFirst、Mov
eLast方法,与DAO/Jet相似,用起来非常便利。
下面在先前的Resultset的例子中追加记录:
Rs.AddNew
Rs(“au_id”) = “111-46-1992”
Rs(“au_lname”) = “Takenami”
RS(“au_fname”) = “Teruo”
'设定所有的field,通常调用Call SetField,在别的模块中设定
Rs.Update
与SQL语句中的INSERT相比起来,这种方法非常简单,而且代码可读性好。记录的
更新方法如下,与追加相似,所不同的只有最初的Edit方法:
Rs.Edit
Rs(“au_lname”) = “Takenami”
RS(“au_fname”) = “Teruo”
'设定所有的field,通常调用Call SetField,在别的模块中设定
Rs.Update
在实际应用中,字段的更新放在别的模块中,便于从AddNew、Edit两种处理中都
可以进行调用。
使用Delete方法删除记录时,当前行被删除。当前行可以通过MoveNext、MovePr
evious等Move方法以及Bookmark属性设定。
Rs.Delete '删除当前记录
这里需要注意的是当前记录被删除之后记录指针的位置。Delete执行后,记录指
针仍然指向已被删除的记录,也就是空的记录,对这个空记录进行读写操作会产
生错误。所以通常在Delete之后应立即执行ReQuery或MoveNext操作:
Rs.ReQuery 或 Rs.MoveNext
以上简单地说明了数据的增加、更新、删除方法,根据数据库的模式的不同,增
加、更新会变得非常复杂。另外,由于数据表的原因,有时会使得删除操作变得
复杂。通常与数据表的构造、相关性有关的处理,为了使客户端的代码尽可能简
洁,应在SQL Server上创建触发器。有关触发器的内容已超出了本文讨论的范围
,这里不详细说明。本文介绍的只是一些基本的操作方法,RDO数据处理功能不仅
限于此,读者可在实际开发中进一步领会。
总结
RDO是开发数据库应用程序功能强大的对象方法,要真正做到应用自如,需要付出
很大努力。本文描绘了RDO基本的构成、功能、编程方式,希望读者由此对数据库
编程方式以及RDO的使用有更为充分的了解。如果需要进一步研究,建议可以从以
下几方面入手:
* SQL Server(或Oracle)的功能,特别是存储过程、View、触发器、安全模式等

* 数据库设计基础;
* SQL语句;
* Visual Basic的对象概念。
这些粗看起来与RDO没有什么联系,但实际上有助于对RDO的结构、原理等基本技
术的理解。换而言之,学习数据库编程的基本内容为大前提,RDO或者ADO的应用
不过是访问数据库的一种手段而已。


c 用VB在窗口中显示动画图标


  indows 3.X系统有一个鲜为人知的地方。首先,选取该系
统所带某一应用程序(如文件管理器,画笔,扫雷等)的“帮助\关于***...”菜单
弹出对话框后,按下Ctrl和Shift键,同时用鼠标左键双击对话框中应用程序的图
标,然后关闭对话框。接下来,重复上述操作(两次打开的应用程序可以不同),
再次双击图标,奇迹出现了!对话框中将出现一面飘扬的Windows旗帜和“Dedica
ted to all the hard-working people of the Microsoft Windows 3.10 Team!
”这样一条文字信息。如果你再做一次,一定还有新的惊喜。在Windows 95中,
上述现象已不复存在,但是在执行其有关“查找”功能以及缺少快捷方式时,对
话框内所显示的来回移动的放大镜或照来照去的手电筒则可谓动画图标的上乘佳
作。

  如果能够在我们自己开发的应用程序中恰当地应用动画图标,一定会给程序
界面增色不少。

  其实,这些用Visual Basic实现起来是很方便的。

(1)使用VB所带的ICONWORK或其他图标制作工具制作各动画帧的图标Demo0.Ico,D
emo1.Ico,Demo2.Ico,……

(2)建立窗口,在合适位置如左上角添加Image(图形)控件,打开其Properties(属
性)窗口,将其中的Stretch(伸展性)项置为True,并从Picture(图片)项右栏点开
Load Picture(加载图片)窗口,从其中的文件列表中选取(1)中制作的第1个图标
(Demo0.Ico),其余属性取其缺省状态。

(3)在窗口中添加Timer(计时器)控件,并设置其Interval(时间间隔)属性值(如1
00ms,该值越大动画速度越慢)。

(4)编写代码,利用计时器控件每隔一个时间间隔调用一次计时器函数的特性,在
该函数中更替图形控件所显示的图标即可获得动画效果。

  下面所附的源程序代码摘自笔者开发的某应用程序,在Windows 95中文版+V
isual Basic 4.0环境下运行效果颇佳。

附:程序清单(Form5.Frm)
VERSION 4.00
Begin VB.Form form5 对话框窗体
BackColor = & H00C0C000& 背景色
BorderStyle =3'Fixed Double 边界类型
Caption ="关于…" 标题
…… ……
Top =1980 上边界
Width =3840 宽度
Begin VB.Image Imagel 图形控件
Height =855 高度
Left =120 左边界
Picture ="FORM5.frx":0000 图片
Stretch =-1'True 伸展性
Top =240 上边界
Width =975 宽度
End
Begin VB.Timer Timerl 计时器控件
Interval =100 时间间隔(ms)
Left =360 左边界
Top =2520 上边界
End
Begin VB.CommandButton Commandl 按钮控件
Caption="确认" 标题
…… ……
Top =2520 上边界
Width =1455 宽度
End
……
End
Attribute VB_Name ="Form5"
Attribute VB_Creatable =False
Attribute VB_Exposed=False
Dim count% 图标序号
Private Sub Form_Load()
count=-1 置初值
End Sub
Private Sub Timerl_Timer() 计时器函数
count=(count+1)Mod 3 更换显示图标
If count =0 Then
Image1.Picture=LoadPicture("Demo0.Ico")
Else If count= 1 Then
Image1.Picture=LoadPicture("Demo1.Ico")
Else
Imagel.Picture=LoadPicture("Demo2.Ico")
End If
End Sub
Private Sub Command1_Click ()
Form5.Hide 关闭窗口
End Sub
……

=============================================
问题征答(6.7)
如何打印一个大于屏幕的窗体?
我在使用 PRINTFORM 时,当窗体面积大于屏幕时,
超过屏幕的窗体部分无法打印
Thanks.
[email protected]
=============================================
其它
====================================================================
欢迎订阅VB免费邮件:
订阅地址 http://server.com/WebApps/mail-list-subscribe.cgi?id=16852

====================================================================

如果您觉得这个邮件列表好的话,请告诉您的朋友。
====================================================================
欢迎投稿 [email protected]
====================================================================

网易上的主页地址:http://www4.netease.com/~aaaaaaaaa
本网站主页镜像地址:goodvbhome.yeah.net
====================================================================

--
欢迎访问主页:goodvbhonme.yeah.net
或:http://www4.netease.com/~aaaaaaaaa
http://personal.gz168.gnet.gd.cn/vbok/

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.47.53]

[关闭][返回]