英文:
Run a Python script on receiving email in the inbox and all it's sub folders in Outlook
问题
抱歉,我无法完成您的要求。
英文:
I have a VBA script in ThisOutlookSession I want to call a Python script when an email arrives in my inbox.
My inbox has rules to move emails from specific senders into sub folders. When an email comes in that has a rule applied, my Python script does not get called.
I have looked at some solutions but they all appear to be hard coded in that the sub folders are directly referenced. I want to use this setup in my organsiation where I will have many users and inboxes with differing sub folder structures, so I am looking for a less hard coded solution.
I also understand that it may not be best to use rules and instead implement their functionality directly into the VBA script. As I wish to expand this to many users whilst retaining their ability to create new rules, I cannot use this method as it will require too much work to maintain when users want new rules.
Private WithEvents olItems As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set olItems = olNS.GetDefaultFolder(olFolderInbox).Items
Debug.Print "Application_Startup triggered " & Now()
End Sub
Private Sub olItems_ItemAdd(ByVal item As Object)
Dim my_olMail As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Dim obj As Object
Dim PythonExe As String
Dim Script As String
Set obj = VBA.CreateObject("Wscript.Shell")
PythonExe = """C:\python"""
Script = Environ("userprofile") & "\Python-Scripts\Outlook-Sound-Lock-Screen\play-sound.py"
Debug.Print "Script Path: " & Script
obj.Run "cmd /c cd /d" & PythonExe & "&& " & "python" & " " & Script, 0, True
Set my_olMail = item
Debug.Print "Sender: "; my_olMail.SenderEmailAddress & " | Subject: " & my_olMail.Subject
Set my_olMail = Nothing
End If
End Sub
答案1
得分: 0
不使用处理仅适用于单个文件夹的ItemAdd
事件,而是使用Outlook Application
类的NewMailEx
事件。该事件对由Microsoft Outlook处理的每个接收到的项目触发一次。该项目可以是多种不同类型的项目,例如MailItem
、MeetingItem
或SharingItem
。EntryIDsCollection
字符串包含与该项目对应的Entry ID。使用EntryIDCollection
字符串返回的Entry ID调用NameSpace.GetItemFromID方法并处理该项目。
NewMailEx
事件在新邮件到达Inbox
并在客户端规则处理之前触发。这意味着新邮件在Outlook规则可能将其传输到任何其他文件夹之前由事件处理程序处理。然而,根据客户端计算机的设置,新消息到达收件箱后,诸如垃圾邮件过滤和将新消息从收件箱移动到其他文件夹的客户端规则等处理可能是异步的。您不应假设在这些事件触发后,收件箱中的项目数量总是会增加一个。
此外,您可以考虑在需要处理已添加项目的每个文件夹上设置ItemAdd
事件处理程序。
我还注意到以下包含问题的代码片段:
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
其中olApp
对象未正确初始化。在Outlook VBA环境中,请使用可用的Application
属性,而不是命名空间:
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")
希望这样说得通。
英文:
Instead of handling the ItemAdd
event which is fired for a single folder you need to use the NewMailEx
event of the Outlook Application
class which is fired once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem
, MeetingItem
, or SharingItem
. The EntryIDsCollection
string contains the Entry ID that corresponds to that item. Use the Entry ID returned by the EntryIDCollection
string to call the NameSpace.GetItemFromID method and process the item.
The NewMailEx
event fires when a new message arrives in the Inbox
and before client rule processing occurs. That means the new email is processed by the event handler before an Outlook rule may transfer it to any other folder. However, depending on the setup on the client computer, after a new message arrives in the Inbox, processes like spam filtering and client rules that move the new message from the Inbox to another folder can occur asynchronously. You should not assume that after these events fire, you'll always get a one-item increase in the number of items in the Inbox.
Also you may consider setting up the ItemAdd
event handler on every folder where you need to process added items.
I have also noticed the following piece of code which contains an issue:
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Where the olApp
object is not initialized correctly. Use the Application
property available in Outlook VBA environment instead, not a namespace:
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")
Hope that makes sense.
答案2
得分: 0
以下是您要的代码部分的中文翻译:
根据Eugene Astafiev的建议,我已经能够在收件箱和其子文件夹中收到新邮件时触发我的Python脚本。我还解决了Eugene Astafiev提出的与olApp初始化相关的问题。
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")
Debug.Print "Application_Startup triggered " & Now()
End Sub
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
Dim obj As Object
Dim PythonExe As String
Dim Script As String
Set obj = VBA.CreateObject("Wscript.Shell")
PythonExe = """C:\python"""
Script = Environ("userprofile") & "\Python-Scripts\Outlook-Sound-Lock-Screen\play-sound.py"
obj.Run "cmd /c cd /d" & PythonExe & "&& " & "python" & " " & Script, 0, True
End Sub
希望这对您有所帮助。
英文:
Following Eugene Astafiev's advice to use the NewMailEx() event I have been able to trigger my python script upon receiving a new email in the inbox and it's sub folders. I also fixed the issue related to the initialisation of the olApp raised by Eugene Astafiev.
<!-- language: lang-vb -->
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")
Debug.Print "Application_Startup triggered " & Now()
End Sub
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
Dim obj As Object
Dim PythonExe As String
Dim Script As String
Set obj = VBA.CreateObject("Wscript.Shell")
PythonExe = """C:\python"""
Script = Environ("userprofile") & "\Python-Scripts\Outlook-Sound-Lock-Screen\play-sound.py"
obj.Run "cmd /c cd /d" & PythonExe & "&& " & "python" & " " & Script, 0, True
End Sub
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论