Archive for September 3rd, 2010

September 3rd, 2010

VBA – Sending Faxes VBA

Sending Faxes of a Document using VBA (Microsoft Shared Fax Driver)

 

I had a requirement for a database to be able to send faxes directly from within the database. At the time, I looked high and low and couldn’t find anything on the subject using the Microsoft Shared Fax Driver (Fax printer). It is only recently that I came across a website that covered the subject very well (Murphy’s Law!).

MSDN Article

The following is a slightly modified version of the code found in the MSDN Article. I use a temporary table to populate the recipient of my broadcast (multiple recipient fax).

'---------------------------------------------------------------------------------------
' Procedure  : SendBroadCast
' Author     : CARDA Consultants Inc.
' Website    : http://www.cardaconsultants.com
' Code Source: http://msdn2.microsoft.com/en-us/library/ms693479.aspx
' Purpose    : Send Broadcast fax (send fax to multiple recipients)
' References : requires 'Microsoft Fax Service Extended COM Type Library'
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and 
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strDoc - path and filname of the document to be faxed
'---------------------------------------------------------------------------------------
'
Function SendBroadCast(strDoc As String)
 
Dim objFaxDocument As New FAXCOMEXLib.FaxDocument
Dim collFaxRecipients As FaxRecipients
Dim JobId As Variant
Dim strMsg As String
 
'Error handling
On Error GoTo Error_Handler
 
'Set the fax body
objFaxDocument.Body = strDoc
 
'Name the document
objFaxDocument.DocumentName = "Database Fax"
 
'Get the recipients collection
Set collFaxRecipients = objFaxDocument.Recipients
 
'Update the table from which the info is pull to generate the fax recipient list
DoCmd.SetWarnings False 'Turn off warning messages so it is transparent to the user
DoCmd.OpenQuery "Qry_Need To Be Faxed", acViewNormal
DoCmd.SetWarnings True 'Turn back on warning messages

'Add the recipients
With collFaxRecipients
    'Using the table created by the above run query loop through the record
    'To populate the fax recipient list
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("Temp01")
    If rst.RecordCount > 0 Then 'ensure there is data
        rst.MoveLast  'goto the last recordset
        Do Until rst.BOF  'beginning of file
           'perform a desired action
           .Add rst![Fax], rst![Company]
           rst.MovePrevious
        Loop
    Else
        MsgBox "There are no faxes to be sent at this time!", vbInformation
    End If
 
End With
 
'Display number of recipients
strMsg = "Total Number of Recipients: " & collFaxRecipients.Count & vbCrLf
 
'Display recipient information
Dim i As Long
For i = 1 To collFaxRecipients.Count
    strMsg = strMsg & "Recipient number " & i & ": " & collFaxRecipients.Item(i).Name & _
             ", " & collFaxRecipients.Item(i).FaxNumber & vbCrLf
Next
MsgBox strMsg, vbInformation, "The following faxes are being processed."
 
'Load the default sender
objFaxDocument.Sender.LoadDefaultSender
 
'Group the broadcast receipts
objFaxDocument.GroupBroadcastReceipts = True
 
'Connect to the fax server, submit the document, and get back the
'job ID array. "" indicates the local server.
JobId = objFaxDocument.Submit("")
 
'UBound finds the size of the array
'Display jobIDs for each of the fax jobs
'For n = 0 To UBound(JobId)
'    MsgBox "The Job ID is " & JobId(n)
'Next

'Remove the recipients from the collection. If you don't take this step,
'and run this code again without closing the program, the recipients
'collection will retain the recipients and keep adding more recipients.
'The count and item numbering will change as you remove the items, so
'just remove item (1) Count times
Dim lCount As Long
lCount = collFaxRecipients.Count
For i = 1 To lCount
    collFaxRecipients.Remove (1)
Next
Exit Function
 
