(一)非access数据库的新建及库结构的修改 VB专业版中的数据库存取对象变量可以分为两类,一类用于数据库结构的维护和管理,另一类用于数据的存取。其中表示数据库结构时可以使用下面的对象:DataBase、TableDef、Field、Index,以及三个集合(Collection):TableDefs、Fields和Indexes。每一个集合都是由若干个对象组成的,这些数据对象的集合可以完全看作是一个数组,并按数组的方法来调用。 一旦数据库对象建立后,就可以用它对数据库的结构进行修改和数据处理。 对于非Access数据库,大部分都是对应于一个目录,所以可以使用VB的MkDir语句先生成一个目录,亦即新建一个数据库。而每一个非access数据库文件可看作是此目录下的一个数据表(Table),但实际上它们是互相独立的。 下面是新建一个FoxPro 2.5格式数据库的程序实例。 Sub CreateNew ( ) Dim Db1 As database, Td As TableDefs Dim T1 As New Tabledef,F1 As New Field, F2 As New Field, F3 As New Field Dim Ix1 As New Index Dim Path As String Const DB_TEXT = 10,DB_INTEGER = 3 ChDir "\" Path$ = InputBox( "请输入新路径名:", "输入对话框" ) MkDir Path$ ’新建一个子目录 Set Db1 = OpenDatabase(Path$, True, False, "FoxPro 2.5;") Set Td = Db1.TableDefs T1.Name = "MyDB" ’新建一个数据表,数据表名为MyDB F1.Name = "Name", F1.Type = DB_TEXT, F1.Size = 20 F2.Name = "Class", F2.Type = DB_TEXT, F2.Size = 20 F3.Name = "Grade", F3.Type = DB_INTEGER T1.Fields.Append F1 ’向数据表中添加这些字段 T1.Fields.Append F2 T1.Fields.Append F3 Ix1.Name = "Name" ,Ix1.Fields = "Name", Ix1.Primary = True ’新建索引 T1.Indexes.Append Ix1 ’向数据库的Indexes集合中添加新的索引 Td.Append T1 ’向TableDefs集合中添加新表 Db1.Close ’必须先关闭数据库对象再退出 End Sub 在此段程序中值得注意的是,对非Access数据库的新建不用CreateDatabase函数,而是用OpenDatabase函数,这点与Access数据库大不一样,但也仅仅是针对非access数据库而言才能用OpenDatabase函数来新建一个数据库对象。 在VB中,外来数据库的不同格式只在OpenDatabase函数的最后一个参数Connect中有所体现,不同格式的外来数据库其Connect参数值也不同,除此以外,在VB专业版中其编程的方法和步骤及技巧是基本相同的。 新建子目录后,不能用ChDir语句进入它,否则会出现“‘MyDB’ is not a valid path”的错误。同时,对F1、F2、F3等新建字段对象的定义也必须分别定义,否则会出现“Element not defined”(变量未定义)的错误。 通过一定的编程技巧还可以实现非access数据库的库结构的拷贝,下面是一段相应的程序。 Function GetPos( TFname$ ) ’此自定义函数完成对带路径文件名中最后一个“\”符号的定位 Dim I As Integer,Tmp As String Tmp$ = TFname$ For I = 0 To 255 Pos% = Pos% + InStr( 1, Tmp$, "\" ) E1% = InStr( 1, Tmp$, "\" ) Tmp$ = Right$( Tmp$, Len(TFname$) - Pos% ) If E1% = 0 Then ’找到最后一个“\”符号的位置,并记下来 GetPos = Pos% Exit For End If Next I End Funtion Sub CopyStruc( ) Dim Db1 As database, Ds1 As Dynaset,Td As TableDefs, Fld As Fields Dim Fname,SourceF,DestF,Path As String,Pos1 As Integer CMD1.Filter = "FoxPro数据库文件(*.DBF)|*.DBF|所有文件|*.*" ’CMD1为一个对话框的控制名 CMD1.DialogTitle = "调入Ms FoxPro数据库文件" CMD1.FilterIndex = 1 CMD1.Action = 1 DestF$ = InputBox$( "请输入目标文件名:", "输入对话框" ) If CMD1.FileName = “ ”Or DestF$ = " " Then MsgBox "源文件或目标文件名为空" Exit Sub Else SourceF$ = CMD1.Filename End If FileCopy SourceF$, DestF$ Pos1% = GetPos( SourceF$ ) Path$ = Left$( SourceF$, Pos1% ) ’获得源文件所在的路径名 Fn$ = Left$( DestF$, InStr(1, DestF$, ".") - 1 ) ’获得新文件的数据库名 ’Fn$为实际的Foxpro数据库名,也即CreateDynaset函数内的source属性值 Set Db1 = OpenDatabase( Path$, True, False, "FoxPro 2.5;" ) Set Ds1 = Db1.CreateDynaset( Fn$ ) If Ds1.EOF And Ds1.BOF Then ’数据库内的无记录则退出 TotalNum% = 0 MsgBox "此数据表为空表!" Exit Sub End If ’删除记录,保留库结构 Ds1.MoveFirst Do Ds1.Delete Ds1.MoveNext Loop Until Ds1.EOF End Sub 可见,拷贝库结构的方法在于把一个已存在的数据库拷贝到一个新文件中,然后再删除新文件内的所有记录,保留其库结构,得到的就是一个新建的库结构完整的空库。
(二)非access数据库的动态调入 在实际应用的很多情况下,经常需要在对一些事先并不知道其具体库结构的数据库进行调入、显示及打印其记录。因而实现未知格式数据库的动态调入也是评价VB数据库应用程序兼容性的一个重要标志。 在VB中,网格控件非常适合用于浏览数据库中的数据,只需把数据放入网格即可。 在使用网格时动态调入的关键在于记录(Colume)内容和字段(Row)内容(包括字段的名称、类型、值等)的读取,因而生成一个可以对应于一个或多个数据表中的全部或部分记录的Dynaset对象是非常必要的。Dynaset对象还可以是一个动态查询的结果,能进行记录的增加、删除和修改等操作。 下面是一段用网格显示FoxPro数据库的程序。 Sub DBLoad( ) Dim Db1 As database, Ds1 As Dynaset,Td As TableDefs,Fld As Fields Dim Fname,Tmp,Path ToTalNum As String,I,J,Pos1 As Integer Dim MyNum ’定义一个变体型数据 CMD1.Filter = "FoxPro数据库文件(*.DBF)|*.DBF|所有文件|*.*" CMD1.DialogTitle = "调入Ms FoxPro数据库文件" CMD1.FilterIndex = 1 CMD1.Action = 1 Fname$ = CMD1.Filename Pos1% = GetPos( Fname$ ) Path$ = Left$( Fname$, Pos1% ) Tmp$ = Right$( Fname$, Len(Fname$)-Pos1) Fn$ = Left$( Tmp$, Instr( 1,Tmp$,“.”) - 1 ) Set Db1 = OpenDatabase( Path$, True, False, "FoxPro 2.5;" ) Set Ds1 = Db1.CreateDynaset( Fn$ ) If Ds1.EOF And Ds1.BOF Then '数据库表内无记录则退出 TotalNum = 0 MsgBox "此数据表为空表!" Exit Sub Else '显示数据库表内的实际记录数 Ds1.MoveLast TotalNum = Ds1.RecordCount Grid1.Rows = TotalNum + 1 ’置网格的实际行数 Total.Caption = Str$(TotalNum) End If '置网格的实际列数并置每列的宽度 Set Td = Db1.TableDefs Set Fld = Td( Fn$ ).Fields Grid1.Cols = Fld.Count + 1 Grid1.ColWidth(0) = 600 For I = 1 To Fld.Count Grid1.ColWidth(I) = 1500 Next I '在网格的第一行内填入字段名 Grid1.Row = 0, Grid1.Col = 0 Grid1.Text = "序号" For I = 1 To Fld.Count Grid1.Col = I Grid1.Text = Fld(I - 1).Name Next I '在网格中填入相应的数据 Ds1.MoveFirst I = 1 Do While Not Ds1.EOF Grid1.RowHeight(I) = 300 Grid1.Row = I Grid1.Col = 0 Grid1.Text = I For J = 1 To Fld.Count Grid1.Col = J MyNum = Ds1.Fields(J - 1).Value '对记录的数据类型进行判断后做相应的处理 If IsNumeric( MyNum ) Or IsDate( MyNum ) Then Grid1.Text = Str$( Ds1.Fields(J - 1).Value ) Else If VarType( MyNum ) = 8 Then Grid1.Text = Ds1.Fields(J - 1).Value Else If VarType( MyNum ) = 0 Or VarType( MyNum ) = 1 Then Grid1.Text = " " End If On Error Resume Next Next J Ds1.MoveNext I = I + 1 Loop Ds1.Close Db1.Close Exit Sub 最后应记住,在VB的数据库应用程序运行之前,一定要在AUTOEXEC.BAT文件中加入一句SHARE.EXE /L:500。 以上所有程序均在Pentium/166机、中文Windows95下用VB4调试通过。