Home > database >  VBA Application-defined error outlook connection
VBA Application-defined error outlook connection

Time:01-08

I have the following code and keep having the error "application-defined or object-defined error" and cannot understand why. The tool Microsoft Office 16.0 Object library is activated, I am confident that the error is liked with the line Set outlookMail = outlookApp.CreateItem(0). For sure I am missing something in the connection with outlook.

Sub send_emails()

Dim outlookApp As Object
Dim outlookMail As Object
Dim cell As Range
Dim lastRow As Long

' Create Outlook object
Set outlookApp = CreateObject("Outlook.Application")

' Determine the last row in the worksheet
lastRow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row

' Loop through each cell in column D
For Each cell In Range("D2:D" & lastRow)
  
  ' Check if the date in the cell is 15 days from today
  If cell.Value = Date   15 Then
    
    ' Retrieve the corresponding email address, name, and surname
    Email = cell.Offset(0, 2).Value
    Name = cell.Offset(0, 1).Value
    surname = cell.Offset(0, -1).Value
    
    ' Create a new email
    Set outlookMail = outlookApp.CreateItem(0)
    
    ' Set the recipient, subject, and body of the email
    outlookMail.To = Email
    outlookMail.Subject = "Reminder"
    outlookMail.Body = "Dear " & Name & " " & surname & ", this is a reminder that your event is coming up in 15 days. Please make sure to prepare accordingly."
    
    ' Set the sender and send the email
    outlookMail.SendUsingAccount = outlookApp.Session.Accounts.Item("YOUR EMAIL ADDRESS")
    outlookMail.Send
    
    ' If the email was sent successfully, color the cell in column E green
    cell.Offset(0, 1).Interior.Color = vbGreen
  End If
Next cell

' Clean up
Set outlookMail = Nothing
Set outlookApp = Nothing

End Sub

CodePudding user response:

The tool Microsoft Office 16.0 Object library is activated

I suppose you have added a reference to the Outlook object model (a COM reference) in Excel VBA environment. In the code I see that the late-binding technology is used:

Dim outlookApp As Object
Dim outlookMail As Object
' Create Outlook object
Set outlookApp = CreateObject("Outlook.Application")

But at the same time you added a COM object reference for using the early-binding in the code. So, I'd suggest using the New operator and declare all Outlook objects in the code with specific types instead:

Dim outlookApp As Outlook.Application
Dim outlookMail As Outlook.MailItem

Set outlookApp = New Outlook.Application()

You can read more about early and late binding technologies in the Using early binding and late binding in Automation article.

CodePudding user response:

Send Emails From Excel

Option Explicit

Private Enum eCols
    ecSurName = 1 ' C
    ecDate = 2 ' D
    ecName = 3 ' E
    ecEmail = 4 ' F
End Enum

Sub SendEmails()
    
    Const MY_EMAIL As String = "YOUR EMAIL ADDRESS"
    
    On Error GoTo ClearError
    
    ' Reference the worksheet.
    
    If ActiveSheet Is Nothing Then Exit Sub ' no visible workbooks open
    If Not TypeOf ActiveSheet Is Worksheet Then Exit Sub ' not a worksheet
    Dim ws As Worksheet: Set ws = ActiveSheet
    
    ' Reference the range.
    
    Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    If LastRow < 2 Then Exit Sub ' no data
    Dim rg As Range: Set rg = ws.Range("C2", ws.Cells(LastRow, "F"))
    
    ' Write the values from the range to an array.
    
    Dim Data(): Data = rg.Value
    
    ' Write the matching rows to a collection.
    
    Dim coll As Collection: Set coll = New Collection
    
    Dim r As Long, rDate As Variant
    
    For r = 1 To UBound(Data, 1)
        rDate = Data(r, eCols.ecDate)
        If IsDate(rDate) Then
            If rDate = Date   15 Then coll.Add r
        End If
    Next r
    
    If coll.Count = 0 Then Exit Sub ' no matches
    
    ' Send the emails.
    
    Dim olApp As Object: Set olApp = CreateObject("Outlook.Application")
    
    Dim crg As Range, rItem, ErrNum As Long, emCount As Long
    Dim olMail As Object, mEmail As String, mName As String, mSurName As String
    
    For Each rItem In coll
        
        mEmail = Data(rItem, eCols.ecEmail)
        mName = Data(rItem, eCols.ecName)
        mSurName = Data(rItem, eCols.ecSurName)
        
        Set olMail = olApp.CreateItem(0)
        
        With olMail
            .To = mEmail
            .Subject = "Reminder"
            .Body = "Dear " & mName & " " & mSurName _
                & ", this is a reminder that your event is coming up " _
                & "in 15 days. Please make sure to prepare accordingly."
            .SendUsingAccount = olApp.Session.Accounts.Item(MY_EMAIL)
            On Error Resume Next ' suppress send error e.g. if invalid email
                olMail.Send
                ErrNum = Err.Number
            On Error GoTo ClearError
        End With
        
        ' Count and combine cells to be highlighted.
        If ErrNum = 0 Then
            emCount = emCount   1
            If crg Is Nothing Then
                Set crg = rg.Cells(rItem, eCols.ecName)
            Else
                Set crg = Union(crg, rg.Cells(rItem, eCols.ecName))
            End If
        End If
    
    Next rItem
    
ProcExit:
    On Error Resume Next
        ' Highlight cells.
        If Not crg Is Nothing Then crg.Interior.Color = vbGreen
        ' Clean up.
        If Not olMail Is Nothing Then Set olMail = Nothing
        If Not olApp Is Nothing Then Set olApp = Nothing
        ' Inform.
        MsgBox IIf(emCount = 0, "No", emCount) & " email" _
            & IIf(emCount = 1, "", "s") & " sent.", _
            IIf(emCount = 0, vbExclamation, vbInformation)
    On Error GoTo 0
Exit Sub

ClearError:
    Debug.Print "Run-time error '" & Err.Number & "':" & Err.Description
    Resume ProcExit
End Sub
  • Related