Export multiple tables to one Excel worksheet (1 Viewer)

ctet143

New member
Local time
Today, 13:22
Joined
Jan 17, 2018
Messages
3
Pretty new to VBA. One table has header row (5 columns) and one detail record. Second table has header row (65 columns) and several detail records.
Need to export row one to be header, row two detail line. Skip row three (should be left blank) row four should be header row, line five and on should be details.

I need help to get code correct as several people have tried at work and now what i originally had is lost in the mess they have created.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 15:22
Joined
Feb 28, 2001
Messages
27,146
First, welcome to the forum. Second, as a formality, you should always post technical questions under the "Access Discussions" heading. Third,

What you ask is not going to be simple because you cannot easily mix things like this. You cannot export to the middle of a spreadsheet without getting some code involvement. However, you can turn the problem on its head. What we need to know is whether is will be a common event or a one-off event.

For a one-off, export two tables to two spreadsheets and then use EXCEL to insert the short segment above the long segment by doing a copy/paste-special in the destination spreadsheet.

For something repetitive, you will probably need to learn some VBA because that "insert into the middle" stuff won't happen with simple commands.

Tell us more about this including required frequency of using it and we might be able to do something to help you.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 04:22
Joined
May 7, 2009
Messages
19,229
here is your code.
copy and paste in standard module.
you can have as many tables to
export as you like provided excel
sheet can accommodate them.

to call:

ExportMultiTableToExcel pathAndFileNameOfExcelFile, StartingRangeToExport, table1Name, table2Name, table3Name, ....

example:
ExportMultiTableToExcel "d:\ExistingFolderName\sample.xlsx", "A1", "table1", "table2", "table3"
Code:
Option Compare Database
Option Explicit

Public Sub ExportMultiTableToExcel(ByVal ExcelFile As String, _
                                    ByVal StartRangeToExport As String, _
                                    ParamArray AccessTables() As Variant)

    ' variable declaration
    Dim xla As Excel.Application
    Dim xlw As Excel.Workbook
    Dim xls As Excel.WorkSheet
    
    Dim ars As DAO.Recordset
    Dim tableName As Variant
    Dim bolExists As Boolean
    Dim bolAppend As Boolean
    Dim strColumn As String
    Dim lngRow As Long
    Dim strMsg As String
    
    strColumn = getColumnName(StartRangeToExport)
    lngRow = getRowValue(StartRangeToExport)
    
    ' open excel application, workbook, worksheet
    ' check if workbook exists, create one if not
    If Dir(ExcelFile) <> "" Then
        bolExists = True
        If MsgBox("Excel file already exists. Do you wish to Overwrite it?", vbExclamation + vbYesNo, "Export Tables") = vbYes Then
            Kill ExcelFile
        Else
            If MsgBox("Do you wish to Append new data to it?", vbInformation + vbYesNo, "Export Tables") = vbNo Then
                Exit Sub
            End If
            bolAppend = True
        End If
    End If
    Set xla = New Excel.Application
    If (bolExists = True And bolAppend = True) Then
        Set xlw = xla.Workbooks.Open(ExcelFile)
    Else
        Set xlw = xla.Workbooks.Add
    End If
    Set xls = xlw.Sheets(1)
    ' loop through each table and save the worksheet
    If (bolAppend = True) Then
        lngRow = xls.UsedRange.Rows.Count + 3
    End If
    With xls
        For Each tableName In AccessTables
            strMsg = strMsg & tableName & ", "
            Set ars = CurrentDb.OpenRecordset(tableName, dbOpenSnapshot)
            ' write the column header
            createColumnHeader xls, StartRangeToExport, ars
            ' export the recordset to this sheet
            lngRow = lngRow + 1
            lngRow = .Range(strColumn & lngRow).CopyFromRecordset(ars) + lngRow + 2
            StartRangeToExport = strColumn & lngRow
            ' close this recordset
            ars.Close
            Set ars = Nothing
        Next
    End With
    ' save the workbook
    If (bolAppend = True) Then
        xlw.Save
    Else
        xlw.SaveAs ExcelFile
    End If
    ' housekeeping
    Set xls = Nothing
    Set xlw = Nothing
    xla.Quit
    Set xla = Nothing
    strMsg = Left(strMsg, Len(strMsg) - Len(", ")) & " table(s) appended to " & ExcelFile
    MsgBox strMsg, vbInformation + vbOKOnly, "Export Tables"
End Sub

