Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Access 2010-2016 VBA:您能否在多个版本上引用MS Outlook对象库?_Vba_Ms Access_Reference_Outlook - Fatal编程技术网

Access 2010-2016 VBA:您能否在多个版本上引用MS 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

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

目前,我们使用Outlook 2013和2016

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

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

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