vba 确定现有 Outlook 实例是否打开
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6481398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Determining whether an existing Outlook instance is open
提问by stanigator
After reading how to use automation to send a message, I'm unclear of whether it's possible to avoid opening a new instance of Outlook if I already have one opened. If so, I'm unsure of how to search for examples determining whether an existing Outlook instance is open.
在阅读了如何使用自动化发送消息后,我不清楚如果我已经打开了一个新的 Outlook 实例,是否可以避免打开它。如果是这样,我不确定如何搜索确定现有 Outlook 实例是否打开的示例。
-----Including the suggestion--------
-----包括建议--------
I have the following snippet, but I found that I can't create the instance properly. I'm basically following this example. I'm either getting this screenshot, or the error of "User-defined type not defined." Any suggestions?
我有以下代码段,但我发现我无法正确创建实例。我基本上遵循这个例子。我要么得到这个屏幕截图,要么是“未定义用户定义的类型”的错误。有什么建议?
Sub Example()
'Dim w As Outlook.Application
Const ERR_APP_NOTRUNNING As Long = 429
On Error Resume Next
' Handle Microsoft outlook
Set w = GetObject(, "Outlook.Application")
If Err = ERR_APP_NOTRUNNING Then
'Set w = New Outlook.Application
Set w = CreateObject("Outlook.Application")
End If
End Sub
回答by JimmyPena
I know this question has been answered, but I thought I'd add that applications like Outlook (and I believe PowerPoint as well) are single-instance applications -- there is no need to determine if Outlook is already open because you can only have one copy of Outlook running.
我知道这个问题已经得到了回答,但我想我会补充说 Outlook(我相信 PowerPoint 也是如此)这样的应用程序是单实例应用程序——没有必要确定 Outlook 是否已经打开,因为你只能拥有一份 Outlook 正在运行。
http://msdn.microsoft.com/en-us/library/aa164542(v=office.10).aspx
http://msdn.microsoft.com/en-us/library/aa164542(v=office.10).aspx
If you need to instantiate Outlook, simply use CreateObject to create the instance; if Outlook is already running, your object reference will point to the existing instance. If not, you will create the class. Binding (late or early) is irrelevant.
如果您需要实例化 Outlook,只需使用 CreateObject 来创建实例;如果 Outlook 已在运行,则您的对象引用将指向现有实例。如果没有,您将创建该类。绑定(晚或早)无关紧要。
For example, let's say Outlook isn't running. We can use this code to create the instance:
例如,假设 Outlook 未运行。我们可以使用此代码来创建实例:
Sub testOutlook()
Dim olApp As Object ' Outlook.Application
Set olApp = CreateObject("Outlook.Application")
MsgBox (olApp2 Is Nothing)
End Sub
This will print "False" because we created the instance.
这将打印“False”,因为我们创建了实例。
Let's say Outlook IS running. We can use this code to verify that using GetObject and CreateObject will refer to the existing instance:
假设 Outlook 正在运行。我们可以使用此代码来验证使用 GetObject 和 CreateObject 是否会引用现有实例:
Sub testOutlook()
Dim olApp As Object ' Outlook.Application
Dim olApp2 As Object ' Outlook.Application
Set olApp = GetObject(, "Outlook.Application")
MsgBox (olApp Is Nothing)
Set olApp2 = CreateObject("Outlook.Application")
MsgBox (olApp2 Is Nothing)
MsgBox "Same object? " & (olApp Is olApp2)
End Sub
This will print "False" (existing instance), "False" (our alleged "new instance"), but the last message box is "True" because the new instance is actually the same object as the existing instance.
这将打印“假”(现有实例)、“假”(我们所谓的“新实例”),但最后一个消息框是“真”,因为新实例实际上是与现有实例相同的对象。
So what do we do if we don't know if Outlook is running or not? As demonstrated above, CreateObject either created a new instance (if one didn't exist, as in the first example) or hooked the existing instance if Outlook was already open (as in the second example).
那么,如果我们不知道 Outlook 是否正在运行,我们该怎么办?如上所示,CreateObject 要么创建一个新实例(如果一个实例不存在,如第一个示例中所示),要么在 Outlook 已打开的情况下挂钩现有实例(如第二个示例中所示)。
回答by Jean-Fran?ois Corbett
I see in your question that you commented out
我在你的问题中看到你注释掉了
'Dim w As Outlook.Application
presumably because this gives you the "User-defined type not defined" error.
大概是因为这会给您“未定义用户定义的类型”错误。
This is likely because you have not set a reference to the Outlook library in your Excel-VBA project. This is done as follows: Tools > References > check "Microsoft Outlook xx.x Object Library". Then you can write this
这可能是因为您尚未在 Excel-VBA 项目中设置对 Outlook 库的引用。这样做的方法如下:工具 > 参考 > 选中“Microsoft Outlook xx.x 对象库”。然后你可以写这个
Dim w As Outlook.Application
Set w = New Outlook.Application
' or,
'Set w = CreateObject("Outlook.Application")
which, by the way, results in compile-time (or "early") binding. And gives you the Outlook
object intellisense.
顺便说一下,这会导致编译时(或“早期”)绑定。并为您提供Outlook
对象智能感知。
Alternatively, you can omit setting the reference and declare w
as a generic object and let it bind at run-time
或者,您可以省略设置引用并声明w
为通用对象并让它在运行时绑定
Dim w As Object
Set w = CreateObject("Outlook.Application")
but runtime (or "late") bindingis less efficient.
但运行时(或“后期”)绑定效率较低。
Do whatever feels best -- I'm going to go ahead and venture that chances are, you won't notice the difference in efficency. I'm a recent convert to the early-binding thing, really just because of the intellisense.
做任何感觉最好的事情——我会继续冒险,很有可能,你不会注意到效率上的差异。我最近才转向早期绑定的东西,真的只是因为智能感知。
EDITSo you've created a new Outlook application, but you can't see it. If you look in the Windows task manager, you'll see that the process is there, running -- but it's just not showing on the screen. Unfortunately, some brilliant engineer at Microsoft decided that Outlook shouldn't have a Visible
property like Word or Excel do, so we have to use an awkward workaround. Open one of the special folders e.g. the Inbox like this:
编辑所以你已经创建了一个新的 Outlook 应用程序,但你看不到它。如果您查看 Windows 任务管理器,您会看到该进程在那里,正在运行——但它只是没有显示在屏幕上。不幸的是,Microsoft 的一些杰出工程师认为 Outlook 不应该Visible
像 Word 或 Excel 那样具有属性,因此我们不得不使用一种笨拙的解决方法。打开特殊文件夹之一,例如收件箱,如下所示:
Dim w As Outlook.Application
Dim wInbox As Outlook.MAPIFolder
Set w = New Outlook.Application
Set wInbox = w.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
wInbox.Display 'This makes Outlook visible
回答by vlscanner
Set w = GetObject(, "Outlook.Application")
this should get running instance, if none is running catch error and do CreateObject
这应该运行实例,如果没有运行捕获错误并执行 CreateObject