Is there a way to programmatically convert an Access 2010 ACCDB file to an Access 95/97 MDB file?
Here are some notes. I do not have an old version to play around with, so I do not know if you can import more than you can export:
Dim ws As Workspace
Dim db As Object
Dim tdf As TableDef
Dim qdf As QueryDef
Dim dbExp As Database
Dim acApp As New Access.Application
acApp.OpenCurrentDatabase "z:\docs\demo.accdb"
Set dbExp = acApp.CurrentDb
Set ws = DBEngine.Workspaces(0)
FName = "z:\docs\oldver95.mdb"
''Access 95
Set db = ws.CreateDatabase(FName, dbLangGeneral, dbVersion30)
''You can only export tables and a limited range of datatypes
For Each tdf In dbExp.TableDefs
If Left(tdf.Name, 4) <> "Msys" Then
acApp.DoCmd.TransferDatabase acExport, "Microsoft Access", _
FName, acTable, tdf.Name, tdf.Name
End If
Next
See http://msdn.microsoft.com/en-us/library/office/bb243161(v=office.12).aspx
A few notes using VBScript to demonstrate using the engine:
Dim objEngine
Dim objWS
Dim objDB
Dim db: db = "z:\docs\oldver95.mdb"
Set objEngine = CreateObject("DAO.DBEngine.36")
Set objDB = objEngine.OpenDatabase(db)
strSQL="SELECT * FROM Table1"
objDB.CreateQueryDef "Query1", strSQL
Related
I'm trying to write query/table contents from access to excel using vba. Currently my code is working to open new workbook every time and write the contents instead i need to specify the path of only one workbook to write. How do i specify the path in the code
My Access VBA
Function WriteToExcel()
Dim cnn As ADODB.Connection
Dim rst As New ADODB.Recordset
Dim strSQL As String
Dim strPath As String
Dim ws As Excel.Application
Dim i As Long
'*************************************************
'First stage is to take the first query and place it
'On sheet1
'*************************************************
Set cnn = CurrentProject.Connection
Set rst = New ADODB.Recordset
strSQL = "SELECT * FROM query1"
rst.Open strSQL, cnn, adOpenKeyset, adLockOptimistic, adCmdTableDirect
rst.MoveFirst
Set ws = CreateObject("Excel.Application")
With ws
.Workbooks.Add
.Visible = True
End With
ws.Sheets("sheet1").Select
For i = 0 To rst.Fields.Count - 1
ws.ActiveCell.Offset(0, i).Value = rst.Fields(i).Name
Next
ws.Range("a2").CopyFromRecordset rst
ws.Columns("A:Q").EntireColumn.AutoFit
rst.Close
End Function
I think there is a little confusion because of your variable prefixes. I've taken the liberty of amending your prefixes and answered the problem. You need Workbooks.Open(<<filename goes here>>) in place of Workbooks.Add. So try this code (untested as I do not have Access). Lastly there are other ways to populate Excel with data from Access, like a DataQuery. You might like to play with Excel GUI to investigate.
Function WriteToExcel()
Dim cnn As ADODB.Connection
Dim rst As New ADODB.Recordset
Dim strSQL As String
Dim strPath As String
Dim appXL As Excel.Application
Dim wb As Excel.Workbook
Dim wsSheet1 As Excel.Worksheet
Dim i As Long
'*************************************************
'First stage is to take the first query and place it
'On sheet1
'*************************************************
Set cnn = CurrentProject.Connection
Set rst = New ADODB.Recordset
strSQL = "SELECT * FROM query1"
rst.Open strSQL, cnn, adOpenKeyset, adLockOptimistic, adCmdTableDirect
rst.MoveFirst
Set appXL = CreateObject("Excel.Application")
With appXL
'Set wb = .Workbooks.Add '<--- to create a new workbook
Set wb = .Workbooks.Open("c:\temp\Myworkbook.xlsx") '<--- to open an exisiting workbook
.Visible = True
End With
Set wsSheet1 = wb.Sheets("sheet1")
wsSheet1.Select
For i = 0 To rst.Fields.Count - 1
wsSheet1.ActiveCell.Offset(0, i).Value = rst.Fields(i).Name
Next
wsSheet1.Range("a2").CopyFromRecordset rst
wsSheet1.Columns("A:Q").EntireColumn.AutoFit
rst.Close
End Function
At start up, my front end front.accdr database links to a back end back.accde using:
DoCmd.TransferDatabase acLink, "Microsoft Access", "back.accde", acTable, "aTable", "aTable"
The back end really needs to be encrypted and so I need to use a password to connect to the encrypted DB. How would I do this?
If you can't find a way to include the database password with TransferDatabase, you can create the table link as a new member of the DAO.TableDefs collection.
I confirmed this code works in an Access 2007 ACCDR file.
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim strConnect As String
Dim strDbFile As String
Dim strLinkName As String
Dim strPassword As String
Dim strSourceTableName As String
strDbFile = "C:\share\Access\PasswordEquals_foo.accdb"
strPassword = "foo"
strSourceTableName = "Contacts"
strLinkName = "link_to_contacts"
strConnect = "MS Access;PWD=" & strPassword & _
";DATABASE=" & strDbFile
Debug.Print strConnect
Set db = CurrentDb
Set tdf = db.CreateTableDef
tdf.Connect = strConnect
tdf.SourceTableName = strSourceTableName
tdf.Name = strLinkName
db.TableDefs.Append tdf
Beware that, even with an ACCDR, anyone who can read the link's TableDef.Connect property will be able to see the stored database password. For example, the following code displays "MS Access;PWD=foo;DATABASE=C:\share\Access\PasswordEquals_foo.accdb" in the Immediate window.
Dim dbRemote As DAO.Database
Dim objWorkspace As Workspace
Set objWorkspace = CreateWorkspace("", "admin", "", dbUseJet)
Set dbRemote = objWorkspace.OpenDatabase("C:\share\Access\Database2.accdr")
Debug.Print dbRemote.TableDefs("link_to_contacts").Connect
dbRemote.Close
objWorkspace.Close
So the link compromises the security of an encrypted db file.
The method I used to do this is actually quite simple:
Set db = CurrentDb
Set dblink = DBEngine.OpenDatabase(strDbFile, False, False, ";PWD=" & strP)
For Each strTable In strLinkedTablesArray
DoCmd.TransferDatabase acLink, "Microsoft Access", dblink.name, acTable, _
strTable, strTable
Next
I have a split database. Experimenting with the frontend, I was able to add fields to a table in the linked backend using VBA until I encrypted the backend with a password.
Is it possible to still add fields to tables in the backend using VBA in the frontend WITHOUT decrypting the backend manually?
Thanks for any reply.
It should be. Try these notes:
Sub AlterDB()
Dim db As DAO.Database
Dim sDB As String
Dim tdf As TableDef
Dim fld As Field
''Encrypted
sDB = "Z:\Docs\Test.enc"
''http://msdn.microsoft.com/en-us/library/office/ff193474.aspx
''Password is case sensitive
Set db = OpenDatabase(sDB, False, False, "MS Access;PWD=pW")
''Option with tabledef
''The table is currently closed
Set tdf = db.TableDefs("table1")
Set fld = tdf.CreateField("NewField", dbText, 20)
tdf.Fields.Append fld
''Option with DDL
ssql = "ALTER TABLE table1 ADD COLUMN AnotherNew Int"
db.Execute ssql, dbFailOnError
End Sub
Sub ListFields()
sDB = "Z:\Docs\Test.enc"
Set db = OpenDatabase(sDB, False, False, "MS Access;PWD=FB")
Set tdf = db.TableDefs("table1")
For Each f In tdf.Fields
Debug.Print f.Name
Next
End Sub
I have an import which I made with the wizard, at least far enough just to save the specification. It imports CSV files, with headers, quote text qualifiers, and comma delimited. I then use the import specification in some vba that fires from a button click event.
Here are some things I am wondering:
So if the fields in the data are out of order the import fails? if the data does not contain all the fields the import fails? if there are extra fields in the data the import fails?
So is there any kind of validation I can do to the data getting imported th ensure that the fields are the same as the spec, they are in the right order (if they need to be), etc.
This works pretty well, but I just see that if something in the data is out of the normal it will import anyway, and throw the whole time off.
Also....this is not a typical access set up...this is mainly for a team of data analysts to import files into a mdb...there is not an front end with this.
thanks
justin
You can inspect the CSV file using an ADO recordset.
Public Sub InspectCsvFile()
Const cstrFolder As String = "C:\Access\webforums"
Const cstrFile As String = "temp.csv"
Dim i As Integer
Dim strConnect As String
Dim strSql As String
'early binding requires reference, Microsoft ActiveX Data Object Library '
'Dim cn As ADODB.Connection '
'Dim rs As ADODB.Recordset '
'Dim fld As ADODB.Field '
'Set cn = New ADODB.Connection '
'Set rs = New ADODB.Recordset '
'late binding; no reference needed '
Dim cn As Object
Dim rs As Object
Dim fld As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
cstrFolder & ";Extended Properties=""text;HDR=Yes;FMT=Delimited"";"
'Debug.Print strConnect '
cn.Open strConnect
strSql = "SELECT * FROM " & cstrFile & ";"
rs.Open strSql, cn
Debug.Print "Fields.Count: " & rs.Fields.Count
For i = 0 To rs.Fields.Count - 1
Set fld = rs.Fields(i)
Debug.Print i + 1, fld.Name, fld.Type
Next i
Set fld = Nothing
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
If that connection string doesn't work for you, see Connection strings for Textfile
I would provide them with a protected spreadsheet in the correct format. The protection ensures that they cannot alter it.
Provide them with the error report if/when it fails to import.
I'm trying to import tables from a FoxPro 9.0 database into Access 2003. So far, from Google searches and many trials, the only way for me to connect to the tables is through an OLE DB connection programatically. I have set up 3 ODBC connections with different configurations but none of them work: I get "unspecified errors" that I can't find any information on.
With OLE DB I can succesfully connect to the FoxPro database, and import tables in ADO recordsets. The problem is that I can't save the recordset into new table in the local database using SQL. The ADO recordsets behave differently than tables, so I can't query them. The code below gives me a "type mismatch" error at DoCmd.RunCommand ("select * from " & rst & " INTO newClients").
Sub newAdoConn()
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim strSQL As String
Dim decision As Integer
Set cnn = New ADODB.Connection
cnn.ConnectionString = "Provider=vfpoledb;" & _
"Data Source=s:\jobinfo\data\jobinfo.dbc;" & _
"Mode=ReadWrite|Share Deny None;" & _
"Collating Sequence=MACHINE;" & _
"Password=''"
strSQL = "Select * from Jobs"
cnn.Open
Set rst = cnn.Execute("Select * from clients")
If rst.EOF = False Then
Do While Not rst.EOF
decision = MsgBox(rst.Fields!ID & " " & rst.Fields!fname & " " & rst.Fields!lname & vbCrLf & vbCrLf & "Continue?", vbYesNo)
If decision = vbYes Then
rst.MoveNext
Else
Exit Do
End If
Loop
End If
DoCmd.RunCommand ("select * from " & rst & " INTO newClients")
rst.Close
Set rst = Nothing
cnn.Close
Set cnn = Nothing
End Sub
I finally worked out a decent solution. It involves saving the ado recordset from memory to an excel file using the copyFromRecordset function, and then linking the file programmatically to a table in excel using the TransferSpreadsheet()...
Sub saveToExcel()
Dim cnn As ADODB.Connection
'declare variables
Dim rs As ADODB.Recordset
Dim strSQL As String
Dim decision As Integer
Dim colIndex As Integer
' Dim fso As New FileSystemObject
' Dim aFile As File
'set up connection to foxpro database
Set cnn = New ADODB.Connection
cnn.ConnectionString = "Provider=vfpoledb;" & _
"Data Source=s:\jobinfo\data\jobinfo.dbc;" & _
"Mode=ReadWrite|Share Deny None;" & _
"Collating Sequence=MACHINE;" & _
"Password=''"
cnn.Open
Set rs = cnn.Execute("Select * from clients")
'Create a new workbook in Excel
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Add
Set oSheet = oBook.Worksheets(1)
oSheet.Name = "clients"
' Copy the column headers to the destination worksheet
For colIndex = 0 To rs.Fields.Count - 1
oSheet.Cells(1, colIndex + 1).Value = rs.Fields(colIndex).Name
Next
'Transfer the data to Excel
oSheet.Range("A2").CopyFromRecordset rs
' Format the sheet bold and auto width of columns
oSheet.Rows(1).Font.Bold = True
oSheet.UsedRange.Columns.AutoFit
'delete file if it exists - enable scripting runtime model for this to run
'If (fso.FileExists("C:\Documents and Settings\user\Desktop\clients.xls")) Then
' aFile = fso.GetFile("C:\Documents and Settings\user\Desktop\clients.xls")
' aFile.Delete
'End If
'Save the Workbook and Quit Excel
oBook.SaveAs "C:\Documents and Settings\user\Desktop\clients.xls"
oExcel.Quit
'Close the connection
rs.Close
cnn.Close
MsgBox ("Exporting Clients Done")
'link table to excel file
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel5, "clientsTest", "C:\Documents and Settings\user\Desktop\clients.xls", True
End Sub
What you will have to do is open the FoxPro table as a recordset and open the local table as another recordset. You can then loop through the FoxPro recordset and do something like this
Do until FoxProRst.EOF
LocatRst.AddNew
LocalRst!SomeField1=FoxProRst!SomeField1
LocalRst!SomeField2=FoxProRst!SomeField2
LocalRst!SomeField3=FoxProRst!SomeField3
LocalRst.Update
FoxProRst.MoveNext
Loop
It might not be the quickest way but it will work
Let me just sketch another approach with SQL queries, that could simplify:
'...
'not required for first time test:
'cnn.Execute("DROP TABLE MyNewTable")
'...
'create the new table in the destination Access database
cnn.Execute("CREATE TABLE MyNewTable (MyField1 int, MyField2 VARCHAR(20), MyField3 Int)")
'insert data in the new table from a select query to the original table
Dim sSQL as string, MyOriginalDBPath as String
sSQL = "INSERT INTO MyNewTable (MyField1, MyField2, MyField3) SELECT OriginalField1, OriginalField2, OriginalField3 FROM [" & MyOriginalDBPath & ";PWD=123].clients"
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open sSQL, cnn, adOpenForwardOnly, adLockReadOnly, adCmdText
'...
Note: this 'draft' idea assumes that the connection string is made to the Access database and the connection to the original database would be inside the SQL string, but i have not idea about the correct sintaxis. I have only tested this approach with different access databases.
Note that this is for Access: ...[" & MyOriginalDBPath & ";PWD=123]...
The Jet database engine can reference external databases in SQL statements by using a special syntax that has three different formats:
[Full path to Microsoft Access database].[Table Name]
[ISAM Name;ISAM Connection String].[Table Name]
[ODBC;ODBC Connection String].[Table Name]
...
You can use an ODBC Data Source Name (DSN) or a DSN-less connection string:
DSN: [odbc;DSN=;UID=;PWD=]
DSN-less: [odbc;Driver={SQL Server};Server=;Database=;
UID=;PWD=]
Some references:
Querying data by joining two tables in two database on different servers
C# - Join tables from two different databases using different ODBC drivers
Why not use ODBC to link to the table? http://support.microsoft.com/kb/225861