Search code examples
sqlexcelvbams-accessexport-to-excel

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

Solution

  • 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.