I have a problem with combining two scripts into one, I tried to the script, "createTask" to add as text, "msg2" from the "SaveMessageAsMsg" script.
When I tried to merge it either didn't pull msg2 or the createtask script didn't execute properly.
The lower script is to save the selected email on the local network and extract the address to this saved .msg element, and this address is to be used as text in the JsonString of "createTask" script under msg2.
If anyone has an idea how to combine this I would be very grateful.
Sub send()
Dim Sarasa As Object
Dim x, mailItem As Outlook.mailItem
For Each x In Application.ActiveExplorer.Selection
If TypeName(x) = "MailItem" Then
Set mailItem = x
Call createTask(mailItem)
End If
Next
End Sub
Sub createTask(ByRef mItem As Outlook.mailItem)
Dim kbUrl As String
Dim title As String
Dim kbUsername As String
Dim kbPassword As String
Dim kbProjectId As Integer
Dim kbSwimlaneId As Integer
kbUrl = "https://website.com/jsonrpc.php"
kbUsername = "test"
kbPassword = "test"
kbProjectId = 1
kbSwimlaneId = 1
Set LoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
LoginRequest.Option(4) = 13056
LoginRequest.Open "POST", kbUrl, False
LoginRequest.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
LoginRequest.SetCredentials kbUsername, kbPassword, 0
title = InputBox(mItem.Subject, "Title")
If StrPtr(title) = 0 Then
ElseIf title = vbNullString Then
JsonString = "{""jsonrpc"": ""2.0"", ""method"": ""createTask"",""id"": 1176509098,""params"": {""score"": 0, ""project_id"": """ & kbProjectId & """, ""swimlane_id"":""" & kbSwimlaneId & """ , ""title"":""" & Format(mItem.CreationTime, "ddd hh:nn") & " / " & Split(mItem.SenderName)(1) & " / " & mItem.Subject & """, ""description"":""" & "[LINK](file:" + msg2 & ")" & """}}"
Else
JsonString = "{""jsonrpc"": ""2.0"", ""method"": ""createTask"",""id"": 1176509098,""params"": {""score"": 0, ""project_id"": """ & kbProjectId & """, ""swimlane_id"":""" & kbSwimlaneId & """ , ""title"":""" & Format(mItem.CreationTime, "ddd hh:nn") & " / " & Split(mItem.SenderName)(1) & " / " & title & """, ""description"":""" & "[LINK](file:" + msg2 & ")" & """}}"
End If
LoginRequest.Send JsonString
If LoginRequest.Status = 200 Then
'MsgBox "Mail: " & mItem.Subject & " - Status: " & LoginRequest.responseText
Call buscaError(LoginRequest.responseText, mItem)
Else
MsgBox "The list did not respond - 200 OK"
End If
End Sub
Function buscaError(strBuscar As String, ByRef mItem As Outlook.mailItem)
Dim useCategory As String
useCategory = "LIST"
Dim olMail As Outlook.mailItem
Dim RegError As RegExp
Dim RegExito As RegExp
Dim M1 As MatchCollection
Dim M As Match
Set olMail = Application.ActiveExplorer().Selection(1)
Set RegError = New RegExp
Set RegExito = New RegExp
With RegError
.Pattern = "(error)"
.Global = True
End With
With RegExito
.Pattern = "(result)"
.Global = True
End With
If RegError.test(strBuscar) Then
'MsgBox "Mail processing error: " & mItem.Subject
ElseIf RegExito.test(strBuscar) Then
Call AddCategory(mItem, useCategory)
'MsgBox "Ok"
End If
End Function
Sub AddCategory(aMailItem As mailItem, newCategory As String)
Dim categories() As String
Dim listSep As String
listSep = CreateObject("WScript.Shell").RegRead("HKEY_CURRENT_USER\Control Panel\International\sList")
categories = Split(aMailItem.categories, listSep)
If UBound(Filter(categories, newCategory)) = -1 Then
ReDim Preserve categories(UBound(categories) + 1)
categories(UBound(categories)) = newCategory
aMailItem.categories = Join(categories, listSep)
aMailItem.Save
End If
End Sub
With this
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 msg2 As String
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 = "\\local.disk\folder"
msg2 = 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
You can split the functions into two separate ones. In both cases you retrieve the currently selected mail item, so after getting the object you can call two separate functions to get the job done.
Sub send()
Dim Sarasa As Object
Dim x, mailItem As Outlook.mailItem
For Each x In Application.ActiveExplorer.Selection
If TypeName(x) = "MailItem" Then
Set mailItem = x
Call createTask(mailItem)
Call SaveMessageAsMsg(mailItem)
End If
Next
End Sub
Sub createTask(ByRef mItem As Outlook.mailItem)
Dim kbUrl As String
Dim title As String
Dim kbUsername As String
Dim kbPassword As String
Dim kbProjectId As Integer
Dim kbSwimlaneId As Integer
kbUrl = "https://website.com/jsonrpc.php"
kbUsername = "test"
kbPassword = "test"
kbProjectId = 1
kbSwimlaneId = 1
Set LoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
LoginRequest.Option(4) = 13056
LoginRequest.Open "POST", kbUrl, False
LoginRequest.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
LoginRequest.SetCredentials kbUsername, kbPassword, 0
title = InputBox(mItem.Subject, "Title")
If StrPtr(title) = 0 Then
ElseIf title = vbNullString Then
JsonString = "{""jsonrpc"": ""2.0"", ""method"": ""createTask"",""id"": 1176509098,""params"": {""score"": 0, ""project_id"": """ & kbProjectId & """, ""swimlane_id"":""" & kbSwimlaneId & """ , ""title"":""" & Format(mItem.CreationTime, "ddd hh:nn") & " / " & Split(mItem.SenderName)(1) & " / " & mItem.Subject & """, ""description"":""" & "[LINK](file:" + msg2 & ")" & """}}"
Else
JsonString = "{""jsonrpc"": ""2.0"", ""method"": ""createTask"",""id"": 1176509098,""params"": {""score"": 0, ""project_id"": """ & kbProjectId & """, ""swimlane_id"":""" & kbSwimlaneId & """ , ""title"":""" & Format(mItem.CreationTime, "ddd hh:nn") & " / " & Split(mItem.SenderName)(1) & " / " & title & """, ""description"":""" & "[LINK](file:" + msg2 & ")" & """}}"
End If
LoginRequest.Send JsonString
If LoginRequest.Status = 200 Then
'MsgBox "Mail: " & mItem.Subject & " - Status: " & LoginRequest.responseText
Call buscaError(LoginRequest.responseText, mItem)
Else
MsgBox "The list did not respond - 200 OK"
End If
End Sub
Function buscaError(strBuscar As String, ByRef mItem As Outlook.mailItem)
Dim useCategory As String
useCategory = "LIST"
Dim olMail As Outlook.mailItem
Dim RegError As RegExp
Dim RegExito As RegExp
Dim M1 As MatchCollection
Dim M As Match
Set olMail = Application.ActiveExplorer().Selection(1)
Set RegError = New RegExp
Set RegExito = New RegExp
With RegError
.Pattern = "(error)"
.Global = True
End With
With RegExito
.Pattern = "(result)"
.Global = True
End With
If RegError.test(strBuscar) Then
'MsgBox "Mail processing error: " & mItem.Subject
ElseIf RegExito.test(strBuscar) Then
Call AddCategory(mItem, useCategory)
'MsgBox "Ok"
End If
End Function
Sub AddCategory(aMailItem As mailItem, newCategory As String)
Dim categories() As String
Dim listSep As String
listSep = CreateObject("WScript.Shell").RegRead("HKEY_CURRENT_USER\Control Panel\International\sList")
categories = Split(aMailItem.categories, listSep)
If UBound(Filter(categories, newCategory)) = -1 Then
ReDim Preserve categories(UBound(categories) + 1)
categories(UBound(categories)) = newCategory
aMailItem.categories = Join(categories, listSep)
aMailItem.Save
End If
End Sub
Public Sub SaveMessageAsMsg(ByVal oMail As Outlook.mailItem)
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Dim msg2 As String
sName = oMail.Subject
ReplaceCharsForFileName sName, "-"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".msg"
sPath = "\\local.disk\folder"
msg2 = sPath & sName
oMail.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, ":", 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
Related
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
When the code constructs my email subject line, adding the date and time, it also adds a big space before the .msg file extension.
If I don't delete the space when the message box comes up for me to check the saving location, the code jumps to the error handler.
If I delete the space (which looks like 4 or 5 spaces), the file saves correctly.
Dim oMail As Outlook.MailItem
Dim objItem As Object
Dim atch As Attachment
Dim sPath, strFolderPath As String
Dim strPath As String
Dim strFile As String
Dim strPathFile As String
Dim answer As String
Dim dtDate As Date
Dim sName As String
Dim enviro As String
Dim jobNumber As String
On Error GoTo errHandler
enviro = CStr(Environ("USERPROFILE"))
jobNumber = InputBox("Please enter job number", "Saving to Job Folder", "Enter Job Number Here")
If jobNumber = "" Then Exit Sub
'create default name for saving file
If IsNumeric(jobNumber) Then
strFile = Int(jobNumber / 100) & "00-" & Int(jobNumber / 100) & "99\" & jobNumber & "\"
Else
strFile = ""
End If
strPathFile = "\\vacdc\VCI JOBS\" & strFile
If Dir(strPathFile, vbDirectory) = vbNullString Then
strFile = Int(jobNumber / 100) & "00-" & Int(jobNumber / 100) & "99\"
strPathFile = "\\vacdc\VCI JOBS\" & strFile
End If
answer = MsgBox(strPathFile, vbYesNoCancel + vbQuestion, "Save emails here?")
If answer = vbYes Then
sPath = strPathFile
Else
If answer = vbCancel Then GoTo exitHandler
strFolderPath = BrowseForFolder("\\vacdc\VCI JOBS\")
sPath = strFolderPath & "\"
End If
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, " mm-dd-yyyy", vbUseSystemDayOfWeek, _
vbUseSystem) & " " & sName & ".msg"
sName = InputBox("", "", sName)
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMSG
I was asked to add this subroutine that my code from earlier post calls:
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
The code where the Subject property is used:
sName = oMail.Subject
ReplaceCharsForFileName sName, "_"
dtDate = oMail.ReceivedTime
sName = Format(dtDate, " mm-dd-yyyy", vbUseSystemDayOfWeek, _
vbUseSystem) & " " & sName & ".msg"
sName = InputBox("", "", sName)
Debug.Print sPath & sName
oMail.SaveAs sPath & sName, olMSG
I'd suggest grabbing the subject string and try to save any file with such name. Are you able to get the file saved?
If the pure subject line works correctly as a file name, than I'd suggest checking the parameter string passed to the SaveAs method. Most probably it contains forbidden symbols. The forbidden printable ASCII characters on Windows are:
< (less than)
> (greater than)
: (colon - sometimes works, but is actually NTFS Alternate Data Streams)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
See What characters are forbidden in Windows and Linux directory names? for more information.
Finally, I'd suggest using string functions to replace forbidden symbols with allowed ones. For example, you may find the VBA Replace function helpful.
I am curious to know as to why every response email and forwarded emails are not being saved with the .msg file extension. Instead, they are being saved as .file extension. Any reason as to why this is happening and how to fix the problem? This is the code that I am working on right now.
Public Sub SaveMsgs(Item As Outlook.MailItem)
'Declare Variables
Dim sPath As String
Dim dtDate As Date
Dim sName As String
Dim sSubject As String
Dim enviro As String
Dim sSender As String
Dim strFolder As String
Dim strNewFolder As String
Dim save_to_folder As String
'enviro = CStr(Environ("USERPROFILE"))
ReplaceCharsForFileName sName, "_"
sSender = Item.Sender
dtDate = Item.ReceivedTime
'sName = sSender & " - " & sSubject & ".msg"
'Set Folder path
strNewFolder = Format(dtDate, "mm-dd-yyyy")
strFolder = "C:\IT Documents\" & strNewFolder & "\"
'Determine if there is subject
If Len(Item.Subject) > 0 Then
sSubject = Item.Subject
Else
sSubject = "No Subject "
End If
'Determine if folder is in the directory
If Len(Dir(strFolder, vbDirectory)) = 0 Then
MkDir (strFolder)
End If
sName = sSender & " - " & sSubject
save_to_folder = strFolder
Item.SaveAs save_to_folder & sName & ".msg"
End Sub
make sure you reference
Microsoft Scripting Runtime
Microsoft outlook Object Library
Microsoft Word Object Library
the following code has been tested on Outlook 2010
Option Explicit
'// Save the message as a native .msg
Public Sub SaveMsg(Item As Outlook.MailItem)
Dim fso As FileSystemObject
Dim olNS As Outlook.NameSpace
Dim SavePath As String
Dim TimeDate As Date
Dim SaveName As String
Dim Enviro As String
Dim NewFolder As String
Dim EmailSubject As String
'// enviro gets the user account part of the path
'// so you can use the same code on different computers
Set olNS = Application.GetNamespace("MAPI")
ReplaceCharsForFileName SaveName, "_"
'// Use My Documents for older Windows.
NewFolder = "C:\IT Documents\" & Format(Now, "YYYY-MM-DD") & "\"
'// Test if directory or file exists
If FileOrDirExists(NewFolder) Then
MsgBox NewFolder & " exists!"
Else
MkDir NewFolder
End If
EmailSubject = FileName(Item.Subject)
'// Determine if there is subject
If Item.Subject <> vbNullString Then
EmailSubject = Item.Subject
Else
EmailSubject = "No Subject"
End If
'// Get Email subject & set name to be saved as
TimeDate = Item.ReceivedTime
SaveName = Format(TimeDate, "YYYYMMDD", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(TimeDate, "-HHNNSS", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & EmailSubject & SaveName & ".msg"
Set fso = CreateObject("Scripting.FileSystemObject")
'// Save .msg File
SavePath = "C:\IT Documents\" & NewFolder & "\"
Debug.Print NewFolder & SaveName
Item.SaveAs NewFolder & SaveName, olMsg
End Sub
'// This function removes invalid and other characters from file names
Private Sub ReplaceCharsForFileName(SaveName As String, _
sChr As String _
)
SaveName = Replace(SaveName, "/", sChr)
SaveName = Replace(SaveName, "\", sChr)
SaveName = Replace(SaveName, ":", sChr)
SaveName = Replace(SaveName, "?", sChr)
SaveName = Replace(SaveName, Chr(34), sChr)
SaveName = Replace(SaveName, "<", sChr)
SaveName = Replace(SaveName, ">", sChr)
SaveName = Replace(SaveName, "|", sChr)
SaveName = Replace(SaveName, "&", sChr)
SaveName = Replace(SaveName, "%", sChr)
SaveName = Replace(SaveName, "*", sChr)
SaveName = Replace(SaveName, " ", sChr)
SaveName = Replace(SaveName, "{", sChr)
SaveName = Replace(SaveName, "[", sChr)
SaveName = Replace(SaveName, "]", sChr)
SaveName = Replace(SaveName, "}", sChr)
SaveName = Replace(SaveName, "!", sChr)
End Sub
'// Good practice suggests that it is wise to check before taking certain actions
'// This function checks if File or Dir Exists
Function FileOrDirExists(PathName As String) As Boolean
Dim iTemp As Integer
'// Ignore errors to allow for error evaluation
On Error Resume Next
iTemp = GetAttr(PathName)
'// Check if error exists and set response appropriately
Select Case Err.Number
Case Is = 0
FileOrDirExists = True
Case Else
FileOrDirExists = False
End Select
'// Resume error checking
On Error GoTo 0
End Function
Function FileName(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
FileName = strText
End Function
good luck.
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 am trying to transfer emails en masse from Outlook 2007 to my C:/ drive. The the idea is to save emails based on their subject and the date as an easy to read identifier.
There is a runtime error when there are two emails with the same subject and date stamp, a naming collision if you will.
Can I add a unique sequential number or a fraction of a second to the file name?
In .NET, I would just add ss^ff or something, but I do not know how to do this with visual basic for applications.
*
Public Sub SaveAllMailsAsFile1()
Dim obj As Object
Dim oItems As Outlook.Items
Dim i As Long
Set oItems = Application.Session.GetDefaultFolder(olFolderInbox).Folders("Acton").Items
For i = oItems.Count To 1 Step -1
Set obj = oItems(i)
If TypeOf obj Is Outlook.MailItem Then
SaveMailAsFile obj, "C:\Users\gasparm\Desktop\MB Emails\Acton\"
End If
Next
End Sub
Private Sub SaveMailAsFile(oMail As Outlook.MailItem, _
sPath As String _
)
Dim dtDate As Date
Dim sName As String
Dim sFile As String
Dim sExt As String
sExt = ".msg"
' Remove invalid file name characters
sName = oMail.Subject
ReplaceCharsForFileName sName, "_"
' Build file name from subject and received date
dtDate = oMail.ReceivedTime
sName = Format(dtDate, "yyyy-mmm-dd HH.mm.ss ", vbMonday, vbFirstJan1) _
& " - " & sName & sExt
oMail.SaveAs sPath & sName, olMSG
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
*
Probably not the prettiest, but try something like this.
Dim ver as long
Dim sValidSubjectName As String
' Remove invalid file name characters
sValidSubjectName = oMail.Subject
ReplaceCharsForFileName sValidSubjectName, "_"
ver = 0
' Build file name from subject and received date
dtDate = oMail.ReceivedTime
uniqueName:
sName = Format(dtDate, "yyyy-mmm-dd HH.mm.ss ", vbMonday, vbFirstJan1) _
& " - " & sValidSubjectName & ver & sExt
If Dir(sPath & sName) = "" Then
oMail.SaveAs sPath & sName, olMSG
Else
ver = ver + 1
Goto uniqueName
End If