三、使用Recordset对象
Recordset(记录集)对象代表你在程序中使用的数据。
在上面的程序中,曾使用一个名为RecordsetType(记录集类型)的数据属性指明数据库信息为一个表。在Visual Basic中,Recordset(记录集)是一个代表你正在程序中使用的数据库部分的对象。当把数据控件的RecordSource属性设置为表或查询的名称时,就定义了一个新的名为Recordset的对象。Recordset对象有它自己的一套特殊属性和方法,使你能查找、排序、添加和删除记录。
在下面的练习中,将使用Recordset对象在zgda.mdb数据库中按编号查找项目,并将它们显示出来。
1、在zgda.mdb中查找数据
在修改程序之前,为保护原始程序,请先以新文件名将它存盘。
1) 在文件菜单中,单击另存为窗体、另存为工程菜单项。以MyFindRec.frm、MyFindRec.vbp为文件名分别保存窗体和工程。
2)在窗体的左下方创建两个命令按钮对象,Caption属性分别设置为“查找”、“结束”。
3)添加代码。
Option Explicit Dim prompt As String, searchSearchStr As String Private Sub Command1_Click() prompt$ = "输入要查找的编号:" searchSearchStr$ = InputBox(prompt$, "搜索记录") Data1.Recordset.Index = "Primarykey" '使用类名 Data1.Recordset.Seek "=", searchSearchStr '进行搜索。Seek方法可以查找匹配的记录。 If Data1.Recordset.NoMatch Then '如果不匹配 Data1.Recordset.MoveFirst '则取第1课记录 End If End Sub
程序说明:
该事件过程显示一个查找对话框,以便用户能输入编号(SearchStr$)。接下来它使用Seek方法从头至尾对数据库“编号”字段进行搜索,直至找到匹配项或者搜索到表的结尾。如果未找到匹配项,Visual Basic将显示一条信息“No current record”,并且在第一个文本框中显示Recordset(记录集)的第一条记录。该事件过程所使用的Recordset属性和方法如下表所示:
Recordset属性或方法 |
说明 |
Index |
用于定义查找和排序过程中所使用的数据库字段的属性 |
Seek |
用于查找记录的方法。除=以外,关系运算符>=、>、<=和<也可用来将所查找的字符串与数据库中的文本进行比较 |
NoMatch |
该属性的值为True时表示未查找到匹配项 |
MoveFirst |
使Recordset的第一条记录成为当前记录的一个方法 |
2、向zgda.mdb数据库添加记录
在向数据库添加新记录时,应在设计模式下将数据对象的ReadOnly(只读)属性设定为False(假),然后使用事件过程中的AddNew(添加新记录)方法在数据库中添加新记录。当窗体中出现空白记录时,用户就可以在需要的字段中填写内容了,添加完毕后,将当前记录移动到数据库中的其它记录即可。用户移动到不同记录的较简单的方法是单击数据对象的一个按钮。当用户移动到其它记录时,新的记录就按字母顺序被插入数据库中了。下面的练习演示了如何使用ReadOnly属性和AddNew方法在数据库中插入新记录。在该过程中,InputBox函数为用户提供了一些可视化反馈信息。
注:AddNew方法用来向数据库添加一条新记录。
让用户向数据库中添加记录在修改程序之前,为保护原始程序,请先以新文件名保存原始程序。
1) 在File(文件)菜单中,单击Save MyFindRec.frm As(MyFindRec.frm另存为)菜单项。将MyFindRec窗体另存为MyAddRec.frm。使用Save Project As(工程另存为)菜单项将该工程另存为MyAddRec.vbp。
2)将Data1对象的ReadOnly属性设定为False。
3)在窗体的Find按钮右边再创建一个命令按钮对象Command3,并设置“Caption”属性为“添加”。

