Access 2010-2016 VBA:您能否在多个版本上引用MS Outlook对象库?
我被要求对从Access数据库发送电子邮件的VBA脚本进行故障排除。DB和VBA是在Access 2010(存储在SQL DB中的数据)上开发的,可能的目标是Outlook 2010 目前,我们使用Outlook 2013和2016 当我的脚本(如下所述)运行时,Outlook上会生成一个错误。应用程序声明:未定义用户定义的数据类型 这是脚本的开头,我们在这里定义数据类型。Access 2010-2016 VBA:您能否在多个版本上引用MS Outlook对象库?,vba,ms-access,reference,outlook,Vba,Ms Access,Reference,Outlook,我被要求对从Access数据库发送电子邮件的VBA脚本进行故障排除。DB和VBA是在Access 2010(存储在SQL DB中的数据)上开发的,可能的目标是Outlook 2010 目前,我们使用Outlook 2013和2016 当我的脚本(如下所述)运行时,Outlook上会生成一个错误。应用程序声明:未定义用户定义的数据类型 这是脚本的开头,我们在这里定义数据类型。 Option Compare Database Option Explicit ' InitOutlook sets
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,从一开始我就非常确定这只是一个简单的问题,“它缺少一个导入语句或引用。”
在深入研究之后,我在网上发现,为了使用此功能,必须向Microsoft Outlook XX.X对象库添加引用
我还没有看到这个数据库上的引用(现在正在努力),因为我对这个access DB的访问权限有限,因为它包含很多敏感信息,我在查看它时必须受到监督
然而,考虑到我们在编写此脚本时使用了Outlook 2010,并且现在分为Outlook 2013和2016,我认为我们需要将此引用更新为更新的引用
我在这里和一位同事讨论这个问题,他问了我一个重要的问题:
我们可以引用多个版本的Microsoft Outlook对象库吗?
如果我们以库的最新版本为目标,例如Outlook 2016,那么脚本是否不适用于Outlook 2013用户
更新:我通过测试发现,如果使用MS Outlook 16.0对象库,Outlook 2013将无法识别该引用,并会抛出错误,指出该引用丢失
如果我们使用MS Outlook 15.0库,则该脚本可在具有任意Outlook版本的计算机上运行
简短的回答:是的,你可以
至于你的第二个问题;图书馆参考资料不应产生上述任何不利影响。我认为最好的确定方法是测试这个问题
长答案:你为什么要这么做?IIRC;较新的引用应该包含较旧的引用所做的一切,以及附加的库信息。但是,如果情况并非如此,且较新的引用未涵盖此问题,则添加新引用可能会解决此问题,但随意添加库引用并不总是最佳做法
我的最佳猜测是,一个Outlook库引用无论如何都可以解决您的问题。如果您需要使用早期绑定,请只添加最早支持的引用(即,如果您只打算支持2013+,则无需添加对2003 Outlook的引用),并且它应该自行处理。很少有东西是不向后兼容的 否则,请使用后期绑定。这需要对任何
Outlook使用CreateObject
函数,而不是New
关键字
注意您需要显式声明Outlook常量,如olMailItem
,否则它们将引发编译错误(假设您使用的是选项Explicit
):
然后对代码主体进行一些小的调整:
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
那么,我应该只针对最新的outlook库吗?或者我应该尝试转换为后期绑定吗?只需使用后期绑定即可。它解决了这类问题。转换为后期绑定应该非常容易。较新的库应该包含旧库(通常)所做的一切。但较新的库在较旧版本的应用程序上不可用,这就是OP问题。如果您必须附加引用(而不仅仅是使用后期绑定的对象引用),我认为您需要附加支持的最早版本。@DavidZemens在这一点上是正确的;我昨天通过一些测试体验到了这一点。已经更新了op。你可以使用后期绑定而不是早期绑定,它会自己决定使用哪个版本。正如我提到的,如果你只使用后期绑定而不是早期绑定,你可以完全避免。如果您坚持早期绑定,并且需要对版本不可知,那么您可能需要使用。早期绑定会容易得多:)@DavidZemens我试图切换到后期绑定,您的帖子对此非常有帮助,但在测试时意识到,我们的代码中有许多不相关的部分也需要更改,它们也使用了早期绑定。我不熟悉其他需要更新的领域,因此无法可靠地测试其他页面上的更改,以确保它们适用于所有用户。我最终引用了MS Outlook 15.0对象库,这纠正了我们Outlook 2013和2016用户的问题。我询问这些引用的原因是为了防止后期绑定不起作用,因为这不是我以前练习过的,如果我遇到问题,我没有资源来解决它,因为这不是我的主要工作,这也行。只需包含最早支持的引用,它应该自行处理。很少有东西是不向后兼容的。干杯
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