2015-12-04 35 views
10

Ho più e-mail in arrivo (Ogni giorno ricevo 3 e-mail per ordini per 3 categorie). L'oggetto dell'e-mail è nel formato:Esegui script batch una volta per più e-mail

"ESTRATTO ORDINI - [Categoria] - [Data]".

Dove [categoria] può essere Category 1, Category 2 o Category 3. [Data] è la data di invio dell'e-mail nel formato GG/MM/AAAA.

Ho una configurazione di regola per cercare 'Ordini' quindi chiamare il codice riportato di seguito.

Voglio eseguire Complete.bat dopo che tutti gli allegati di posta elettronica sono stati salvati e voglio solo chiamarlo una volta.

Ho provato a farlo creando un altro sottotitolo chiamato saveAttachtoDisk_CATEGORY1(itm) che viene chiamato solo quando trova "Categoria 1" nell'oggetto. Quindi salva l'allegato ma cerca anche una categoria 1 nell'oggetto E cerca anche la data di ieri.

Voglio una soluzione migliore che non dipende dalla data. Una variabile globale potrebbe funzionare dove imposto che la variabile sia 1, quindi eseguire Complete.bat e quindi in futuro se variabile = 1, quindi non eseguire Complete.bat. Non sai dove mettere questa variabile (variabile globale?) Poiché entrambi i sottomoduli sembrano il posto sbagliato per metterlo e riferirlo.

Entrambi questi due moduli vengono salvati nella sezione "Moduli" di Microsoft Outlook VBA.

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 

altro modulo:

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

che chiamerei [SetTimer] (http://stackoverflow.com/q/20269844/3959875) con un timeout di dire 1 secondo al termine della procedura e salvare il suo ID con 'SaveSetting', e all'inizio della procedura, caricarlo e cancellare l'ID di timeout. Pertanto, se il salvataggio di ciascun elemento richiede meno di 1 secondo, il timeout dell'ultimo elemento non verrà cancellato e verrà richiamata la funzione di richiamata del timer, in cui verrà richiamato il file batch. – wOxxOm

+0

"Voglio eseguire 'Complete.bat' dopo che tutti gli allegati di posta elettronica sono stati salvati e voglio solo chiamarlo una volta." Una volta per posta o al giorno? Non è chiaro quale sia il tuo vero problema. Puoi elaborare un po '? –

+0

Il problema potenziale è che ci saranno gli stessi nomi allegati. Dovresti prefisso/aggiungi codice Data ricevuta al nome del file - o qualcosa lo rende più unico? Dato che rimuovi gli allegati dall'elemento di posta, non c'è traccia sul tuo capo e non sappiamo cosa fa il 'Complete.bat'. Anche su "Categoria 1" trovato e cerca ieri, allora cosa? – PatricK

risposta

3

Ipotesi

  • OP riceverà esattamente tre email al giorno (anche se questo è personalizzabile nel codice)
  • I soggetti saranno inizia sempre con "ORDINI ESTRATTI -" e nessun altroLe e-mailinizieranno con quel codice
  • OP vorrebbe eseguire Complete.bat una volta al giorno al ricevimento della terza e-mail ORDERS EXTRACT .
  • OP ha una regola impostata per eseguire SaveAttachtoDisk al ricevimento di un'e-mail ORDINI ESTRATTI. Questa regola può essere modificato per funzionare CategorySaveAndComplete
  • OP sta utilizzando Outlook 2013 o successivamente

Soluzione proposta

Il codice qui sotto salverà gli allegati per ogni Ordini estratto di posta elettronica e quindi verificare se tutti e tre sono stati ricevuti. Ho scelto di non utilizzare .Find e .FindNext in quanto tali metodi non possono utilizzare i caratteri jolly e richiederebbero pertanto la codifica dei nomi delle categorie. Ho anche scelto di non usare .Restrict in quanto ci sono solo tre elementi per i quali stiamo cercando.

Detto questo, le soluzioni con .Find e .Restrict sarebbero ugualmente valide e funzionerebbero meglio del sotto in determinate condizioni, come ad esempio un utente con molti articoli in modo coerente nella propria Posta in arrivo.

Si prega di notare che il conteggio previsto degli ordini Estrai e-mail, la stringa soggetta a corrispondere e le date precedenti da verificare possono essere impostate tramite costanti. Ho implementato il controllo della data precedente nel caso in cui l'OP volesse controllare anche ogni giorno precedente.

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