' write the column header to the worksheet
Private Sub createColumnHeader(ByVal WorkSheet As Excel.WorkSheet, _
                                ByVal RangeName As String, _
                                ByRef Record As DAO.Recordset)
    Dim intLoop As Integer
    Dim lngColumn As Long
    Dim lngRow As Long
    lngColumn = ColumnLetterToNumber(WorkSheet, getColumnName(RangeName))
    lngRow = getRowValue(RangeName)
    With WorkSheet
        For intLoop = 1 To Record.Fields.Count
            .Range(ColumnNumberToLetter(WorkSheet, lngColumn) & lngRow).Value = _
                Record.Fields(intLoop - 1).Name
            lngColumn = lngColumn + 1
        Next
    End With
End Sub

Public Function ColumnNumberToLetter(ByRef xlsheet As Excel.WorkSheet, ByVal ColumnNumber As Long) As String
    ColumnNumberToLetter = Split(xlsheet.Cells(1, ColumnNumber).Address(True, False), "$")(0)
End Function

Public Function ColumnLetterToNumber(ByRef xlsheet As Excel.WorkSheet, ByVal ColumnName As String) As Long
    ColumnLetterToNumber = xlsheet.Range(ColumnName & 1).Column
End Function

Private Function getColumnName(RangeName As String) As String
    Dim intLoop As Integer
    Dim strColumn As String
    intLoop = 1
    strColumn = Mid(RangeName, intLoop, 1)
    While (IsNumeric(strColumn) = False)
        getColumnName = getColumnName & strColumn
        intLoop = intLoop + 1
        strColumn = Mid(RangeName, intLoop, 1)
    Wend
End Function
                                    
Private Function getRowValue(RangeName As String) As Long
    Dim intLoop As Integer
    Dim strRow As String
    Dim strRows
    intLoop = Len(RangeName)
    strRow = Mid(RangeName, intLoop, 1)
    While (IsNumeric(strRow) = True)
        strRows = strRow & strRows
        intLoop = intLoop - 1
        strRow = Mid(RangeName, intLoop, 1)
    Wend
    getRowValue = Val(strRows)
End Function


Private Function FileNameOnly(ByVal PathFile As String) As String
    FileNameOnly = PathFile
    If InStr(PathFile, "\") <> 0 Then
        FileNameOnly = Mid(PathFile, InStrRev(PathFile, "\") + 1)
    End If
End Function
 
Last edited:

ctet143

New member
Local time
Today, 13:22
Joined
Jan 17, 2018
Messages
3
The_Doc_Man
This will be a recurrent process performed by users that know nothing about Access other than pushing a button to perform an action.
I originally found some code to find the end of the previous exported two lines (header line one with line two data record) then to add two lines and place second header on line four and the data in line five and etc. But like i said couple others i work with thought they knew better. I do know there was a + 2, 1) to the code for the starting the second header on line two from end of previous data. Sorry still trying to find what i originally started with.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 04:22
Joined
May 7, 2009
Messages
19,229
I forgot ti mention that you need ti add reference to Microsoft Excel XX.X object library in vba. Go to Tools, Reference.
 

pbaldy

Wino Moderator
Staff member
Local time
Today, 13:22
Joined
Aug 30, 2003
Messages
36,124
FYI, thread moved to a more appropriate forum.

I'd use late binding to avoid needing the reference and accommodate users with different versions of Excel.
 

ctet143

New member
Local time
Today, 13:22
Joined
Jan 17, 2018
Messages
3
This is what I've been messing with and it keeps throwing error that it doesn't find my excel spreadsheet.

For my first table:

DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "qryNameFirst", "test1.xlsx", True, "MyWorksheetName"

For my second table:

Dim rstName As Recordset Set rstName = CurrentDb.OpenRecordset("qryNameSecond")

Dim objApp As Object, objMyWorkbook As Object, objMySheet As Object, objMyRange As Object *
Set objApp = CreateObject("Excel.Application")
Set objMyWorkbook = objApp.Workbooks.Open("test1.xlsx") Set objMySheet =objMyWorkbook.Worksheets("MyWorksheetName") Set objMyRange =objMySheet.Cells(objApp.ActiveSheet.UsedRange.Rows.Count + 2, 1) *

With objMyRange rstName.MoveFirst 'Rewind to the first record
.Clear
.CopyFromRecordset rstName

End With
 

pbaldy

Wino Moderator
Staff member
Local time
Today, 13:22
Joined
Aug 30, 2003
Messages
36,124
I suspect you need the full path to the excel file. I use a known path for the export and any following code.
 

Users who are viewing this thread

Top Bottom