access 2007 vba -using excel templates to create formatted worksheets filled with access data

Upload: sigma70eg

Post on 06-Jul-2018

233 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    1/18

    Using a query as a data source allows you to combine data from multiple tables and also

    to format data as you want it to appear in the target worksheet, using data type conver-sion functions such as CDate, CCur, or CStr.

     With a few clicks, you can resize the worksheet columns as needed, edit the column headers asneeded, and make the column header row bold, and a plain but serviceable worksheet (Figure 3.4)is ready for use.

    FIGURE 3.4

    The exported worksheet with a little formatting applied manually.

    Using Excel Templates to Create FormattedWorksheets Filled with Access DataIf you want to produce a more formatted worksheet, you can prepare an Excel template and formatit as needed — for example, adding a large, centered title and column headings with appropriatetext, perhaps in a larger or bolder font than the data area. Then, instead of using the Excel com-mand on the Ribbon, use VBA code to export the Access data row by row to the data area of a newworksheet created from the template. I created a set of queries for archiving data, again using thesample Northwind data, and a dialog form (fdlgArchiveOrders) that allows the user to select a date

    range for archiving Orders data, as shown in Figure 3.5.

    Note the calendar icon next to the date controls (it appears when a control bound to a

    Date field has the focus). Clicking the icon opens a calendar for selecting a valid date,as shown in Figure 3.6. The new calendar pop-up is definitely useful, though selecting a date far in thepast can be tedious, because there is no way to move year by year.

    NEW FEATURENEW FEATURE

    TIPTIP

    52

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    2/18

    FIGURE 3.5

    A dialog form for selecting Northwind Orders data to archive.

    FIGURE 3.6

    Selecting a date from the calendar pop-up.

    Once the start date and end date have been entered or selected, clicking the Archive button runsa procedure that creates a new Excel worksheet from a template (Orders Archive.xltx) in the samefolder as the database, fills it with data from tblOrders in the selected date range, and deletes thearchived records.

    The ArchiveData procedure uses the Start Date and End Date values selected in the dialog asarguments. This procedure is listed as follows, together with the CreateAndTestQuery proce-dure it uses to create a query programmatically, and another procedure (TestFileExists) thattests whether a file exists in a specific folder:

    Public Sub ArchiveData(dteStart As Date, dteEnd As Date)

    On Error GoTo ErrorHandler

    Dim appExcel As Excel.Application

    Dim intReturn As Integer

    Dim lngCount As Long

    Dim n As Long

    53

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    3/18

    Dim rng As Excel.Range

    Dim rngStart As Excel.Range

    Dim strDBPath As String

    Dim strPrompt As String

    Dim strQuery As StringDim strSaveName As String

    Dim strSheet As String

    Dim strSheetTitle As String

    Dim strSQL As String

    Dim strTemplate As String

    Dim strTemplateFile As String

    Dim strTemplatePath As String

    Dim strTitle As String

    Dim wkb As Excel.Workbook

    Dim wks As Excel.Worksheet

    Create a filtered query using the dates selected in the dialog:

    strQuery = “qryArchive”

    Set dbs = CurrentDb

    strSQL = “SELECT * FROM tblOrders WHERE “ _

    & “[ShippedDate] Between #” & dteStart & “# And #” _

    & dteEnd & “#;”

    Debug.Print “SQL for “ & strQuery & “: “ & strSQL

    lngCount = CreateAndTestQuery(strQuery, strSQL)

    Debug.Print “No. of items found: “ & lngCount

    If lngCount = 0 Then

    Exit if no orders are found in the selected date range:

    strPrompt = “No orders found for this date range; “ _& “canceling archiving”

    strTitle = “Canceling”

    MsgBox strPrompt, vbOKOnly + vbCritical, strTitle

    GoTo ErrorHandlerExit

    Else

    strPrompt = lngCount & “ orders found in this date “ _

    & “range; archive them?”

    strTitle = “Archiving”

    intReturn = MsgBox(strPrompt, vbYesNo + vbQuestion, _

    strTitle)

    If intReturn = vbNo Then

    GoTo ErrorHandlerExit

    End If

    End If

    Create a new worksheet from the template and export the Access data to it:

    strDBPath = Application.CurrentProject.Path & “\”

    Debug.Print “Current database path: “ & strDBPath

    54

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    4/18

    strTemplate = “Orders Archive.xltx”

    strTemplateFile = strDBPath & strTemplate

    If TestFileExists(strTemplateFile) = False Then

    Put up a message and exit if the template is not found:

    strTitle = “Template not found”

    strPrompt = “Excel template ‘Orders Archive.xlt’” _

    & “ not found in “ & strDBPath & “;” & vbCrLf _

    & “please put template in this folder and try again”

    MsgBox strPrompt, vbCritical + vbOKOnly, strTitle

    GoTo ErrorHandlerExit

    Else

    Debug.Print “Excel template used: “ & strTemplateFile

    End If

    Template found; create a new worksheet from it:

    Set appExcel = GetObject(, “Excel.Application”)

    Set rst = dbs.OpenRecordset(“qryRecordsToArchive”)

    Set wkb = appExcel.Workbooks.Add(strTemplateFile)

    Set wks = wkb.Sheets(1)

     wks.Activate

    appExcel.Visible = True

     Write the date range to title cell:

    Set rng = wks.Range(“A1”)

    strSheetTitle = “Archived Orders for “ _

    & Format(dteStart, “d-mmm-yyyy”) _

    & “ to “ & Format(dteEnd, “d-mmm-yyyy”)Debug.Print “Sheet title: “ & strSheetTitle

    rng.Value = strSheetTitle

    Go to the first data cell:

    Set rngStart = wks.Range(“A4”)

    Set rng = wks.Range(“A4”)

    Reset lngCount to the number of records in the data source query:

    rst.MoveLast

    rst.MoveFirst

    lngCount = rst.RecordCount

    For n = 1 To lngCount

     Write data from the recordset to the data area of the worksheet, using the columnoffset argu-ment to move to the next cell:

    55

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    5/18

    rng.Value = Nz(rst![OrderID])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Customer])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Employee])Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![OrderDate])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![RequiredDate])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![ShippedDate])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Shipper])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Freight])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![ShipName])

    Set rng = rng.Offset(columnoffset:=1)rng.Value = Nz(rst![ShipAddress])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![ShipCity])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![ShipRegion])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![ShipPostalCode])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![ShipCountry])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Product])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![UnitPrice])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Quantity])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Discount])

    Go to the next row in the worksheet, using the rowoffset argument:

    rst.MoveNext

    Set rng = rngStart.Offset(rowoffset:=n)

    Next n

    Save and close the filled-in worksheet, using a workbook save name with the date range selected in

    the dialog:

    strSaveName = strDBPath & strSheetTitle & “.xlsx”

    Debug.Print “Time sheet save name: “ & strSaveName

    56

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    6/18

    ChDir strDBPath

    On Error Resume Next

    If there already is a saved worksheet with this name, delete it:

    Kill strSaveName

    On Error GoTo ErrorHandler

     wkb.SaveAs FileName:=strSaveName, _

    FileFormat:=xlWorkbookDefault

     wkb.Close

    rst.Close

    Put up a success message, listing the name and path of the new worksheet:

    strTitle = “Workbook created”

    strPrompt = “Archive workbook ‘“ & strSheetTitle & “‘“ _& vbCrLf & “created in “ & strDBPath

    MsgBox strPrompt, vbOKOnly + vbInformation, strTitle

    Delete the archived records, processing the “many” table first, because you can’t delete a record inthe “one” table if there are linked records in the “many” table:

    DoCmd.SetWarnings False

    strSQL = “DELETE tblOrderDetails.*, “ _

    & “tblOrders.ShippedDate “ _

    & “FROM tblOrderDetails INNER JOIN qryArchive “ _

    & “ON tblOrderDetails.OrderID = qryArchive.OrderID;”

    Debug.Print “SQL string: “ & strSQL

    DoCmd.RunSQL strSQLstrSQL = “DELETE tblOrders.* FROM tblOrders WHERE “ _

    & “[ShippedDate] Between #” & dteStart & “# And #” _

    & dteEnd & “#;”

    Debug.Print “SQL string: “ & strSQL

    DoCmd.RunSQL strSQL

    Put up a message listing the cleared records:

    strTitle = “Records cleared”

    strPrompt = “Archived records from “ _

    & Format(dteStart, “d-mmm-yyyy”) _

    & “ to “ & Format(dteEnd, “d-mmm-yyyy”) _

    & “ cleared from tables”MsgBox strPrompt, vbOKOnly + vbInformation, strTitle

    ErrorHandlerExit:

    Exit Sub

    57

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    7/18

    ErrorHandler:

    ‘Excel is not running; open Excel with CreateObject

    If Err.Number = 429 Then

    Set appExcel = CreateObject(“Excel.Application”)

    Resume NextElse

    MsgBox “Error No: “ & Err.Number & “; Description: “

    Resume ErrorHandlerExit

    End If

    End Sub

    Public Function CreateAndTestQuery(strTestQuery As String, _

    strTestSQL As String) As Long

    This function is called from other procedures to create a filtered query, using a SQL string in itsstrTestSQL argument:

    On Error Resume Next

    Dim qdf As DAO.QueryDef

    ‘Delete old query

    Set dbs = CurrentDb

    dbs.QueryDefs.Delete strTestQuery

    On Error GoTo ErrorHandler

    ‘Create new query

    Set qdf = dbs.CreateQueryDef(strTestQuery, strTestSQL)

    ‘Test whether there are any records

    Set rst = dbs.OpenRecordset(strTestQuery)

     With rst

    .MoveFirst

    .MoveLast

    CreateAndTestQuery = .RecordCount

    End With

    ErrorHandlerExit:

    Exit Function

    ErrorHandler:If Err.Number = 3021 Then

    CreateAndTestQuery = 0

    Resume ErrorHandlerExit

    Else

    MsgBox “Error No: “ & Err.Number & “; Description: “ &

    Err.Description

    Resume ErrorHandlerExit

    End If

    58

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    8/18

    End Function

    Public Function TestFileExists(strFile As String) As Boolean

    On Error Resume Next

    TestFileExists = Not (Dir(strFile) = “”)

    End Function

    The code in the sample database requires a reference to the Excel object library;Figure 3.7 shows this reference checked in the References dialog, which is opened

    from the Tools menu in the Visual Basic window.

    FIGURE 3.7

    Setting a reference to the Excel object model.

     After the worksheet of archived records has been created and saved, you will get a message

    (depicted in Figure 3.8) listing the location where the archive worksheet was saved.

    FIGURE 3.8

    A success message after records are archived.

    NOTENOTE

    59

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    9/18

    See Chapter 7 for a more flexible way of specifying a Templates folder and a Documents

    folder.

     After the code deletes the archived records — first the ones in tblOrderDetails (the “many” table)

    and then those in tblOrders (the “one” table) — a final message appears, as shown in Figure 3.9.

    FIGURE 3.9

    A final informative message stating that the archived database records have been cleared.

     A worksheet filled with archived data is shown in Figure 3.10.

    FIGURE 3.10

    A worksheet filled with archived Access data.

    Saving the newly created worksheet with the xlWorkbookDefault value for the FileFormatargument saves it as a standard Excel worksheet. If you need to save the worksheet in another for-

    mat, perhaps for use by someone running an older version of Excel, you can use one of the othervalues in the XlFileFormat enum, which are shown in the Object Browser in Figure 3.11. The

    xlExcel9795 named constant will create a worksheet in a format usable by people runningExcel 95 or 97. (The worksheet format choices available in VBA code are much more numerous

    than those available in the interface, as shown in Figure 3.12.)

    NOTENOTE

    60

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    10/18

    FIGURE 3.11

    Viewing the file format choices for saving an Excel workbook.

    If you create a worksheet in the new .xlsx format, only Office 2007 users will be able

    to open it. To create a worksheet that can be opened and edited by users with earlierversions of Office, select one of the other formats. The Excel 97–Excel 2003 Workbook (.xls) format(shown being selected in Figure 3.12) is usable in Office 97 through 2007, so it is generally the mostuseful worksheet format.

    FIGURE 3.12

    Selecting a worksheet save format.

    WARNINGWARNING

    61

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    11/18

    To open the Object Browser for examining components of an object model, open the

    Visual Basic window and select Object Browser from the View menu, or press F2.

    Formatting Excel Worksheets in VBA CodeIf you need to sort, group, indent, or otherwise format exported data in an Excel worksheet, or cre-ate a total under the last row of data, you can write VBA code to use Excel commands to do thework in code. You can apply formatting to a worksheet created by the TransferSpreadsheetmethod, or one created from the Ribbon command, or a worksheet created programmatically froma template.

    See Chapter 7 for examples of creating worksheets using the TransferSpreadsheet

    method.

    In this section, data from qryOrdersAndDetails is exported to a new worksheet made from a tem-plate and is then formatted in code. For convenience, the ExportNorthwindData procedurecan be run from the macro mcrExportNorthwindData.

    The procedure starts by creating a new worksheet from a template (Northwind Orders.xltx), as forthe ArchiveData procedure. Data from the query qryOrdersAndDetails is written to rowsin the worksheet, and then a set of Excel commands is used to apply hairline borders to the dataarea, and a double bottom border to the column headings row.

    Next, the worksheet’s data area is sorted by the first two columns (Country and Category), and theextra values are removed (the effect is similar to turning on Hide Duplicates in an Access report).Finally, a Grand Total is created under the last row, made large and bold, and enclosed in a box.The procedure is listed as follows:

    Public Sub ExportNorthwindData()

    On Error GoTo ErrorHandler

    Dim appExcel As Object

    Dim i As Integer

    Dim lngCount As Long

    Dim lngCurrentRow As Long

    Dim lngRows As Long

    Dim n As Long

    Dim objFind As Object

    Dim rng As Excel.RangeDim rngData As Excel.Range

    Dim rngStart As Excel.Range

    Dim strCategory As String

    Dim strCountry As String

    Dim strCurrAddress As String

    Dim strDBPath As String

    Dim strFormula As String

    CROSS-REFCROSS-REF

    NOTENOTE

    62

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    12/18

    Dim strPrompt As String

    Dim strDataRange As String

    Dim strRange As String

    Dim strSaveName As String

    Dim strSheetName As StringDim strStartAddress As String

    Dim strTemplate As String

    Dim strTemplateFile As String

    Dim strTitle As String

    Dim wkb As Excel.Workbook

    Dim wks As Excel.Worksheet

    Create a new worksheet from the template and export data to it:

    strDBPath = Application.CurrentProject.Path & “\”

    Debug.Print “Current database path: “ & strDBPath

    strTemplate = “Northwind Orders.xltx”

    strTemplateFile = strDBPath & strTemplateIf TestFileExists(strTemplateFile) = False Then

    Put up a message and exit if the template is not found:

    strTitle = “Template not found”

    strPrompt = “Excel template ‘Northwind Orders.xlt’” _

    & “ not found in “ & strDBPath & “;” & vbCrLf _

    & “please put template in this folder and try again”

    MsgBox strPrompt, vbCritical + vbOKOnly, strTitle

    GoTo ErrorHandlerExit

    Else

    Debug.Print “Excel template used: “ & strTemplateFile

    End If

    Set appExcel = GetObject(, “Excel.Application”)

    Set dbs = CurrentDb

    Create a recordset based on the Access query:

    Set rst = dbs.OpenRecordset(“qryOrdersAndDetails”)

    Create a new worksheet based on the template:

    Set wkb = appExcel.Workbooks.Add(strTemplateFile)

    Set wks = wkb.Sheets(1)

     wks.ActivateappExcel.Visible = True

    Go to the first data cell in the worksheet:

    Set rngStart = wks.Range(“A4”)

    Set rng = wks.Range(“A4”)

    63

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    13/18

    Reset lngCount to the number of records in the query:

    rst.MoveLast

    rst.MoveFirst

    lngCount = rst.RecordCount

    For n = 1 To lngCount

     Write data from the recordset to cells in the current row of the worksheet, using the columnoff-set argument to move to the next cell:

    rng.Value = Nz(rst![ShipCountry])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Category])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Product])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Customer])Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![OrderID])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![UnitPrice])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Quantity])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![Discount])

    Set rng = rng.Offset(columnoffset:=1)

    rng.Value = Nz(rst![TotalPrice])

    Go to the next row of the worksheet, using the rowoffset argument:

    rst.MoveNext

    Set rng = rngStart.Offset(rowoffset:=n)

    Next n

    Determine the number of data rows in the worksheet with the UsedRange property:

    lngRows = wks.UsedRange.Rows.Count

    Debug.Print “Number of data rows in worksheet: “ & lngRows

    Define the data range:

    strRange = “A4:I” & CStr(lngRows)

    Set rngData = wks.Range(strRange)

     Apply hairline borders to the data range:

     With rngData

    .Borders(xlDiagonalDown).LineStyle = xlNone

    .Borders(xlDiagonalUp).LineStyle = xlNone

    64

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    14/18

    .Borders(xlEdgeLeft).LineStyle = xlContinuous

    .Borders(xlEdgeLeft).Weight = xlHairline

    .Borders(xlEdgeLeft).ColorIndex = xlAutomatic

    .Borders(xlEdgeTop).LineStyle = xlContinuous

    .Borders(xlEdgeTop).Weight = xlHairline

    .Borders(xlEdgeTop).ColorIndex = xlAutomatic

    .Borders(xlEdgeBottom).LineStyle = xlContinuous

    .Borders(xlEdgeBottom).Weight = xlHairline

    .Borders(xlEdgeBottom).ColorIndex = xlAutomatic

    .Borders(xlEdgeRight).LineStyle = xlContinuous

    .Borders(xlEdgeRight).Weight = xlHairline

    .Borders(xlEdgeRight).ColorIndex = xlAutomatic

    .Borders(xlInsideVertical).LineStyle = xlContinuous

    .Borders(xlInsideVertical).Weight = xlHairline

    .Borders(xlInsideVertical).ColorIndex = xlAutomatic

    .Borders(xlInsideHorizontal).LineStyle = xlContinuous

    .Borders(xlInsideHorizontal).Weight = xlHairline

    .Borders(xlInsideHorizontal).LineStyle = xlContinuousEnd With

     Apply a double border to the bottom of the column headings row:

     wks.Rows(“3:3”).Select

     With appExcel.Selection

    .Borders(xlDiagonalDown).LineStyle = xlNone

    .Borders(xlDiagonalUp).LineStyle = xlNone

    .Borders(xlEdgeLeft).LineStyle = xlNone

    .Borders(xlEdgeTop).LineStyle = xlNone

    End With

     With appExcel.Selection.Borders(xlEdgeBottom)

    .LineStyle = xlDouble

    .ColorIndex = 0

    .TintAndShade = 0

    .Weight = xlThick

    End With

     With appExcel.Selection

    .Borders(xlEdgeRight).LineStyle = xlNone

    .Borders(xlInsideVertical).LineStyle = xlNone

    End With

    Sort the data range by country and category:

    strDataRange = “A3:I” & CStr(lngRows)

    strKey1Range = “A4:A” & CStr(lngRows)

    strKey2Range = “B4:B” & CStr(lngRows)

    Debug.Print “Data range: “ & strDataRange

    65

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    15/18

     wks.Range(strDataRange).Select

     wks.Sort.SortFields.Clear

     wks.Sort.SortFields.Add Key:=Range(strKey1Range), _

    SortOn:=xlSortOnValues, _

    Order:=xlAscending, _DataOption:=xlSortNormal

     wks.Sort.SortFields.Add Key:=Range(strKey2Range), _

    SortOn:=xlSortOnValues, _

    Order:=xlAscending, _

    DataOption:=xlSortNormal

     With wks.Sort

    .SetRange Range(strDataRange)

    .Header = xlYes

    .MatchCase = False

    .Orientation = xlTopToBottom 

    .SortMethod = xlPinYin

    .Apply

    End With

    Remove the duplicate countries:

    Set rng = wks.Range(“A:A”)

    For i = 4 To lngRows

    Debug.Print rng.Cells(i, 1).Address & “ contains “ _

    & rng.Cells(i, 1).Value

    If rng.Cells(i, 1) = rng.Cells(i - 1, 1) Then

    rng.Cells(i, 1).Font.ColorIndex = 2

    ElseIf rng.Cells(i, 1).Value strCountry Then

    Debug.Print “Different data in “ _

    & rng.Cells(i, 1).Address

    strCountry = rng.Cells(i, 1).Value

    End If

    Next i

    Remove the duplicate categories:

    Set rng = wks.Range(“B:B”)

    For i = 4 To lngRows

    Debug.Print rng.Cells(i, 1).Address & “ contains “ _

    & rng.Cells(i, 1).Value

    If rng.Cells(i, 1).Value = rng.Cells(i - 1, 1) Then

    rng.Cells(i, 1).Font.ColorIndex = 2

    ElseIf rng.Cells(i, 1).Value strCategory Then

    Debug.Print “Different data in “ _

    & rng.Cells(i, 1).Address

    strCategory = rng.Cells(i, 1).Value

    End If

    Next i

    66

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    16/18

     Add a Grand Total, and format its cell:

    strFormula = “=SUM(R[-” & CStr(lngRows - 2) _

    & “]C:R[-1]C)”

    Debug.Print “Formula: “ & strFormula

    strRange = “I” & CStr(lngRows + 2)

    Debug.Print “Range: “ & strRange

     wks.Range(strRange).FormulaR1C1 = strFormula

     wks.Range(strRange).Select

     With appExcel.Selection.Font

    .Name = “Calibri”

    .Size = 14

    .Strikethrough = False

    .Superscript = False

    .Subscript = False

    .OutlineFont = False

    .Shadow = False

    .Underline = xlUnderlineStyleNone

    .ThemeColor = 2

    .TintAndShade = 0

    .ThemeFont = xlThemeFontMinor

    End With

     With appExcel.Selection

    .Font.Bold = True

    .Borders(xlDiagonalDown).LineStyle = xlNone

    .Borders(xlDiagonalUp).LineStyle = xlNone

    End With

     With appExcel.Selection.Borders(xlEdgeLeft)

    .LineStyle = xlContinuous

    .ColorIndex = 0

    .TintAndShade = 0

    .Weight = xlMedium 

    End With

     With appExcel.Selection.Borders(xlEdgeTop)

    .LineStyle = xlContinuous

    .ColorIndex = 0

    .TintAndShade = 0

    .Weight = xlMedium 

    End With

     With appExcel.Selection.Borders(xlEdgeBottom)

    .LineStyle = xlContinuous

    .ColorIndex = 0

    .TintAndShade = 0

    .Weight = xlMedium 

    End With

    67

    Analyzing Data with Excel

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    17/18

     With appExcel.Selection.Borders(xlEdgeRight)

    .LineStyle = xlContinuous

    .ColorIndex = 0

    .TintAndShade = 0

    .Weight = xlMedium End With

     With appExcel.Selection

    .Borders(xlInsideVertical).LineStyle = xlNone

    .Borders(xlInsideHorizontal).LineStyle = xlNone

    End With

    Save and close the filled-in worksheet, using a workbook save name with the date range:

    strSheetName = “Northwind Orders as of “ _

    & Format(Date, “d-mmm-yyyy”)

    Debug.Print “Sheet name: “ & strSheetName

     Write the title with the date range to the worksheet:

     wks.Range(“A1”).Value = strSheetName

    strSaveName = strDBPath & strSheetName & “.xlsx”

    Debug.Print “Time sheet save name: “ & strSaveName

    ChDir strDBPath

    On Error Resume Next

    If there already is a saved worksheet with this name, delete it:

    Kill strSaveName

    On Error GoTo ErrorHandler

     wkb.SaveAs FileName:=strSaveName, _

    FileFormat:=xlWorkbookDefault

     wkb.Close

    rst.Close

    Put up a success message with the name and path of the new worksheet:

    strTitle = “Workbook created”

    strPrompt = strSheetName & vbCrLf & “created in “ _

    & strDBPath

    MsgBox strPrompt, vbOKOnly + vbInformation, strTitle

    ErrorHandlerExit:

    Exit Sub

    ErrorHandler:

    ‘Excel is not running; open Excel with CreateObject

    68

    The Office Components and What They Do BestPart I

  • 8/17/2019 Access 2007 VBA -Using Excel Templates to Create Formatted Worksheets Filled With Access Data

    18/18

    If Err.Number = 429 Then

    Set appExcel = CreateObject(“Excel.Application”)

    Resume Next

    Else

    MsgBox “Error No: “ & Err.Number & “; Description: “ _& Err.Description

    Resume ErrorHandlerExit

    End If

    End Sub

     A finished worksheet is shown in Figure 3.13.

    FIGURE 3.13

    A worksheet filled with data and formatted using VBA code.

    Summary 

     When you need to export Access data to Excel worksheets so that everyone who has Office can

    work with them, you can use the techniques discussed in this chapter to export Access data in theinterface, or using VBA code, either to a plain default worksheet, or a formatted worksheet createdfrom an Excel template.

    Analyzing Data with Excel