Error_Handler:
    'Implement error handling at the end of your subroutine. This
    'implementation is for demonstration purposes
    If Err.Number = -2147024864 Then
        MsgBox "You currently have the document to be faxed open and are therefore" & _
               " stopping the fax from being sent.  Please close the document in " & _
               "question and then try again.", vbInformation, "Your Fax cannot be " & _
               "sent at this time"
    Else
        MsgBox "Error number: " & Err.Number & ", " & Err.Description
    End If
End Function

September 3rd, 2010

Word – VBA – Print a Word Document

The following code will print out a word document.

'---------------------------------------------------------------------------------------
' Procedure : PrintDoc
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Print a Word Document
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and 
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strDoc - The path and filename of the document to be printes
' intCopies - The number of copies to be printed
'
' Usage:
' ~~~~~~~~~~~~~~~~
' PrintDoc("c:\management\evaluation.doc",1)
'---------------------------------------------------------------------------------------
Function PrintDoc(strDoc As String, intCopies As Integer)
 
   Dim WordObj As Object
 
   Set WordObj = CreateObject("Word.Application")
 
   WordObj.Documents.Open strDoc
   WordObj.PrintOut Background:=False, Copies:=intCopies
   WordObj.Documents.Close SaveChanges:=wdDoNotSaveChanges
   WordObj.Quit
 
   Set WordObj = Nothing
 
 End Function

September 3rd, 2010

VBA – Word – Open Word using Late Binding

The following procedure will launch MS Word. The beauty is it uses late binding so you do not need to use reference libraries and as such avoid/minimize versioning issues. This same procedure can easily be modified to launch just about any MS Office application by simply changing the “Word.Application” portions of the code to correspond with the application you are trying to automate.

A few other strings used for common MS Office application are:

  • Excel – “Excel.Application”
  • Access – “Access.Application”
  • Publisher – “Publisher.Application”
  • PowerPoint – “Powerpoint.Application”

Sub LaunchWord()
Dim objApp As Object
 
    'See if Word is already running
    On Error Resume Next
    Set objApp = GetObject(, "Word.Application")
 
    If Err.Number <> 0 Then
        'Launch a new instance of Word
        Err.Clear
        On Error GoTo Error_Handler
        Set objApp = CreateObject("Word.Application")
        objApp.Visible = True 'Make the application visible to the user (if wanted)
    End If
 
Exit Sub
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: LaunchWord" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Exit Sub
End Sub

September 3rd, 2010

VBA – Excel – Execute/Run an Excel Worksheet Function

Have you ever needed to use an Excel function within one of your databases, or other application. Below is a generic example of how you can call just about any Excel function using VBA to extend your database’s functionalities even further.

'---------------------------------------------------------------------------------------
' Procedure : GetXLWkSHtFuncVal
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Execute an Excel Worksheet Function from MS Access
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-Jan-31             Initial Release
'---------------------------------------------------------------------------------------
Function GetXLWkSHtFuncVal()
   Dim xlApp      As Object
On Error GoTo Error_Handler
 
   Set xlApp = CreateObject("Excel.Application")
   xlApp.Visible = False   'Control whether or not Excel should be visible to
                           'the user or not.
   
   'This is a generic example using the NormInv(), but you can do the same with just
   'about any other Excel Worksheet function.
   GetXLWkSHtFuncVal = xlApp.WorksheetFunction.NormInv(0.25, 4, 1)
 
   xlApp.Quit           'Close the instance of Excel we create

Error_Handler_Exit:
   On Error Resume Next
   Set xlApp = Nothing
   Exit Function
 
Error_Handler:
   MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
   Err.Number & vbCrLf & "Error Source: GetXLWkSHtFuncVal" & vbCrLf & "Error Description: " & _
   Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

September 3rd, 2010

VBA – Excel – Clear/Delete an Excel Worksheet

Have you ever needed to blank an Excel worksheet from an Access (or other programs as well – Word, PowerPoint, …) database? The following procedure does exactly that!

