Save current email and recreate it as new mail - vba

I need a macro for Outlook that will do:
Saves the open e-mail as email.msg (including attachments)
Closes the curent e-mail window
Creates a new email, which is read from email.msg (from step 1.)
I did some research on google, but nothing works for me.
This is what i've done so far (the 1. step.. but not working)
Option Explicit
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
enviro = CStr(Environ("USERPROFILE"))
For Each objItem In ActiveExplorer.Selection
If objItem.MessageClass = "IPM.Note" Then
Set oMail = objItem
sName = oMail.Subject
ReplaceCharsForFileName sName, "email"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
sPath = enviro & "\Documents\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMsg
'this closes window:
Dim myinspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Set myinspector = Application.ActiveInspector
Set myItem = myinspector.CurrentItem
myItem.Close olSave
End If
Next
End Sub

Option Explicit
Sub SaveCurrentItemAsMsg()
Dim oMail As MailItem
Dim objItem As Object
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Dim enviro As String
Dim myItem As MailItem
enviro = CStr(Environ("USERPROFILE"))
Set objItem = ActiveInspector.currentItem
If objItem.MessageClass = "IPM.Note" Then
Set oMail = objItem
sName = oMail.Subject
ReplaceCharsForFileName sName, "email"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
sPath = enviro & "\Documents\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMsg
oMail.Close olDiscard
Set oMail = Nothing
Set myItem = Session.OpenSharedItem(sPath & sName)
myItem.Display
End If
End Sub
Sub SaveSelectedMessagesAsMsg()
Dim oMail As MailItem
Dim objItem As Object
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Dim enviro As String
Dim myItem As MailItem
enviro = CStr(Environ("USERPROFILE"))
For Each objItem In ActiveExplorer.Selection
If objItem.MessageClass = "IPM.Note" Then
Set oMail = objItem
sName = oMail.Subject
ReplaceCharsForFileName sName, "email"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
sPath = enviro & "\Documents\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMsg
Set myItem = Session.OpenSharedItem(sPath & sName)
myItem.Display
End If
Next
End Sub

Related

How to copy email to clipboard to save as a file in Windows folder?

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

Outlook Button in Ribbon for saving mail (incoming and outgoing) to nominated destination in new folder

I want to create a button in Outlook that saves an incoming mail in a folder named:
"yyyymmdd - {sender's initials} - {email subject}".
Similarly, I need a button for outgoing mail that needs to be saved in a folder named:
"yyyymmdd - {email subject}".
Since I work in a variety of directories, a user input will be required to specify the project number where the relevant mail needs to go, ie:
C:\Users\User.Name{project_name_input}.
I tried some VBA scripts, but I am not good at it. I haven't gotten close to a solution.
I have managed to solve this by using some script found at the link below and some modifications to make it work the way I wanted on my machine:
https://www.slipstick.com/developer/code-samples/save-selected-message-file/
The script:
Option Explicit
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
Dim ShellApp As Object
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
Set ShellApp = Nothing
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
BrowseForFolder = False
End Function
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 mSender As String
Dim sendName As String
Dim sendSurname As String
Dim strFolderpath As String
Dim fName As String
Dim objAttachments As Outlook.Attachments
Dim i As Long
Dim lngCount As Long
Dim objOL As Outlook.Application
Dim StrFile As String
enviro = CStr(Environ("USERPROFILE"))
strFolderpath = BrowseForFolder(enviro)
For Each objItem In ActiveExplorer.Selection
If objItem.MessageClass = "IPM.Note" Then
Set oMail = objItem
sName = oMail.Subject
sName = Replace(sName, "FW: ", "")
sName = Replace(sName, "RE: ", "")
ReplaceCharsForFileName sName, "-"
mSender = oMail.Sender
sendName = Split(mSender)(0)
sendName = Left(sendName, 1)
sendSurname = Split(mSender)(1)
sendSurname = Left(sendSurname, 1)
dtDate = oMail.ReceivedTime
fName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & " - " & sendName & sendSurname & " - " & sName
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & " - " & sName & ".msg"
CreateIncomeFolder strFolderpath, fName
sPath = strFolderpath & fName & "\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMSG
End If
Next
Set objOL = Outlook.Application
Set objItem = objOL.ActiveExplorer.Selection.Item(1)
Set objAttachments = objItem.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = lngCount To 1 Step -1
If objAttachments.Item(i).Size > 10000 Then
StrFile = objAttachments.Item(i).FileName
Debug.Print StrFile
StrFile = sPath & StrFile
objAttachments.Item(i).SaveAsFile StrFile
End If
Next i
End If
End Sub
Public Sub SaveOutogingMessageAsMsg()
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 mSender As String
Dim strFolderpath As String
Dim fName As String
enviro = CStr(Environ("USERPROFILE"))
strFolderpath = BrowseForFolder(enviro)
For Each objItem In ActiveExplorer.Selection
If objItem.MessageClass = "IPM.Note" Then
Set oMail = objItem
sName = oMail.Subject
sName = Replace(sName, "FW: ", "")
sName = Replace(sName, "RE: ", "")
ReplaceCharsForFileName sName, "-"
mSender = oMail.Sender
sName = Replace(sName, "FW- ", "")
sName = Replace(sName, "RE- ", "")
dtDate = oMail.ReceivedTime
fName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & " - " & sName
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & " - " & sName & ".msg"
CreateFolder strFolderpath, fName
sPath = strFolderpath & fName & "\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMSG
End If
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, ":", 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
Sub CreateFolder(strFolderpath As String, fName As String)
On Error GoTo eh
MkDir strFolderpath & fName
Exit Sub
eh:
MsgBox "Message has already been saved", vbOKOnly
End Sub
Sub CreateIncomeFolder(strFolderpath As String, fName As String)
On Error GoTo eh
MkDir strFolderpath & fName
Exit Sub
eh:
MsgBox "Message has already been saved", vbOKOnly
End Sub

