|
|
Title | Copy data from an Access database into an Excel spreadsheet |
Description | |
Keywords | ADO, Access, Excel, database |
Categories | Database, Office |
|
|
Use ADO to open the database. Using Excel as a server, open the spreadsheet.
Read the field names from the ADO Recordset and add them to the first row
in the spreadsheet to make column headers. Read the values from the
Recordset and add them to the spreadsheet.
To make things neater, use the Excel server to make the column headers bold.
Then select the data and make the columns autofit. Finally, select the second row
and freeze the pane above, making the column headers a non-scrolling region.
|
|
Private Sub cmdLoad_Click()
Dim excel_app As Object
Dim excel_sheet As Object
Dim row As Long
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim statement As String
Dim col As Integer
Screen.MousePointer = vbHourglass
DoEvents
' Create the Excel application.
Set excel_app = CreateObject("Excel.Application")
' Uncomment this line to make Excel visible.
' excel_app.Visible = True
' Open the Excel spreadsheet.
excel_app.Workbooks.Open FileName:=txtExcelFile.Text
' Check for later versions.
If Val(excel_app.Application.Version) >= 8 Then
' Uncomment the following code to select
' a particular worksheet.
' excel_app.Sheets(2).Select
Set excel_sheet = excel_app.ActiveSheet
Else
Set excel_sheet = excel_app
End If
' Open the Access database.
Set conn = New ADODB.Connection
conn.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & txtAccessFile.Text & ";" & _
"Persist Security Info=False"
conn.Open
' Select the data.
Set rs = conn.Execute( _
"SELECT * FROM Books ORDER BY Title", , _
adCmdText)
' Make the column headers.
For col = 0 To rs.Fields.Count - 1
excel_sheet.Cells(1, col + 1) = rs.Fields(col).Name
Next col
' Get data from the database and insert
' it into the spreadsheet.
row = 2
Do While Not rs.EOF
For col = 0 To rs.Fields.Count - 1
excel_sheet.Cells(row, col + 1) = _
rs.Fields(col).Value
Next col
row = row + 1
rs.MoveNext
Loop
' Make the columns autofit the data.
excel_sheet.Range( _
excel_sheet.Cells(1, 1), _
excel_sheet.Cells(1, _
rs.Fields.Count)).Columns.AutoFit
' Close the database.
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
' Make the header bold.
excel_sheet.Rows(1).Font.Bold = True
' Freeze the header row so it doesn't scroll.
excel_sheet.Rows(2).Select
excel_app.ActiveWindow.FreezePanes = True
' Select the first cell.
excel_sheet.Cells(1, 1).Select
' Comment the Close and Quit lines to keep
' Excel running so you can see it.
' Close the workbook saving changes.
excel_app.ActiveWorkbook.Close True
excel_app.Quit
Set excel_sheet = Nothing
Set excel_app = Nothing
Screen.MousePointer = vbDefault
MsgBox "Copied " & Format$(row - 2) & " values."
End Sub
|
|
Thanks to Kent Finkle for recommending that
the row variable be declared as Long instead of Integer (because
the maximum number of rows in an Excel worksheet is 65,536
and the maximum integer is 32,767). Of course if you have that many rows, this method will
take a long time to execute.
Toby Bascom pointed out that this example will crash
if the database contains OLE fields or GUIDs. He offers this solution:
You can use the OpenSchema method of the Connection object to first scrutinize the
"DATA_TYPE" value of each of the columns in the Access table you are attempting to
export and if the "DATA_TYPE" value is adLongVarBinary then *exclude* that column from the SELECT statement.
Then create the Excel file & sheet with this. You do not need ADOX and the Excel file
does *not* need to exist; it will be created by Jet if it does not.
|
|
Dim cSource As String
cSource = App.Path & _
IIf(Right$(App.Path, 1) <> "\", "\", "") & _
"books.mdb"
Dim cTarget As String
cTarget = App.Path & _
IIf(Right$(App.Path, 1) <> "\", "\", "") & _
"Books.xls].[Table1]"
Dim oCon As ADODB.Connection
Set oCon = New ADODB.Connection
Dim cSQL As String
With oCon
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _
& _
"Data Source=" & cSource & ";" & _
"Persist Security Info=False"
.Open
cSQL = "SELECT " & _
"[Title],[URL],[ISBN],[Picture],[Pages],[CD],[Year] " & _
"" & _
"INTO [Excel 8.0;Database=" & cTarget " " & _
"FROM [Books]"
.Execute cSQL
End With
|
|
Michael Yereniuk of Chickenlip Consulting Corp pointed out a better way to autofit the columns, using the number of fields in the recordset to determine the number of columns rather than hard coding in the number.
|
|
|
|
|
|