'---------------------------------------------------------------------------------------
' Procedure : ClearXLSWrkSht
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Clear the specified worksheet in a given excel workbook from MS Access
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sXLSFile     Excel workbook filename with full path (ie: "C:\test.xls")
' sXLSWrkSht   Excel worksheet to be cleared (ie: "Sheet1")
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' ClearXLSWrkSht("C:\test.xls", "Sheet1")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-Jan-28             Initial Release
'---------------------------------------------------------------------------------------
Sub ClearXLSWrkSht(sXLSFile As String, sXLSWrkSht As String)
   Dim xlApp      As Object
   Dim xlBook     As Object
   Dim xlSheet    As Object
On Error GoTo Error_Handler
 
   Set xlApp = CreateObject("Excel.Application")
   xlApp.Visible = True 'Control whether or not Excel should be visible to
                        'the user or not.
   Set xlBook = xlApp.Workbooks.Open(sXLSFile)  'Open the workbook
   Set xlSheet = xlBook.Worksheets(sXLSWrkSht)  'Worksheet we are working with
   
   xlSheet.Cells.Select
   xlSheet.Cells.ClearContents   'Clear the contents
   
   xlBook.Close True 'Close and save the workbook
   xlApp.Quit        'Close the instance of Excel we create

Error_Handler_Exit:
   On Error Resume Next
   Set xlSheet = Nothing
   Set xlBook = Nothing
   Set xlApp = Nothing
   Exit Sub
 
Error_Handler:
   MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
   Err.Number & vbCrLf & "Error Source: ClearXLSWrkSht" & vbCrLf & "Error Description: " & _
   Err.Description, vbCritical, "An Error has Occured!"
   Resume Error_Handler_Exit
End Sub

September 3rd, 2010

VBA – Excel – List the Sheet Names of an Excel Workbook

'---------------------------------------------------------------------------------------
' Procedure : ListXlsSheets
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : List the sheet name of an Excel Workbook
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFile - The Excel file to list the sheets
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2008-Jul-15                 Initial Release
'---------------------------------------------------------------------------------------
Function ListXlsSheets(sFile As String)
On Error GoTo Error_Handler
    Dim NumSheets   As Integer
    Dim i           As Integer
    Dim xlApp       As Object
    Dim xlWrkBk     As Object
    Dim xlWrkSht    As Object
 
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application") 'Bind to existing instance of Excel
    
    If Err.Number <> 0 Then
        'Could not get instance of Excel, so create a new one
        Err.Clear
        On Error GoTo Error_Handler
        Set xlApp = CreateObject("excel.application")
    Else
        On Error GoTo Error_Handler
    End If
 
    xlApp.Visible = False 'make excel visible or not to the user
    Set xlWrkBk = xlApp.Workbooks.Open(sFile)
 
    NumSheets = xlWrkBk.Sheets.Count
    For i = 1 To NumSheets
        Debug.Print i & " - " & xlWrkBk.Sheets(i).Name
    Next i
 
    xlWrkBk.Close False
    xlApp.Close
 
    Set xlWrkSht = Nothing
    Set xlWrkBk = Nothing
    Set xlApp = Nothing
 
Exit Function
 
Error_Handler:
    If Err.Number <> 438 Then
        MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
        Err.Number & vbCrLf & "Error Source: ListXlsSheets" & vbCrLf & "Error Description: " & _
        Err.Description, vbCritical, "An Error has Occured!"
        Exit Function
    Else
        Resume Next
    End If
 
End Function

September 3rd, 2010

VBA – Excel – Print an Excel WorkSheet Range

