简体   繁体   中英

Most Efficient Way To Export Access 2003 Listbox RowSource (query) To Excel 2003

The users dynamically generate queries in a form, and the results are shown in a listbox on the same form. The listbox can have anywhere from 1 to 12 columns.

The users want the results of this query to be able to be exported to Excel. I believe not saving the file is preferred but whatever works will work.

I have currently found two methods, each with its own problem(s)

1

myExApp.visible = True              
myExApp.Workbooks.Add               

Set myExSheet = myExApp.Workbooks(1).Worksheets(1)
If myExApp.Ready = True Then
For i = 1 To Me!listDynamicSearchResult.ColumnCount   
    Me!listDynamicSearchResult.BoundColumn = 
    Me!listDynamicSearchResult.BoundColumn + 1 
    For j = 1 To Me!listDynamicSearchResult.ListCount 
        myExSheet.Cells(j, i) = Me!listDynamicSearchResult.ItemData(j - 1)
    Next j  
Next i  
Me!listDynamicSearchResult.BoundColumn = 0    
End If

Which works fine, but becomes exponentially slow, for obvious reasons.

That method also causes an error when the user clicks within the now open Excel sheet.

Coupled with how slow it is, it is very likely that the user will cause an error, trying to manipulate the form before the looping is completed.

2

DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "test", "I:\\test.xls"

That method involves saving the query made dynamically to a saved query on click.

The issue with this is that the columns don't get formatted and excel reads everything as strings rather than the data type, whereas in the first method the data types are read correctly.

Are there any ways to mitigate the issues or is there a more efficient way to do this?

SOLUTION (Currently Formats As String)

Set xlApp = New Excel.Application
Set xlWb = xlApp.Workbooks.Add
Set xlWs = xlWb.Worksheets(1)

xlApp.visible = True
strFile = CurrentProject.FullName
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile & ";"

Set cn = CurrentProject.AccessConnection
Set rs = CreateObject("ADODB.recordset")
With rs
    Set .ActiveConnection = cn
    .Source = Me!listDynamicSearchResult.RowSource
    .Open
End With

With xlWs
  .QueryTables.Add Connection:=rs, Destination:=.Range("A1")
  .QueryTables(1).Refresh
End With

You could make a ListObject in excel with an external data source that's the same as the RowSource of the Listbox.

Private Sub Command2_Click()

    Dim xlApp As Excel.Application
    Dim xlWb As Excel.Workbook
    Dim xlWs As Excel.Worksheet
    Dim xlLo As Excel.ListObject

    Set xlApp = GetObject(, "Excel.Application")
    Set xlWb = xlApp.Workbooks.Add
    Set xlWs = xlWb.Worksheets(1)

    Set xlLo = xlWs.ListObjects.Add(xlSrcExternal, "OLEDB;" & CurrentProject.Connection, , xlYes, xlWs.Range("A3"))
    xlLo.QueryTable.CommandType = xlCmdSql
    xlLo.QueryTable.CommandText = Me.listDynamicSearchResult.RowSource

    DoCmd.Close acForm, Me.Name

End Sub

I couldn't refresh the list in the Excel until I closed the form in Access. So you may have some permissions issues to deal with.

Try generating a XML file. Here an example: http://blogs.msdn.com/b/brian_jones/archive/2005/06/27/433152.aspx

PS About first method. To avoid users clicks you can hide Excel. Also you can speed up Excel (see functions below). Use Prepare() before putting data and Ended() after it or in case of error.

Public Sub Prepare()
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    ActiveSheet.DisplayPageBreaks = False
    Application.DisplayStatusBar = False
    Application.DisplayAlerts = False
End Sub

Public Sub Ended()
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    ActiveSheet.DisplayPageBreaks = True
    Application.DisplayStatusBar = True
    Application.DisplayAlerts = True
End Sub

Please refer to this site for all possible methods as well as advantages/disadvantages of them. For your problem , I would prefer to use DAO method. The example codes are also in this site.

Way to transer data from access to excel

While you import Cell by Cell, you can format any Row, Column, Cell as you wished. For Example:

 xlActiveSheet.Cells(4,5).Characters(2).Font.ColorIndex = 5

or

xlActiveSheet.Columns("A:AZ").EntireColumn.AutoFit

or

xlActiveSheet.Range(xlActiveSheet.Cells(1, 1), xlActiveSheet.Cells(1, rec1.Fields.count)).Interior.ColorIndex = 15

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM