无限循环 - 当MailItem添加到已发送文件夹时运行的VBA脚本,然后创建复制

时间:2013-05-09 22:01:18

标签: vba outlook infinite-loop

我最近完成了一个outlook vba脚本,它将扫描添加到已发送文件夹的每个mailitem的主题行,查找主题中的项目编号。检测到时,脚本将提取项目编号,创建mailitem的副本,然后根据项目编号将该副本移动到共享邮箱文件夹(首先执行文件夹检查)。我目前已将其设置为首先创建邮件项的副本,然后将该副本移动到新文件夹目标。这样,原始发送的mailitem将保留在已发送文件夹中,而不会被删除。

我遇到的问题是当脚本在已发送文件夹中创建邮件项目的副本时,它会触发脚本的新实例(因为它在将新项目添加到已发送文件夹时运行)并且将无限期地重复此过程,创建和移动副本,直到Outlook被强制关闭。添加循环计数检查似乎没有帮助,因为每次添加项目时脚本都会从头开始。

以下是完整的代码,有没有比我目前更好的方法来解决这个问题?任何见解或方向将不胜感激!

编辑:忘记添加我已将此代码粘贴在我的Outlook的vb开发人员选项卡中的ThisOutlookSession(VbaProject.OTM文件)


Private WithEvents Items As Outlook.Items

Private Sub Application_Startup()
  Dim olApp As Outlook.Application

  Set olApp = Outlook.Application
  Set Items = GetNS(olApp).GetDefaultFolder(olFolderSentMail).Items
End Sub

Private Sub Items_ItemAdd(ByVal item As Object)

  On Error Resume Next

  MsgBox "Mail Added to Sent Folder, Checking for T-#"

  Dim EmailSub As String
  Dim EmailSubArr As Variant
  Dim ProjectNum As String
  Dim FullProjectNum As String
  Dim ProjNumLen As Long
  Dim ParentFolderName As String
  Dim SubFolderName As String

    If TypeName(item) = "MailItem" Then
        'Checks Email Subject for Project Number Tag
        If InStr(item.Subject, "T-") > 0 Then

            MsgBox "T-# Detected"

            'Splits out Project Number into an Array for Extraction
            EmailSub = item.Subject
            EmailSubArr = Split(EmailSub, Chr(32))

              For i = LBound(EmailSubArr) To UBound(EmailSubArr)
                  If InStr(EmailSubArr(i), "T-") > 0 Then

                      FullProjectNum = EmailSubArr(i)
                      MsgBox "T-# Extracted"
                      ProjNumLen = Len(FullProjectNum)

                      MsgBox ("T-# is " & ProjNumLen & " Characters Long")

                      'Project Number Length Check and Formatting

                      If ProjNumLen >= 11 Then
                        Exit Sub
                      End If

                      If ProjNumLen <= 6 Then
                        Exit Sub
                      End If

                      If ProjNumLen = 10 Then
                      'Really Extended T-# Format 1(ie T-38322X12)
                      ProjectNum = Right(FullProjectNum, 8)
                      ParentFolderName = Left(ProjectNum, 2)
                      SubFolderName = Left(ProjectNum, 8)
                      End If

                      If ProjNumLen = 9 Then
                      'Extended T-# Format 1(ie T-38322X1)
                      ProjectNum = Right(FullProjectNum, 7)
                      ParentFolderName = Left(ProjectNum, 2)
                      SubFolderName = Left(ProjectNum, 7)
                      End If

                      If ProjNumLen = 8 Then
                      'Uncommon T-# Format (ie T-38322A)
                      ProjectNum = Right(FullProjectNum, 6)
                      ParentFolderName = Left(ProjectNum, 2)
                      SubFolderName = Left(ProjectNum, 6)
                      End If

                      If ProjNumLen = 7 Then
                      'Standard T-# Format (ie T-38322)
                      ProjectNum = Right(FullProjectNum, 5)
                      ParentFolderName = Left(ProjectNum, 2)
                      SubFolderName = Left(ProjectNum, 5)
                      End If

                      Exit For

                  End If
              Next i

            MsgBox ("Confirm Extraction (1 of 3) - Project Number is T-" & ProjectNum)
            MsgBox ("Confirm Extraction (2 of 3) - Parent Folder Will Be " & ParentFolderName)
            MsgBox ("Confirm Extraction (3 of 3) - Sub Folder Will Be " & SubFolderName)
            MsgBox ("Will Now Perform Folder Checks")

            'Perform Folder Checks, Creates Folders When Needed

            Dim fldrparent As Outlook.MAPIFolder
            Dim fldrsub As Outlook.MAPIFolder

            Set fldrparent = Outlook.Session.Folders("Projects").Folders("Project Root").Folders(ParentFolderName)
            Set fldrsub = Outlook.Session.Folders("Projects").Folders("Project Root").Folders(ParentFolderName).Folders(SubFolderName)

            If fldrparent Is Nothing Then
                MsgBox "Parent Folder Does Not Exist, Creating Folder"
                Set fldrparent = Outlook.Session.Folders("Projects").Folders("Project Root").Folders.Add(ParentFolderName)
            Else
                MsgBox "Parent Folder Already Exists, Do Nothing"
            End If

            If fldrsub Is Nothing Then
                MsgBox "Sub Folder Does Not Exist, Creating Folder"
                Set fldrsub = Outlook.Session.Folders("Projects").Folders("Project Root").Folders(ParentFolderName).Folders.Add(SubFolderName)
            Else
                MsgBox "Sub Folder Already Exists, Do Nothing"
            End If

            'Moves Copy of Email to Folder

            MsgBox "Copying Sent Email to Project Folder"

            Dim FolderDest As Outlook.MAPIFolder
            Dim myItem As Outlook.MailItem
            Dim myCopiedItem As Outlook.MailItem


            Set FolderDest = Outlook.Session.Folders("Projects").Folders("Project Root").Folders(ParentFolderName).Folders(SubFolderName)
            'Set myCopiedItem = item.Copy

            item.Move FolderDest

        Else
        MsgBox "Did not detect T-##### project number"
        End If

    End If