'---------------------------------------------------------------------------------------
' Procedure : PrinWrkShtRng
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Print a specified worksheet range
' Copyright : It is not to be altered or distributed,
'             except as part of an application.
'             You are free to use it in any application,
'             provided the copyright notice is left unchanged.
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strWrkBk      Workbook file name(full path and filename)
' strWrkSht     Worksheet name which whose range are to be printed
' strRng        Worksheet Range to be printed
'
'
' Revision History:
' Rev       Date(yyyy/mm)           Description
' **************************************************************************************
' 1         2008-Feb                Initial Release
'---------------------------------------------------------------------------------------
Function PrinWrkShtRng(strWrkBk As String, strWrkSht As String, strRng As String)
On Error GoTo PrinWrkShtRng_Error
    Dim xlApp       As Object
    Dim xlWrkBk     As Object
    Dim xlWrkSht    As Object
 
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application") 'Bind to existing instance of Excel
    
    If Err.Number <> 0 Then
        'Could not get instance of Excel, so create a new one
        Err.Clear
        On Error GoTo PrinWrkShtRng_Error
        Set xlApp = CreateObject("excel.application")
    Else
        On Error GoTo PrinWrkShtRng_Error
    End If
 
    xlApp.Visible = True 'make excel visible to the user
    Set xlWrkBk = xlApp.Workbooks.Open(strWrkBk)
 
    Set xlWrkSht = xlApp.Worksheets(strWrkSht)
 
    With xlWrkSht.PageSetup
        .PrintArea = strRng
        .Zoom = False
        .FitToPagesTall = 1
        .FitToPagesWide = 1
        .Orientation = xlLandscape
    End With
 
    xlWrkSht.PrintOut Copies:=1
 
    xlWrkBk.Close False
    xlApp.Close
 
    Set xlWrkSht = Nothing
    Set xlWrkBk = Nothing
    Set xlApp = Nothing
 
Exit Function
 
PrinWrkShtRng_Error:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: PrinWrkShtRng" & vbCrLf & _
    "Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
    Exit Function
 
End Function

September 3rd, 2010

VBA – Excel – Delete a Worksheet from a Workbook

'---------------------------------------------------------------------------------------
' Procedure : DelWrkSht
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Delete a worksheet from an Excel workbook
' Copyright : It is not to be altered or distributed,
'             except as part of an application.
'             You are free to use it in any application,
'             provided the copyright notice is left unchanged.
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strWrkBk      Workbook to delete the worksheet in/from (full path and filename)
' strWrkSht     Worksheet to be deleted
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2008-Feb                 Initial Release
'---------------------------------------------------------------------------------------
Function DelWrkSht(strWrkBk As String, strWrkSht As String) As Boolean
    Dim xlApp       As Object
    Dim xlWrkBk     As Object
 
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application") 'Bind to existing instance of Excel
    
    If Err.Number <> 0 Then
        'Could not get instance of Excel, so create a new one
        Err.Clear
        On Error GoTo DelWrkSht_Error
        Set xlApp = CreateObject("excel.application")
    Else
        On Error GoTo DelWrkSht_Error
    End If
 
    Set xlWrkBk = xlApp.Workbooks.Open(strWrkBk)
 
        xlApp.DisplayAlerts = False 'surpress user confirmation prompt
        xlApp.Worksheets(strWrkSht).Delete
        xlApp.DisplayAlerts = True  'reengage user confirmation prompt
        xlApp.Visible = True
 
    Set xlApp = Nothing
    Set xlWrkBk = Nothing
 
    DelWrkSht = True
 
Exit Function
 
DelWrkSht_Error:
    DelWrkSht = False
    If Err.Number = 9 Then
        'Worksheet not found
        MsgBox "Worksheet '" & strWrkSht & "' not found in Workbook '" & strWrkBk & "'", vbCritical
        Exit Function
    ElseIf Err.Number = 1004 Then
        'Workbook not found
        MsgBox "Unable to locate Workbook '" & strWrkBk & "'", vbCritical
        Exit Function
    Else
        'Othere Errors
        MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
        Err.Number & vbCrLf & "Error Source: basExcel / DelWrkSht" & vbCrLf & _
        "Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
        Exit Function
    End If
End Function

September 3rd, 2010

VBA – Create an Outlook Contact

The following procedure illustrates how easily one can use VBA to create an Outlook Contact using Late binding so no references are required. Also note, there are many more contact properties available to the VBA programmer, for a full list consult the Outlook Help file.

