Search code examples
vbams-accessexport-to-excelms-access-2013

Export Each Access Table To Individual Workbook


I have been using this syntax which will export every table in a database to ONE excel workbook, but now my needs are to export every table to it's own workbook. How could this be tweaked to export each table to it's own workbook?

Sub ExportToExcel()
  Dim td As DAO.TableDef, db As DAO.Database
  Dim out_file As String

  out_file = "C:\fromaccess.xlsx"

  Set db = CurrentDb()
    For Each td in db.TableDefs
      If Left(td.Name, 4) = "MSys" Then
        'Do Nothing
      Else
        DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, td.Name, out_file, True, Replace(td.Name, "dbo_","")
      End If
      Next
End Sub

EDIT
I tried the suggestion by @HA560 but get an error of

Run-time error '91':
Object variable or With block variable not set

This is updated code:

Sub ExportToExcel()
Dim td As DAO.TableDef, db As DAO.Database
Dim out_file As String
Dim xl As Excel.Application

out_file = "C:\fromaccess.xlsx"

Set db = CurrentDb()
For Each td in db.TableDefs
xl.Workbooks.Add  
If Left(td.Name, 4) = "MSys" Then
    'Do Nothing
  Else
    DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, td.Name, out_file, True, Replace(td.Name, "dbo_","")
  End If
  Next
End Sub

