How to get all .XML files from a specific folder and attached in email and send it in VBA for a specific date (today for example) - vba

I made a VBA code that gets the last saved file in a folder and send it via Outlook, but I need to get all files from a specific date (from current day) not only the last one.
Sub SendEmail_Demo()
'Declare the variables
Dim MyPath As String
Dim MyFile As String
Dim LatestFile As String
Dim LatestDate As Date
Dim LMD As Date
'Specify the path to the folder
MyPath = "..................\XML\"
'Make sure that the path ends in a backslash
If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
'Get the first XML file from the folder
MyFile = Dir(MyPath & "*.xml*", Today(), vbNormal)
'If no files were found, exit the sub
If Len(MyFile) = 0 Then
MsgBox "No files were found...", vbExclamation
Exit Sub
End If
'Loop through each XML file in the folder
Do While Len(MyFile) > 0
'Assign the date/time of the current file to a variable
LMD = FileDateTime(MyPath & MyFile)
'If the date/time of the current file is greater than the latest
'recorded date, assign its filename and date/time to variables
If LMD > LatestDate Then
LatestFile = MyFile
LatestDate = LMD
End If
'Get the next XML file from the folder
MyFile = Dir
Loop
Dim OutlookApp As Outlook.Application
Dim OutlookMail As Outlook.MailItem
Set OutlookApp = New Outlook.Application
Set OutlookMail = OutlookApp.CreateItem(olMailItem)
With OutlookMail
.BodyFormat = olFormatHTML
.Display
.HTMLBody = "Hi demo"
.To = "myEmial.com"
.Subject = "Test demo"
.Attachments.Add MyPath & LatestFile
.Send
End With
End Sub

Try this:
Sub SendEmail_Demo()
Dim MyPath As String
Dim MyFile As String
'Specify the path to the folder
MyPath = "..................\XML\"
'Make sure that the path ends in a backslash
If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
'Get the first XML file from the folder
MyFile = Dir(MyPath & "*.xml", vbNormal)
'If no files were found, exit the sub
If Len(MyFile) = 0 Then
MsgBox "No files were found...", vbExclamation
Exit Sub
End If
Dim filesToSend As New Collection
Dim fileFullName As Variant
Dim startOfToday As Date
startOfToday = Now() - Timer() / 86400!
'Timer() ... elapsed seconds since the start of today
'86400 ..... seconds per day
'Loop through each XML file in the folder
Do While Len(MyFile) > 0
fileFullName = MyPath & MyFile
'If the date/time of the current file is greater than
'today 00:00 then add the file to 'filesToSend collection
If FileDateTime(fileFullName) > startOfToday Then
filesToSend.Add fileFullName
End If
'Get the next XML file from the folder
MyFile = Dir
Loop
Dim OutlookApp As Outlook.Application
Dim OutlookMail As Outlook.Mailitem
Set OutlookApp = New Outlook.Application
Set OutlookMail = OutlookApp.CreateItem(olMailItem)
With OutlookMail
.BodyFormat = olFormatHTML
.Display
.HTMLBody = "Hi demo"
.To = "myEmial.com"
.Subject = "Test demo"
'Attach all the files to one mail
For Each fileFullName In filesToSend
.Attachments.Add fileFullName
Next fileFullName
.SEND
End With
End Sub

Related

VB.net - Read .msg file from the shared folder and extract the attachments inside it