Exporting new email to file

There are a few sources from which we receive specific emails. The easiest way to categorize them is by mail title or even source email address.
We are trying to automatically save all incoming emails to file, whether it's a TXT or PDF so we can pull up a back up file when there is a problem with the network, email or whatever else is malfunctioning.
I tried to create a macro from a few similar topics;
Private Sub Application_Startup()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set Items = Inbox.Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
SaveMailAsFile Item ' call sub
End If
End Sub
Public Sub SaveMailAsFile(ByVal Item As Object)
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim SubFolder As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim ItemSubject As String
Dim NewName As String
Dim RevdDate As Date
Dim Path As String
Dim Ext As String
Dim i As Long
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set Items = Inbox.Items.Restrict("[Subject] = 'VVAnalyze Results'")
Path = Environ("USERPROFILE") & "\Desktop\Backup Reports\"
ItemSubject = Item.Subject
RevdDate = Item.ReceivedTime
Ext = "txt"
For i = Items.Count To 1 Step -1
Set Item = Items.Item(i)
DoEvents
If Item.Class = olMail Then
Debug.Print Item.Subject ' Immediate Window
Set SubFolder = Inbox.Folders("Temp") ' <--- Update Fldr Name
ItemSubject = Format(RevdDate, "YYYYMMDD-HHNNSS") _
& " - " & _
Item.Subject & Ext
ItemSubject = FileNameUnique(Path, ItemSubject, Ext)
Item.SaveAs Path & ItemSubject, olTXT
Item.Move SubFolder
End If
Next
Set olNs = Nothing
Set Inbox = Nothing
Set SubFolder = Nothing
Set Items = Nothing
End Sub
'// Check if the file exists
Private Function FileExists(FullName As String) As Boolean
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(FullName) Then
FileExists = True
Else
FileExists = False
End If
Exit Function
End Function
'// If the same file name exist then add (1)
Private Function FileNameUnique(Path As String, _
FileName As String, _
Ext As String) As String
Dim lngF As Long
Dim lngName As Long
lngF = 1
lngName = Len(FileName) - (Len(Ext) + 1)
FileName = Left(FileName, lngName)
Do While FileExists(Path & FileName & Chr(46) & Ext) = True
FileName = Left(FileName, lngName) & " (" & lngF & ")"
lngF = lngF + 1
Loop
FileNameUnique = FileName & Chr(46) & Ext
Exit Function
End Function
While I understand that Outlook cache is available even off line some are insisting to have back up files on a physical hard drive.
I know I could manually select those files and create a copy by drag&drop but that is insufficient.
I am aware of
https://www.techhit.com/messagesave/screenshots.html. It would be difficult to have this idea accepted because GDPR blah blah blah.
You could use this code, paste it in the ThisOutlookSession module.
To test this code sample without restarting Outlook, click in the Application_Startup procedure then click Run.
Option Explicit
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim Ns As Outlook.NameSpace
Set Ns = Application.GetNamespace("MAPI")
Set Items = Ns.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Dim enviro As String
enviro = CStr(Environ("USERPROFILE"))
sName = Item.Subject
ReplaceCharsForFileName sName, "_"
dtDate = Item.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
' use My Documents for older Windows.
sPath = enviro & "\Documents\"
Debug.Print sPath & sName
Item.SaveAs sPath & sName, olMSG
End If
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
For more information, please refer to this link:
Save all incoming messages to the hard drive
Save outlook mail automatically to a specified folder