ProgramExit:
  Exit Sub

End Sub

Function GetNS(ByRef app As Outlook.Application) As Outlook.NameSpace
  Set GetNS = app.GetNamespace("MAPI")
End Function

3 个答案:

答案 0 :(得分:0)

在保存之前,您可以使用MailItem.UserProperties在新邮件上设置自己的特殊属性。然后,您可以在ItemAdd事件触发时检查该属性是否存在(MailItem.UserProperties.Find),如果设置了属性,则跳过该项。

答案 1 :(得分:0)

而不是ItemAdd尝试Application_ItemSend。

http://msdn.microsoft.com/en-us/library/office/ff865076(v=office.14).aspx

它看起来比它简单。在 ThisOutlookSession 模块中。

Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
'  your code here
End Sub

您可以使用链接中提供的示例对其进行测试。

Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) 

    Dim prompt As String 

    prompt = "Are you sure you want to send " & Item.Subject & "?" 

    If MsgBox(prompt, vbYesNo + vbQuestion, "Sample") = vbNo Then 

        Cancel = True 

    End If 

End Sub

答案 2 :(得分:0)

添加模块级变量,例如'm_cancelAdd'在Item.Copy 之前将其值设置为true。在ItemAdd事件处理程序的beginnig中,检查m_cancelAdd和的值,如果它为true,则重置它并退出处理程序。 HTH。

Private WithEvents Items As Outlook.Items
Private m_cancelAdd As Boolean

Private Sub Items_ItemAdd(ByVal Item As Object)

    If (m_cancelAdd) Then
        m_cancelAdd = False
        Exit Sub
    End If

    Dim myCopiedItem As Outlook.MailItem
    Dim FolderDest

    m_cancelAdd = True
    Set myCopiedItem = Item.Copy
    Debug.Print "Item copy created..."

    Set FolderDest = Outlook.Session.Folders("Projects").Folders("Project Root").Folders(ParentFolderName).Folders(SubFolderName)
    Item.Move FolderDest

End Sub