I'm completely new to VB and I'm trying to extract the attachment which is saved available inside the .msg file using the below code.
Could someone help me if this is the right approach to do this ?
I'm facing below compiler errors. Could someone help me how to resolve this issue ?
Outlook.Attachment is not defined.
End Sub' must be preceded by a matching 'Sub'
Reference to a non-shared member requires an object reference.
Statement cannot appear within a method body. End of method assumed
Method arguments must be enclosed in parentheses.
Type 'Outlook.MailItem' is not defined.
Sub SaveOlAttachments()
Dim msg As Outlook.MailItem
Dim att As Outlook.Attachment
Dim strFilePath As String
Dim strAttPath As String
Dim strFile As String
strFilePath = "C:\Users\...\Desktop\Test\"
strAttPath = "C:\Users\...\extracted attachment\"
strFile = Dir(strFilePath & "<Doc Name>.msg")
Do While Len(strFile) > 0
msg = Application.CreateItemFromTemplate(strFilePath & strFile)
If msg.Attachments.Count > 0 Then
For Each att In msg.Attachments
att.SaveAsFile strAttPath & att.FileName
Next
End If
strFile = Dir
Loop
End Sub
First of all, check out the file path where you try to find the template:
msg = Application.CreateItemFromTemplate(strFilePath & strFile)
The strFilePath string may include the file name already:
strFile = Dir(strFilePath & "<Doc Name>.msg")
Second, make sure attachments are saved using unique file names:
att.SaveAsFile strAttPath & att.FileName
The FileName string can be the same in different emails. I'd recommend adding IDs or the current time and etc. to the file name to uniquely name attached files on the disk.
Here is the code we use to grab a daily report attachment. I left a few commented statements in case you might need them (we didn't).
Sub Extract_Outlook_Email_Attachments()
On Error GoTo ErrHandler
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim folder As MAPIFolder
Dim OutlookMail As Variant
Dim i As Integer
Dim olNS As Outlook.Namespace
Dim objOwner As Outlook.Recipient
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Dim saveFolder As String
saveFolder = strAttPath ' SAVE THE ATTACHMENT TO
'this bit is added to get a shared email
Set objOwner = OutlookNamespace.CreateRecipient("SHARED FOLDER NAME")
objOwner.Resolve
If objOwner.Resolved Then
Debug.Print "Outlook GB Fulfillment is good."
Set folder = OutlookNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) 'can use olFolderInbox or olFolderSentMail
End If
'Write mail to spreadsheet - create named range, from and to dates on the spreadsheet
i = 1
For Each OutlookMail In folder.Items
' Debug.Print "SenderEmailAddress: " & OutlookMail.SenderEmailAddress
'If OutlookMail.SenderEmailAddress = "no-reply#OurCompany.com" Then
If OutlookMail.subject = "Daily Report" Then
' If OutlookMail.SenderName = "no-reply#OurCompany.com" And OutlookMail.Subject = "Daily New Subscriber Plan Election Fulfillment" And OutlookMail.Attachments(1) = "NewSubscriberPlanElectionFulfillment_Subscription.xls" Then
Debug.Print "Received: " & OutlookMail.ReceivedTime
Debug.Print "Attach: " & OutlookMail.Attachments(1)
dateformat = Format(OutlookMail.ReceivedTime, "m-d-yy")
Debug.Print dateformat
FName = dateformat & " " & OutlookMail.Attachments(1).fileName
Debug.Print "FName: " & FName
Dim strFileExists As String
strFileExists = Dir(saveFolder & FName)
If strFileExists = "" Then
' MsgBox "The selected file doesn't exist"
Else
' MsgBox "The selected file exists"
Exit Sub
End If
OutlookMail.Attachments(1).SaveAsFile saveFolder & FName
Set outAttachment = Nothing
End If
Next OutlookMail
Set folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
ErrHandler:
Debug.Print Err.Description
End Sub
Instead of using CreateItemFromTemplate, you can use Namespace.OpenSharedItem to open an MSG file.
You also need to add Outlook to your VB.Net project references.

Excel VBA - Moving an email to a different folder

