Access 2010-2016 VBA:您可以在多个版本上引用 MS Outlook 对象库吗?

Posted

技术标签:

【中文标题】Access 2010-2016 VBA:您可以在多个版本上引用 MS Outlook 对象库吗?【英文标题】:Access 2010-2016 VBA: Can you reference MS Outlook Object Library on multiple versions? 【发布时间】:2018-05-01 14:34:41 【问题描述】:

有人要求我对从 Access 数据库发送电子邮件的 VBA 脚本进行故障排除。 DB 和 VBA 是在 Access 2010 上开发的(数据存储在 SQL 数据库中),可能针对 Outlook 2010。

目前,我们使用 Outlook 2013 和 2016。

当我的脚本(如下所述)运行时,Outlook.Application 声明中会生成一个错误:用户定义的数据类型未定义

这是脚本的开头,我们定义数据类型。

Option Compare Database
Option Explicit
 
' InitOutlook sets up outlookApp and outlookNamespace.
Private outlookApp As Outlook.Application
Private outlookNamespace As Outlook.NameSpace

脚本的其余部分如下。它是由直接调用 SendEmail() 并将电子邮件地址作为变量传递的表单按钮触发的。

Private Sub InitOutlook()
    ' Initialize a session in Outlook
    Set outlookApp = New Outlook.Application
    
    'Return a reference to the MAPI layer
    Set outlookNamespace = outlookApp.GetNamespace("MAPI")
    
    'Let the user logon to Outlook with the
    'Outlook Profile dialog box
    'and then create a new session
    outlookNamespace.Logon , , True, False
End Sub

Public Sub SendEmail(varTo As Variant)
    Dim mailItem As Outlook.mailItem
        
    InitOutlook
    Set mailItem = outlookApp.CreateItem(olMailItem)
    mailItem.To = varTo & ""
    mailItem.Subject = "subject text"
    mailItem.Body = "Body text"
    mailItem.Display
    
    Set mailItem = Nothing
    CleanUp
End Sub

我对 VBA / Access 不是很熟悉,但我使用过 VB.NET,从一开始我就相当确定这是一个简单的问题,即“它缺少导入语句或引用。 "

在深入研究之后,我发现在线here 要使用此功能,您必须添加对 Microsoft Outlook XX.X 对象库的引用

我还没有看到这个数据库上的参考资料(现在正在努力到达那里),因为我对这个访问数据库的访问权限有限,因为它包含很多敏感信息,查看时我必须受到监督它。

但是,鉴于我们在编写此脚本时使用的是 Outlook 2010,并且现在分为 Outlook 2013 和 2016,我认为我们需要将此参考更新为更新的参考。

我在这里和一位同事讨论这个问题,他问了我一个重要问题:

我们可以引用多个版本的 Microsoft Outlook 对象库吗?

如果我们以最新版本的库为目标,例如 Outlook 2016,那么该脚本是否对 Outlook 2013 用户不起作用?

更新:我通过测试发现,如果我们使用 MS Outlook 16.0 对象库,Outlook 2013 将无法识别引用,并会抛出引用丢失的错误。

如果我们使用 MS Outlook 15.0 库,该脚本可以在具有任一版本 Outlook 的机器上运行。

【问题讨论】:

您可以使用后期绑定代替早期绑定,它会自行确定使用哪个版本。 正如我提到的here,如果你只使用后期绑定而不是早期绑定,你可以避免这一切。如果您坚持提前绑定,并且需要与版本无关,您可能需要走使用Conditional Compilation 的路线。早期绑定会容易得多:) @DavidZemens 我尝试切换到后期绑定,您的帖子对此非常有帮助,但在测试时意识到我们的代码中有许多不相关的部分也需要更改,即也使用了早期绑定。我不熟悉需要更新的其他区域,因此无法可靠地测试其他页面上的更改以确保它们适用于所有用户。我最终引用了 MS Outlook 15.0 对象库,这为我们的 Outlook 2013 和 2016 用户解决了问题。 我询问参考资料的原因是万一后期绑定不起作用,因为这不是我以前练习过的东西,如果我遇到问题我没有资源来解决它有了它,因为这不是我的主要工作职能 也可以。只包括最早支持的参考,它应该照顾好自己。很少有东西不向后兼容。干杯 【参考方案1】:

如果您需要使用早期绑定,请仅添加最早支持的引用(即,如果您只打算支持 2013+,则无需添加对 2003 Outlook 的引用),它应该会自行处理。很少有东西不向后兼容

否则,请使用后期绑定。这需要对任何Outlook.__object__ 使用CreateObject 函数而不是New 关键字。

注意,您需要显式声明 Outlook 常量,例如 olMailItem,否则它们会引发编译错误(假设您使用的是 Option Explicit):

Option Compare Database
Option Explicit

' InitOutlook sets up outlookApp and outlookNamespace.
Private outlookApp As Object ' Outlook.Application
Private outlookNamespace As  Object ' Outlook.NameSpace

然后对代码主体进行一些小调整:

Const olMailItem As Long = 0 '## You need to add this enumeration!

Private Sub InitOutlook()
    ' Initialize a session in Outlook
    Set outlookApp = CreateObject("Outlook.Application")

    'Return a reference to the MAPI layer
    Set outlookNamespace = outlookApp.GetNamespace("MAPI")

    'Let the user logon to Outlook with the
    'Outlook Profile dialog box
    'and then create a new session
    outlookNamespace.Logon , , True, False
End Sub

Public Sub SendEmail(varTo As Variant)
    Dim mailItem As Object ' Outlook.mailItem

    InitOutlook
    Set mailItem = outlookApp.CreateItem(olMailItem)
    mailItem.To = varTo & ""
    mailItem.Subject = "subject text"
    mailItem.Body = "Body text"
    mailItem.Display

    Set mailItem = Nothing
    CleanUp
End Sub

【讨论】:

【参考方案2】:

简短(-ish)答案:是的,您可以。

关于你的第二个问题;图书馆参考不应该像描述的那样有任何不利影响。我会说最好的检查方法是测试问题。

长答案:为什么需要?国际研究委员会;较新的参考应该包含旧参考所做的一切,以及额外的图书馆信息。但是,如果情况并非如此,并且较新的参考文献未涵盖该问题,则添加新参考文献可能会解决问题,但随意添加库参考文献并不总是最佳实践。

我最好的猜测是,一个 Outlook 库参考无论如何都可以解决您的问题。

【讨论】:

所以我应该只针对最新的 Outlook 库吗?还是我应该尝试转换为后期绑定? 只是去后期绑定。它解决了这类问题。转换为后期绑定应该很容易。 较新的库应该包含旧库所做的一切(通常)。但是较新的库在旧版本的应用程序上将不可用,这是 OP 问题。如果您必须附加一个引用(而不仅仅是使用后期绑定的对象引用),我认为您需要附加 earliest 支持的版本。 @DavidZemens 在这张纸条上是正确的;我昨天通过一些测试体验了这一点。已更新操作。

以上是关于Access 2010-2016 VBA:您可以在多个版本上引用 MS Outlook 对象库吗?的主要内容,如果未能解决你的问题,请参考以下文章

Access 2010 VBA 错误 2425“您输入的表达式具有数据库找不到的函数名称”

在 Access VBA 中禁止写入冲突消息

Access VBA中一列的总和

使用 VBA 激活打开的 MS Access 文件以发送密钥

MS ACCESS---全部通过VBA刷新

Access vba:如何打开系统消息或提示?