Save msg file as htm - excel

I am trying to save a list of email in msg format to htm format so that Xceptor tool can read the email as pdf. (Without a vba, Currently I manually open the email in Outlook and save as htm one by one.)
I found below script but I get
"Run Time error 287: Application-defined or object-defined error".
Sub SaveMSG_as_HTML()
Dim olMsg As MailItem
Dim strPath As String
Dim strMsg As String
Dim strHTML As String
strPath = "\\Hbap.adroot.hsbc\hk\Finance\224017\AMH_A2R_2\WRK\AAC\PL\To GFC\Movement Table\MvtXceptor\Configuration\Table18.1\"
strMsg = "RE CRR Inquiry as atJan-00-00 - --.msg"
strHTML = Left(strMsg, InStrRev(strMsg, Chr(46))) & "html"
Set olMsg = Session.OpenSharedItem(strPath & strMsg)
olMsg.SaveAs Path:=strPath & strHTML, Type:=olHTML
olMsg.Close olDiscard
lbl_Exit:
Set olMsg = Nothing
Exit Sub
End Sub

Without a vba, i need to open the email in outlook and save as htm one by one.
Without VBA? So I guess you want to use VBScript? Say, directly run it from desktop by clicking on the .vbs file? If yes, then you need to declare and create/get the outlook object before you can work with it. Otherwise how will your code know what is Session? Also olHTML and olDiscard are Outlook constants. VbScript will not know what they are.
Is this what you are trying? Paste this in Notepad and save it as Sample.Vbs
Private Const olHTML = 5
Private Const olDiscard = 1
Dim OutApp
Dim olMsg
Dim nsOutlook
Dim strPath
Dim strMsg
Dim strHTML
'~~> I used these values for testing. Change as applicable
strPath = "C:\Temp\"
strMsg = "test.msg"
strHTML = "test.html"
Set OutApp = CreateObject("Outlook.Application")
Set nsOutlook = OutApp.GetNamespace("MAPI")
Set olMsg = nsOutlook.OpenSharedItem(strPath & strMsg)
olMsg.SaveAs strPath & strHTML, olHTML
olMsg.Close olDiscard
Set olMsg = Nothing
Set nsOutlook = Nothing
Set OutApp = Nothing

Related

VBA Excel File staying open in the background

I am currently using a module on Microsoft Access to Open an Excel file and paste the results into an email. The module is working properly, but the Excel file is remaining open in the background. This is causing an issue when I try to run the same module using the same file.
The Excel file I am using also automatically updates a date field, so I also need the close call to save the file beforehand, or ignore the save changes pop-up.
Public Function emailPaste(exFile As String, exSheet As String, exRange As String, _
EmailSubject As String, To_Field As String, Optional CC_Field As String)
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim ApXL As Object
Set ApXL = CreateObject("Excel.Application")
ApXL.Workbooks.Open (exFile)
Set rng = Nothing
' Only send the visible cells in the selection.
Set rng = Sheets(exSheet).Range(exRange).SpecialCells(xlCellTypeVisible)
'If rng Is Nothing Then
'MsgBox "The selection is not a range or the sheet is protected. " & _
vbNewLine & "Please correct and try again.", vbOKOnly
'Exit Sub
'End If
With ApXL.Application
.EnableEvents = False
.ScreenUpdating = False
End With
Call OpenOutlook
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = To_Field
.CC = CC_Field
.Subject = EmailSubject
.HTMLBody = "<BODY style=font-size:12pt;font-family:Calibri> The report: " & EmailSubject & " " & _
"is pasted below. <br><br> Please review it and contact me if there are any issues.<br><br> " _
& RangetoHTML(rng) & ""
' In place of the following statement, you can use ".Display" to
' display the e-mail message.
.Display
End With
On Error GoTo 0
With ApXL.Application
.EnableEvents = True
.ScreenUpdating = True
End With
ApXL.Quit
Set ApXL = Nothing
Set OutMail = Nothing
Set OutApp = Nothing
End Function
How can I add at the end the code needed to save the excel file and close it without any user intervention?
You must be very strict in opening the Excel objects and closing them in reverse order - as done in this example:
Public Sub RenameWorkSheet()
Dim xls As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Set xls = New Excel.Application
Set wkb = xls.Workbooks.Open("c:\test\workbook1.xlsx")
Set wks = wkb.Worksheets(1)
wks.Name = "My New Name"
wkb.Close True
Set wks = Nothing
Set wkb = Nothing
xls.Quit
Set xls = Nothing
End Sub
You should try to tell the Application, that the Worksheet is saved
as it is.
Then Close the Worksheet
Then try to Close the Application.
something like this:
exFile.Sheets(exSheet).Saved = True
exFile.Sheets(exSheet).Close
ApXL.Quit
Or tell, that it doesn't have to save on closing...:
exFile.Sheets(exSheet).Close False
ApXL.Quit
I'd also propose, that you should store a direct reference to the Sheet and not implicitly calling the sheet via the active window...
Something like
dim wsh as Worksheet
set wsh = exFile.Sheets(exSheet)
then you can work with the variable wsh... more comfortable