I've been given a project where I go into a particular folder within an inbox.
Once I am in the folder I have to extract the attachment and save the body of the email as a text file.
Once that is done I need to attach those two onto an email to send it to a different mailbox (Mailbox2) which has a file-watcher attached to it.
I am encountering an issue when attempting to move the email to a different folder once sent to Mailbox2
-------------------------------------
Private Sub Application_NewMail()
Dim NS As Outlook.NameSpace
Set NS = Outlook.Application.GetNamespace("MAPI")
Dim Inbox As Folder
Set Inbox = NS.GetDefaultFolder(olFolderInbox)
Dim SubFolder As Folder
Set SubFolder = Inbox.Folders("TESTER")
Dim Destination As String
Destination = "MyFolder\"
Dim Atmt As Attachment
Dim FileName As String
Dim Subject As String
Dim txtFile As String
For Each Email In SubFolder.Items
For Each Atmt In Email.Attachments
If LCase(Right(Atmt.FileName, Len(ExtString))) = LCase(ExtString) Then
FileName = Destination & Email.SenderName & " " & Atmt.FileName
Atmt.SaveAsFile FileName
I = I + 1
End If
Next Atmt
Subject = Email.SenderName
Dim rmv As Variant
rmv = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
Dim r As Variant
For Each r In rmv
Subject = Replace(Subject, r, "")
Next r
txtFile = Destination & Subject & ".txt"
Open txtFile For Output As #1
Write #1, Email.Body
Close #1
Call Send_Mail(Subject)
Call DeleteExample
Next Email
End Sub
-------------------------------------
Public Sub Send_Mail(Subject As String)
Dim OutlookApp As Outlook.Application
Dim OutlookMail As Outlook.MailItem
Set OutlookApp = New Outlook.Application
Set OutlookMail = OutlookApp.CreateItem(olMailItem)
StrPath = "MyFolder\"
With OutlookMail
.Display
.To = "Mailbox2#gmail.com"
.CC = "Mailbox2#gmail.com"
.BCC = "Mailbox2#gmail.com"
.Subject = "Test mail"
strfile = Dir(StrPath & "*.*")
Do While Len(strfile) > 0
If (Right(strfile, 3) = "txt" Or Right(strfile, 3) = "pdf" Or Right(strfile, 4) = "xlsx") Then
.Attachments.Add StrPath & strfile
End If
strfile = Dir
Loop
.Send
End With
End Sub
-------------------------------------
Sub DeleteExample()
'Deletes all files in the folder
Kill "MyFolder\*.*"
End Sub
-------------------------------------
What I have been attempting is this logic embeded within the for loop in the Application_NewMail()
For Each Email In SubFolder.Items
For Each Atmt In Email.Attachments
If LCase(Right(Atmt.FileName, Len(ExtString))) = LCase(ExtString) Then
FileName = Destination & Email.SenderName & " " & Atmt.FileName
Atmt.SaveAsFile FileName
I = I + 1
End If
Next Atmt
Subject = Email.SenderName
Dim rmv As Variant
rmv = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
Dim r As Variant
For Each r In rmv
Subject = Replace(Subject, r, "")
Next r
txtFile = Destination & Subject & ".txt"
Open txtFile For Output As #1
Write #1, Email.Body
Close #1
Call Send_Mail(Subject)
Call DeleteExample
Call MoveEmail()
Next Email
-------------------------------
Sub MoveEmail()
Dim NS As Outlook.NameSpace
Set NS = Outlook.Application.GetNamespace("MAPI")
Dim Inbox As Folder
Set Inbox = NS.GetDefaultFolder(olFolderInbox)
Dim SubFolder As Folder
Set SubFolder = Inbox.Folders("TESTER")
For Each Email In SubFolder.Items
SubFolder.MoveTo (Inbox.Folders("END"))
Next Email
End Sub
Yet what it is doing is moving the entire "TESTER" folder into the "END" folder
Messing with it some more I found out how to move the email to a different folder.
Here is the logic
Sub MoveEmail()
Dim NS As Outlook.NameSpace
Set NS = Outlook.Application.GetNamespace("MAPI")
Dim Inbox As Folder
Set Inbox = NS.GetDefaultFolder(olFolderInbox)
Dim SubFolder As Folder
Set SubFolder = Inbox.Folders("TESTER")
For Each Email In SubFolder.Items
Email.Move (Inbox.Folders("END"))
Next Email
End Sub
Do not use "for each" when modifying a collection - use a down loop:
set items = SubFolder.Items
for i = items.Count to 1 step -1
set Email = items(i)
Email.Move (Inbox.Folders("END"))
Next

Attach all CSV files in a folder

