Exporting Access Data into Excel spreadsheet (1 Viewer)

Kayleigh

Member
Local time
Today, 07:19
Joined
Sep 24, 2020
Messages
706
Hi,

I have a complex database system which currently outputs the data in a number of very detailed forms. I would like to have a button on the form to export this to an Excel spreadsheet whilst substituting the complex details with specific codes and apply formatting for certain situations. What function do I use to do this?

Also is it possible to automatically add comments to certain cells?


Thank you
Krayna
 
Solution
1609136186116.png


UncleGizmo's comment: "Instead of having the lookups as queries you could just have a combobox on your form" means in the query above, you don't need either the outer join to 'qrylkpStaffName' nor join to 'lkptblStaffyType. Both of these complicate your form unnecessarily and could cause problems later on. Whatever information you need in these tables can be handled with a combo box on your form. for qrylkpStaffName information, Set the control source of the combo box to 'fldStaffID' and the rowsource to qrylkpstaffname. make it a 2 column combo box and set the column widths to 0,2. Your combo box will then display the staffname on the form, but store the 'fldstaffid' value in qrySCR!fldstaffid...

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 23:19
Joined
Oct 29, 2018
Messages
21,467
Hi. To do all that (formatting, comments, etc.), you may have to use Excel Automation.

I don't know of any one function that will do all that. If you simply want to export the data to Excel, you can take a look at the TransferSpreadsheet method.
 

Kayleigh

Member
Local time
Today, 07:19
Joined
Sep 24, 2020
Messages
706
Can you direct me to specific guidance on Excel Automation?
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 01:19
Joined
Feb 28, 2001
Messages
27,156
I'm going to add my voice in agreement with theDBguy. To do simple transfers, you use TransferSpreadSheet. To do formatted transfers you have to go through an Excel Application Object. To add comments into the cells, you MUST use the App object.
 

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 23:19
Joined
Oct 29, 2018
Messages
21,467
Great. Will this work directly in Access VB or would the syntax vary?
Hmm, good question. Looking at the sample code in that page, I don't see why it won't work in VBA. But if it doesn't, we can point you to other examples on the Net. Cheers!
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 01:19
Joined
Feb 28, 2001
Messages
27,156
Great. Will this work directly in Access VB or would the syntax vary?
As it happens, Access VBA isn't Access VBA. It is OFFICE VBA, and all members of MS Office that have the ability at all will use the same syntax. The only thing that differs between Access VBA and Excel VBA and Word VBA is the syntax of implied references and when you can use them. It is mostly a matter of having the correct references. By default, Access and Excel have different library references. Once you get those straight, it is a reasonably homogeneous environment.
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 07:19
Joined
Jul 9, 2003
Messages
16,278
Can you direct me to specific guidance on Excel Automation?

I have used this code from Bob:-
https://btabdevelopment.com/export-a-table-or-query-to-excel/

To move data from MS Access to Excel.

I have also made some nice products with it, in particular, this one:-

"Show/Hide & Export to Excel"

Which I'm quite pleased with.


Download Here:-

If you want a free copy of the code, contact me for details on how to get free copy....
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 07:19
Joined
Jul 9, 2003
Messages
16,278
Here's another example of what can be accomplished with Bob's Code:-


This 1:41 min video is fascinating to watch!!!!
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 02:19
Joined
Feb 19, 2002
Messages
43,257
A lot of the formatting can be done in the query itself. Here's a snippet from one of my apps. It exports data using TransferSpreadsheet. The query joins to lookup tables to export the text values rather than IDs, it formats dates to remove time, and does a few other things.

Calling code:
Code:
    strFileName = Me.txtPath & "\" & Me.cboJob.Column(4) & "_" & Me.txtExcelQueryName & "_" & Me.cboJob.Column(1) & "_" & Format(Date, "yyyymmdd") & ".xls"
    Kill strFileName
    If Me.lstReports.Column(3) = "P-01" Then        'Weekly Job Status
        DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, Me.txtExcelQueryName, strFileName, False
        Call FormatWeeklyJobStatus(strFileName)
    Else
        DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, Me.txtExcelQueryName, strFileName, True
    End If

    MsgBox "Export Complete - File name = " & strFileName

