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
finds the account amongst those available that matches a string that contains a unique part of the email address I want to send from
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
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
,