I'm trying to do write a VBA script that takes the body of an incoming email and sends it on to another person.
If I don't open the email the .body is empty and the email that is then sent is empty as well.
However when I open the email and then manually execute the script, it works and then .body isn't empty.
Here is the code I'm using:
Option Explicit
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
' default local Inbox
Set Items = objNS.GetDefaultFolder(olFolderInbox).Folders("Test").Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
' ******************
Dim patternRef As String
Dim patternDemandeur As String
Dim patternNumero As String
Dim patternDescriptionPanne As String
Dim patternAdresse As String
Dim patternDomaine As String
Dim patternStatut As String
Dim patternMotifDemande As String
item.UnRead = False
patternRef = "Numéro de la demande[\r\n]+([^\r\n]+)"
patternDemandeur = "Emetteur[\r\n]+([^\r\n]+)"
patternNumero = "N° tel de l'émetteur de la demande[\r\n]+([^\r\n]+)"
patternDescriptionPanne = "Commentaires initial[\r\n]+([^\r\n]+)"
patternAdresse = "Localisation de la demande[\r\n]+([^\r\n]+)"
patternDomaine = "Famille motif[\r\n]+([^\r\n]+)"
patternStatut = "Statut[\r\n]+([^\r\n]+)"
patternMotifDemande = "Motif de la demande[\r\n]+([^\r\n]+)"
' Creation des differentes variables récuperées dans l'émail de base
Dim sText As String 'Variable qui reprendra le corps de l'émail reçu.
Dim xText As String 'Variable reférence de la demande.
Dim yText As String 'Variable reférence du demandeur.
Dim zText As String 'Variable reférence du numero de telephone.
Dim dText As String 'Variable reférence de la description de la panne.
Dim aText As String 'Variable reférence de l'adresse.
Dim bText As String 'Variable reférence du domaine d'intervention.
Dim cText As String 'Variable reférence du statut fournit par l'entreprise.
Dim oText As String 'Variable reférence du motif de la demande.
sText = Msg.Body ' affectation de la variable
xText = TestRegExp(sText, patternRef, 0)
yText = TestRegExp(sText, patternDemandeur, 0)
zText = TestRegExp(sText, patternNumero, 0)
dText = TestRegExp(sText, patternDescriptionPanne, 0)
aText = TestRegExp(sText, patternAdresse, 0)
aText = Left(aText, InStr(1, aText, "-") - 1) 'Permet de supprimer tout les charactères après le tiret. Garde dans le aText, du premier charactere au tiret -1 donc sans le tiret.
oText = TestRegExp(sText, patternMotifDemande, 0)
bText = TestRegExp(sText, patternDomaine, 1)
cText = TestRegExp(sText, patternStatut, 0)
Dim NewMail As MailItem ' nouvel email
Dim obApp As Object
Set obApp = Outlook.Application
Set NewMail = obApp.CreateItem(olMailItem) 'ces 3 lignes creent le mail.
With NewMail 'remplissage du mail
.Subject = "Domain"
.To = "email"
.Body = "REF=" & xText & vbCrLf & "DOM=" & bText & vbCrLf & "OBJ=" & aText & vbCrLf & "DEMANDE D'INTERVENTION : " & oText & vbCrLf & dText & vbCrLf & "Appelant : " & yText & " / " & zText
.Importance = olImportanceHigh
End With
NewMail.Send
End If
End Sub
Function TestRegExp(myString As String, pattern As String, casDomaine As Integer)
'Create objects.
Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection
Dim RetStr As String
Dim result As String
Dim resultPrep As String
' Create a regular expression object.
Set objRegExp = New RegExp
'Set the pattern by the Pattern property.
objRegExp.pattern = pattern
' Set Case Insensitivity.
objRegExp.IgnoreCase = True
'Set global applicability.
objRegExp.Global = True
'Test whether the String can be compared.
If (objRegExp.Test(myString) = True) Then
'Get the matches.
Set colMatches = objRegExp.Execute(myString) ' Execute search.
If (objRegExp.Test(myString) = True) Then
'Get the matches.
Set colMatches = objRegExp.Execute(myString) ' Execute search.
For Each objMatch In colMatches ' Iterate Matches collection.
If casDomaine = 0 Then
result = objMatch.SubMatches(0)
End If
If casDomaine = 1 Then
'Idealement ne demander que si le texte contient un mot clé pour éviter les erreurs de typo. Resolu par utilisation de conditions, à tester avec Case
' Select Case objMatch.SubMatches(0)
If trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Faible")) Then
' "Electricité (C.Faible)"
result = "28"
ElseIf trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Fort")) Then
' "Electricité (C.Fort)"
result = "27"
ElseIf trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Plomberie")) Or trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Sanitaire")) Then
' "Plomberie / Sanitaire" / essayer d'eviter de lancer 2 cases (FaT)
result = "30"
ElseIf trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Clim")) Or trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Chauf")) Or trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Ventil")) Then
' "Clim / Chauf / Ventil"
result = "24"
ElseIf trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Sécurité")) Or trouverMotDomaine(LCase(objMatch.SubMatches(0)), LCase("Incendie")) Then
' "Sécurité / Incendie"
result = "32"
Else
result = "3"
End If
End If
Next
End If
End If
TestRegExp = result
'Affichage de chaque resultat pour la phase test
' MsgBox result // Affiche resultat à chaque fois pour les phases de test.
End Function
Function trouverMotDomaine(domaine As String, motCle As String) As Boolean
Dim intPos As Integer
intPos = 0
intPos = InStr(domaine, motCle)
trouverMotDomaine = intPos > 0
End Function
You can try using the .display message and then close .olDiscard immediately.
For more information, please see the following link:
VBA Outlook 2010 received mail .Body is empty
Related
I want to send an email in Outlook that includes my query result from Access. The body of the email includes a table (columns/rows) with the results. I want to use a Number format with commas xx,xxx when value is a number.
I recycled this code I found here. How do I format the table output?
Public Sub NewEmail()
Dim olApp As Object
Dim olItem As Variant
Dim db As DAO.Database
Dim rec As DAO.Recordset
Dim strQry As String
Dim aHead(1 To 3) As String
Dim aRow(1 To 3) As String
Dim aBody() As String
Dim lCnt As Long
'Create the header row
aHead(1) = "Date"
aHead(2) = "Request Type"
aHead(3) = "Total" 'I want this to be comma separate number format?
lCnt = 1
ReDim aBody(1 To lCnt)
aBody(lCnt) = "<HTML><body><table border='2'><tr><th>" & Join(aHead, "</th><th>") & "</th></tr>"
'Create each body row
strQry = "SELECT * From Email_Query"
Set db = CurrentDb
Set rec = CurrentDb.OpenRecordset(strQry)
If Not (rec.BOF And rec.EOF) Then
Do While Not rec.EOF
lCnt = lCnt + 1
ReDim Preserve aBody(1 To lCnt)
aRow(1) = rec("Test1")
aRow(2) = rec("Test2")
aRow(3) = rec("Test3")
aBody(lCnt) = "<tr><td>" & Join(aRow, "</td><td>") & "</td></tr>"
rec.MoveNext
Loop
End If
aBody(lCnt) = aBody(lCnt) & "</table></body></html>"
'create the email
Set olApp = CreateObject("Outlook.application")
Set olItem = olApp.CreateItem(0)
olItem.display
olItem.To = "example#example.com"
olItem.Subject = "Test E-mail"
olItem.htmlbody = Join(aBody, vbNewLine)
olItem.display
End Sub
Try something like this:
aRow(1) = Format(rec("YourDateField"), "yyyy-mm-dd")
aRow(2) = rec("YourRequestType")
aRow(3) = Format(rec("YourTotal"), "0.000")
If that leaves a dot as the decimal separator, try:
aRow(3) = Replace(LTrim(Str(rec("YourTotal"))), ".", ",")
If comma is your thousand separator, try:
aRow(3) = Format(rec("YourTotal"), "00,000")
I am trying to show the start time and end time.
In the end time, I don't want the date, as I am trying to show availability.
It shows under the print window "25/06/2021 14:45:34 25/06/2021 16:05:00".
I want to remove the middle date. I tried masks, but just erroring.
Also when the dialog box shows, I want to copy the content to clipboard.
Dim CalFolder As Outlook.Folder
Dim nameFolder
Dim strKeyword As String
Dim strResults As String
' Run this macro
Sub SearchinSharedCalendars()
Dim objPane As Outlook.NavigationPane
Dim objModule As Outlook.CalendarModule
Dim objGroup As Outlook.NavigationGroup
Dim objNavFolder As Outlook.NavigationFolder
Dim objCalendar As Folder
Dim objFolder As Folder
Dim i As Integer
Dim g As Integer
On Error Resume Next
Set objCalendar = Session.GetDefaultFolder(olFolderCalendar)
Set Application.ActiveExplorer.CurrentFolder = objCalendar
DoEvents
strKeyword = InputBox("Search subject and body", "Search Shared Calendars")
Set objPane = Application.ActiveExplorer.NavigationPane
Set objModule = objPane.Modules.GetNavigationModule(olModuleCalendar)
With objModule.NavigationGroups
For g = 1 To .Count
Set objGroup = .Item(g)
For i = 1 To objGroup.NavigationFolders.Count
Set objNavFolder = objGroup.NavigationFolders.Item(i)
If objNavFolder.IsSelected = True Then
Set CalFolder = objNavFolder.Folder
Set nameFolder = objNavFolder
Dim NS As Outlook.NameSpace
Dim objOwner As Outlook.Recipient
Set NS = Application.GetNamespace("MAPI")
Set objOwner = NS.CreateRecipient(nameFolder)
objOwner.Resolve
If objOwner.Resolved Then
Set CalFolder = NS.GetSharedDefaultFolder(objOwner, olFolderCalendar)
End If
SearchSharedCalendar
txtSearchResults = strResults & vbCrLf & txtSearchResults
End If
Next i
Next g
End With
MsgBox txtSearchResults
Set objPane = Nothing
Set objModule = Nothing
Set objGroup = Nothing
Set objNavFolder = Nothing
Set objCalendar = Nothing
Set objFolder = Nothing
End Sub
Private Sub SearchSharedCalendar()
Dim CalItems As Outlook.Items
Dim ResItems As Outlook.Items
Dim oFinalItems As Outlook.Items
Dim sFilter As String
Dim iNumRestricted As Integer
Dim itm As Object
Dim strAppt As String
Dim endAppt As String
Dim dStart1 As Date, dStart2 As Date
Set CalItems = CalFolder.Items
If CalFolder = printCal Then
Exit Sub
End If
' Sort all of the appointments based on the start time
CalItems.Sort "[Start]"
' body key word doesn't work if including recurring
CalItems.IncludeRecurrences = True
On Error Resume Next
' if you arent search subfolders, you only need parent name
strName = CalFolder.Parent.Name & " - " & CalFolder.Name
' set dates
dStart1 = Date
dStart2 = Date + 30
' fileer by date first
sFilter = "[Start] >= '" & dStart1 & "'" & " And [Start] < '" & dStart2 & "'"
Debug.Print sFilter
'Restrict the Items collection for the 30-day date range
Set ResItems = CalItems.Restrict(sFilter)
' Filter the results by keyword
' filter for Subject containing strKeyword '0x0037001E
' body is 0x1000001f
Const PropTag As String = "http://schemas.microsoft.com/mapi/proptag/"
sFilter = "#SQL=(" & Chr(34) & PropTag _
& "0x0037001E" & Chr(34) & " like '%" & strKeyword & "%' OR " & Chr(34) & PropTag _
& "0x1000001f" & Chr(34) & " like '%" & strKeyword & "%')"
Debug.Print sFilter
'Restrict the last set of filtered items for the subject
Set oFinalItems = ResItems.Restrict(sFilter)
'Sort and collect final results
oFinalItems.Sort "[Start]"
iNumRestricted = 0
For Each oAppt In oFinalItems
If oAppt.Start >= dStart1 And oAppt.Start <= dStart2 Then
iNumRestricted = iNumRestricted + 1
strAppt = oAppt.Start & " " & endAppt
endAppt = oAppt.End
End If
Next
strResults = iNumRestricted & " matching Appointment found in " & vbCrLf & strAppt & " " & endAppt
Set itm = Nothing
Set newAppt = Nothing
Set ResItems = Nothing
Set CalItems = Nothing
Set CalFolder = Nothing
End Sub
First of all, there is no need to iterate over all items in the collection:
For Each oAppt In oFinalItems
Instead, you can apply a filter by using the Restrict or Find/FindNext methods of the Items class as you did that earlier in the code.
To format the dates values you need to use the Format function available in VBA:
strAppt = oAppt.Start & " " & Format(endAppt, "hh:mm:ss")
I would like to run my macro 5 minutes after Outlook has been opened
You could use this solution from fmsinc. My prefred piece of code to do this.
Public Sub WaitSeconds(intSeconds As Integer)
' Comments: Waits for a specified number of seconds
' Params : intSeconds Number of seconds to wait
' Source : Total Visual SourceBook
' Source : http://www.fmsinc.com/microsoftaccess/modules/examples/avoiddoevents.asp
Private Declare Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
On Error GoTo PROC_ERR
Dim datTime As Date
datTime = DateAdd("s", intSeconds, Now)
Do
' Yield to other programs (better than using DoEvents which eats up all the CPU cycles)
Sleep 100
DoEvents
Loop Until Now >= datTime
PROC_EXIT:
Exit Sub
PROC_ERR:
MsgBox "Error: " & Err.Number & ". " & Err.Description, , "modDateTime.WaitSeconds"
Resume PROC_EXIT
End Sub
At the opening of Outlook, I have a code that will launch a macro on excel,
Private Sub Application_Startup()
Dim ExApp As Excel.Application
Dim ExWbk As Workbook
Set ExApp = New Excel.Application
Set ExWbk = ExApp.Workbooks.Open("C:\Users\z003zj4s\Desktop\MICHEL PACQUET\Nouveau dossier\MichelPaquet.xlsm")
ExApp.Visible = False
ExWbk.Application.Run "Module1.TEST1"
ExWbk.Close SaveChanges:=True
End Sub
the macro that was launched on excel is actually sending mail with outlook
Sub TEST1()
Dim Plage_de_recherche As Range ' correspond à la plage de recherche
Dim Valeur_cherchée As String ' correspond à ce que l'on cherche
Dim Trouvé As Range ' c'est le résultat de la recherche
Dim La_colonne As Integer ' colonne du mois où il y a "ok"
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Valeur_cherchée = "ORANGE" 'définition de ce que l'on cherche
Set Plage_de_recherche = Sheets("Feuil1").Range("J2:J58") ' définition de la plage de recherche
Set Trouvé = Plage_de_recherche.Find(what:=Valeur_cherchée, LookIn:=xlValues) ' on effectue la recherche : xlvalues car ok est le résultat d'une formule
If Trouvé Is Nothing Then ' si Trouvé = rien c'est qu'on a rien trouvé...
' ce qu'il y a à faire si on ne trouve pas "OK"
Else
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "Bonjour Michel," & vbCrLf & _
" " & vbCrLf & _
"La date de péremption de certain documents approche," & vbCrLf & _
"Vérifiez si une nouvelle version à été mise en ligne." & vbCrLf & " " & vbCrLf & _
"Cordialement," & vbCrLf & _
"Excel"
On Error Resume Next
With OutMail
.To = "armand.akdogan#siemens.com"
.CC = ""
.BCC = ""
.Subject = "MISE A JOUR DES DOCUMENTS"
.Body = strbody
'You can add a file like this
'.Attachments.Add ("C:\test.txt")
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
' ce qu'il faut faire si on trouve
End If
End Sub
Suddenly the macro blocks because Outlook is not open yet and give this
“Run-time error ‘429’: ActiveX component can’t create object.”
(Since I'm from Brazil, there is some text in Portuguese, so if you need some help, just let me know).
I've got 2 macros in my Outlook "This Outlook Session" in 1 master macro that calls the others 2 that I mentioned before.
The master macro do:
Macro name: "Salvar_CNAB_Registro"
Discovers the subject of the e-mail and give the path I want depending what it's writing.
After discover the path, save all the attachments from e-mail on the path discovered.
Sub Salvar_CNAB_Registro(Email As MailItem)
'Dim strSubject As String
Dim objMsg As Outlook.MailItem
Dim objSubject As String
objSubject = Email.Subject
'Defino qual caminho salvará os registros dos arquivos CNAB dependendo do produto da Funcesp ou da forma de liquidação
If InStr(1, objSubject, "Registro de Boletos de Saúde - Vencimento") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201658\"
'DiretorioAnexos = "K:\Divisao_Administrativa_Financeira\Tesouraria\Contas_Receber\COBRANÇAS\SAÚDE\2019\03 MARÇO 2019\25.03.2019\TESTE\"
ElseIf InStr(1, objSubject, "Registro de Boletos de Autopatrocínio - Vencimento") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201658\"
ElseIf InStr(1, objSubject, "Registro de Boletos de Seguros - Vencimento") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201717\"
ElseIf InStr(1, objSubject, "Registro de Débito Automático de Saúde - Vencimento") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201775\"
ElseIf InStr(1, objSubject, "Registro de Débito Automático de Autopatrocínio - Vencimento") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201775\"
ElseIf InStr(1, objSubject, "Registro de Débito Automático de Seguros - Vencimento") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201775\"
ElseIf InStr(1, objSubject, "Registro de Boletos de Empréstimo") > 0 Then
DiretorioAnexos = "S:\AFTData\OUTBOX\GE201717\"
End If
Debug.Print "Diretório Macro Salvar_CNAB_Registro:"
Debug.Print DiretorioAnexos
Dim MailID As String
Dim Mail As Outlook.MailItem
MailID = Email.EntryID
Set Mail = Application.Session.GetItemFromID(MailID)
'Verifico se o anexo no e-mail é arquivo unixo TXT e salvo todos
For Each Anexo In Mail.Attachments
If Right(Anexo.FileName, 3) = "txt" Then
Anexo.SaveAsFile DiretorioAnexos & "\" & Anexo.FileName
End If
Next
'Verifico se o anexo no e-mail é arquivo unixo zip e salvo todos
For Each Anexo In Mail.Attachments
If Right(Anexo.FileName, 3) = "zip" Then
Anexo.SaveAsFile DiretorioAnexos & Anexo.FileName
Call Unzipar_Arquivos
End If
Next
DoEvents
Call Reply_Email
Set Mail = Nothing
End Sub
The first macro do:
Macro name: Unzipar_Arquivos (calls the macro UnzipAFile)
It has two macros, it unzip any zip file attached in any e-mail called by the rule on Outlook.
Sub UnzipAFile(zippedFileFullName As Variant, unzipToPath As Variant)
Dim ShellApp As Object
'Copy the files & folders from the zip into a folder
Set ShellApp = CreateObject("Shell.Application")
ShellApp.NameSpace(unzipToPath).CopyHere ShellApp.NameSpace(zippedFileFullName).Items
End Sub
Sub Unzipar_Arquivos()
Dim diretorio As Variant
Dim diretorio_ext As Variant
Dim nome_arquivo As String
'------------------------------------ Extraio os arquivos da pasta do Santander Outbox 1658 --------------------------------'
'Caminho que o arquivo será unzipado
diretorio_ext = "S:\AFTData\OUTBOX\GE201658\"
'Descobre o nome do arquivo zip + caminho que ele se encontra
nome_arquivo = Dir(diretorio_ext & "*.zip")
'Caminho que encontra-se o arquivo zipado
diretorio = "S:\AFTData\OUTBOX\GE201658\" & nome_arquivo
'Executo a macro enquanto houver arquivos zipados na pasta
Do While Len(nome_arquivo) > 0
'A primeira parte refere-se ao nome do arquivo que será unzipado, e a segunda parte refere-se ao caminho que ele será unzipado
Call UnzipAFile(diretorio, diretorio_ext)
'Apago o primeiro arquivo zip que foi extraído
'Primeiro remove o atributo de arquivo "somente leitura" caso esteja definido
On Error Resume Next
SetAttr FileToDelete, vbNormal
'Depois apago o arquivo
Kill diretorio
'Procura o próximo arquivo
nome_arquivo = Dir
'Exibe mensagem de sucesso
MsgBox "Arquivo " & nome_arquivo & "descompactado e arquivos registrados! " & "no diretório: " & diretorio_ext
Loop
'------------------------------------ Extraio os arquivos da pasta do Santander Outbox 1717 --------------------------------'
'Caminho que o arquivo será unzipado
diretorio_ext = "S:\AFTData\OUTBOX\GE201717\"
'Descobre o nome do arquivo zip + caminho que ele se encontra
nome_arquivo = Dir(diretorio_ext & "*.zip")
'Caminho que encontra-se o arquivo zipado
diretorio = "S:\AFTData\OUTBOX\GE201717\" & nome_arquivo
'Executo a macro enquanto houver arquivos zipados na pasta
Do While Len(nome_arquivo) > 0
'A primeira parte refere-se ao nome do arquivo que será unzipado, e a segunda parte refere-se ao caminho que ele será unzipado
Call UnzipAFile(diretorio, diretorio_ext)
'Apago o primeiro arquivo zip que foi extraído
'Primeiro remove o atributo de arquivo "somente leitura" caso esteja definido
On Error Resume Next
SetAttr FileToDelete, vbNormal
'Depois apago o arquivo
Kill diretorio
'Procura o próximo arquivo
nome_arquivo = Dir
'Exibe mensagem de sucesso
MsgBox "Arquivo " & nome_arquivo & "descompactado e arquivos registrados! " & "no diretório: " & diretorio_ext
Loop
'------------------------------------ Extraio os arquivos da pasta do Santander Outbox 1775 --------------------------------'
'Caminho que o arquivo será unzipado
diretorio_ext = "S:\AFTData\OUTBOX\GE201775\"
'Descobre o nome do arquivo zip + caminho que ele se encontra
nome_arquivo = Dir(diretorio_ext & "*.zip")
'Caminho que encontra-se o arquivo zipado
diretorio = "S:\AFTData\OUTBOX\GE201775\" & nome_arquivo
'Executo a macro enquanto houver arquivos zipados na pasta
Do While Len(nome_arquivo) > 0
'A primeira parte refere-se ao nome do arquivo que será unzipado, e a segunda parte refere-se ao caminho que ele será unzipado
Call UnzipAFile(diretorio, diretorio_ext)
'Apago o primeiro arquivo zip que foi extraído
'Primeiro remove o atributo de arquivo "somente leitura" caso esteja definido
On Error Resume Next
SetAttr FileToDelete, vbNormal
'Depois apago o arquivo
Kill diretorio
'Procura o próximo arquivo
nome_arquivo = Dir
'Exibe mensagem de sucesso
MsgBox "Arquivo " & nome_arquivo & "descompactado e arquivos registrados! " & "no diretório: " & diretorio_ext
Loop
End Sub
The second macro do:
Macro name: Reply_Email
Discover the name of each file that was saved before and then add the name on the body of the HTML e-mail that it's going to reply to all.
Sub Reply_Email()
Dim strFolder As String
Const strPattern As String = "*.txt"
Dim strFile As String
Dim nome_cnab As String
Dim quantidade As Integer
Dim add_msg As String
Dim validador As Integer
Dim i As Integer
Debug.Print "Diretório Macro Responder_Email:"
Debug.Print strFolder
'Define o nome do caminho de acordo com o assunto (produto da funcesp que o cnab está sendo registrado) do e-mail enviado pelo funcionário solicitando o registro
strFolder = DiretorioAnexos
'Define a quantidade inicial de arquivos dentro da pasta que foi registrada
quantidade = 0
'Define o validador inicial igual a 0, isso significa que ainda não começou a montar o e-mail de resposta para a pessoa
validador = 0
'Nome do passo quando ele montar o e-mail, e adicionará os nomes dos arquivos cnab através do loop
Add_Nome_Cnab:
strFile = Dir(strFolder & strPattern, vbNormal)
Do While Len(strFile) > 0
'Caso queira ver o nome do arquivo CNAB na janela de verificação imediata (CTRL + G)
'Debug.Print strFile
strFile = Dir
nome_cnab = strFile
'Adiciono 1 na quantidade toda vez que passar por aqui, assim teremos a quantidade de arquivos salvos de cada e-mail
quantidade = quantidade + 1
'Se o validador for 1, ele grava o nome do arquivo na variavel
If validador = 1 Then
add_msg = nome_cnab
'Vai para o passo de adicionar de fato o nome do arquivo no corpo do e-mail através da variavel criada acima
GoTo Check_Validador
End If
Loop
Dim olItem As Outlook.MailItem
Dim olReply As MailItem ' Reply
For Each olItem In Application.ActiveExplorer.Selection
Set olReply = olItem.ReplyAll
'Define o validador como 1, para começar a montar o e-mail
validador = 1
'Se tiver 1 arquivo ou mais, ele começa a montar o e-mail
If quantidade > 0 Then
For i = 1 To quantidade
'Vai para o passo de gravar o nome do arquivo na variavel
GoTo Add_Nome_Cnab
Check_Validador:
'Essa etapa que ele adiciona de fato o nome no corpo do e-mail através da variavel criada acima
olReply.HTMLBody = "<br>" & add_msg & vbCrLf & olReply.HTMLBody
DoEvents
Next i
Else
olReply.HTMLBody = "<br>" & "Nenhum arquivo CNAB registrado" & "<br>" & vbCrLf & olReply.HTMLBody
End If
'Escreve as duas primeiras linhas no corpo do e-mail: "Arquivos registrados no dia e hora: " + Data e Hora + "Segue arquivos registrados: "
olReply.HTMLBody = "<br>" & "Arquivos registrados no dia e hora: " & Now & "<br>" & "Segue arquivos registrados: " & "<br>" & vbCrLf & olReply.HTMLBody
DoEvents
'Mostra o e-mail na tela
olReply.Display
DoEvents
'Envia o e-mail
olReply.Send
DoEvents
Next olItem
End Sub
All the macros works as a charm individually, but my problem is when the master macro "Salvar_CNAB_Registro" calls the last macro (Reply_Email) and the e-mail doesn't send by itself automatically.
So, if I run the script alone, it works!!! But, it doesn't work called by another macro.
EDIT 1:
I did some tests, but still can't work unless I debug.
What I did:
Added the macro to test all the macros together, each one calling each other.
Sub Test()
Dim x, mailItem As Outlook.mailItem
For Each x In Application.ActiveExplorer.Selection
If TypeName(x) = "MailItem" Then
Set mailItem = x
Call Salvar_CNAB_Registro(mailItem)
End If
Next
End Sub
So, still works sending the e-mail by debugging but it doesn't work by calling from the rule. I mean, all the macro works, but only don't display and send the e-mail.
I tried the solution from #0m3r, removing the line Application.ActiveExplorer.Selection from the macro Reply_Email, using Sub Reply_Email(ByVal Email As Object) and then calling it like Reply_Email(Email), but this method don't work.
I tried even using Sub Reply_Email(Email As Outlook.mailItem) and then calling it like Reply_Email(Email), this method worked by debugging again, but not automatically.
I also tried this method (How to Auto Reply with Outlook rule), by replying the e-mail from the rule directly but the original message in the body was not there, also I can't sign this code in my work.
It worked! I followed #0m3r tips, and also I did some research on web to try to fix this issue.
What I did:
Now, my macro is Sub Reply_Email(ByVal Email As Object) I named only Dim olReply As mailItem and Set olReply = Email.ReplyAll.
And the main difference that I saw was this part:
With olReply
'Envia o e-mail
.Send
End With
So after added this, the e-mail was send. The macro is called by Call Reply_Email(Email).
And finally, I added a rule that will not reply the e-mail if there is the word "ENC:" or "RES:" in the subject, it means that if there is some reply e-mail in the inbox, it will do nothing.
I want my emails saved to different folders on my hard drive based on what the email is about. Some emails should be saved in two or more folders.
The designated hard drive folders are created as they should, and files are saved with the right filenames, but all emails are saved in all folders.
If there is only one keyword from one 'category' present in the mail body. It seems like the script somehow 'remembers' the previously found keywords, even in the following If-Then statements - resulting in the email being saved in all folders.
I have edited the code based on your comments. It now gives
error 450: Wrong number of arguments.
Private WithEvents InboxItems As Outlook.Items
Option Explicit
Sub Application_Startup()
Dim xNameSpace As Outlook.NameSpace
Set xNameSpace = Outlook.Application.Session
Set InboxItems = xNameSpace.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal objItem As Object)
'Define variables
Dim FSO
Dim xFilePath As String
Dim xFilePathAgro As String
Dim xFilePathGras As String
Dim xFilePathIndustrie As String
Dim xFilePathActief As String
Dim xFilePathOppTech As String
Dim xMailItem As Outlook.MailItem
Dim xRegEx
Dim xFileName As String
'Create directories if not existing
xFilePath = CreateObject("WScript.Shell").SpecialFolders(16)
xFilePath = xFilePath & "\MyEmails"
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(xFilePath) = False Then
FSO.CreateFolder (xFilePath)
End If
xFilePathAgro = CreateObject("WScript.Shell").SpecialFolders(16)
xFilePathAgro = xFilePath & "\WBSO 13-01A Agro-reststromen"
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(xFilePathAgro) = False Then
FSO.CreateFolder (xFilePathAgro)
End If
xFilePathGras = CreateObject("WScript.Shell").SpecialFolders(16)
xFilePathGras = xFilePath & "\WBSO 13-01B Grassen"
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(xFilePathGras) = False Then
FSO.CreateFolder (xFilePathGras)
End If
'Change filenames of emails to save
Set xRegEx = CreateObject("vbscript.regexp")
xRegEx.Global = True
xRegEx.IgnoreCase = False
xRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?" 'Is vereist om de onderwerptitel op te nemen in bestandsnaam
If objItem.Class = olMail Then
Set xMailItem = objItem
xFileName = xRegEx.Replace(xMailItem.Subject, "")
xFileName = xRegEx.Replace(xMailItem.Subject, ":", "")
xFileName = xRegEx.Replace(xMailItem.Subject, "/", "_")
xFileName = xRegEx.Replace(xMailItem.Subject, "\", "")
xFileName = xRegEx.Replace(xMailItem.Subject, "<", "")
xFileName = xRegEx.Replace(xMailItem.Subject, ">", "")
xFileName = xRegEx.Replace(xMailItem.Subject, ";", "")
xFileName = Format(xMailItem.ReceivedTime, "YYYYMMDD hhmm") & " " & xFileName
'saving emails that contain the searchwords in the right folders
If InStr(1, xMailItem.Body, "Agro", vbTextCompare) > 0 Then
MsgBox "Opgeslagen in Agro"
'xMailItem.SaveAs xFilePathAgro & "\" & xFileName & ".msg"
End If
If InStr(1, xMailItem.Body, "Gras", vbTextCompare) > 0 Then
MsgBox "opgeslagen in Gras"
'xMailItem.SaveAs xFilePathGras & "\" & xFileName & ".msg"
End If
End If
End Sub