Function AddOlContact()
On Error GoTo Error_Handler
    Const olContactItem = 2
    Dim olApp As Object
    Dim Ctct As Object
 
    Set olApp = CreateObject("Outlook.Application")
    Set olContact = olApp.CreateItem(olContactItem)
 
    With olContact
        .FirstName = "Daniel"
        .LastName = "Alba"
        .JobTitle = ""
        .CompanyName = "MINI CARDA"
        .BusinessAddressStreet = "22 ClearPoint"
        .BusinessAddressCity = "Pointe-Claire"
        .BusinessAddressState = "Quebec"
        .BusinessAddressCountry = "Canada"
        .BusinessAddressPostalCode = "H9X 3A6"
        .BusinessTelephoneNumber = "(514) 488-0956"
        .BusinessFaxNumber = ""
        .Email1Address = "mini@mini.com"
        .MobileTelephoneNumber = ""
        .Save 'use .Display if you wish the user to see the contact pop-up
    End With
 
Error_Handler_Exit:
    On Error Resume Next
    Set olContact = Nothing
    Set olApp = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "MS Access has generated the following error" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: AddOlContact" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

September 3rd, 2010

VBA – Create an Outlook Task

Below is a simple function which permits you to use VBA to add a task into Outlook using late binding, so no references are required!

'---------------------------------------------------------------------------------------
' Procedure : AddOlTask
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Create a task in Outlook using late binding (no need for references)
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sSubject          : Task subject
' sBody             : Task body (the actual content message in the task)
' dtDueDate         : Task due date
' dtReminderDate    : Task reminder date/time
'
' Usage Example:
' ~~~~~~~~~~~~~~~~
' ? AddOlTask("Meeting with Daniel","Meeting w/ Daniel to discuss the database.", _
'             #5/31/2010#, #5/29/2010 9:00 AM#)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2010-May-20                 Initial Release
'---------------------------------------------------------------------------------------
Function AddOlTask(sSubject As String, sBody As String, _
                    dtDueDate As Date, _
                    dtReminderDate As Date)
On Error GoTo Error_Handler
 
    Const olTaskItem = 3
    Dim OlApp As Object
    Dim OlTask As Object
 
    Set OlApp = CreateObject("Outlook.Application")
    Set OlTask = OlApp.CreateItem(olTaskItem)
 
    With OlTask
        .Subject = sSubject
        .DueDate = dtDueDate
        .Status = 1                 '0=not started, 1=in progress, 2=complete, 3=waiting,
                                    '4=deferred
        .Importance = 1             '0=low, 1=normal, 2=high
        .ReminderSet = True
        .ReminderTime = dtReminderDate
        .Categories = "Business" 'use any of the predefined Categorys or create your own
        .Body = sBody
        .Save   'use .Display if you wish the user to see the task form and make
                'them perform the save
    End With
 
Error_Handler_Exit:
    On Error Resume Next
    Set OlTask = Nothing
    Set OlApp = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & "Error Number: " & _
    Err.Number & vbCrLf & "Error Source: AddOlkTask" & vbCrLf & "Error Description: " & _
    Err.Description, vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

September 3rd, 2010

VBA – HTML Outlook Automation

Creating HTML Emails From Access using VBAVery similarily to the VBA Outlook Automation procedure, one need only make a slight modification.

Simply replace the line:

.Body = strBody

with

.HTMLBody = strBody

In which case, the strBody must now be in HTML format “Your content goes here” . Do not forget the HTML and BODY tags. The .HTMLBody can use most basic HTML Tags so go wild creating your messages (<i></i>, <b></b>, <br />, <p>, <h1>,…, <h6>, <a href>…, <img>, <src>…., ..)

So our new HTML Email procedure would be:

'---------------------------------------------------------------------------------------
' Procedure : SendHTMLEmail
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Automate Outlook to send an HTML email with or without attachments
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strTo         To Recipient email address string (semi-colon separated list)
' strSubject    Text string (HTML) to be used as the email subject line
' strBody       Text string to be used as the email body (actual message)
' bEdit         True/False whether or not you wish to preview the email before sending
' strBCC        BCC Recipient email address string (semi-colon separated list)
' AttachmentPath    single value or array of attachment (complete file paths with
'                   filename and extensions)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2007-Nov-16             Initial Release
'---------------------------------------------------------------------------------------
Function SendHTMLEmail(strTo As String, strSubject As String, strBody As String, bEdit As Boolean, _
                   Optional strBCC As Variant, Optional AttachmentPath As Variant)
