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“您输入的表达式具有数据库找不到的函数名称”