2015-12-04 5 views
10

Ich habe mehrere E-Mails kommen (Jeden Tag bekomme ich 3 E-Mails für Bestellungen für 3 Kategorien). Die E-Mails Betreff sind im Format:Batch-Skript einmal für mehrere E-Mails ausführen

"Bestellungen EXTRACT - [Kategorie] - [Datum]".

Wo [Kategorie] kann Category 1, Category 2 oder Category 3 sein. [Datum] ist das Datum, an dem die E-Mail im Format TT/MM/JJJJ gesendet wurde.

Ich habe eine Regel-Setup für die Suche nach 'Orders' dann rufen Sie den folgenden Code.

Ich möchte Complete.bat ausführen, nachdem alle E-Mail-Anhänge gespeichert wurden und ich möchte nur einmal anrufen.

Ich habe versucht, dies zu tun, indem Sie eine andere Unter namens saveAttachtoDisk_CATEGORY1(itm), die nur aufgerufen wird, wenn es "Kategorie 1" im Betreff findet. Es speichert dann den Anhang, sucht aber auch nach einer Kategorie 1 im Betreff UND sucht auch nach dem gestrigen Datum.

Ich möchte eine bessere Lösung, die nicht datumsabhängig ist. Eine globale Variable könnte funktionieren, wo ich die Variable auf 1 setze, dann renne Complete.bat gesendet wird und dann in Zukunft, wenn Variable = 1 dann führe Complete.bat nicht aus. Nicht sicher, wo diese Variable platziert werden soll (Globale Variable?). Da beide Untermodule der falsche Ort sind, um dies zu setzen und darauf Bezug zu nehmen.

Diese beiden Module werden im Abschnitt "Module" von Microsoft Outlook VBA gespeichert.

Public Sub saveAttachtoDisk(itm As Outlook.MailItem) 
    Dim objAtt As Outlook.Attachment 
    Dim SaveFolder As String 
    SaveFolder = "D:\Orders\" 
    For Each objAtt In itm.Attachments 
     objAtt.SaveAsFile SaveFolder & "\" & objAtt.DisplayName 
     objAtt.Delete 
    Next 
    itm.Save 
End Sub 

Andere Modul:

Public Sub saveAttachtoDisk_CATEGORY1(itm As Outlook.MailItem) 
    Dim objAtt As Outlook.Attachment 
    Dim SaveFolder As String 
    SaveFolder = "D:\Orders\" 
    For Each objAtt In itm.Attachments 
     objAtt.SaveAsFile SaveFolder & "\" & objAtt.DisplayName 
     objAtt.Delete 
    Next 
    itm.Save 
    If InStr(1, itm.Subject, "ORDERS EXTRACT - Category 1 -" & Format(Date, "dd/mm/yyyy")) Then 
     Shell "D:\Orders\Complete.bat" 
    End If 
End Sub 
+0

