今天研究了一下很久以前就看到的vb把Excel写入Access和Access写入Excel的函数。
先看这两个函数(原来有些错误,我改掉了,还有记得要引用“Microsoft DAO 3.6 Object Library”):
Private Sub XlsToMdb(sExcelPath As String, sAccessDBPath As String, sSheetName As String, sAccessTable As String)
'功能:将Excel文件中的工作簿导出到Access数据库中的表
'输入参数1、sExcelPath:要导出资料的 Excel 档案路径名称 (Workbook path),例如 C:\book1.xls
'输入参数2、sAccessDBPath:要导入的 Access 档案路径名称,例如 C:\Test.mdb
'输入参数3、sSheetName:要导出资料的文件名称 (Sheet name),例如 Sheet1
'输入参数4、sAccessTable:要导入的 Access Table 名称,例如 TestTable
'作者:YOKI 最后修改:2003-08-21
'调用:Call XlsToMdb("c:\book1.xls","c:\test1.mdb",,"$Sheet1","TestTable")
'结果:將 C:\book1.xls 中的 Sheet1 导入 C:\Test.mdb 成为 TestTable
Dim db As Database
Set db = OpenDatabase(sExcelPath, True, False, "Excel 5.0")
db.Execute ("Select * into [;database=" & sAccessDBPath & "]." & sAccessTable & " FROM [" & sSheetName & "$]")
End Sub
Public Sub MdbToxls(sAccessFileName As String, sExcelPath As String, sSheetName As String, sAccessTable As String)
'功能:将Access数据库中表导出到Excel文件中
'输入参数1:cAccessFileName Access文件全路径 如:c:\temp\test1.mdb
'输入参数2:sExcelPath Excel文件的全路径 如:c:\temp\test2.xls
'输入参数3:sSheetName Excel中的工作簿名 如:$Sheet1
'输入参数4:sAccessTable Access数据库中的表 如:Table1
'作者:YOKI 最后修改:2003-08-21
'调用:Call MdbToxls("c:\temp\test1.mdb","c:\temp\test2.xls","$Sheet1","Table1")
'结果:将C:\temp\test1.mdb中的Table1表导入到c:\temp\test2.xls的$Sheet1中
Dim db As DAO.Database
Set db = Workspaces(0).OpenDatabase(sAccessFileName)
db.Execute "SELECT * INTO [Excel 8.0;DATABASE=" & sExcelPath & "].[" & sSheetName & "] FROM [" & sAccessTable & "]"
db.Close
Set db = Nothing
End Sub
看看这两个函数,都相当简单,就一句sql就完成了。
我发现这两个函数速度非常快,专门弄了一个5000行10列的Excel表格,先复制到Access,再复制回来,大概也就1秒。
想起了原来写的一个波形分析的程序,读取Excel非常慢,所以就想用这种办法改一下那个程序看看。
下面是原来程序读取Excel的部分,从Excel读取数据,存到data数组里面
Private Sub GetData2()
Dim ColCount As Long, RowCount As Long
Dim i As Long '行
Dim j As Long '列
Dim xlApp As New Excel.Application
Dim xlBook As Excel.Workbook
Dim xlsheet As Excel.Worksheet
xlApp.Visible = False
Set xlBook = xlApp.Workbooks.Open(App.Path & "\aaa.XLS")
Set xlsheet = xlBook.Worksheets(1)
ColCount = xlsheet.UsedRange.Cells.Columns.Count '得到总列
RowCount = xlsheet.UsedRange.Cells.Rows.Count '得到总行
ReDim Data(RowCount - 2, ColCount) '前两行不是数据,所以可以少掉2行
For i = 3 To RowCount
For j = 1 To ColCount
Data(i - 2, j) = xlsheet.Cells(i, j) '先行后列
Next j
Next i
xlBook.Close
xlApp.Quit
Set xlApp = Nothing
End Sub
修改后的程序Private Sub GetData()
Dim db As Database
Dim rs As Recordset
Dim i As Integer
Dim j As Integer
Set db = OpenDatabase(App.Path + "\aaa.xls", True, False, "Excel 5.0")
Set rs = db.OpenRecordset("select * from [sheet1$]")
i = 1
rs.MoveLast
ReDim Data(rs.RecordCount - 1, 2)
rs.MoveFirst
rs.MoveNext
While Not rs.EOF
Data(i, 1) = rs.Fields(0).Value
Data(i, 2) = rs.Fields(1).Value
i = i + 1
rs.MoveNext
Wend
End Sub
可以看出,用这种办法读取Excel速度比原来快多了。这个程序最重要的地方就是那个sql语句,下面分析一下。
Select * into [;database=" & sAccessDBPath & "]." & sAccessTable & " FROM [" & sSheetName & "$]
用几个参数代进去
Select * into [;database="c:\1.mdb"].table1 FROM [Sheet1$]
select是选择语句,加个into [;database="c:\1.mdb"].table1就是把结果直接存入数据库,from字句表示了把Sheet1当成一个数据库的表(要在Sheet1后面加个$,不然就找不到表),这其实也就是一句简单的sql语句
从这里可以想象,读取excel的语句大概是这样"select * from sheet1$"这样的形式
引用的DAO组件有rs对象,db对象,经过实验后,发现Set rs = db.OpenRecordset("select * from [sheet1$]")就可以把Excel读出来放到rs这个记录集里面,后面的操作就简单了,跟操作数据库的记录集一摸一样,不过其中有两个地方要注意。
1、这个Excel文件前两行都不是数据,如下
| A1 |
Buffer( ) | Decimal |
这样读出来记录集,Field(0).name="F1"不知道哪里来的,Field(1).name="A1"这个是对的
然后第一条记录不能读,不然会有错误,我是先后移一条记录开始读取,就没问题了
2、如果要读取rs.recordcount,要先rs.movelast,不然读取到的数值会比较小,可能vb有啥优化吧。