Procedure that automates Excel

Code:
Private Sub FormatWeeklyJobStatus(sFileName)

Const xlDown = -4121
Const xlCellTypeLastCell = 11
Const xlThemeFontMinor = 2
Const xlPrintNoComments = -4142
Const xlPortrait = 1
Const xlPaperLegal = 5
Const xlPaperLetter = 1
Const xlOverThenDown = 2
Const xlPrintErrorsDisplayed = 0

    Dim sPath           As String
    Dim sTemplateName   As String
    Dim lngRows           As Long       'MUST be long
Dim ref As Reference

' 0 if Late Binding
' 1 if Reference to Excel set.
#Const ExcelRef = 0
#If ExcelRef = 0 Then ' Late binding
    Dim appExcel As Object     'Excel Object
    Dim wbkNew As Object    'Workbook Object
    Dim wksNew As Object    'Sheet Object
    Dim wbkTemplate As Object   'Workbook Object for Template

    Set appExcel = CreateObject("Excel.Application")
    ' Remove the Excel reference if it is present   -   <=======
    On Error Resume Next
    Set ref = References!Excel
    If Err.Number = 0 Then
        References.Remove ref
    ElseIf Err.Number <> 9 Then 'Subscript out of range meaning not reference not found
        MsgBox Err.Description
        Exit Sub
    End If
' Use your own error handling label here
On Error GoTo FormatWeeklyJobStatus_Error
#Else
    ' a reference to MS Excel <version number> Object Library must be specified
    Dim appExcel As Excel.Application      'Excel Object
    Dim wbkNew As Excel.Workbook        'Workbook Object
    Dim wksNew As Excel.Worksheet       'Sheet Object
    Dim wbkTemplate As Excel.Workbook   'Workbook Object for Template

    Set appExcel = New Excel.Application
