vba loops email outlook-vba

vba - Ejecute el script por lotes una vez para múltiples correos electrónicos



loops email (1)

Tengo varios correos electrónicos entrando (cada día recibo 3 correos electrónicos para pedidos de 3 categorías). Los correos electrónicos están en el formato:

" EXTRACTO DE ÓRDENES - [Categoría] - [Fecha] ".

Donde [Categoría] puede ser Category 1 , Category 2 o Category 3 . [Fecha] es la fecha en que se envió el correo electrónico en el formato DD / MM / YYYY.

Tengo una configuración de reglas para buscar '' Pedidos '' y luego llamo al código siguiente.

Quiero ejecutar Complete.bat después de que todos los archivos adjuntos de correo electrónico se hayan guardado y solo deseo llamarlo una vez.

Intenté hacer esto creando otro sub llamado saveAttachtoDisk_CATEGORY1(itm) que solo se llama cuando encuentra " Categoría 1 " en el asunto. Luego guarda el archivo adjunto pero también busca una categoría 1 en el asunto Y también busca la fecha de ayer.

Quiero una mejor solución que no dependa de la fecha. Una variable global podría funcionar donde establezco que la variable sea 1, luego ejecuto Complete.bat y luego, en el futuro si variable = 1, no ejecuto Complete.bat . No estoy seguro de dónde colocar esta variable (¿variable global?) Ya que ambos submódulos parecen ser el lugar equivocado para poner esto y referenciarlo.

Ambos estos dos módulos se guardan en la sección ''Módulos'' de 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

Otro módulo:

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


Suposiciones

  • OP recibirá exactamente tres correos electrónicos por día (aunque eso se puede personalizar en el código)
  • Los sujetos siempre comenzarán con "EXTRACTO DE PEDIDOS -" y ningún otro correo electrónico comenzará con ese código.
  • A OP le gustaría ejecutar Complete.bat una vez por día al recibir el tercer correo electrónico de ORDERS EXTRACT.
  • OP aready tiene una regla configurada para ejecutar SaveAttachtoDisk al recibir un correo electrónico ORDERS EXTRACT. Esta regla se puede cambiar para ejecutar CategorySaveAndComplete
  • OP está utilizando Outlook 2013 o posterior

Solución propuesta

El siguiente código guardará los archivos adjuntos para cada correo electrónico de extracción de pedidos y luego verificará si se han recibido los tres. Decidí no usar .Find y .FindNext, ya que esos métodos no pueden usar comodines y, por lo tanto, requieren una codificación física de los nombres de las categorías. También elegí no usar .Restrict ya que solo hay tres elementos para los que estamos buscando.

Dicho esto, las soluciones con .Find y .Restrict también serían válidas y funcionarían mejor que las siguientes bajo ciertas condiciones, como un usuario con muchos elementos en su bandeja de entrada.

Tenga en cuenta que el recuento esperado de pedidos, extractos de correos electrónicos, cadenas de materias para hacer coincidir y fechas anteriores para verificar, se puede establecer a través de constantes. Implementé la verificación de fecha previa en caso de que OP quisiera verificar cada día anterior también.

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