i am trying to save a selected mail from outlook to a folder dynamically created with mail's subject name. The code ran successfully for one mail. if i select different mail and try to run the macro it is showing path not found error. My code is below:
Public Sub OpslaanMails()
Dim OlApp As Outlook.Application
Set OlApp = New Outlook.Application
Set OlApp = CreateObject("Outlook.Application")
Dim fName, sName As String
Dim oMail As Outlook.MailItem
fName = "F:\Test\inwards\"
Set oMail = OlApp.ActiveExplorer.Selection.Item(1)
sName = oMail.Subject
makeSelectionDir (sName)
sPath = fName & "\" & sName & "\"
oMail.SaveAs sPath & sName & ".msg", olMsg
For Each oAttach In oMail.Attachments
oAttach.SaveAsFile sPath & oAttach.FileName
Set oAttach = Nothing
Next
End Sub
Sub makeSelectionDir(sName As String)
Dim fName, sPath As String
fName = "F:\Test\inwards\"
sPath = fName & sName
With CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(sName) Then .CreateFolder sPath 'error is in this line
End With
End Sub
Make sure sName does not contain any characters illegal in a file name, such as ":".
I used your idea and changed two or three things to make it more robust.
Put this in a module in Outlook VBA Editor and run, having selected an email.
I also added the time and date at the beginning of the folder and email file names.
I left the part about saving file attachements but know that they are already embedded in the .msg file.
Const ILLEGAL_CHARACTERS = Array("*", "/", "\", "?", """", "<", ">", ":", "|")
Sub SaveEmailToFile()
Dim oMail As MailItem
Dim sPath As String
Dim sObj As String
Dim oAttach As Attachment
'Select email and process subject
If ActiveExplorer.Selection.Count = 0 Then
MsgBox "No emails are selected."
Exit Sub
End If
Set oMail = ActiveExplorer.Selection.Item(1)
With oMail
sObj = oMail.Subject
'Remove illegal characters from email subject
If sObj = "" Then
sObj = "No Object"
Else
For Each s In ILLEGAL_CHARACTERS
sObj = Replace(sObj, s, "")
Next s
End If
'Get date and time string from email received timestamp
dateStr = Year(.ReceivedTime) & "_" & _
Month(.ReceivedTime) & "_" & _
Day(.ReceivedTime) & " " & _
Hour(.ReceivedTime) & " " & _
Minute(.ReceivedTime) & " " & _
Second(.ReceivedTime) & " "
End With
sPath = "C:\Someplace\" & dateStr & sObj & "\"
'Create folder
With CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(sPath) Then .CreateFolder sPath
End With
'Save email and attachements
oMail.SaveAs sPath & oMail.Subject & ".msg", olMSG
For Each oAttach In oMail.Attachments
oAttach.SaveAsFile sPath & oAttach.FileName
Next oAttach
End Sub
I could only recreate the error
path not found
if fName was not valid.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Public Sub OpslaanMails()
Dim fName As String
Dim sName As String
Dim sPath As String
Dim oMail As MailItem
Dim oAttach As Attachment
fName = "F:\Test\inwards\"
Debug.Print "fName: " & fName
Set oMail = ActiveExplorer.Selection.Item(1)
sName = oMail.subject
Debug.Print "sName: " & sName
' Double slash accepted by Windows but not by some programmers
'If Right(fName, 1) = "\" Then
' fName = Left(fName, Len(fName) - 1)
' Debug.Print
' Debug.Print "fName: " & fName
'End If
' Double slash after fName preferable to no slash
sPath = fName & "\" & sName & "\"
Debug.Print "sPath: " & sPath
makeSelectionDir fName, sPath
' Possible illegal characters in sName not addressed.
' Do not test with replies nor forwards,
' the : in the subject is not a legal character.
oMail.SaveAs sPath & sName & ".msg", olMsg
For Each oAttach In oMail.Attachments
oAttach.SaveAsFile sPath & oAttach.FileName
Set oAttach = Nothing
Next
End Sub
Sub makeSelectionDir(fName As String, sPath As String)
With CreateObject("Scripting.FileSystemObject")
' Test for fName
' Otherwise there is file not found error in the create
If .FolderExists(fName) Then
' if subfolder does not exist create it
If Not .FolderExists(sPath) Then
.createFolder sPath
End If
Else
Debug.Print
Debug.Print "Folder " & fName & " does not exist."
'MsgBox "Folder " & fName & " does not exist."
End
End If
End With
End Sub
Inconsistency of sName vs sPath has been addressed in
If Not .FolderExists(sName) Then .CreateFolder sPath
Related
After selecting the email item in Outlook, press ctrl+C and open a folder in Windows Explorer and press ctrl+V act save the email msg file to this folder.
At this time, the saved file name is designated as the subject of the email.
I succeeded in changing the title and saving it, but this method is cumbersome because it saves to a specific folder.
I'm trying to make a similar user experience with ctrl+C/ctrl+V.
How do I copy the email object item to the clipboard in the form of a file?
I tried MSForms.
Public Sub SaveMessageAsMsg()
Dim oMail As Outlook.MailItem
Dim objItem As Object
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Dim enviro As String
Dim sSender As String
'Dim buf As MSForms.DataObject
enviro = CStr(Environ("USERPROFILE"))
For Each objItem In ActiveExplorer.Selection
If objItem.MessageClass = "IPM.Note" Then
Set oMail = objItem
sName = oMail.Subject
ReplaceCharsForFileName sName, "_"
sSender = oMail.Sender
If InStr(sSender, "/") > 0 Then sSender = Left(sSender, InStr(sSender, "/") - 1)
If InStr(sSender, "(") > 0 Then sSender = Left(sSender, InStr(sSender, "(") - 1)
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "_hhnn", _
vbUseSystemDayOfWeek, vbUseSystem) & "_" & sSender & "_" & sName & ".msg"
sPath = enviro & "\Documents\SaveMails\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMSG
End If
Next
End Sub
I would like to find a way to save selected Outlook emails using a UNC path to a shared drive as a .msg file.
I have code that does exactly what I am looking to do (below), however it uses a folder picker, and I would just like to hard-code the UNC path instead
Example "\\ent.core.company.com\emails\".
Public Sub SaveMessageAsMsg123() 'This works, but with folder picker
'http://www.vbaexpress.com/forum/showthread.php?64358-Saving-Multiple-Selected-Emails-As-MSG-Files-In-Bulk-In-Outlook
Dim xShell As Object
Dim xFolder As Object
Dim strStartingFolder As String
Dim xFolderItem As Object
Dim xMail As MailItem
Dim xObjItem As Object
Dim xPath As String
Dim xFileName As String
Dim xName As String
Dim xDtDate As Date
Set xShell = CreateObject("Shell.Application")
''Set xFolder = CreateObject("WScript.Shell").specialfolders(16)
On Error Resume Next
' Bypass error when xFolder is nothing on Cancel
Set xFolder = xShell.BrowseForFolder(0, "Select a folder:", 0, strStartingFolder)
'' xFolder = "\\ent.core.company.com\emails\"
'Remove error bypass as soon as the purpose is served
On Error GoTo 0
Debug.Print xFolder
If Not TypeName(xFolder) = "Nothing" Then
Set xFolderItem = xFolder.Self
xFileName = xFolderItem.Path
' missing path separator
If Right(xFileName, 1) <> "\" Then xFileName = xFileName & "\"
Else
xFileName = ""
Exit Sub
End If
For Each xObjItem In ActiveExplorer.Selection
If xObjItem.Class = olMail Then
Set xMail = xObjItem
xName = CleanFileName(xMail.Subject)
Debug.Print xName
xDtDate = xMail.ReceivedTime
xName = Format(xDtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(xDtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & xName & ".msg"
xPath = xFileName & xName
xMail.SaveAs xPath, olMsg
End If
Next
End Sub
Public Function CleanFileName(strFileName As String) As String
' http://windowssecrets.com/forums/sho...Charaters-(VBA)
Dim Invalids
Dim e
Dim strTemp As String
Invalids = Array("?", "*", ":", "|", "<", ">", "[", "]", """", "/")
strTemp = strFileName
For Each e In Invalids
strTemp = Replace(strTemp, e, " ")
'strTemp = Replace(strTemp, e, "")
Next
CleanFileName = strTemp
End Function
I figured it out!
Public Sub SaveMessageAsMsg
Dim xShell As Object
Dim xFolder As Object
Dim strStartingFolder As String
Dim xFolderItem As Object
Dim strFolderpath As String
Dim xMail As MailItem
Dim xObjItem As Object
Dim xPath As String
Dim xFileName As String
Dim xName As String
Dim xDtDate As Date
' Get the path to your My Documents folder
strFolderpath = CreateObject("WScript.Shell").specialfolders(16)
' Instantiate an Outlook Application object.
Set objOL = Application
' Get the collection of selected objects.
Set objSelection = objOL.ActiveExplorer.Selection
' You can change this to another folder name of your choice
' Set the Attachment folder.
strFolderpath = "\\ent.core.medtronic.com\mit-msp01\CVG US Field Inventory\Lookup_Data\TransportationDelayEmails\"
xFileName = strFolderpath
' missing path separator
If Right(xFileName, 1) <> "\" Then xFileName = xFileName & "\"
For Each xObjItem In ActiveExplorer.Selection
If xObjItem.Class = olMail Then
Set xMail = xObjItem
xName = CleanFileName(xMail.Subject)
Debug.Print xName
xPath = xFileName & xName
xMail.SaveAs xPath & ".msg" ', olMsg ' & ".msg"
End If
Next
End Sub
I am trying to save selected emails in Outlook as Text files.
I would like it to work like this:
Saves one email at a time but saves all selected emails instead of just a single email.
They need to each be saved as a new file. I know that the export feature saves them all as one large text file, but need them to each have their own.
Here's what I have so far:
Sub SaveEmail()
Dim Msg As Outlook.MailItem
' assume an email is selected
Set Msg = ActiveExplorer.Selection.item(2)
' save as text
Msg.SaveAs "C:\My Location", OLTXT
End Sub
It looks like you need to iterate over all selected items in the explorer window and save each one using the txt file format. Be aware, the Selection object may contain various Outlook item types. The following code showshow to iterate over all items selected and detect what item is:
Private Sub GetSelectedItem_Click()
' This uses an existing instance if available (default Outlook behavior).
' Dim oApp As New Outlook.Application - for running in external applications
Dim oExp As Outlook.Explorer
Dim oSel As Outlook.Selection ' You need a selection object for getting the selection.
Dim oItem As Object ' You don't know the type yet.
Set oExp = Application.ActiveExplorer ' Get the ActiveExplorer.
Set oSel = oExp.Selection ' Get the selection.
For i = 1 To oSel.Count ' Loop through all the currently .selected items
Set oItem = oSel.Item(i) ' Get a selected item.
DisplayInfo oItem ' Display information about it.
Next i
End Sub
Sub DisplayInfo(oItem As Object)
Dim strMessageClass As String
Dim oAppointItem As Outlook.AppointmentItem
Dim oContactItem As Outlook.ContactItem
Dim oMailItem As Outlook.MailItem
Dim oJournalItem As Outlook.JournalItem
Dim oNoteItem As Outlook.NoteItem
Dim oTaskItem As Outlook.TaskItem
' You need the message class to determine the type.
strMessageClass = oItem.MessageClass
If (strMessageClass = "IPM.Appointment") Then ' Calendar Entry.
Set oAppointItem = oItem
MsgBox oAppointItem.Subject
MsgBox oAppointItem.Start
ElseIf (strMessageClass = "IPM.Contact") Then ' Contact Entry.
Set oContactItem = oItem
MsgBox oContactItem.FullName
MsgBox oContactItem.Email1Address
ElseIf (strMessageClass = "IPM.Note") Then ' Mail Entry.
Set oMailItem = oItem
MsgBox oMailItem.Subject
MsgBox oMailItem.Body
ElseIf (strMessageClass = "IPM.Activity") Then ' Journal Entry.
Set oJournalItem = oItem
MsgBox oJournalItem.Subject
MsgBox oJournalItem.Actions
ElseIf (strMessageClass = "IPM.StickyNote") Then ' Notes Entry.
Set oNoteItem = oItem
MsgBox oNoteItem.Subject
MsgBox oNoteItem.Body
ElseIf (strMessageClass = "IPM.Task") Then ' Tasks Entry.
Set oTaskItem = oItem
MsgBox oTaskItem.DueDate
MsgBox oTaskItem.PercentComplete
End If
End Sub
You can add the SaveAs statement shown in your code where required.
Thank you everybody for your help. I was able to find the answer. Below is what worked for me.
Sub SaveSelectedMailAsTxtFile()
Const OLTXT = 0
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim oMail As Outlook.MailItem
Dim obj As Object
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
For Each obj In Selection
Set oMail = obj
sName = oMail.Subject
ReplaceCharsForFileName sName, "_"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".txt"
oMail.SaveAs "C:\my\path\" & sName, OLTXT
Next
End Sub
Private Sub ReplaceCharsForFileName(sName As String, _
sChr As String _
)
sName = Replace(sName, "/", sChr)
sName = Replace(sName, "\", sChr)
sName = Replace(sName, ":", sChr)
sName = Replace(sName, "?", sChr)
sName = Replace(sName, Chr(34), sChr)
sName = Replace(sName, "<", sChr)
sName = Replace(sName, ">", sChr)
sName = Replace(sName, "|", sChr)
End Sub
To save a single selected mail to a text file:
Selected email will be saved to a text file in the path specified in the code
Sub SaveMailAsFile()
Const OLTXT = 0
Dim oMail As Outlook.mailItem
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Set oMail = Application.ActiveExplorer.Selection.Item(1)
sName = oMail.Subject
ReplaceCharsForFileName sName, "_"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".txt"
oMail.SaveAs "C:\path\to\save\" & sName, OLTXT
End Sub
Private Sub ReplaceCharsForFileName(sName As String, _
sChr As String _
)
sName = Replace(sName, "/", sChr)
sName = Replace(sName, "\", sChr)
sName = Replace(sName, ":", sChr)
sName = Replace(sName, "?", sChr)
sName = Replace(sName, Chr(34), sChr)
sName = Replace(sName, "<", sChr)
sName = Replace(sName, ">", sChr)
sName = Replace(sName, "|", sChr)
End Sub
To save all selected mails to a text file:
NOTE: Click on Tools -> References -> Check the box for Microsoft Scripting Runtime before using this code.
Selected email(s) will be save to the user's standard Documents folder with the date and time stamp
Sub MergeSelectedEmailsIntoTextFile()
Dim objFS As New Scripting.FileSystemObject, objFile As Scripting.TextStream
Dim objItem As Object, strFile As String
Dim Folder As Folder
Dim sName As String
' Use your User folder as the initial path
Dim enviro As String
enviro = CStr(Environ("USERPROFILE"))
If ActiveExplorer.Selection.Count = 0 Then Exit Sub
' use the folder name in the filename
Set Folder = Application.ActiveExplorer.CurrentFolder
' add the current date to the filename
sName = Format(Now(), "yyyy-mm-dd-hh-MM-ss")
' The folder pathyou use needs to exist
strFile = enviro & "\Documents\" & sName & "-" & Folder & ".txt"
Set objFile = objFS.CreateTextFile(strFile, False)
If objFile Is Nothing Then
MsgBox "Error creating file '" & strFile & "'.", vbOKOnly + vbExclamation _
, "Invalid File"
Exit Sub
End If
For Each objItem In ActiveExplorer.Selection
With objFile
.Write vbCrLf & "--Start--" & vbCrLf
.Write "Sender: " & objItem.Sender & " <" & objItem.SenderEmailAddress & ">" & vbCrLf
.Write "Recipients : " & objItem.To & vbCrLf
.Write "Received: " & objItem.ReceivedTime & vbCrLf
.Write "Subject: " & objItem.Subject & vbCrLf & vbCrLf
.Write objItem.Body
.Write vbCrLf & "--End--" & vbCrLf
End With
Next
objFile.Close
MsgBox "Email text extraction completed!", vbOKOnly + vbInformation, "DONE!"
Set objFS = Nothing
Set objFile = Nothing
Set objItem = Nothing
End Sub
Reference: Save email message as text file
Hers is a shorter Solution I came up with that just saves the body of the message.
Sub selectToText()
Dim Omail As Outlook.MailItem
Set Omail = Application.ActiveExplorer.Selection.Item(1)'Selected Message
Dim subject As String: subject = Omail.subject 'Get subject
Dim rmv As Variant: rmv = Array("\", "/", ":", "*", "?", """", "<", ">", "|") 'Invalid chars for a file name
Dim r As Variant 'holds a char
Dim txtFile As String 'holds dir to save to
For Each r In rmv ' remove invalid chars
subject = Replace(subject, r, "")
Next r
txtFile = "C:\" & subject & ".txt" 'set save to location CHANGE this to where you want to save!
Open txtFile For Output As #1
Write #1, Omail.Body 'write email body to save location
Close #1
End Sub
I save incoming mail with an inbox rule and VBA code.
When there are multiple emails with the same name and also if the attachments have the same name they overwrite each other.
I need both the email and the attachments to loop through 1-10. There can be up to ten emails and attachments with the same names.
Sub SaveAsMsg(MyMail As MailItem)
' requires reference to Microsoft Scripting Runtime
' \Windows\System32\Scrrun.dll
' Also requires reference to Microsoft Word Object Library
Dim fso As FileSystemObject
Dim strSubject As String
Dim strSaveName As String
Dim blnOverwrite As Boolean
Dim strFolderPath As String
Dim looper As Integer
Dim strID As String
Dim olNS As Outlook.NameSpace
Dim oMail As Outlook.MailItem
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)
'Get Sender email domain
sendEmailAddr = oMail.SenderEmailAddress
companyDomain = Right(sendEmailAddr, Len(sendEmailAddr) - InStr(sendEmailAddr, "#"))
' ### USER OPTIONS ###
blnOverwrite = False ' False = don't overwrite, True = do overwrite
'### THIS IS WHERE SAVE LOCATIONS ARE SET ###
'Currently only saves to yPath. Change the yPath variable to mPath in other areas of the script to enable the month folder.
bPath = "C:\email\" 'Defines the base path to save the email
cPath = bPath & companyDomain & "\" 'Adds company domain to base path
yPath = cPath & Format(Now(), "yyyy") & "\" 'Add year subfolder
mPath = yPath & Format(Now(), "MMMM") & "\" 'Add month subfolder
'### Path Validity ###
'Make sure base path exists
If Dir(bPath, vbDirectory) = vbNullString Then
MkDir bPath
End If
'Make sure company domain path exists
'If Dir(cPath, vbDirectory) = vbNullString Then
'MkDir cPath
'End If
'Make sure year path exists
'If Dir(yPath, vbDirectory) = vbNullString Then
'MkDir yPath
'End If
'Make sure month path exists (uncomment below lines to enable)
'If Dir(mPath, vbDirectory) = vbNullString Then
'MkDir mPath
'End If
'### Get Email subject & set name to be saved as ###
emailSubject = CleanFileName(oMail.Subject)
saveName = Format(oMail.ReceivedTime, "yyyymmdd") & "_" & emailSubject & ".txt"
Set fso = CreateObject("Scripting.FileSystemObject")
'### If don't overwrite is on then ###
If blnOverwrite = False Then
looper = 0
Do While fso.FileExists(yPath & saveName)
looper = looper + 1
saveName = Format(oMail.ReceivedTime, "yyyymmdd") & "_" & emailSubject & "_" & looper & ".txt"
Loop
Else '### If don't overwrite is off, delete the file ###
If fso.FileExists(yPath & saveName) Then
fso.DeleteFile yPath & saveName
End If
End If
'### Save MSG File ###
oMail.SaveAs bPath & saveName, olTXT
'### If Mail Attachments: clean file name, save into path ###
If oMail.Attachments.Count > 0 Then
For Each atmt In oMail.Attachments
atmtName = CleanFileName(atmt.FileName)
atmtSave = bPath & Format(oMail.ReceivedTime, "yyyymmdd") & "_" & atmtName
atmt.SaveAsFile atmtSave
Next
End If
Set oMail = Nothing
Set olNS = Nothing
Set fso = Nothing
End Sub
Function CleanFileName(strText As String) As String
Dim strStripChars As String
Dim intLen As Integer
Dim i As Integer
strStripChars = "/\[]:=," & Chr(34)
intLen = Len(strStripChars)
strText = Trim(strText)
For i = 1 To intLen
strText = Replace(strText, Mid(strStripChars, i, 1), "")
Next
CleanFileName = strText
End Function
Sub SaveAsPDF(MyMail As MailItem)
' requires reference to Microsoft Scripting Runtime
' \Windows\System32\Scrrun.dll
' Also requires reference to Microsoft Word Object Library
Dim fso As FileSystemObject
Dim strSubject As String
Dim strSaveName As String
Dim blnOverwrite As Boolean
Dim strFolderPath As String
Dim looper As Integer
Dim strID As String
Dim olNS As Outlook.NameSpace
Dim oMail As Outlook.MailItem
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)
'Get Sender email domain
sendEmailAddr = oMail.SenderEmailAddress
companyDomain = Right(sendEmailAddr, Len(sendEmailAddr) - InStr(sendEmailAddr, "#"))
' ### USER OPTIONS ###
blnOverwrite = False ' False = don't overwrite, True = do overwrite
'### THIS IS WHERE SAVE LOCATIONS ARE SET ###
bPath = "C:\email\" 'Defines the base path to save the email
cPath = bPath & companyDomain & "\" 'Adds company domain to base path
yPath = cPath & Format(Now(), "yyyy") & "\" 'Add year subfolder
mPath = yPath & Format(Now(), "MMMM") & "\" 'Add month subfolder
'### Path Validity ###
If Dir(bPath, vbDirectory) = vbNullString Then
MkDir bPath
End If
'If Dir(cPath, vbDirectory) = vbNullString Then
' MkDir cPath
'End If
'If Dir(yPath, vbDirectory) = vbNullString Then
' MkDir yPath
'End If
'### Get Email subject & set name to be saved as ###
emailSubject = CleanFileName(oMail.Subject)
saveName = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & ".mht"
Set fso = CreateObject("Scripting.FileSystemObject")
'### If don't overwrite is on then ###
If blnOverwrite = False Then
looper = 0
Do While fso.FileExists(bPath & saveName)
looper = looper + 1
saveName = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & "_" & looper & ".mht"
pdfSave = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & "_" & looper & ".pdf"
Loop
Else '### If don't overwrite is off, delete the file ###
If fso.FileExists(bPath & saveName) Then
fso.DeleteFile bPath & saveName
End If
End If
oMail.SaveAs bPath & saveName, olMHTML
pdfSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & ".pdf"
'### Open Word to convert file to PDF ###
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
Set wrdDoc = wrdApp.Documents.Open(FileName:=bPath & saveName, Visible:=True)
wrdApp.ActiveDocument.ExportAsFixedFormat OutputFileName:= _
pdfSave, ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=0, To:=0, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
wrdDoc.Close
wrdApp.Quit
'### Clean up files ###
With New FileSystemObject
If .FileExists(bPath & saveName) Then
.DeleteFile bPath & saveName
End If
End With
'### If Mail Attachments: clean file name, save into path ###
If oMail.Attachments.Count > 0 Then
For Each atmt In oMail.Attachments
atmtName = CleanFileName(atmt.FileName)
atmtSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & atmtName
atmt.SaveAsFile atmtSave
Next
End If
Set oMail = Nothing
Set olNS = Nothing
Set fso = Nothing
End Sub
This works really well once you delete the if statements that delete the file. Thank you for the foundation.
I've modified the PDF portion of your code (for the better, I hope) and fixed an issue that the pdf filename would not increment if it existed already. I had to write a separate loop for the PDF because you basically stopped the loop with this line: pdfSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & ".pdf" but I can't seem to get rid of that line without producing an error so made a new loop. Maybe someone can simplify that part for me.
I've also added a line to delete the .mht file only used to create the PDF and modified the filenames a bit:
Function CleanFileName(strText As String) As String
Dim strStripChars As String
Dim intLen As Integer
Dim i As Integer
strStripChars = "/\[]:=," & Chr(34)
intLen = Len(strStripChars)
strText = Trim(strText)
For i = 1 To intLen
strText = Replace(strText, Mid(strStripChars, i, 1), "")
Next
CleanFileName = strText
End Function
Sub SaveAsPDF(MyMail As MailItem)
' ### Requires reference to Microsoft Scripting Runtime ###
' ### Requires reference to Microsoft Word Object Library ###
' --- In VBE click TOOLS > REFERENCES and check the boxes for both of the above ---
Dim fso As FileSystemObject
Dim strSubject As String
Dim strSaveName As String
Dim blnOverwrite As Boolean
Dim strFolderPath As String
Dim sendEmailAddr As String
Dim senderName As String
Dim looper As Integer
Dim plooper As Integer
Dim strID As String
Dim olNS As Outlook.NameSpace
Dim oMail As Outlook.MailItem
Dim bPath, EmailSubject, saveName, pdfSave As String
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)
' ### Get username portion of sender email address ###
sendEmailAddr = oMail.SenderEmailAddress
senderName = Left(sendEmailAddr, InStr(sendEmailAddr, "#") - 1)
' ### USER OPTIONS ###
blnOverwrite = False ' False = don't overwrite, True = do overwrite
' ### Path to save directory ###
bPath = "Z:\email\"
' ### Create Directory if it doesnt exist ###
If Dir(bPath, vbDirectory) = vbNullString Then
MkDir bPath
End If
' ### Get Email subject & set name to be saved as ###
emailSubject = CleanFileName(oMail.Subject)
saveName = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & emailSubject & ".mht"
Set fso = CreateObject("Scripting.FileSystemObject")
' ### Increment filename if it already exists ###
If blnOverwrite = False Then
looper = 0
Do While fso.FileExists(bPath & saveName)
looper = looper + 1
saveName = Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & senderName & "_" & emailSubject & "_" & looper & ".mht"
Loop
Else
End If
' ### Save .mht file to create pdf from Word ###
oMail.SaveAs bPath & saveName, olMHTML
pdfSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & senderName & "_" & emailSubject & ".pdf"
If fso.FileExists(pdfSave) Then
plooper = 0
Do While fso.FileExists(pdfSave)
plooper = plooper + 1
pdfSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & senderName & "_" & emailSubject & "_" & plooper & ".pdf"
Loop
Else
End If
' ### Open Word to convert .mht file to PDF ###
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
' ### Open .mht file we just saved and export as PDF ###
Set wrdDoc = wrdApp.Documents.Open(FileName:=bPath & saveName, Visible:=True)
wrdApp.ActiveDocument.ExportAsFixedFormat OutputFileName:= _
pdfSave, ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=0, To:=0, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
wrdDoc.Close
wrdApp.Quit
' ### Delete .mht file ###
Kill bPath & saveName
' ### Uncomment this section to save attachments ###
'If oMail.Attachments.Count > 0 Then
' For Each atmt In oMail.Attachments
' atmtName = CleanFileName(atmt.FileName)
' atmtSave = bPath & Format(oMail.ReceivedTime, "yyyy-mm-dd-hhmm") & "_" & atmtName
' atmt.SaveAsFile atmtSave
' Next
'End If
Set oMail = Nothing
Set olNS = Nothing
Set fso = Nothing
End Sub
I have noticed the following lines of code:
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)
There is no need to get a new instance of the MailItem class. You can use the instance passed as a parameter.
If fso.FileExists(bPath & saveName) Then
fso.DeleteFile bPath & saveName
It looks like you delete existing files instead of saving a new ones with different names.
You may consider using the datetime (not only the date) marker when saving emails/attachments. Or you may check out whether such file exists on the disk already.
I’m trying to create a VBA macro that saves an email attachment to folder depending on the email address. For example if I receive and email with an attachment from joey#me.com I want to save that attachment to the directory
\server\home\joey
or if I receive it from steve#me.com the attachment should be saved in
\server\home\steve .
And finally I want send a reply email with the name of the file that has been saved. I found some code that almost does what I want but I having a difficult time modifying it. This is all being done in Outlook 2010. This is what I have so far. Any help would be greatly appreciated
Const mypath = "\\server\Home\joe\"
Sub save_to_v()
Dim objItem As Outlook.MailItem
Dim strPrompt As String, strname As String
Dim sreplace As String, mychar As Variant, strdate As String
Set objItem = Outlook.ActiveExplorer.Selection.item(1)
If objItem.Class = olMail Then
If objItem.Subject <> vbNullString Then
strname = objItem.Subject
Else
strname = "No_Subject"
End If
strdate = objItem.ReceivedTime
sreplace = "_"
For Each mychar In Array("/", "\", ":", "?", Chr(34), "<", ">", "|")
strname = Replace(strname, mychar, sreplace)
strdate = Replace(strdate, mychar, sreplace)
Next mychar
strPrompt = "Are you sure you want to save the item?"
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
objItem.SaveAs mypath & strname & "--" & strdate & ".msg", olMSG
Else
MsgBox "You chose not to save."
End If
End If
End Sub
Is this what you are trying? (UNTESTED)
Option Explicit
Const mypath = "\\server\Home\"
Sub save_to_v()
Dim objItem As Outlook.MailItem
Dim strPrompt As String, strname As String, strSubj As String, strdate As String
Dim SaveAsName As String, sreplace As String
Dim mychar As Variant
Set objItem = Outlook.ActiveExplorer.Selection.Item(1)
If objItem.Class = olMail Then
If objItem.Subject <> vbNullString Then
strSubj = objItem.Subject
Else
strSubj = "No_Subject"
End If
strdate = objItem.ReceivedTime
sreplace = "_"
For Each mychar In Array("/", "\", ":", "?", Chr(34), "<", ">", "|")
strSubj = Replace(strSubj, mychar, sreplace)
strdate = Replace(strdate, mychar, sreplace)
Next mychar
strname = objItem.SenderEmailAddress
strPrompt = "Are you sure you want to save the item?"
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
Select Case strname
Case "joey#me.com"
SaveAsName = mypath & "joey\" & strSubj & "--" & strdate & ".msg"
Case "steve#me.com"
SaveAsName = mypath & "steve\" & strSubj & "--" & strdate & ".msg"
End Select
objItem.SaveAs SaveAsName, olMSG
Else
MsgBox "You chose not to save."
End If
End If
End Sub
It will never work. As Outlook 2010 is not saving any msg file to a network drive only local drive is working !!
As described in the documentation of M$ and tested by me.
Simple test with fixed path and filename.
Local c:\ works. Network drive in UNC or L: does not work !!!!