'Send Email using late binding to avoid reference issues
   Dim objOutlook As Object
   Dim objOutlookMsg As Object
   Dim objOutlookRecip As Object
   Dim objOutlookAttach As Object
   Dim i As Integer
   Const olMailItem = 0
 
   On Error GoTo ErrorMsgs
 
   Set objOutlook = CreateObject("Outlook.Application")
 
   Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
   With objOutlookMsg
      Set objOutlookRecip = .Recipients.Add(strTo)
      objOutlookRecip.Type = 1
 
      If Not IsMissing(strBCC) Then
        Set objOutlookRecip = .Recipients.Add(strBCC)
        objOutlookRecip.Type = 3
      End If
 
      .Subject = strSubject
      .HTMLBody = strBody
      .Importance = 2  'Importance Level  0=Low,1=Normal,2=High
      
      ' Add attachments to the message.
      If Not IsMissing(AttachmentPath) Then
        If IsArray(AttachmentPath) Then
           For i = LBound(AttachmentPath) To UBound(AttachmentPath) - 1
              If AttachmentPath(i) <> "" And AttachmentPath(i) <> "False" Then
                Set objOutlookAttach = .Attachments.Add(AttachmentPath(i))
              End If
           Next i
        Else
            If AttachmentPath <> "" And AttachmentPath(i) <> "False" Then
                Set objOutlookAttach = .Attachments.Add(AttachmentPath)
            End If
        End If
      End If
 
      For Each objOutlookRecip In .Recipients
         If Not objOutlookRecip.Resolve Then
            objOutlookMsg.Display
         End If
      Next
 
      If bEdit Then 'Choose btw transparent/silent send and preview send
        .Display
      Else
        .Send
      End If
   End With
 
   Set objOutlookMsg = Nothing
   Set objOutlook = Nothing
   Set objOutlookRecip = Nothing
   Set objOutlookAttach = Nothing
 
ErrorMsgs:
   If Err.Number = "287" Then
      MsgBox "You clicked No to the Outlook security warning. " & _
      "Rerun the procedure and click Yes to access e-mail " & _
      "addresses to send your message. For more information, " & _
      "see the document at http://www.microsoft.com/office" & _
      "/previous/outlook/downloads/security.asp."
      Exit Function
   ElseIf Err.Number <> 0 Then
      MsgBox Err.Number & " - " & Err.Description
      Exit Function
   End If
End Function

September 3rd, 2010

VBA – Outlook Automation

---------------------------------------------------------------------------------------
' Procedure : SendEmail
' Author    : CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Automate Outlook to send emails with or without attachments
' Copyright : The following may be altered and reused as you wish so long as the
'             copyright notice is left unchanged (including Author, Website and
'             Copyright).  It may not be sold/resold or reposted on other sites (links
'             back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' strTo         To Recipient email address string (semi-colon separated list)
' strSubject    Text string to be used as the email subject line
' strBody       Text string to be used as the email body (actual message)
' bEdit         True/False whether or not you wish to preview the email before sending
' strBCC        BCC Recipient email address string (semi-colon separated list)
' AttachmentPath    single value or array of attachment (complete file paths with
'                   filename and extensions)
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2007-Nov-16             Initial Release
'---------------------------------------------------------------------------------------
Function SendEmail(strTo As String, strSubject As String, strBody As String, bEdit As Boolean, _
                   Optional strBCC As Variant, Optional AttachmentPath As Variant)