I'm running a script to automatically send emails with attachments. All attachments will have a .csv extension.
I do not know the name of the files before hand. I am using the Dir statement.
I tried breaking the Dir statement into different strings, but that was not working either.
Dim cAttachment As String
Dim Folder As String
Dim fileCriteria As String
Folder = "C:\Users\____\Desktop\Test Folder"
fileCriteria = ".csv"
cAttachment = Dir(Folder & "\*" & fileCriteria)
I also tried:
Dim cAttachment As String
cAttachment = Dir("C:\Users\___\Desktop\Test Folder\*.csv")
I get
expected end of statement
on the leading parenthesis of my Dir statement.
You can easily achieve your result without having to use the old Dir() Function. To do that you need to use "Scripting.FileSystemObject".
This is the code to discover all files with .csv extension in a specific folder:
Dim oFile As Object
Dim oFSO As Object
Dim oFolder As Object
Dim oFiles As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder("C:\my\Folder\") 'Set this accordingly
Set oFiles = oFolder.Files
'For all files in the folder
For Each oFile In oFiles
If (oFile Like "*.csv") Then
'Add this file to attachments
objMessage.AddAttachment oFile.Path
End If
Next
Hope this helps.
Should be
Folder = "C:\Users\____\Desktop\Test Folder\"
cAttachment = Dir(Folder & "*.csv")`
'// Loop to attch
Do While Len(cAttachment ) > 0
.Attachments.Add Folder & cAttachment
Atmt_File = Dir
Loop
Full Example code
Option Explicit
Private Sub Example()
Dim olMsg As Outlook.MailItem
Dim olRecip As Outlook.Recipient
Dim Atmt_Path As String
Dim olInsp As Outlook.Inspector
Dim wdDoc As Object
Dim rng As Object
Dim Atmt_File As String
'// Attachments Path.
Atmt_Path = "C:\Temp\"
'// Create the message.
Set olMsg = Application.CreateItem(olMailItem)
With olMsg
.Display '// This line must be retained
Atmt_File = Dir(Atmt_Path & "*.csv")
'// Loop to attch
Do While Len(Atmt_File) > 0
.Attachments.Add Atmt_Path & Atmt_File
Atmt_File = Dir
Loop
'// Cancell email if no files to send
If .Attachments.Count = 0 Then
'MsgBox "There are no reports to attach.", vbInformation
.Close 0
.Delete
Else
'// Add the To recipient(s)
Set olRecip = .Recipients.Add("0m3r#email.com")
Set olRecip = .Recipients.Add("0m3r#email.com")
olRecip.Type = olTo
'// Add the CC recipient(s)
Set olRecip = .Recipients.Add("0m3r#email.com")
olRecip.Type = olCC
'// Set the Subject, Body, and Importance of the message.
.Subject = "Reports - " & Format(Now, "Long Date")
.Importance = olImportanceHigh '// High importance
.BodyFormat = olFormatHTML
'// Edit the message body.
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
'// Set message body (to retain the signature)
Set rng = wdDoc.Range(0, 0)
'// add the text to message body
rng.Text = "Files are Attached, Thank you" & vbCrLf & vbCrLf
'// Resolve each Recipient's name.
For Each olRecip In .Recipients
olRecip.Resolve
If Not olRecip.Resolve Then
olMsg.Display
End If
Next
' .Send '//This line optional
End If
End With
End Sub

Saving Outlook Emails as ".msg" not as "File"

I've got this block of code to go through all the emails in my "Today" folder in Outlook, then save all the emails (.msg) to a folder named as the sender name.
Sometimes the files are saving with the file type "file".
How do I fix this to make sure the emails are saved as .msg files?
Sub SaveAttachments()
'https://www.fontstuff.com/outlook/oltut01.htm
'Declare Variables
Dim ns As NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim Savefolder As String
Dim i As Integer
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox).Folders("Today")
i = 0
'Stop script if there are no emails
If Inbox.Items.Count = 0 Then
MsgBox "There are no messages in the Inbox.", vbInformation, "Nothing Found"
Exit Sub
End If
'Display the number of emails
MsgBox Inbox.Items.Count, vbInformation, _
"Number of Emails?"
'Go through each email
For Each Item In Inbox.Items
'Create a path for the save folder
Savefolder = "C:\Users\work\Desktop\22_11_18\Test\" & Item.SenderName
'If the email has attachments, then create a folder
If Item.Attachments.Count > 0 Then
MkDir Savefolder
'If the folder already exists, skip to the next statement
On Error Resume Next
'Save the email as a .msg file
Item.SaveAs Savefolder & "\" & Item.Subject & ".msg"
End If
Next Item
End Sub
You can use subject if the characters in the subject are all valid.
Option Explicit
Private Sub SaveMail_ContainingAttachments_ValidSubject()
'Declare Variables
Dim ns As Namespace
Dim targetFolder As Folder
Dim itm As Object
Dim atmt As Attachment
Dim strSaveFolder As String
Dim validSubject As String
Set ns = GetNamespace("MAPI")
Set targetFolder = ns.GetDefaultFolder(olFolderInbox)
Set targetFolder = targetFolder.Folders("Today")
'Stop script if there are no emails
If targetFolder.Items.count = 0 Then
MsgBox "There are no messages in " & targetFolder & ".", vbInformation, "Nothing Found"
Exit Sub
End If
'Display the number of emails
MsgBox targetFolder.Items.count, vbInformation, "Number of Emails?"
'Go through each email
For Each itm In targetFolder.Items
'If the email has attachments, then create a folder
If itm.Attachments.count > 0 Then
'Create a path for the save folder
strSaveFolder = "C:\Users\work\Desktop\22_11_18\Test\" & itm.senderName
' Bypass error if the folder already exists
On Error Resume Next
MkDir strSaveFolder
' Discontinue error bypass as soon as the purpose is served
' Let unknown errors generate then fix them
On Error GoTo 0
' Replace or remove invalid characters
' Possible options "_" or " " or "" ....
validSubject = ReplaceIllegalChar(itm.subject, "_")
If validSubject <> itm.subject Then
Debug.Print itm.subject
Debug.Print validSubject
End If
'Save the email as a .msg file
itm.SaveAs strSaveFolder & "\" & validSubject & ".msg"
End If
Next itm
End Sub
Private Function ReplaceIllegalChar(strInput, strReplace)
Dim RegX As Object
Set RegX = CreateObject("vbscript.regexp")
RegX.Pattern = "[\" & Chr(34) & "\!\#\#\$\%\^\&\*\(\)\=\+\|\[\]\{\}\`\'\;\:\<\>\?\/\,]"
RegX.IgnoreCase = True
RegX.Global = True
' Replace with another string
ReplaceIllegalChar = RegX.Replace(strInput, strReplace)
ExitFunction:
Set RegX = Nothing
End Function

Batch file code for a vba program

I have a vba code which works fine, but I want to create the same code as batch file which can do the same thing the vba code is doing.
I have created the code which sends all files in a folder to a specified email address and after sending delete the file.
Can anyone help me in creating the same thing with a batch file which can do the same thing.
Below is the VBA code:
Private Sub Click()
Dim mess_body As String, StrFile As String, StrPath As String
Dim appOutLook As Outlook.Application
Dim MailOutLook As Outlook.MailItem
Set appOutLook = CreateObject("Outlook.Application")
Set MailOutLook = appOutLook.CreateItem(olMailItem)
'~~> Change path here
StrPath = "\Project\New folder\New folder\"
With MailOutLook
.BodyFormat = olFormatRichText
.To = "test#sdm.com"
.Subject = "test"
.HTMLBody = "test"
'~~> *.* for all files
StrFile = Dir(StrPath & "*.*")
Do While Len(StrFile) > 0
.Attachments.Add StrPath & StrFile
StrFile = Dir
Loop
'.DeleteAfterSubmit = True
.Send
End With
Kill "\Project\New folder\New folder\*.*"
MsgBox "Reports have been sent", vbOKOnly
End Sub
U can use cell ("A1") value as folder reference.
Dim objFolder As Object
Set appOutLook = CreateObject("Outlook.Application")
Set MailOutLook = appOutLook.CreateItem(olMailItem)
'~~> Change path here
VAR1 = Range("A1").Value
If VAR1 = False Then MsgBox "Cell is empty"
If VAR1 = False Then Exit Sub
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(VAR1)
With MailOutLook
.BodyFormat = olFormatRichText
.To = "test#test.com"
.Subject = "test"
.HTMLBody = "test"
'~~> *.* for all files
StrFile = Dir(objFolder & "*.*")
...
'.DeleteAfterSubmit = True
.Send
End With
'delete files
Kill objFolder & "\*.*"