Saving messages of MessageClass IPM.Note.EnterpriseVault.Shortcut to desktop folder

I'm trying to save selected messages in Outlook on a tempfolder on my Desktop.
Public Sub SaveMessageAsMsg1()
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
enviro = CStr(Environ("USERPROFILE"))
For Each objItem In ActiveExplorer.Selection
If objItem.MessageClass = "IPM.Note*" Then
Set oMail = objItem
sName = oMail.Subject
ReplaceCharsForFileName sName, "-"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek,vbUseSystem) & Format(dtDate, "-hhnnss", vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
sPath = "C:\Users\XBBLC1C\Desktop\TempEmail\"
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMSG
End If
Next
End Sub
Some of the messages are already archived in Enterprise vault and while saving those messages objItem.MessageClass generates the value IPM.Note.EnterpriseVault.Shortcut.
To accommodate this I tried an asterisk with IPM.Note in the above code.
I don't know exactly what you're trying to do, but the line:
If objItem.MessageClass = "IPM.Note*" Then
is likely not going to do the comparison you are hoping for. While '*' is a wildcard character in certain circumstances, it isn't for a string comparison like this.
I'd suggest trying:
If inStr(objItem.MessageClass, "IPM.Note") <> 0 Then
which will be true if "IPM.Note" is anywhere in the message class
OR
If InStr(objItem.MessageClass, "IPM.Note") = 1 Then
which will be true if "IPM.Note" is at the beginning of the message class.
Similarly you could use
If objItem.MessageClass like "IPM.Note*" Then
if you want something closer to what you were originally writing.
You can do what OpiesDad suggested and check the MessageClass property, or you can check the MailItem.Class property - for regular MailItem objects, it will be 43 (OlObjectClass.olMail):
If objItem.Class = 43 Then
...

Outlook .Restrict method does not work with Date

Restrict() does not seem to accept a date value when it is specified outside.
Public Sub EBS()
Dim oMail As MailItem
Dim sPath As String
Dim dtDate As Date
Dim dtRecDate As Date
Dim sName As String
Dim oNameSpace As Outlook.NameSpace
Dim oInboxFolder As Outlook.Folder
Dim oSentFolder As Outlook.Folder
Dim i As Long
Set oNameSpace = Application.GetNamespace("MAPI")
Set oInboxFolder = oNameSpace.GetDefaultFolder(olFolderInbox)
Set oSentFolder = oNameSpace.GetDefaultFolder(olFolderSentMail)
dtRecDate = DateAdd("d", -180, Now)
Set setItems = oInboxFolder.Items
Set RestrictedItems = setItems.Restrict("[ReceivedTime] < dtRecDate AND [MessageClass] = 'IPM.Note'")
For i = RestrictedItems.Count To 1 Step -1
Set oMail = RestrictedItems.item(i)
sName = oMail.Subject
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, vbUseSystem) & Format(dtDate, "_hhnnss", vbUseSystemDayOfWeek, vbUseSystem) & "_" & sName & ".msg"
sName = Left(sName, 256)
sPath = "C:\ARCHIVE\OUTLOOK\Inbox\"
Debug.Print dtRecDate
oMail.SaveAs sPath & sName, olMSG
oMail.Delete
Next i
End Sub
The restriction works when, for example, '2014/06/13' is used instead of dtRecDate.
When dtRecDate is used, it does not restrict any item.
Can you please help?
I see the following filter criteria in the code:
"[ReceivedTime] < dtRecDate AND [MessageClass] = 'IPM.Note'"
You can't declare object in the string. It will not be converted to string automatically. You have to do so in the code, for example:
"[ReceivedTime] < '" + Format(Date, "yyyy/mm/dd") +"' AND [MessageClass] = 'IPM.Note'"
The Restrict method has the following sample on the page in MSDN:
sFilter = "[LastModificationTime] > '" & Format("1/15/99 3:30pm", "ddddd h:nn AMPM") & "'"