#End If

    On Error GoTo FormatWeeklyJobStatus_Error

    sPath = DLookup("Database", "MsysObjects", "[Name] = 'tblJob'")
    sPath = Left(sPath, InStrRev(sPath, "\"))
    sTemplateName = sPath & "WeeklyJobStatusHeaders.xlsx"

    Set wbkNew = appExcel.Workbooks.Open(sFileName)
    Set wksNew = appExcel.Worksheets("qWeeklyJobStatusReportExcel")
   
    'remove column names - some bug is preventing HasFieldNames argument from working on the export
    If wksNew.Range("A1").Value = "ContractName" Then
        appExcel.Rows("1:1").Select
        appExcel.Rows("1:1").Delete
    End If
   
    ' Insert 5 rows at top to make room for headers
    With appExcel

        .Rows("1:1").Select
        .Selection.Insert Shift:=xlDown
        .Selection.Insert Shift:=xlDown
        .Selection.Insert Shift:=xlDown
        .Selection.Insert Shift:=xlDown
        .Selection.Insert Shift:=xlDown
       
        ' Get headers from template file
        Set wbkTemplate = .Workbooks.Open(sTemplateName)
        wbkTemplate.Activate
        .Rows("1:5").Select
        .Selection.Copy
       
        ' Paste into new Workbook.
        wbkNew.Activate
        .ActiveSheet.Paste
       
        ' Close template
        .CutCopyMode = False    'clear clipboard to get rid of warning message
        wbkTemplate.Close
       
        'add job name
        .Range("A5").Value = Me.cboJob.Column(3)
       
        ' Count rows in new Workbook.
        .Selection.SpecialCells(xlCellTypeLastCell).Select
        lngRows = .Selection.Row
       
        'insert sum functions
            'the reference style below uses the current position so we subtract the number of rows (lngRows)
            'to get to the top and then add 5 to get past the headers
        .Cells(lngRows + 1, 4).Select     'column D - Total plan pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 5).Select     'column E - OFA pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 6).Select     'column F - BFA pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 7).Select     'column G - Issued to Shop pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 9).Select     'column I - Cut Issue pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 11).Select     'column K - Fitted pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 12).Select     'column L - Welded pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Cells(lngRows + 1, 13).Select     'column M - Shipped pieces
        .ActiveCell.FormulaR1C1 = "=SUM(R[" & -lngRows + 5 & "]C:R[" & -1 & "]C)"
       
        .Range("A" & lngRows + 1 & ":N" & lngRows + 1).Select
       
       
        ' Freeze panes
        .Range("A6").Select
        .ActiveWindow.FreezePanes = True
       
        ' Header should print on every page when in Print Preview
        .ActiveSheet.PageSetup.PrintTitleRows = "$1:$5"
        .ActiveSheet.PageSetup.PrintTitleColumns = ""
       
       'format cells as numeric
        .Cells.NumberFormat = "#,##0_);[Red](#,##0)"
       
        ' Set format for date columns
        wksNew.Columns("H").NumberFormat = "d-mmm;@"
        wksNew.Columns("J").NumberFormat = "d-mmm;@"
           
        ' Set font and size
        .Cells.Select
        With .Selection.Font
            .Name = "Calibri"
            .Size = 11
            .Strikethrough = False
            .Superscript = False
            .Subscript = False
            .OutlineFont = False
            .Shadow = False
            .Underline = xlUnderlineStyleNone
            .TintAndShade = 0
            .ThemeFont = xlThemeFontMinor
        End With
       
        ' Set page setup properties
        .Columns("A:N").Select
        .Selection.Columns.AutoFit
       
        With .ActiveSheet.PageSetup
            .PrintArea = "$A$1:$N$" & CStr(lngRows + 2)
            .LeftHeader = ""
            .CenterHeader = ""
            .RightHeader = ""
            .LeftFooter = ""
            .CenterFooter = ""
            .RightFooter = ""
            .LeftMargin = appExcel.InchesToPoints(0.5)
            .RightMargin = appExcel.InchesToPoints(0.5)
            .TopMargin = appExcel.InchesToPoints(0.5)
            .BottomMargin = appExcel.InchesToPoints(0.5)
            .HeaderMargin = appExcel.InchesToPoints(0.5)
            .FooterMargin = appExcel.InchesToPoints(0.5)
            .PrintHeadings = False
            .PrintGridlines = True
            .PrintComments = xlPrintNoComments
           ' .PrintQuality = 600
            .CenterHorizontally = False
            .CenterVertically = False
            .Orientation = xlPortrait
            .Draft = False
            .PaperSize = IIf(lngRows > 44, xlPaperLegal, xlPaperLetter)
            .FirstPageNumber = xlAutomatic
            .Order = xlOverThenDown                         ' Change order to print all "page 1" before "page 2"
            .BlackAndWhite = False
            ''.Zoom = 80                                      ' Shrink down a little
            .Zoom = False                                   ' Should not need both
            .FitToPagesWide = 1
            .FitToPagesTall = False
            .PrintErrors = xlPrintErrorsDisplayed
        End With
    End With

    wbkNew.Save

FormatWeeklyJobStatus_Exit:
    On Error Resume Next
    ' Required for cleanup.
    wbkNew.Close
    Exit Sub

FormatWeeklyJobStatus_Error:
    Select Case Err.Number
        Case Else
            MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure FormatWeeklyJobStatus of VBA Document Form_frmReports"
    End Select

    Resume FormatWeeklyJobStatus_Exit

End Sub
 

Kayleigh