Solution

  • Bit of a long one which includes a three procedures. After running you should have a list of table names and TRUE/FALSE in the immediate window saying whether the export was successful.

    ExportAll - The main procedure.
    CreateXL - this creates an instance of Excel. It uses late binding, so no need to set references.

    QueryExportToXL - this is the code to export the table. I haven't used TransferSpreadsheet as I like more control.

    • You need to pass a worksheet reference to the function.
    • You can pass either a query name or a recordset to the function.
    • You can pass an alternative sheet name.
    • The default cell to paste into is A1, but you can change this.
    • By default it adjusts the column widths to fit.
    • You can pass a collection of heading names to use instead of the field names.

    There's not much error handling in there - such as passing a different number of heading names than there are fields, giving illegal sheet names.
    It needs work :)

    Public Sub ExportAll()
    
        Dim db As DAO.Database
        Dim tdf As DAO.TableDef
        Dim rst As DAO.Recordset
        Dim oXL As Object
        Dim oWrkBk As Object
    
        Set db = CurrentDb
    
        'Create instance of Excel.
        Set oXL = CreateXL
    
        For Each tdf In db.TableDefs
            If Left(tdf.Name, 4) <> "MSys" Then
    
                'Create workbook with single sheet.
                Set oWrkBk = oXL.WorkBooks.Add(-4167) 'xlWBATWorksheet
    
                'Open the table recordset.
                Set rst = tdf.OpenRecordset
    
                'In the immediate window display table name and TRUE/FALSE if exported successfully.
                Debug.Print tdf.Name & " - " & QueryExportToXL(oWrkBk.worksheets(1), , rst, tdf.Name)
    
                'Save and close the workbook.
                oWrkBk.SaveAs "<path to folder>" & tdf.Name
                oWrkBk.Close
    
            End If
        Next tdf
    
    End Sub
    
    '----------------------------------------------------------------------------------
    ' Procedure : CreateXL
    ' Author    : Darren Bartrup-Cook
    ' Date      : 02/10/2014
    ' Purpose   : Creates an instance of Excel and passes the reference back.
    '-----------------------------------------------------------------------------------
    Public Function CreateXL(Optional bVisible As Boolean = True) As Object
    
        Dim oTmpXL As Object
    
        '''''''''''''''''''''''''''''''''''''''''''''''''''''
        'Defer error trapping in case Excel is not running. '
        '''''''''''''''''''''''''''''''''''''''''''''''''''''
        On Error Resume Next
        Set oTmpXL = GetObject(, "Excel.Application")
    
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'If an error occurs then create an instance of Excel. '
        'Reinstate error handling.                            '
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''
        If Err.Number <> 0 Then
            Err.Clear
            On Error GoTo ERROR_HANDLER
            Set oTmpXL = CreateObject("Excel.Application")
        End If
    
        oTmpXL.Visible = bVisible
        Set CreateXL = oTmpXL
    
        On Error GoTo 0
        Exit Function
    
    ERROR_HANDLER:
        Select Case Err.Number
    
            Case Else
                MsgBox "Error " & Err.Number & vbCr & _
                    " (" & Err.Description & ") in procedure CreateXL."
                Err.Clear
        End Select
    
    
    End Function
    
    
    '----------------------------------------------------------------------------------
    ' Procedure : QueryExportToXL
    ' Author    : Darren Bartrup-Cook
    ' Date      : 26/08/2014
    ' Purpose   : Exports a named query or recordset to Excel.
    '-----------------------------------------------------------------------------------
    Public Function QueryExportToXL(wrkSht As Object, Optional sQueryName As String, _
                                                      Optional rst As DAO.Recordset, _
                                                      Optional SheetName As String, _
                                                      Optional rStartCell As Object, _
                                                      Optional AutoFitCols As Boolean = True, _
                                                      Optional colHeadings As Collection) As Boolean
    
        Dim db As DAO.Database
        Dim prm As DAO.Parameter
        Dim qdf As DAO.QueryDef
        Dim fld As DAO.Field
        Dim oXLCell As Object
        Dim vHeading As Variant
    
        On Error GoTo ERROR_HANDLER
    
        If sQueryName <> "" And rst Is Nothing Then
    
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            'Open the query recordset.                               '
            'Any parameters in the query need to be evaluated first. '
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            Set db = CurrentDb
            Set qdf = db.QueryDefs(sQueryName)
            For Each prm In qdf.Parameters
                prm.Value = Eval(prm.Name)
            Next prm
            Set rst = qdf.OpenRecordset
        End If
    
        If rStartCell Is Nothing Then
            Set rStartCell = wrkSht.cells(1, 1)
        Else
            If rStartCell.Parent.Name <> wrkSht.Name Then
                Err.Raise 4000, , "Incorrect Start Cell parent."
            End If
        End If
    
    
        If Not rst.BOF And Not rst.EOF Then
            With wrkSht
                Set oXLCell = rStartCell
    
                ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                'Paste the field names from the query into row 1 of the sheet. '
                'Or the alternative field names provided in a collection.      '
                ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                If colHeadings Is Nothing Then
                    For Each fld In rst.Fields
                        oXLCell.Value = fld.Name
                        Set oXLCell = oXLCell.Offset(, 1)
                    Next fld
                Else
                    For Each vHeading In colHeadings
                        oXLCell.Value = vHeading
                        Set oXLCell = oXLCell.Offset(, 1)
                    Next vHeading
                End If
    
                ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                'Paste the records from the query into row 2 of the sheet. '
                ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                Set oXLCell = rStartCell.Offset(1, 0)
                oXLCell.copyfromrecordset rst
                If AutoFitCols Then
                    .Columns.Autofit
                End If
    
                If SheetName <> "" Then
                    .Name = SheetName
                End If
    
                '''''''''''''''''''''''''''''''''''''''''''
                'TO DO: Has recordset imported correctly? '
                '''''''''''''''''''''''''''''''''''''''''''
                QueryExportToXL = True
    
            End With
        Else
    
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            'There are no records to export, so the export has failed. '
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            QueryExportToXL = False
        End If
    
        Set db = Nothing
    
        On Error GoTo 0
        Exit Function
    
    ERROR_HANDLER:
        Select Case Err.Number
    
            Case Else
                MsgBox "Error " & Err.Number & vbCr & _
                    " (" & Err.Description & ") in procedure QueryExportToXL."
                Err.Clear
                Resume
        End Select
    
    End Function