ich nennen würde [SetTimer] (http://stackoverflow.com/q/20269844/3959875) mit einem Timeout von sagen wir 1 Sekunde am Ende des Verfahrens und seiner ID speichern mit 'SaveSetting' und Zu Beginn des Verfahrens laden Sie es und löschen Sie die Timeout-ID. Wenn das Speichern der einzelnen Elemente weniger als 1 Sekunde dauert, wird nur die Zeitüberschreitung des letzten Elements nicht gelöscht und Ihre Timer-Callback-Funktion wird aufgerufen, wo Sie Ihre Batch-Datei aufrufen. – wOxxOm

+0

"Ich möchte 'Complete.bat' ausführen, nachdem alle E-Mail-Anhänge gespeichert wurden und ich sie nur einmal aufrufen möchte." Einmal pro Post oder pro Tag? Es ist nicht klar, was dein wirkliches Problem ist. Kannst du ein wenig weiterarbeiten? –

+0

Mögliches Problem ist, dass es gleiche Anlagennamen gibt. Solltest du den Code "Received Date" an den Dateinamen anhängen/anhängen - oder etwas "einzigartiger" machen? Da Sie die Anhänge von der Mail entfernen, gibt es keine Rückverfolgung an Ihrem Ende und wir wissen nicht, was die 'Complete.bat' tut. Auch auf "Kategorie 1" gefunden und suche nach Gestern, was dann? – PatricK

Antwort

3

Annahmen

  • OP erhalten genau drei E-Mails pro Tag
  • Die Probanden (obwohl das anpassbare im Code ist) wird Beginnen Sie immer mit "ORDERS EXTRACT -" und keinem anderen E-Mails beginnen mit diesem Code
  • OP möchte Complete.bat einmal pro Tag nach Erhalt der dritten ORDERS EXTRACT E-Mail ausführen.
  • OP hat bereits eine Regel eingerichtet, um SaveAttachtoDisk nach Erhalt von eine ORDERS EXTRACT E-Mail auszuführen. Diese Regel kann geändert werden CategorySaveAndComplete
  • OP ausgeführt wird unter Verwendung von Outlook 2013 oder später

vorgeschlagene Lösung

Der Code unten wird die Anhänge speichert für jeden Auftrag E-Mail extrahiert und dann überprüfen, um zu sehen, wenn alle drei empfangen wurden. Ich entschied mich, .Find und .FindNext nicht zu verwenden, da diese Methoden keine Platzhalter verwenden können und daher die Kategorienamen hartcodieren müssten. Ich entschied mich auch nicht zu verwenden .Restrik, da es nur drei Elemente gibt, nach denen wir suchen.

Das heißt, Lösungen mit .Find und .Restrict wären ebenfalls gültig und würden unter bestimmten Bedingungen besser funktionieren als die unten genannten, wie ein Benutzer mit vielen Artikeln konsistent in seinem Posteingang.

Bitte beachten Sie, dass die erwartete Anzahl von Bestellungen extrahieren E-Mails, Betreff Zeichenfolge zu übereinstimmen, und vorherige Termine zu überprüfen, können alle über Konstanten gesetzt werden. Ich implementierte die vorherige Terminüberprüfung, falls OP auch jeden Vortag überprüfen wollte.

Option Explicit 

Public Const C_ExpectedOrderCount As Integer = 3 'Set number of expected emails for categories 
Public Const C_SubjectFormat As String = "ORDERS EXTRACT - *" 
Public Const C_PrevDatesToCheck As Integer = 0 'If the Outlook app may not be open every day, set this to the number of prior days the script should also check. 

Public Sub CategorySaveAndComplete(itm As Outlook.MailItem) 

    'Do not take any action if this is not an ORDERS EXTRACT email. 
    If itm.Subject Like C_SubjectFormat Then 

     Dim objAtt As Outlook.Attachment 
     Dim SaveFolder As String 
     SaveFolder = "D:\Orders\" 
     For Each objAtt In itm.Attachments 
      objAtt.SaveAsFile SaveFolder & "\" & objAtt.DisplayName 
      objAtt.Delete 
     Next 
     itm.Save 

     'Check all emails in Inbox for ORDERS EXTRACT - * - DATE 
     Dim Item As Object 
     Dim objNS As Outlook.NameSpace 
     Set objNS = GetNamespace("MAPI") 
     Dim olFolder As Outlook.MAPIFolder 
     Set olFolder = objNS.GetDefaultFolder(olFolderInbox) 
     Dim iLoop As Integer 
     Dim iCount As Integer 
     Dim DateCheck As Date 

     For iLoop = 0 To C_PrevDatesToCheck 
      'Reset DateCheck and iCount if we are looping through days 
      DateCheck = DateSerial(Year(Date), Month(Date), Day(Date)) - iLoop 
      iCount = 0 
      'Loop through mail items 
      For Each Item In olFolder.Items 
       If Item.Class = 43 Then 
        'This is an email. Check if it matches our criteria. 
        If Item.Subject Like C_SubjectFormat And CDate(CLng(Item.ReceivedTime)) = DateCheck Then iCount = iCount + 1 
       End If 
      Next 
      'If we have met the expected targets, then run the batch file. 
      If iCount = C_ExpectedOrderCount Then 
       'We have exactly the expected number of items. Run the batch file. 
       Shell "D:\Orders\Complete.bat" 
      ElseIf iCount > C_ExpectedOrderCount Then 
       'More items than expected. Check if user is OK with running batch file; if so, run it now. 
       If MsgBox("More order extracts than expected were received. Expected " & _ 
       C_ExpectedOrderCount & "; received " & iCount & " for " & Format(DateCheck, "mmm d, yy") & _ 
       ". Would you like to run the Complete.bat file now?", vbYesNo) = vbYes Then Shell "D:\Orders\Complete.bat" 
      End If 
     Next iLoop 
    End If 
End Sub