4)双击“添加”按纽,编写代码。
Private Sub Command3_Click() Dim reply prompt$ = "Enter the new record, and then click the left arrow button." reply = MsgBox(prompt$, vbOKCancel, "Add Record") If reply = vbOK Then 'if the user clicks OK Text3.SetFocus 'move cursor to Title box Data1.Recordset.AddNew 'and get new record End If End Sub
该过程首先向用户显示一个包含数据输入提示的对话框。MsgBox函数使用vbOKCancel参数(由Visual Basic定义的数字型常量)显示一个含有OK(是)和Cancel(取消)按钮的对话框。如果用户单击OK,AddNew方法将创建一条新记录。如果用户单击Cancel,则操作被取消。该事件过程还使用SetFocus方法使Text3文本框中得到输入焦点。SetFocus方法可用来激活任何一个可以得到输入焦点的对象。
现在你就可以使用“添加”按钮向数据库添加新记录了。
运行:单击“添加”按钮,程序显示Add Record对话框,单击OK按钮,窗体中出现新的空记录。按顺序输入新记录信息(按Tab键在字段间切换)。你可以使用“添加”铵钮向zgda.mdb数据库中添加任意条记录。
3、从zgda.mdb数据库中删除记录
从数据库中删除记录时,你可以先显示出想要删除的记录,然后使用Recordset对象中的Delete方法将该条记录删除。在程序中打开数据库之前,你必须将数据对象的ReadOnly属性设定为False(在前面使用AddNew方法添加记录时你也执行过此类操作)。记录被删除后,你的代码应当显示数据库中的另一条记录,原因在于数据对象无法自动完成这一工作。一般情况下,最好的技巧是使用MoveNext方法来显示数据库中的下一条记录。
下面的练习演示了如何使用Visual Basic从zgda.mdb数据库中删除记录。要特别注意程序中MsgBox函数的用法。由于数据对象不提供“撤销”特性,因此在程序从数据库中永久删除一条记录之前,使程序确认用户的确想执行这一操作是十分重要的。
特别强调:Delete方法从数据库中永久删除一条记录。如果你不想让你的用户具有删除记录的能力,切勿为他们提供这种方法。
让用户从数据库中删除记录
注:Delete方法可以从数据库中删除一条记录。
在修改MyAddRec程序之前,为保护原始程序,请先以新文件将其存盘。
1) 在File(文件)菜单中,单击Save MyAddRec.frm As(MyAddRec.frm另存为)菜单项,将MyAddRec窗体另存为MyDelRec.frm。使用Save Project As(工程另存为)菜单项将工程另存为MyDelRec.vbp。
2) 确认Data1对象的ReadOnly属性被设置为False。
3) 在窗体中的“添加”按钮右边再创建一个命令按钮对象Command4,Caption属性为“删除”。
4) 双击“删除”按纽,编写代码。
Private Sub Command4_Click() Dim reply prompt$ = "Do you really want to delete this course?" reply = MsgBox(prompt$, vbOKCancel, "Delete Record") If reply = vbOK Then 'if the user clicks OK Data1.Recordset.Delete 'delete current record Data1.Recordset.MoveNext 'move to next record End If End Sub
该过程首先显示一个对话框,询问用户是否希望删除当前记录。同样,此处MsgBox与vbOKCancel参数一同使用,如果用户决定不想执行删除操作则可以退出。如果用户单击OK,则Delete方法将删除当前记录,同时MoveNext方法显示下一条记录。如果用户单击Cancel按钮,则删除操作被取消。
4、FileCopy语句用来对文件进行备份
对于大多数人来说,存放于数据库中的信息都十分重要,一旦数据库出了问题,他们就将面临很大的麻烦。因此,在对每个数据库做任何修改之前,你都应当先对该数据库进行备份。当所使用的备份出现问题时,你就可以简单地用原始数据库覆盖备份即可。你经常使用的备份方法也许是使用一种商业备份程序、Windows Explorer或者你的数据库软件中所包含的你自己的专用备份功能。作为一种额外的保险措施,你可以使用FileCopy语句从Visual Basic程序内部制作一个或多个文件的备份。FileCopy可以制作独立的文件备份(如同Windows Explorer中的Edit菜单下的Copy菜单项一样),其使用语法为:
FileCopy sourcepath destinationpath
其中,sourcepath(源路径)是你想备份的文件的路径名,destinationpath(目标路径)是你想建立的文件的路径名。
注意:如果源路径所指明的文件目前正被打开,则FileCopy不能正常工作。
在下面的练习中,将通过把FileCopy语句放入Form_Load事件过程中而在你的MyDelRec程序中添加备份特性。
使用FileCopy制作zgda.mdb的备份
为保护原始程序,首先你应将MyDelRec程序以新文件名存盘。
注:在启动过程中添加FileCopy语句,就可以使用户在对数据库做任何修改之前先行备份数据库了。
1) 在File(文件)菜单中,单击Save MyDelRec.frm As(MyDelRec.frm另存为)菜单项。将MyDelRec窗体另存为MyBackup.frm。使用Save Project As(工程另存为)菜单项,将该工程保存为MyBackup.vbp。
2)双击窗体(不是对象),在代码窗口中打开Form_Load事件过程。在Form_Load事件过程中输入下面的程序语句:
Private Sub Form_Load() Dim reply, FileNm As String prompt$ = "Would you like to create a backup copy of the database?" reply = MsgBox(prompt$, vbOKCancel, Data1.DatabaseName) If reply = vbOK Then 'copy the database if the user clicks OK FileNm$ = InputBox$("Enter the pathname for the backup copy.") If FileNm$ <> "" Then FileCopy Data1.DatabaseName, FileNm$ End If End If End Sub
该例程在程序启动时显示一个消息框,询问用户是否想要对数据库进行备份。MsgBox函数与vbOKCancel参数一同使用,使用户能够取消备份操作。此处MsgBox函数中又使用了DatabaseName属性以便在对话框标题条中显示数据库名称。如果用户单击了OK按钮,则出现另一个消息框,让用户指定备份文件的路径名。当用户再次单击OK按钮时,FileCopy语句就开始备份文件。
本节内容总结:
目的 |
执行步骤 |
打开数据库 |
使用Data控件在窗体中创建一个数据对象,将其DatabaseName属性设定为该数据库名。使用Connect(连接)属性指明数据库类型,使用RecordsetType(记录集合类型)属性指明记录的类型 |
以只读模式打开数据库 |
将数据对象的ReadOnly属性设定为True |
在文本框对象中显示数据字段 |
在文本框中设置DataField和DataSource属性 |
在数据库中查找数据 |
提示用户输入一个查找字符串,然后在事件过程中使用Recordset对象的Index、Seek、NoMatch和MoveFirst属性。 |
向数据库添加记录 |
使用Recordset对象的AddNew方法。例如: Date1.Recordset.AddNew |
从数据库中删除记录 |
使用Recordset对象的Delete方法。例如: Date1.Recordset.Delete |
显示数据库的第一条记录 |
使用Recordset对象的MoveFirst方法。例如:Date1.Recordset.Movefirst |
拷贝文件 |
使用FileCopy语句。例如: FileCopy Date1.DatabaseName, FileNm$ |
让对象得到输入焦点 |
使用对象的SetFocus方法。例如: text3.SetFocus |
补充说明:
数据控件常用属性
1、Connect属性
Connect属性指定数据控件所要连接的数据库类型。
2、DatabaseName属性
DatabaseName属性指定具体使用数据库的名称,包括所有的路径名。
如果连接的是单表数据库,则DatabaseName属性应设置为数据库文件所在的子目录名,而具体文件名放在RecordSource属性中。
如果在“属性”窗口中单击DatabasName属性右边的按钮,会出现一个公用对话框用于选择相应的数据库。
例如,下面语句设置了可访问的数据库名称:
如果连接一个Microsoft Access的数据库C:\职员档案.mdb,则Data1.DatabaseName=“C:\职员档案.mdb”;如果连接一个Foxpro数据库C:\yang\职员档案1.dbf,因为Foxpro数据库只含有一个表,则Data1.DatabaseName=“C:\yang”,RecordSource=“职员档案1.dbf”。
如果未写数据库文件的扩展名,则缺省情况下为使用以.mdb为扩展名的数据库文件。
3、RecordSource属性
RecordSource属性确定具体可访问的数据,这些数据构成记录集对象Recordset。
4、RecordsetType属性
RecordsetType属性确定记录集类型。
5、ReadOnly属性
在对数据库只查看不修改时,通常将ReadOnly属性设置为True,而在运行时根据一定的条件,响应一定的指令后,才将它设置为False。
6、Exclusive属性
Exclusive属性值设置为True时,则在通过关闭数据库撤消这个设置前,其他任何人不能对数据库访问。这个属性的缺省值是False。
7、BOFAction、EOFAction属性
当BOFAction值为0,控件重定位到第一个记录;BOFAction值为1,移过记录集开始位,定位到一个无效记录,触发数据控件对第一个记录的无效事件。
当EOFAction值为0,控件重定位到最后一个记录;当EOFAction值为1,移过记录集结束位,定位到一个无效记录,触发数据控件对最后一个记录的无效事件;EOFAction值为2,向记录集加入新的空记录,可以对新纪录进行编辑,移动记录指针新纪录写入数据库。
数据绑定控件常用属性
要使文本等控件与数据控件捆绑在一起,成为数据控件的绑定控件。并且能够受到数据库约束,必须在运行时对这些控件的两个属性进行设置:
1、DataSource属性
DataSource属性用来将一个有效的数据控件与一个数据库连接。
2、DataField属性
DataField属性设置数据库有效的字段与绑定控件建立联系。
数据控件上的对象
数据控件是依靠数据对象来获取对数据访问的,与其相关的数据对象有:
1、 Database对象
Database对象是物理数据库的逻辑表示。数据控件通过DatabaseName属性连接到一个具体的数据库,并通过它的Database对象表现出来。
除了数据控件获取Database对象之外,还可以在程序中定义Database对象,并通过OpenDatabase()函数实现对物理数据库的连接;或者将数据控件的Database对象传递给被定义的Database对象。
例如以下语句:
Dim Ds1 As Database '定义数据对象
Dim Ds2 As Database
Set Ds1= OpenDatabase(“e:\VB\class.mdb) '使Ds1获取物理数据库
Set Ds2=Me.data1. Database '将数据控件的Database对象传递给Ds2
2、Recordset对象
Recordset对象代表一组与数据库相关的逻辑记录集合。它所对应的数据来源可以是数据表,也可以是和SQL语言中查询语句(SELECT)有关的查询结果。
Recordset对象有三种类型:
Table类型:记录集为表集,可以显示、添加、删除和修改,具有较好的更新性能。
Dynaset类型:记录集为动态集,可以显示、添加、删除和修改,并具有较大的操作灵活性。
Snapshot类型:记录集为快照集,只能显示,具有较好的显示速度。
除了Data控件获取Recordset对象之外,还可以在程序中定义Recordset对象,并通过函数获得数据。
Dim Ds As Database '定义数据对象
Dim Rs As Recorderset
'定义记录对象
Set Ds= OpenDatabase("e:\VB\class.mdb") '使Ds获取物理数据库
Set Rs=Me.data1. Database. OpenRecordset("SElECT *FROM 学生情况",dbOpenDynaset) '以动态集方式打开从“学生情况”数据表取得的SQL查询,传给Rs对象
Set Me.data1. Recorderset=. Rs
数据控件的常用方法
1、 Refresh方法
如果在设计状态没有为打开数据控件的有关属性全部赋值,或当RecordSource在运行时被改变后,必须使用激活数据控件的Refresh方法激活这些变化。
2、 UpdateCountrols方法
UpdateCountrols方法可以将数据从数据库中重新读到被数据控件绑定的控件内。使用UpdateCountrols方法终止用户对绑定内控件的修改。
3、UpdateRecord方法
当对绑定内的控件修改后,数据控件需要移动记录集的指针才能保存修改,如果使用UpdateRecord方法可强制数据控件将绑定控件内的数据写入到数据库中而不再触发Vaildate事件。在代码中用该方法修改。
数据控件的事件
1、Reposition事件
Reposition事件发生在一条记录成为当前记录后。
只要改变记录集的指针使其从一条指针移到另一条记录。会产生Reposition事件,可以在该事件过程中建立程序,可反映出记录位置、记录总数等。
2、Validate事件
当要移动记录指针前,修改与删除记录前或卸载含有数据控件的窗体时触发Validate事件。Validate事件检查被数据控绑定的控件内的数据是否发生变化。它通过save参数(True或False)判断是否有数据发生变化,Action参数判断哪一种操作触发了Validate事件。Action参数可为下表中的值:
Action值 |
描述 |
0 |
取消对数据控件的操作 |
1 |
MoveFirst |
2 |
MovePrevious |
3 |
MoveNext |
4 |
MoveLast |
5 |
Addnew |
6 |
Updata |
7 |
Delete |
8 |
Find |
9 |
设置BookMark |
10 |
Close |
11 |
卸载窗体 |
数据库记录的增删改操作
对记录的操作能够通过Recordset对象的方法实现。其常用方法有:
1、AddNew方法
加入一条新记录到记录集内存缓冲区。
例如:Rs. AddNew
2、 Edit方法
允许对当前记录进行修改。
3、Delete方法
用于删除当前记录。
4、Update方法
把内存缓冲区的内容写进数据库文件,保存对数据库所作的改动。
5、Close方法
关闭记录集和数据库。该方法也能用在数据库对象上,将数据库关闭。
Rs.Close '关闭记录集
Ds.Close '关闭数据库
6、 Move方法
使用Move方法可代替对数据库控件对象的4个箭头的操作遍历整个记录几种的记录。
5种Move方法是:
(1)MoveFirst方法移至第一条记录
(2)MoveLast方法移至最后一条记录
(3)MoveNext方法移至下一条记录
(4)MovePrevious方法移至上一条记录
(5)Move[n]方法向前或向后移动n条记录,n为指定的数值。
例1:在窗体上用4个命令按钮代替数据控件对象的4个箭头的操作。
窗体属性设置如下:在窗体上增加4个命令按钮,将数据控件的Visible属性设置为False.。通过对4个按钮的编程代替数据控件的4个箭头。窗体如下图所示。

