vbaoutlook

When is an object not an object? Sendusingaccount in Excel VBA


Following up an earlier thread (how to set an Account object by MailItem.SendUsingAccount when sending an email?), I'm interested in the fact that one of the replies in that post uses SET when setting the property of the mail item, and one does not. This is rather odd! I have a large and quite complex lump of VBA code which

  1. finds the account amongst those available that matches a string that contains a unique part of the email address I want to send from

  2. creates a new mail item , and then sets the account to be used to send it.

In my code, the SET statement is required to be present in step 1), but is required not to be there in step 2) which is rather odd (including SET generates a 91 run time error). I think that somehow the account object is morphing into the string that is the SMTP address of that account, and that outlook is then working from that email address to use the required account.

Thank you. Key parts of the code:

a) Various declarations

Public g_olapp As outlook.Application
Public g_ol_account As outlook.Account
Private olmsg As outlook.MailItem

b) Initialise things

Set g_olapp = New outlook.Application
Set g_ol_account = find_account(g_from_email, b_err)

c) Find account function, this does seem to return an object, the SET statement is required

Private Function find_account(s As String, b As Boolean) As outlook.Account


Dim p_olaccount As outlook.Account
Dim s_send_from As String
s_send_from = UCase(s)
If s_send_from = "" Then

If MsgBox("No account specified, do you want to use the default account <SPJUDGE> ?", Title:=box_title, Buttons:=vbYesNo + vbQuestion) = vbNo Then
    b = True
    Exit Function
End If
s_send_from = "SPJUDGE"
End If
Set find_account = Nothing
For Each p_olaccount In g_olapp.Session.Accounts  
If (Not InStr(UCase(p_olaccount.SmtpAddress), s_send_from) = 0) Then

Set find_account = p_olaccount
    s = p_olaccount.SmtpAddress
    Exit Function
End If
Next

 MsgBox "Account <" & s_send_from & "> not found" _
& String(2, 13) & "Program terminating", Title:=box_title, _
 Buttons:=vbOKOnly + vbCritical
b = True
End Function

d) Make the email item

Set olmsg = make_new_email(g_olapp, s_email) 

e) Another function to create a new email object.

Public Function make_new_email(olapp As Object, s As String) As outlook.MailItem

Dim arr() As String
Dim jloc As Integer
Dim jlb As Integer
Dim recip As outlook.Recipient

Set make_new_email = olapp.CreateItem(olMailItem)
'    MsgBox g_ol_account note this does work.
With make_new_email

     .SendUsingAccount = g_ol_account ' WHY NOT SET IN THIS LINE ??
     If gb_set_reply Then
     .ReplyRecipients.add (g_reply_to_email)
    End If
    .OriginatorDeliveryReportRequested = b_askfor_receipts
    .ReadReceiptRequested = b_askfor_receipts
End With
s = Replace(s, "SIMON JUDGE", "", , , vbTextCompare)
arr = Split(s, ";") ' changed from comma Nov 2023
jlb = LBound(arr)
For jloc = jlb To UBound(arr)
    Set recip = make_new_email.Recipients.add(Trim(arr(jloc)))
    If jloc = jlb Then
        recip.Type = olTo

    Else
        recip.Type = olCC
    End If
Next jloc

End Function

Solution

  • In one case you are assigning a variable, which requires VB to increment the COM object reference count (hence Set). In another case you are setting a property (SendUsingAccount), which is essentially a call to a function like Set_SendUsingAccount(SomeValue). What that function does is up to it, so you don't need Set,