Attach created Word doc to Outlook Message

I have read numerous responses that are close to what I am looking for, but each time it doesn't work in my code.
This should be a pretty basic question, but I am hoping someone can look at this and see my error quickly.
I am using Excel to create a Word Doc which is then saved on the users Desktop in a folder named with the current date.
Everything works perfectly, but now all I am trying to do is add to the Word doc the name of the string "IRN" which is a cell in the Excel worksheet.
I also need to attach the created Word doc to an Outlook message.
I will only include the intro and end of my code as the body should not matter.
Sub TDOutlook()
Dim TD As Word.Application
Dim Doc As Word.Document
Dim path As String
Dim filename As String
Dim StudentName As String
Dim StudentAddress1 As String
Dim City As String
Dim MrMrs As String
Dim StudentLast As String
Dim IRN As String
Dim CourseReq As String
Dim CourseName As String
Dim CourseStart As String
Dim Cost As String
Dim Deferred As String
Dim Graphic As String
Dim Footer1 As Word.Range
Dim Body As Word.Paragraph
Dim OutApp As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
path = Environ("USERPROFILE") & "\Desktop\" & Format(Now, "mm-dd-yyyy")
On Error Resume Next
MkDir path
On Error GoTo 0
'Outlook
Set OutApp = CreateObject("Outlook.Application")
Set objOutlookMsg = OutApp.CreateItem(olMailItem)
objOutlookMsg.SentOnBehalfOfName = "bbb#ppp.edu"
objOutlookMsg.Subject = "FinServ-TD"
objOutlookMsg.HTMLBody = "Testing this macro" & vbCrLf & vbCrLf
'Display Outlook
objOutlookMsg.Display
'Opens Word
Set TD = CreateObject("Word.Application")
'Displays the document
TD.Visible = False
'Add New Document
Set Doc = TD.Documents.Add
filename = path & "\TD" '& IRN
Doc.SaveAs filename
'Attach Word to Outlook
objOutlookMsg.Attachments.Add Doc.filename <----This is broken
Doc.Close
TD.Quit
'Application.ScreenUpdating = True
End Sub
Everything works perfectly, but now all I am trying to do is add to the Word doc the name of the string "IRN" which is a cell in the Excel worksheet.
To get the Cell Value Try this
FileName = Path & "\TD" & Sheets("Sheet1").Range("A1").Text & ".docx"
I also need to attach the created Word doc to an Outlook message.
To attached saved file, change this
objOutlookMsg.Attachments.Add Doc.filename To this
ObjOutlookMsg.Attachments.Add (FileName)

Open Outlook Mail .msg file using VBA from Excel

