我们有一个VB6应用程序,它将Ms-Access 97数据库文件与工作组文件结合使用。为防止用户直接意外打开文件,我们已将文件的扩展名分别从mdb
和mdw
更改为sdb
和sdw
。
我们的应用程序的下一个版本是与Ms-Access 2013数据库一起运行。我们还使用新的accdb
文件完成了扩展修改,它们现在具有扩展名sccdb
。
由于Microsoft在MSO 2013中停止使用旧的mdb文件(阅读:MS-Access 2013无法再打开旧的mdb / sdb文件,我们需要更新数据),我们希望从中传输数据旧文件的表之一到新accdb文件中的表(已包含正确的表)。
为此,我目前正在做以下事情:
Const cNewFile = "C:\test\myNewAccdb.sccdb" 'new DB
Const cOldFile = "C:\test\myOldMDB.sdb" 'old DB
Const cOldMDW = "C:\test\myOldMDW.sdw" 'workgroup file of old DB, no Idea where to put this
Const cOldMDWUsr = "user" 'username and pwd for old mdw/sdw
Const cOldMDWPwd = "pass" ' also no idea where to put this
Dim dbConn As ADODB.Connection
Dim tName As String
tName = "Table1" 'name of table to work with
Set dbConn = new ADODB.Connection 'connection to new db
dbConn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source= " & cnewfile
'remove existing data in new table
dbConn.Execute "DELETE FROM " & tName, , adExecuteNoRecords
'now the tricky part: Copy all rows from the old mdb/sdb ****************
dbConn.Execute "INSERT INTO " & tName & " SELECT * FROM " & _
"[MSAccess;DATABASE=" & cOldFile & ";].[" & tName & "]"
' ***********************************************************************
'this currently leads to an "could not find installable isam" error
我不知道如何告诉打开的连接文件实际上是MDB(= SDB),并且有一个带有用户名和密码的MDW(= SDW)。
有人知道如何在Execute(...)
命令中制定这个吗?
我真的想避免使用记录集复制big for循环中的所有记录。
任何帮助都非常感激。
编辑: 谢谢大家的评论和提示,这是我最后做的: 我们使用Microsoft Access数据库引擎2010 Redistributable作为后端(http://www.microsoft.com/en-us/download/confirmation.aspx?id=13255)并逐字段复制所有记录。这种行为很奇怪,因为ADODB允许我使用connectionstring中的相应提供程序非常好地打开重命名的accdb或mdb文件(accdb / sccdb:“Microsoft.ACE.OLEDB.12.0”,mdb / sdb:“Microsoft.Jet。 OLEDB.4.0“),但似乎无法说服在accdb提供程序上运行的连接为上述INSERT命令打开mdb。 所以 - 我所做的是打开两个文件的两个连接,然后使用这样的函数推送数据:
Public Sub DB_Copy_Table(dbConnNew As ADODB.Connection, _
dbConnOld As ADODB.Connection, _
TableName As String)
Dim f As Long
Dim rsOld As ADODB.Recordset, rsNew As ADODB.Recordset
On Error GoTo err_Copy
'delete new data
dbConnNew.Execute "DELETE FROM " & TableName, i, adExecuteNoRecords 'adExecuteNoRecords=128
Set rsOld = New ADODB.Recordset'make a recordset for old data
With rsOld
.CursorType = adOpenStatic
.CursorLocation = adUseClient
.LockType = adLockReadOnly
.Open "select * from " & TableName, dbConnNew
End With
Set rsNew = New ADODB.Recordset'make a recordset into the new table
With rsNew
.CursorType = adOpenDynamic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open "select * from " & TableName, dbConnNew
End With
If rsOld.RecordCount > 0 Then
rsOld.MoveFirst'copy data if we have some
Do While Not rsOld.EOF
rsNew.AddNew
For f = 0 To rsOld.Fields.Count - 1
rsNew.Fields.Item(f).value = rsOld.Fields.Item(f).value
Next
rsNew.Update
rsOld.MoveNext
Loop
End If
End Sub
答案 0 :(得分:1)
您的问题不是Access 2013无法打开具有用户级安全性(ULS)的.mdb文件。实际上,Access 2013仍然可以选择使用受ULS保护的.mdb文件,包括“用户级安全向导”以及“文件”选项卡上“管理用户和权限”下的相关实用程序。
您的问题是Access 2013无法与Access 97数据库文件 完全 一起使用,无论它们是否受ULS保护。此外,它不仅仅是Microsoft Access 2013(应用程序)拒绝使用Access 97文件的功能,相应版本的Access数据库引擎(版本15.0)也拒绝与Access 97文件有任何关系。
因此,如果一台机器安装了Access 2013并且您的应用程序指定了“Microsoft.ACE.OLEDB.12.0”,那么您实际上使用的是ACE 15.0版,而不是版本12.0,并且您将无法打开 any 访问97 .mdb文件。 (有关详细信息,请参阅我的其他答案here。)
您可以通过标准化Access 2010后端(而不是Access 2013)来避免一些不便,因为该版本的ACE仍将读取Access 97文件。但是,对于已经拥有Access 2013的用户,您仍然需要一种方法来升级旧数据库文件,而无需降级到Access 2010。
实现这一目标的一种方法是创建一个32位转换应用程序,该应用程序使用旧的Jet数据库引擎将Access 97文件转换为Access 2013可以使用的格式。一个简单的VBScript示例就是这样......
Option Explicit
Const dbLangGeneral = ";LANGID=0x0409;CP=1252;COUNTRY=0"
Const dbVersion40 = 64
Const dbFailOnError = 128
Dim dbe, con
Dim sourceDbSpec, mdwSpec, destinationDbSpec, uid, pwd, tableName
sourceDbSpec = "Z:\_test\a97file.mdb"
mdwSpec = "Z:\_test\Security.mdw"
destinationDbSpec = "Z:\_test\converted.mdb"
uid = "Gord"
pwd = "whatever"
tableName = "Table1"
Set con = CreateObject("ADODB.Connection")
con.Open _
"Driver={Microsoft Access Driver (*.mdb)}" & _
";Dbq=" & sourceDbSpec & _
";SystemDB=" & mdwSpec & _
";Uid=" & uid & _
";Pwd=" & pwd
' create target .mdb file
Set dbe = CreateObject("DAO.DBEngine.36")
dbe.CreateDatabase destinationDbSpec, dbLangGeneral, dbVersion40
Set dbe = Nothing
' copy table
con.Execute _
"SELECT * " & _
"INTO [;Database=" & destinationDbSpec & "].[" & tableName & "] " & _
"FROM [" & tableName & "]", _
dbFailOnError
con.Close
Set con = Nothing
...将创建Access 2003 .mdb文件。然后,该文件可以通过Access 2013版本的Access数据库引擎导入到.accdb文件中。