我正在根据另一位成员的建议创建这个新主题。有关事情如何到达的其他历史记录,请参阅this question。
我有这个VBA脚本,我知道 如果 它会被触发。如果我使用TestLaunch子例程,并且我的收件箱中已经存在符合规则标准的消息(当然,该规则没有启动),它会激活我希望它完美激活的链接。如果,当我创建规则时,我说要将其应用于收件箱中的所有现有邮件,它可以完美地运行。但是,如果需要,当新邮件到达时则不会。
我知道脚本没有被触发,因为如果我有这样的规则:
Outlook "New Message" rule that has "play sound" enabled
以“播放声音”作为其中的一部分,当消息从两个指定的发件人中的任何一个到达时,声音总是播放,因此规则被触发。我已从规则中删除了声音播放部分,并将其集成到VBA代码中以进行测试:
Option Explicit
Private Declare Function ShellExecute _
Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal Operation As String, _
ByVal Filename As String, _
Optional ByVal Parameters As String, _
Optional ByVal Directory As String, _
Optional ByVal WindowStyle As Long = vbMinimizedFocus _
) As Long
Private Declare Function sndPlaySound32 _
Lib "winmm.dll" _
Alias "sndPlaySoundA" ( _
ByVal lpszSoundName As String, _
ByVal uFlags As Long) As Long
Sub PlayTheSound(ByVal WhatSound As String)
If Dir(WhatSound, vbNormal) = "" Then
' WhatSound is not a file. Get the file named by
' WhatSound from the Windows\Media directory.
WhatSound = Environ("SystemRoot") & "\Media\" & WhatSound
If InStr(1, WhatSound, ".") = 0 Then
' if WhatSound does not have a .wav extension,
' add one.
WhatSound = WhatSound & ".wav"
End If
If Dir(WhatSound, vbNormal) = vbNullString Then
Beep ' Can't find the file. Do a simple Beep.
Exit Sub
End If
Else
' WhatSound is a file. Use it.
End If
sndPlaySound32 WhatSound, 0& ' Finally, play the sound.
End Sub
Public Sub OpenLinksMessage(olMail As Outlook.MailItem)
Dim Reg1 As RegExp
Dim AllMatches As MatchCollection
Dim M As Match
Dim strURL As String
Dim RetCode As Long
Set Reg1 = New RegExp
With Reg1
.Pattern = "(https?[:]//([0-9a-z=\?:/\.&-^!#$;_])*)"
.Global = True
.IgnoreCase = True
End With
PlayTheSound "chimes.wav"
' If the regular expression test for URLs in the message body finds one or more
If Reg1.test(olMail.Body) Then
' Use the RegEx to return all instances that match it to the AllMatches group
Set AllMatches = Reg1.Execute(olMail.Body)
For Each M In AllMatches
strURL = M.SubMatches(0)
' Don't activate any URLs that are for unsubscribing; skip them
If InStr(1, strURL, "unsubscribe") Then GoTo NextURL
' If the URL ends with a > from being enclosed in darts, strip that > off
If Right(strURL, 1) = ">" Then strURL = Left(strURL, Len(strURL) - 1)
' The URL to activate to accept must contain both of the substrings in the IF statement
If InStr(1, strURL, ".com") Then
PlayTheSound "TrainWhistle.wav"
' Activate that link to accept the job
RetCode = ShellExecute(0, "Open", "http://nytimes.com")
Set Reg1 = Nothing
Exit Sub
End If
NextURL:
Next
End If
Set Reg1 = Nothing
End Sub
Private Sub TestLaunchURL()
Dim currItem As MailItem
Set currItem = ActiveExplorer.Selection(1)
OpenLinksMessage currItem
End Sub
如果在所有情况下触发VBA脚本,则应该播放“chimes.wav”,如果我的实际链接激活处理发生,则播放“TrainWhistle.wav”。当新邮件到达时,两种情况都不会发生,但如果Outlook规则中有“播放声音”,则应运行此脚本播放声音。
目前我的宏信任中心设置允许所有内容,因为Outlook在测试过程早期使用selfcert.exe进行签名时感到头晕目眩。我真的希望能够再次提升宏观保护,而不是在完成所有操作时将它们留在“全部运行”。
但是,首先,我不能为我的生活找出为什么这个脚本将通过调试器完美运行或者如果应用于现有消息,但是不是由应用于现有消息的相同Outlook规则触发的实际的新消息到来了。在Outlook 2010中,我正在开发此脚本,也在Outlook 2016下,在正在部署它的朋友的计算机上。
非常感谢任何有关解决此问题的指导。
答案 0 :(得分:0)
这是最终有效的代码。很明显,olTail的.Body成员在某些幕后处理有时间发生之前是不可用的,如果你不等待很长时间,那么当你去测试使用它时它就不会存在。专注于Public Sub OpenLinksMessage
显然,允许进行处理的主要变化是添加了代码行:Set InspectMail = olMail.GetInspector.CurrentItem。运行此set语句所需的时间允许.Body在Outlook规则传入的olMail参数上可用。有趣的是,如果你在set语句后立即显示InspectMail.Body它显示为空,就像olMail.Body一样。
Option Explicit
Private Declare Function ShellExecute _
Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal Operation As String, _
ByVal Filename As String, _
Optional ByVal Parameters As String, _
Optional ByVal Directory As String, _
Optional ByVal WindowStyle As Long = vbMinimizedFocus _
) As Long
Public Sub OpenLinksMessage(olMail As Outlook.MailItem)
Dim InspectMail As Outlook.MailItem
Dim Reg1 As RegExp
Dim AllMatches As MatchCollection
Dim M As Match
Dim strURL As String
Dim SnaggedBody As String
Dim RetCode As Long
' The purpose of the following Set statement is strictly to "burn time" so that the .Body member of
' olMail is available by the time it is needed below. Without this statement the .Body is consistently
' showing up as empty. What's interesting is if you use MsgBox to display InspectMail.Body immediately after
' this Set statement it shows as empty.
Set InspectMail = olMail.GetInspector.CurrentItem
Set Reg1 = New RegExp
With Reg1
.Pattern = "(https?[:]//([0-9a-z=\?:/\.&-^!#$;_])*)"
.Global = True
.IgnoreCase = True
End With
RetCode = Reg1.Test(olMail.Body)
' If the regular expression test for URLs in the message body finds one or more
If RetCode Then
' Use the RegEx to return all instances that match it to the AllMatches group
Set AllMatches = Reg1.Execute(olMail.Body)
For Each M In AllMatches
strURL = M.SubMatches(0)
' Don't activate any URLs that are for unsubscribing; skip them
If InStr(1, strURL, "unsubscribe") Then GoTo NextURL
' If the URL ends with a > from being enclosed in darts, strip that > off
If Right(strURL, 1) = ">" Then strURL = Left(strURL, Len(strURL) - 1)
' The URL to activate to accept must contain both of the substrings in the IF statement
If InStr(1, strURL, ".com") Then
' Activate that link to accept the job
RetCode = ShellExecute(0, "Open", strURL)
Set InspectMail = Nothing
Set Reg1 = Nothing
Set AllMatches = Nothing
Set M = Nothing
Exit Sub
End If
NextURL:
Next
End If
Set InspectMail = Nothing
Set Reg1 = Nothing
Set AllMatches = Nothing
Set M = Nothing
End Sub
特别感谢 niton 的耐心和帮助。