I'm trying to open .msg files from a specified directory using VBA but I keep getting a runtime error.
The code i have:
Sub bla()
Dim objOL As Object
Dim Msg As Object
Set objOL = CreateObject("Outlook.Application")
inPath = "C:\Users\SiliconPlus\Desktop\Si+ Contact Lists\Contact_Si+"
thisFile = Dir(inPath & "\*.msg")
Set Msg = objOL.CreateItemFromTemplate(thisFile)
' now use msg to get at the email parts
MsgBox Msg.Subject
Set objOL = Nothing
Set Msg = Nothing
End Sub
Here is the runtime error:
Run-time error '-2147287038 (80030002)':
Cannot open file: AUTO Andy Low Yong Cheng is out of the office (returning 22 09 2014).msg.
The file may not exist, you may not have permission to open it, or it may be open in another program. Right-click the folder that contains the file, and then click properties to check your permissions for the folder.
Kenneth Li You didn't had the full path when opening the file. Try this:
Sub bla_OK()
Dim objOL As Object
Dim Msg As Object
Set objOL = CreateObject("Outlook.Application")
inPath = "C:\Users\SiliconPlus\Desktop\Si+ Contact Lists\Contact_Si+"
thisFile = Dir(inPath & "\*.msg")
'Set Msg = objOL.CreateItemFromTemplate(thisFile)
Set Msg = objOL.Session.OpenSharedItem(inPath & "\" & thisFile)
' now use msg to get at the email parts
MsgBox Msg.Subject
Set objOL = Nothing
Set Msg = Nothing
End Sub
If you get an error, try the Late Biding (Dim Msg As Object) right under the MsgBox (need to be uncommented) :
Sub Kenneth_Li()
Dim objOL As Outlook.Application
Dim Msg As Outlook.MailItem
Msgbox "If you get an error, try the Late Biding right under this (need to be uncommented)"
'Dim objOL As Object
'Dim Msg As Object
Set objOL = CreateObject("Outlook.Application")
inPath = "C:\Users\SiliconPlus\Desktop\Si+ Contact Lists\Contact_Si+"
thisFile = LCase(Dir(inPath & "\*.msg"))
Do While thisFile <> ""
'Set Msg = objOL.CreateItemFromTemplate(thisFile)
'Or
'Set Msg = objOL.OpenSharedItem(thisFile)
'Set Msg = GetNameSpace("MAPI").OpenSharedItem(thisFile)
'Eventually with Shell command (here for notepad)
'Shell "notepad " & thisFile
Set Msg = objOL.Session.OpenSharedItem(thisFile)
Msg.display
MsgBox Msg.Subject
thisFile = Dir
Loop
Set objOL = Nothing
Set Msg = Nothing
End Sub
Or you can find a nice VB solution there : http://www.mrexcel.com/forum/excel-questions/551148-open-msg-file-using-visual-basic-applications.html#post2721847
And here for more details on Shell method : http://p2p.wrox.com/access-vba/27776-how-open-msg-file-vbulletin.html#post138411
Another way is to run the file programmatically (in VBA use the Shell command). It will be opened in Outlook where you can get an active inspector window with the item opened.
You should check follow code and can modify your code
Sub CreateFromTemplate()
Dim MyItem As Outlook.MailItem
Set MyItem = Application.CreateItemFromTemplate("C:\temp\*.msg")
MyItem.Display
End Sub
Try this
Sub GetMSG()
' True includes subfolders
' False to check only listed folder
ListFilesInFolder "C:\Users\lengkgan\Desktop\Testing", True
End Sub
Sub ListFilesInFolder(SourceFolderName As String, IncludeSubfolders As Boolean)
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Scripting.Folder, SubFolder As Scripting.Folder
Dim FileItem As Scripting.File
Dim strFile, strFileType, strAttach As String
Dim openMsg As MailItem
Dim objAttachments As Outlook.Attachments
Dim i As Long
Dim lngCount As Long
Dim strFolderpath As String
'where to save attachments
strFolderpath = "C:\Users\lengkgan\Desktop\Testing"
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(SourceFolderName)
For Each FileItem In SourceFolder.Files
strFile = FileItem.Name
' This code looks at the last 4 characters in a filename
' If we wanted more than .msg, we'd use Case Select statement
strFileType = LCase$(Right$(strFile, 4))
If strFileType = ".msg" Then
Debug.Print FileItem.Path
Set openMsg = Outlook.Application.CreateItemFromTemplate(FileItem.Path)
openMsg.Display
'do whatever
Set objAttachments = openMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = lngCount To 1 Step -1
' Get the file name.
strAttach = objAttachments.Item(i).Filename
' Combine with the path to the Temp folder.
strAttach = strFolderpath & strAttach
' Save the attachment as a file.
objAttachments.Item(i).SaveAsFile strAttach
Next i
End If
openMsg.Close olDiscard
Set objAttachments = Nothing
Set openMsg = Nothing
' end do whatever
End If
Next FileItem
If IncludeSubfolders Then
For Each SubFolder In SourceFolder.SubFolders
ListFilesInFolder SubFolder.Path, True
Next SubFolder
End If
Set FileItem = Nothing
Set SourceFolder = Nothing
Set FSO = Nothing
End Sub
Edited : How to add the reference
Click Tools > Reference.
Check the needed reference

How can I run an Excel macro from an Outlook macro?

How can I run an Excel macro from an Outlook macro?
You will need to add the Microsoft Excel 14.0 Data Objects library. Go to Tools -> References.
You will also need to open the workbook before you can run a macro from it.
This should work:
Dim ExApp As Excel.Application
Dim ExWbk As Workbook
Set ExApp = New Excel.Application
Set ExWbk = ExApp.Workbooks.Open("C:\Folder\Folder\File.xls")
ExApp.Visible = True
ExWbk.Application.Run "ModuleName.YourMacro"
ExWbk.Close SaveChanges:=True
If you want to run this macro in the background and not open a visible instance of Excel, then set ExApp.Visible to False.
I just wanted to share how I do this. It doesn't apply to OP's needs, but the title may lead others here for more what I'm sharing. This will (optionally filter by sender/subject) save/open/run macro from spreadsheet received in outlook. I then have a macro in excel sometimes which sends notification/response etc, but I don't do this from Outlook (probably could though!).
Create a VBS script which will launch the excel file and run a macro (optionally the macro can be stored in a separate spreadsheet.)
"runmacro.vbs"
Set args = Wscript.Arguments
ws = WScript.Arguments.Item(0)
macro = WScript.Arguments.Item(1)
If wscript.arguments.count > 2 Then
macrowb = WScript.Arguments.Item(2)
End If
LaunchMacro
Sub LaunchMacro()
Dim xl
Dim xlBook
Set xl = CreateObject("Excel.application")
Set xlBook = xl.Workbooks.Open(ws, 0, True)
If wscript.arguments.count > 2 Then
Set macrowb = xl.Workbooks.Open(macrowb, 0, True)
End If
'xl.Application.Visible = True ' Show Excel Window
xl.Application.run macro
'xl.DisplayAlerts = False ' suppress prompts and alert messages while a macro is running
'xlBook.saved = True ' suppresses the Save Changes prompt when you close a workbook
'xl.activewindow.close
xl.Quit
End Sub
Outlook VBA Code (ThisOutlookSession):
https://www.slipstick.com/outlook/email/save-open-attachment/
Private Declare Function GetShortPathName Lib "kernel32" _
Alias "GetShortPathNameA" (ByVal lpszLongPath As String, _
ByVal lpszShortPath As String, ByVal cchBuffer As Long) As Long
Private Sub objItems_ItemAdd(ByVal Item As Object)
Dim objMail As Outlook.MailItem
Dim objWsShell As Object
Dim strTempFolder As String
Dim objAttachments As Outlook.Attachments
Dim objAttachment As Attachment
Dim strFileName As String
Dim Subject As String
Subject = Item.Subject
'If Subject Like "*SubTest*" Then
If Item.Class = olMail Then
Set objMail = Item
'Change sender email address
'If objMail.SenderEmailAddress = "boss#datanumen.com" Then
Set objWShell = CreateObject("WScript.Shell")
strTempFolder = Environ("Temp") & "\"
Set objWsShell = CreateObject("WScript.Shell")
Set objAttachments = objMail.Attachments
If objAttachments.Count > 0 Then
For Each objAttachment In objAttachments
strFileName = objAttachment.DisplayName
On Error Resume Next
Kill strTempFolder & strFileName
On Error GoTo 0
'Save the attachment
objAttachment.SaveAsFile strTempFolder & strFileName
'Open the attachment
vbs = (Chr(34) & "\\Server\Excel\" & "\runmacro.vbs " & Chr(34))
strFileName = GetShortFileName(strTempFolder & strFileName)
macro = "MacroName"
xlam = Environ("APPDATA") & "\Microsoft\Excel\XLSTART\Add-In.xlam"
On Error Resume Next
objWsShell.Run vbs & " " & strFileName & " " & macro & " " & xlam
objMail.UnRead = False
Next
'End If
End If
End If
'End If
End Sub
Function GetShortFileName(ByVal FullPath As String) As String
Dim lAns As Long
Dim sAns As String
Dim iLen As Integer
On Error Resume Next
If Dir(FullPath) <> "" Then
sAns = Space(255)
lAns = GetShortPathName(FullPath, sAns, 255)
GetShortFileName = Left(sAns, lAns)
End If
End Function

Saving .XLSX Attachments from Outlook 2010 w/ VBA

We use Outlook 2010 and receive emails with Excel attachments. We manually save the attachment in a sub-folder that we create within a divisional folder on a network drive.
What I'm curious about is if it's possible to
Use code to check incoming emails to see if they have an attachment,
Then check the attachment to see if it's an .XLSX,
If so, open the attachment, check the value of a particular cell,
then store the account name and account number as a string and a variable
then use those to create the sub-folders in the appropriate Windows directory.
** I forgot to post what I had done so far. I believe Brett answered my ??, but maybe someone else would be able to use snippets of it.
Private Sub cmdConnectToOutlook_Click()
Dim appOutlook As Outlook.Application
Dim ns As Outlook.Namespace
Dim inbox As Outlook.MAPIFolder
Dim item As Object
Dim atmt As Outlook.Attachment
Dim filename As String
Dim i As Integer
Set appOutlook = GetObject(, "Outlook.Application")
Set ns = appOutlook.GetNamespace("MAPI")
Set inbox = ns.GetDefaultFolder(olFolderInbox)
i = 0
If inbox.Items.Count = 0 Then
MsgBox "There are no messages in the Inbox.", vbInformation, _
"Nothing Found"
Exit Sub
End If
For Each item In inbox.Items
For Each atmt In item.Attachments
If Right(atmt.filename, 4) = "xlsx" Then
filename = "\\temp\" & atmt.filename
atmt.SaveAsFile filename
i = i + 1
End If
Next atmt
Next item
MsgBox "Attachments have been saved.", vbInformation, "Finished"
Set atmt = Nothing
Set item = Nothing
Set ns = Nothing
End Sub
Having said it is lengthy here is one way to do it. My code from VBA Code to save an attachment (excel file) from an Outlook email that was inside another email as an attachment may also be of interest
You will need to update your file path, and the cell range from the file that you are opening
In my testing I sent a message to myself with a pdf file and an excel workbook with "bob" in the A1 in the first sheet
The code below found the excel file, saved it, opened it, create a directory c:\temp\bob then killed the saved file
Private Sub Application_NewMailEx _
(ByVal EntryIDCollection As String)
'Uses the new mail techniquer from http://www.outlookcode.com/article.aspx?id=62
Dim arr() As String
Dim lngCnt As Long
Dim olAtt As Attachment
Dim strFolder As String
Dim strFileName As String
Dim strNewFolder
Dim olns As Outlook.NameSpace
Dim olItem As MailItem
Dim objExcel As Object
Dim objWB As Object
'Open Excel in the background
Set objExcel = CreateObject("excel.application")
'Set working folder
strFolder = "c:\temp"
On Error Resume Next
Set olns = Application.Session
arr = Split(EntryIDCollection, ",")
On Error GoTo 0
For lngCnt = 0 To UBound(arr)
Set olItem = olns.GetItemFromID(arr(lngCnt))
'Check new item is a mail message
If olItem.Class = olMail Then
'Force code to count attachments
DoEvents
For Each olAtt In olItem.Attachments
'Check attachments have at least 5 characters before matching a ".xlsx" string
If Len(olAtt.FileName) >= 5 Then
If Right$(olAtt.FileName, 5) = ".xlsx" Then
strFileName = strFolder & "\" & olAtt.FileName
'Save xl attachemnt to working folder
olAtt.SaveAsFile strFileName
On Error Resume Next
'Open excel workbook and make a sub directory in the working folder with the value from A1 of the first sheet
Set objWB = objExcel.Workbooks.Open(strFileName)
MkDir strFolder & "\" & objWB.sheets(1).Range("A1")
'Close the xl file
objWB.Close False
'Delete the saved attachment
Kill strFileName
On Error Goto 0
End If
End If
Next
End If
Next
'tidy up
Set olns = Nothing
Set olItem = Nothing
objExcel.Quit
Set objExcel = Nothing
End Sub

Resources