Как скопировать содержимое таблицы из файла Access 97 в файл Access 2013
У нас есть приложение VB6, которое использовало файлы базы данных Ms-Access 97 вместе с файлом рабочей группы. Чтобы пользователи не могли случайно открыть файлы напрямую, мы изменили расширение файлов с mdb
а также mdw
в sdb
а также sdw
соответственно. Следующая версия нашего приложения должна работать с базами данных Ms-Access 2013. Мы также продлили искажение с новым accdb
файлы, теперь они имеют расширение sccdb
, Поскольку Microsoft прекращает использование старых файлов mdb в MSO 2013 (читай: 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(...)
команда? Я действительно хотел бы избежать необходимости копировать все записи в большом цикле, используя набор записей. Любая помощь с благодарностью.
Изменить: Спасибо всем за ваши комментарии и советы, вот что я наконец-то сделал: Мы используем Microsoft Access Database Engine 2010 в качестве бэкэнда ( http://www.microsoft.com/en-us/download/confirmation.aspx?id=13255) и копируют все записи поле за полем. Поведение довольно странное, так как ADODB позволяет мне очень красиво открыть переименованный файл accdb или mdb, используя соответствующих провайдеров в строке соединения (accdb/sccdb: "Microsoft.ACE.OLEDB.12.0", mdb/sdb: "Microsoft.Jet.OLEDB.4.0"), но, похоже, нет способа убедить соединение, работающее на провайдере accdb, открыть mdb для вышеупомянутой команды INSERT. Итак, что я делаю, это открываю два соединения с двумя файлами, а затем перенаправляю данные, используя такую функцию:
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
1 ответ
Ваша проблема не в том, что Access 2013 не может открыть файлы.mdb с помощью пользовательской безопасности (ULS). На самом деле Access 2013 по-прежнему имеет опции для работы с файлами.mdb, защищенными ULS, включая "Мастер безопасности на уровне пользователя" и связанные утилиты в разделе "Управление пользователями и разрешениями" на вкладке "Файл".
Ваша проблема в том, что Access 2013 не будет работать с файлами базы данных Access 97 вообще, независимо от того, защищены ли они ULS или нет. Кроме того, это не просто функция Microsoft Access 2013 (приложение), отказывающаяся работать с файлами Access 97, соответствующая версия Access Database Engine (версия 15.0) также отказывается иметь какое-либо отношение к файлам Access 97.
Таким образом, если на компьютере установлен Access 2013 и ваше приложение указывает "Microsoft.ACE.OLEDB.12.0", вы фактически используете версию 15.0 ACE, а не версию 12.0, и вы не сможете открыть файл Access 97 .mdb. (Для получения дополнительной информации см. Мой другой ответ здесь.)
Можно избежать некоторых неудобств, стандартизировав серверную часть 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. Этот файл затем может быть импортирован в ваш файл.accdb с помощью Access 2013 версии Access Database Engine.