You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel VBA中Outlook SendUsingAccount为何有时无需Set语句?

Outlook VBA中SendUsingAccount属性的Set语句使用疑惑

我在跟进相关讨论时发现,部分回复设置邮件项的SendUsingAccount属性时用了Set语句,部分却没有,这让我很困惑。我的VBA代码主要做两件事:

  • 在Outlook可用账户中,查找与目标发件邮箱标识字符串匹配的账户对象
  • 创建新邮件项并设置其发送账户

实际测试中,步骤1给对象变量赋值必须用Set,但步骤2设置SendUsingAccount属性时加Set就会触发91运行时错误,不能用。我猜测这里的账户对象可能被自动转换为SMTP地址字符串,Outlook后台通过地址匹配对应账户。

关键代码片段

a) 变量声明

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

b) 初始化操作

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

c) 账户查找函数(返回对象,必须用Set)

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) 创建邮件项

Set olmsg = make_new_email(g_olapp, s_email) 

e) 创建邮件对象的函数

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 ' 此处为何不能用Set?
         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

原因解析

VBA中Set语句的作用是给对象变量赋值,而SendUsingAccount是MailItem的一个属性,虽然它的类型是Account对象,但Outlook对象模型对这个属性的设计是直接接收Account对象赋值,不需要额外加Set。

  • 步骤1中g_ol_account是一个Account类型的对象变量,给它赋值必须用Set,这是VBA对象变量赋值的语法要求。
  • 步骤2中是给MailItem的属性赋值,属性本身已经封装了对象的接收逻辑,加Set反而会违反语法规则,触发运行时错误91(对象变量或With块变量未设置)。

另外,关于你猜测的“账户对象被转换为SMTP地址”:实际上SendUsingAccount确实可以直接接收SMTP字符串赋值,Outlook会自动匹配对应账户;但直接传入Account对象也是支持的,两种方式都有效,只是语法上对象赋值不需要Set。

内容的提问来源于stack exchange,提问作者Simon J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:41:04