上一条和下一条按钮的代码需要考虑Recordset对象的边界,可用Bof和Eof属性检测记录集的首尾,如越界,则用指令定位到第一条或最后一条记录。程序代码如下:
Private Sub Command1_Click() Data1.Recordset.MoveFirst End Sub
Private Sub Command2_Click() Data1.Recordset.MovePrevious If Data1.Recordset.BOF Then Data1.Recordset.MoveFirst End Sub
Private Sub Command3_Click() Data1.Recordset.MoveNext If Data1.Recordset.EOF Then Data1.Recordset.MoveLast End Sub
Private Sub Command4_Click() Data1.Recordset.MoveLast End Sub
例2:在浏览数据库的基础上再增加5个按钮:新增、删除、修改、查找和放弃。如下图所示。

Dim editcheck As Boolean '全局变量
Private Sub Command1_Click() On Error Resume Next Command2.Enabled = Not Command2.Enabled Command3.Enabled = Not Command3.Enabled Command4.Enabled = Not Command4.Enabled Command5.Enabled = Not Command5.Enabled If Command1.Caption = "添加" Then Command1.Caption = "确认" Data1.Recordset.AddNew Text1.SetFocus Else Command1.Caption = "添加" Data1.Recordset.Updata Data1.Recordset.MoveLast
End If End Sub
Private Sub Command2_Click() Dim mst, res As String mst = "您是否真的要删除?" On Error Resume Next res = MsgBox(mst, vbOKCancel + vbExclamation) Select Case res Case vbOK Data1.Recordset.Delete Data1.Recordset.MoveNext If Data1.Recordset.EOF Then Data1.Recordset.MoveLast End Select End Sub
Private Sub Command3_Click() On Error Resume Next Command1.Enabled = Not Command1.Enabled Command2.Enabled = Not Command2.Enabled Command4.Enabled = Not Command4.Enabled Command5.Enabled = Not Command5.Enabled If Command3.Caption = "修改" Then Command3.Caption = "确认": Data1.Recordset.Edit: Text1.SetFocus Else Command3.Caption = "修改": Data1.Recordset.Updata End If End Sub
Private Sub Command4_Click() On Error Resume Next Command1.Caption = "添加": Command3.Caption = "修改" Command1.Enabled = True: Command2.Enabled = True Command3.Enabled = True: Command4.Enabled = False Command5.Enabled = True Data1.UpdateControls Data1.Recordset.MoveLast End Sub
Private Sub Command5_Click() Dim mno As String mno = InputBox$("请输入学号", "查找窗") Data1.Recordset.FindFirst "学号='" & mno & "'" If Data1.Recordset.NoMatch Then MsgBox "无此学号!", , "提示" End Sub
Private Sub Command6_Click() student.Hide: Form1.Show End Sub
Private Sub Data1_Reposition() Data1.Caption = Data1.Recordset.AbsolutePosition + 1 End Sub
Private Sub Data1_Validate(Action As Integer, Save As Integer) If editcheck = True Then If Text1.Text = "" And (Action = 6 Or Text1.DataChanged) Then MsgBox " 数据不完整,必须要有学号!" Data1.UpdateControls End If If Action >= 1 And Action <= 4 Then Command1.Caption = "添加": Command3.Caption = "修改" Command1.Enabled = True: Command2.Enabled = True Command3.Enabled = True: Command4.Enabled = False End If End If End Sub
Private Sub Form_Load() editcheck = False Command1.Enabled = True: Command2.Enabled = True Command3.Enabled = True: Command4.Enabled = False Command5.Enabled = True End Sub
|