'Send Email using late binding to avoid reference issues
   Dim objOutlook As Object
   Dim objOutlookMsg As Object
   Dim objOutlookRecip As Object
   Dim objOutlookAttach As Object
   Dim i As Integer
   Const olMailItem = 0
 
   On Error GoTo ErrorMsgs
 
   Set objOutlook = CreateObject("Outlook.Application")
 
   Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
   With objOutlookMsg
      Set objOutlookRecip = .Recipients.Add(strTo)
      objOutlookRecip.Type = 1
 
      If Not IsMissing(strBCC) Then
        Set objOutlookRecip = .Recipients.Add(strBCC)
        objOutlookRecip.Type = 3
      End If
 
      .Subject = strSubject
      .Body = strBody
      .Importance = 2  'Importance Level  0=Low,1=Normal,2=High
      
      ' Add attachments to the message.
      If Not IsMissing(AttachmentPath) Then
        If IsArray(AttachmentPath) Then
           For i = LBound(AttachmentPath) To UBound(AttachmentPath) - 1
              If AttachmentPath(i) <> "" And AttachmentPath(i) <> "False" Then
                Set objOutlookAttach = .Attachments.Add(AttachmentPath(i))
              End If
           Next i
        Else
            If AttachmentPath <> "" Then
                Set objOutlookAttach = .Attachments.Add(AttachmentPath)
            End If
        End If
      End If
 
      For Each objOutlookRecip In .Recipients
         If Not objOutlookRecip.Resolve Then
            objOutlookMsg.Display
         End If
      Next
 
      If bEdit Then 'Choose btw transparent/silent send and preview send
        .Display
      Else
        .Send
      End If
   End With
 
   Set objOutlookMsg = Nothing
   Set objOutlook = Nothing
   Set objOutlookRecip = Nothing
   Set objOutlookAttach = Nothing
 
ErrorMsgs:
   If Err.Number = "287" Then
      MsgBox "You clicked No to the Outlook security warning. " & _
      "Rerun the procedure and click Yes to access e-mail " & _
      "addresses to send your message. For more information, " & _
      "see the document at http://www.microsoft.com/office" & _
      "/previous/outlook/downloads/security.asp."
      Exit Function
   ElseIf Err.Number <> 0 Then
      MsgBox Err.Number & " - " & Err.Description
      Exit Function
   End If
End Function

September 3rd, 2010

Outlook Automation – Bypass Outlook’s Security Prompt

Once you finally get your Outlook automation up and running you will notice that your users receive a security prompt each time your database attempts to send an automated email. Obviously, as a programmer this is not the ideal situation and there are a couple of options available to you.

 

What you need to know before going any further:

The security prompt appears for a reason. MS added this prompt to try and stop malicious usage of peoples email without their knowledge and/or consent. Many virii were propagating themselves through peoples email. This type of added security will hinder this type of attack. As a developper you must way this carefully when considering implementing any of the following work arounds.

 

Redemtion

This solution is often mentioned in numerous Forums. For more information refer to http://www.slipstick.com/outlook/esecup.htm, specifically ‘Outlook Redemption’ which is located in the ‘Automation Security’ section.

 

CDO

Another commonly refered to solution found in numerous Discussion Forums. The following website provides several example of programming with CDO.

http://www.paulsadowski.com/WSH/cdo.htm

 

Thrid Party Emailing Utilities

In my past life, when I was working for a multinational company, the work around that I implemented was to use BLAT to send the emails. I used VBA to produce a text file based on this information from within the database and it in turn was utilized by BLAT to send the email. It worked seemlessly! Best of all it is free.

 

VBScript?

Someone once mentioned that they could send emails using VBScripts without getting the security prompt. This said, I have never validated this yet.

 

Third Party Application to Automate the Confirmation

There are several little utilities available online that you can install on your clients computers that will simply automatically Click the Yes button to authorize that the email be sent. One of these programs is ClickYes. This however, bypasses security completely and could be considered a serious security issue.

September 3rd, 2010

VBA – Automating Outlook

Automating Outlook from Access has become a more and more requested feature. The link provided below is the best source of information on this subject with complete code examples. However, before lauching into automating Outlook to send emails from Access make sure that the DoCmd.SendObject method does not suffice your needs as it is much simpler to code.

http://msdn2.microsoft.com/en-us/library/aa159619(office.11).aspx