Member
Local time
Today, 07:19
Joined
Sep 24, 2020
Messages
706
Thanks for all your suggestions!
@UncleGizmo - I finally got round to looking at your code here. It looks so good - I purchased and downloaded it!
However I am having trouble implementing in my DB... Main problem being that it very difficult to have datasheet as a subform (split form) since it is being called and filtered from a previous form. Is there any way I can have the macro on same form as datasheet?
Another query: I was inspired by @UncleGizmo's demo clip above - so how is each sheet renamed - I was thinking of exporting based on current filter, with option of output all options - each on new sheet.
Final point - code should produce new Excel file and offer user where to save.

Many thanks!
Ps. Have signed up to your newsletters :)
 

Attachments

  • StaffSCRTest_2.accdb
    876 KB · Views: 189

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 07:19
Joined
Jul 9, 2003
Messages
16,278
However I am having trouble implementing in my DB... Main problem being that it very difficult to have datasheet as a subform (split form) since it is being called and filtered from a previous form. Is there any way I can have the macro on same form as datasheet?
I've had a look at your database and it needs a lot of reworking to get it to something that can be useful to you in MS Access. Now don't get me wrong, you are going in the right direction, however you have quite a bit of duplication and there are some techniques that you don't know about, which you could employ to make your form much simpler.

Instead of having the lookups as queries you could just have a combobox on your form which would provide the same functionality. This would simplify the SQL statement for the form.

And the code that is operated by the SQL statements and the option group, this could be made into one single function. However it's not a problem how you've got it, it's just an improvement that would provide some useful gains in your a database design, especially if you intend adding further option control selections in the future.


I would suggest you posted the different aspects of your database on the forum and ask advice on how to change the structure into A more suitable structure.
 
Last edited:

Jjaeger14

New member
Local time
Today, 09:19
Joined
Dec 26, 2020
Messages
15
I see you've gotten enough suggestions on VBA automation of Excel to keep you going. But might I suggest another, much simpler approach? Create an Excel Template file. Start your code by copy/pasting your excel template. For example: filecopy "c:\exceltemplate.xlsx", c:\exceltemplate - " & format(date,"mmddyy") & ".xlsx". Then proceed with either the standard docmd.transferspreadsheet ... command into the excel file you just created. The advantage? You can perform all of your desired formatting including fancy conditional coloring of excel cells all within Excel where you are most likely more familiar than the excel automation formatting commands.

But if you are brave and love learning, then by all means go the excel automation route. I've certainly done that many times myself.

Jack
 

Jjaeger14

New member
Local time
Today, 09:19
Joined
Dec 26, 2020
Messages
15
1609136186116.png


UncleGizmo's comment: "Instead of having the lookups as queries you could just have a combobox on your form" means in the query above, you don't need either the outer join to 'qrylkpStaffName' nor join to 'lkptblStaffyType. Both of these complicate your form unnecessarily and could cause problems later on. Whatever information you need in these tables can be handled with a combo box on your form. for qrylkpStaffName information, Set the control source of the combo box to 'fldStaffID' and the rowsource to qrylkpstaffname. make it a 2 column combo box and set the column widths to 0,2. Your combo box will then display the staffname on the form, but store the 'fldstaffid' value in qrySCR!fldstaffid. Use the same technique on lkptblStaffType. One of my goals in developing databases is to have a single table for each form. I avoid multitable recordsources
 
Solution

Jjaeger14

New member
Local time
Today, 09:19
Joined
Dec 26, 2020
Messages
15
Simple enough! I can see now it really wasn't necessary to add extra lookup tables.
Thank you
Actually, a database like this would typically keep the lookup tables in order to populate the combo boxes with a unique list of values, thus restricting data entry to the list (data validation). But maybe for your purposes this isn't necessary.

Jack
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 02:19
Joined
Feb 19, 2002
Messages
43,257
I created a mini-app some years ago and I include it in all my applications. It is an easy way to manage lots of little simple code tables. It works for ALL simple lookups and even lets you offload maintenance of some of the tables to the users.
 

Attachments

  • TableMaintExample190820.zip
    643.6 KB · Views: 186

Users who are viewing this thread

Top Bottom