We have an VB6 application that used Ms-Access 97 database files in conjunction with a workgroup file. To keep users from accidentically opening the files directly, we have changed the extension of the files from mdb
and mdw
to sdb
and sdw
, respectively.
The next Version of our application is to run with Ms-Access 2013 databasees. We also have done the extension mangling with the new accdb
files, they now have the extension sccdb
.
Since Microsoft is discontinuing the use of old mdb files in MSO 2013 (read: MS-Access 2013 can't open the old mdb/sdb files any more, which we have to do to update data), we want to transport the data from one of the old file's tables to a table in the new accdb file (that already contains the correct table).
To do that I am currently doing the following:
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
I have no idea how to tell the open connection that the file actually is an MDB (=SDB) and that there is an MDW (=SDW) with a username and password.
Does anybody have a clue how to formulate this in an Execute(...)
command?
I really would like to avoid having to copy all records in big for loop using a recordset.
Any help is greately appreciated.
Edit: Thank you all for you comments and hints, here is what I finally did: We are using the Microsoft Access Database Engine 2010 Redistributable as a backend (http://www.microsoft.com/en-us/download/confirmation.aspx?id=13255) and are copying all records field by field. The behaviour is quite strange, as ADODB lets me open a renamed accdb or mdb file very nicely using the respective providers in the connectionstring (accdb/sccdb: "Microsoft.ACE.OLEDB.12.0", mdb/sdb: "Microsoft.Jet.OLEDB.4.0"), but there seems to be no way to convince a connection that is running on an accdb provider to open an mdb for the abovementioned INSERT command. So - what I do is open two connections to the two files and then shove the data across using a function like this:
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