automatic email via Outlook from vba - vba

I have been working and did some Google searches to create code that sends an automatic email with information from my active Excel sheet. The code prepares the email properly, but I still need to press "Send" on the email. I would like to send it automatically, so I tried to add .Send on the code, but it didn't work.
At the moment my code looks like that:
Sub CreateMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngCc As Range
Dim rngSubject As Range
Dim rngBody As Range
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
With ActiveSheet
Set rngTo = .Range("t2")
Set rngSubject = .Range("t3")
Set rngBody = .Range("a1:r35")
End With
rngBody.Copy
With objMail
.To = rngTo.Value
.Subject = rngSubject.Value
.Display
End With
SendKeys "^({v})", True
.Send
Set objOutlook = Nothing
Set objMail = Nothing
Set rngTo = Nothing
Set rngCc = Nothing
Set rngSubject = Nothing
Set rngBody = Nothing
End Sub

With objMail
.To = rngTo.Value
.Subject = rngSubject.Value
.body = rngBody.Value
.Send
End With
Should do the trick. (Note: I set the body of the message, since you seemed to have missed that.)
remove these lines:
SendKeys "^({v})", True
.Send

The Outlook object model provides three different ways for working with item bodies:
Body - a plain text.
HTMLBody - an HTML markup.
The Word Editor. Outlook uses Word as an email editor, so you can use it to format the email message. The WordEditor property of the Inspector class returns an instance of the Document class which represents the message body.
You can read more about all these ways in the Chapter 17: Working with Item Bodies in MSDN.
The simplest way to get the job done is to use the Word object model for modifying the message body. For example:
mail.GetInspector().WordEditor
Then you can use the Word object model for working with message body.
Finally, you need to call the Send method to submit the message for processing by the transport provider.

here is complete code that is working for me.
Option Explicit
Sub CreateMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngCc As Range
Dim rngBCC As Range
Dim rngSubject As Range
Dim rngBody As Range
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
With ActiveSheet
Set rngTo = .Range("T2")
Set rngCc = .Range("T2")
Set rngBCC = .Range("T2")
Set rngSubject = .Range("T3")
Set rngBody = .Range("A1:R35")
End With
rngBody.Copy
With objMail
.To = rngTo.Value
.CC = rngCc.Value
.BCC = rngBCC.Value
.Subject = rngSubject.Value
.HTMLBody = RangetoHTML(rngBody)
ActiveWorkbook.Save
.Send
End With
Set objOutlook = Nothing
Set objMail = Nothing
Set rngTo = Nothing
Set rngCc = Nothing
Set rngSubject = Nothing
Set rngBody = Nothing
End Sub
Function RangetoHTML(rng As Range)
' Works in Excel 2000, Excel 2002, Excel 2003, Excel 2007, Excel 2010, Outlook 2000, Outlook 2002, Outlook 2003, Outlook 2007, and Outlook 2010.
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "/" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
' Copy the range and create a workbook to receive the data.
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
Cells(1).Select
Cells(1).Cells.EntireRow.AutoFit
Cells.EntireColumn.AutoFit
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
' Publish the sheet to an .htm file.
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
' Read all data from the .htm file into the RangetoHTML subroutine.
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.ReadAll
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
' Close TempWB.
TempWB.Close savechanges:=False
' Delete the htm file.
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function

Related

Different pivot tables to different emails vba

I have multiple pivot tables that I want to send out individually to different emails. The problem is, the email keeps getting written over by the second email. Each pivot table is named different and the code works fine with only one reference. I have tried multiple ways to get it but cant. Can someone help?
Private Sub Workbook_Open()
Dim wk As Worksheet
Dim wk1 As Worksheet
wk = Worksheets("EPSICAR")
wk.Connections("owssvr").Refresh
wk1 = Worksheets("PastDue")
wk1.RefreshAll
End Sub
Sub pastdue()
Dim myApp As Outlook.Application, mymail As Outlook.Mailitem
Dim Lap As Object
Dim rng As Range
Dim rngmtl As Range
Dim Mailitem As Object
Set myApp = New Outlook.Application
Set mymail = myApp.CreateItem(olMailItem)
Set rng = Sheets("PastDue").PivotTables("Q Group Past
Due").TableRange1
Set rngmtl = Sheets("PastDue").PivotTables("Mtl Group Past
Due").TableRange2
With mymail
.To = "sponge.bobh#12345.com"
.CC = "pat.star#12345.com"
.Subject = "ICAR/EPS past due"
.HTMLBody = "The following are a list of ICARs/EPS that are past due" &
RangetoHTML(rng)
.Display
'.send
With mymail
.To = "blue.berry#12345.com"
.CC = "black.berry#12345.com"
.Subject = "ICAR/EPS past due"
.HTMLBody = "The following are a list of ICARs/EPS that are past due" &
RangetoHTML(rngmtl)
.Display
'.send
Set myApp = Nothing
Set mymail = Nothing
End With
End With
End Sub
Function RangetoHTML(rng As Range)
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "/" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.ReadAll
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
TempWB.Close savechanges:=False
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
I think your approach is off a bit. I suppose there are a few ways to do this kind of thing. You can refresh the pivot multiple ways, and email a snapshot of each to different recipients. You could refresh the pivot multiple ways, save each, and email the saved version of each to separate people. If you want to go down this path, try to code sample below.
Make a list in Sheets("Sheet1") with :
In column A : Names of the people
In column B : E-mail addresses
In column C:Z : Filenames like this C:\Data\Book2.xls (don't have to be Excel files)
The Macro will loop through each row in "Sheet1" and if there is a E-mail address in column B
and file name(s) in column C:Z it will create a mail with this information and send it.
Sub Send_Files()
'Working in Excel 2000-2016
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("Sheet1")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("B").Cells.SpecialCells(xlCellTypeConstants)
'Enter the path/file names in the C:Z column in each row
Set rng = sh.Cells(cell.Row, 1).Range("C1:Z1")
If cell.Value Like "?*#?*.?*" And _
Application.WorksheetFunction.CountA(rng) > 0 Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Testfile"
.Body = "Hi " & cell.Offset(0, -1).Value
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Send 'Or use .Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
There are probably a couple other approaches you could consider. Just get one thing to work, before trying a different means to the same end.

Paste Excel range to Outlook email body

I want to copy data from a fixed range in an Excel sheet and paste on an email body.
Below is the code I have come up with. However I am not able to paste the specified range A11:H12.
Private Sub CommandButton1_Click()
On Error GoTo ErrHandler
' SET Outlook APPLICATION OBJECT.
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
' CREATE EMAIL OBJECT.
Dim objEmail As Object
Set objEmail = objOutlook.CreateItem(olMailItem)
With objEmail
.To = "email"
.Subject = "test"
.Body = ActiveSheet.Range("A11:H12").Select
.Display ' DISPLAY MESSAGE.
End With
' CLEAR.
Set objEmail = Nothing: Set objOutlook = Nothing
ErrHandler:
'
End Sub
as in the comments Ron has this figured. The bellow code and function does the trick. Copy them both
Private Sub CommandButton1_Click()
' SET Outlook APPLICATION OBJECT.
Dim rng As Range
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
Set rng = Nothing
On Error Resume Next
Set rng = ActiveSheet.Range("A11:H12").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
' CREATE EMAIL OBJECT.
Dim objEmail As Object
Set objEmail = objOutlook.CreateItem(olMailItem)
With objEmail
.To = "email"
.Subject = "test"
.HTMLBody = RangetoHTML(rng)
.Display ' DISPLAY MESSAGE.
End With
' CLEAR.
Set objEmail = Nothing:
Set objOutlook = Nothing
End Sub
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2016
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Code:
Sub sendEmail()
'call outlook
Dim MyOlapp As Object, MyItem As Object
Set MyOlapp = CreateObject("Outlook.Application")
Set MyItem = MyOlapp.CreateItem(olMailItem)
'ajust range of sheet
Range("A11:H12").Select
Selection.Copy
With MyItem
'ajust number of sheet
.To = Sheet17.[b1].Value 'e-mail adress
.Subject = Sheet17.[b2].Value 'subject of e-mail
.Body = Sheet17.[b3].Value 'body of e-mail
.Display
SendKeys ("^{DOWN}")
SendKeys ("^{DOWN}")
SendKeys ("%m")
SendKeys ("v")
SendKeys ("s")
SendKeys ("{UP}")
SendKeys ("{UP}")
SendKeys ("{ENTER}")
SendKeys ("{ENTER}")
SendKeys ("%m")
SendKeys ("q")
SendKeys ("{ENTER}")
End With
End Sub

Using RangetoHtml Function and Excel Won't Close after functions are done running

Basically I created a report and then send it via an email. I use Ron B's function to paste the excel sheets into the body of the email. What happens is excel doesn't destroy or close after the send email function is done. When I end task on it and run it again it says that the remote machine or server doesn't exits. This is probably because I am not explicitly defining the objects but I don't know how to between the two procedures. I tried making the xlApp Public but that didn't work. I even tried adding it to the rangetohtml function but at the point of where it says rng.copy it says there is an object that is required. I tried adding xlApp.rng.copy or wb.rng.copy or ws.rng.copy. So i have the below where the range to html copies the rng. That is added to a temp workbook and copied into the email. It call from the one function over to the other and I can't figure out how to destroy the excel session when it is done.
Set rng = xlApp.Selection.SpecialCells(xlCellTypeVisible)
Set rng = wb.Sheets(2).Range("A:U").SpecialCells(xlCellTypeVisible)
Set rng2 = xlApp.Selection.SpecialCells(xlCellTypeVisible)
Set rng2 = wb.Sheets(1).Range("A:U").SpecialCells(xlCellTypeVisible)
Now the range to html says RangetoHtml(rng as Range) then at the bottom it says
rng.copy
Below that when you debug it after end tasking on excel it stops on this line:
Set TempWB = Workbooks.Add(1)
I know you are supposed to put either XlApp.Workbooks.Add(1) but in the rangeto Html function it isn't declared as an object but it is in the function that it is calling from. I don't know what to do next and how to fix the code. I am posting both functions so you can see the code. When the send email happens it brings up the email and pastes the excel sheet into the email but excel doesn't closed.
Public Function sendEmailorbetechprealert()
Dim appOutLook As Outlook.Application
Dim Items As Outlook.Items
Dim Item As Object
Dim strPath As String
Dim strFilter As String
Dim strFile As String
Dim rng As Range
Dim rng2 As Range
Dim xlApp As Excel.Application
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim MyFileName As String
Dim bfile As String
Dim Cell As Range
bfile = "S:\_Reports\Orbotech\Orbotech - Open Deliveries Pre-Alert\Orbotech - Open Deliveries Pre-Alert - "
MyFileName = bfile & Format(Date, "mm-dd-yyyy") & ".xls"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err.Number > 0 Then Set xlApp = CreateObject("Excel.Application")
On Error GoTo 0
Set wb = xlApp.Workbooks.Open(MyFileName)
Set ws = wb.Sheets(1)
ws.Activate
Set rng = Nothing
Set rng2 = Nothing
On Error Resume Next
Set rng = xlApp.Selection.SpecialCells(xlCellTypeVisible)
Set rng = wb.Sheets(2).Range("A:U").SpecialCells(xlCellTypeVisible)
Set rng2 = xlApp.Selection.SpecialCells(xlCellTypeVisible)
Set rng2 = wb.Sheets(1).Range("A:U").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If rng Is Nothing Then
Set appOutLook = Nothing
Set Items = Nothing
End If
If rng2 Is Nothing Then
Set appOutLook = Nothing
Set Items = Nothing
Exit Function
End If
strPath = "S:\_Reports\Orbotech\Orbotech - Open Deliveries Pre-Alert\" 'Edit to your path
strFilter = "*.xls"
strFile = Dir(strPath & strFilter)
'For Each Cell In Columns("E").Cells.SpecialCells(xlCellTypeConstants)
If strFile <> "" Then
Set appOutLook = CreateObject("Outlook.Application")
Set Items = Outlook.Application.ActiveExplorer.CurrentFolder.Items
Set Item = Items.Add("IPM.Note.iCracked")
With Item
.To = ""
'.CC =
''.bcc = ""
.Subject = "Orbotech Open Deliveries Report Pre-Alert"
.htmlBody = "This is the Open Deliveries Report. Please open the attachment. These lines are what have been inbound." & RangetoHTML(rng) & "This is what is still due" & RangetoHTML(rng2)
.Attachments.Add (strPath & strFile)
'.Send
Item.Display 'Used during testing without sending (Comment out
.Send if using this line)
wb.CheckCompatibility = False
wb.Save
wb.CheckCompatibility = True
DoEvents
End With
Else
MsgBox "No file matching please re run Orbotech Report"
Exit Function 'This line only required if more code past End If
End If
'Next Cell
DoEvents
On Error GoTo 0
wb.CheckCompatibility = False
wb.Save
wb.CheckCompatibility = True
xlApp.Quit
Set rng = Nothing
Set rng2 = Nothing
Set wb = Nothing
Set ws = Nothing
Set xlApp = Nothing
Exit Function
End Function
Now in the htmlbody it calls the RangetoHtml(rng) to paste it in the email. He is the rangetohtml function:
Public Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2016
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
'xlApp.Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
fileName:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.CheckCompatibility = False
TempWB.Save
TempWB.CheckCompatibility = True
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Any help that anyone can provide it would certainly be appreciated.

Meeting invite from Excel macro - no body, set as appointment

I'm trying to create a vba macro which generates a meeting invite that uses variable data from a worksheet.
My first problem is that it only opens up as an appointment, but not as a meeting with the invitees listed (however, if i click "Invite Attendees" on the appointment, they are prepopulated).
My second problem is that the required information I want in the body does not display.
Below is the code, can anyone assist?
Sub Consolidation_Invite()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Don't forget to copy the function RangetoHTML in the module.
'Working in Excel 2000-2016
Dim rng As Range
Dim OutApp As Object
Dim objMyApptItem As Object
Dim recipients As Range
Set rng = Nothing
On Error Resume Next
'You can use a fixed range or the visible cells in the selection
'Selection.SpecialCells(xlCellTypeVisible)
'Set rng = Sheets("YourSheet").Range("D4:D12").SpecialCells(xlCellTypeVisible)
Set rng = Sheets("Calendar Invite").Range("A21:B50").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
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 Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set objMyApptItem = OutApp.CreateItem(1)
Set recipients = Worksheets("Calendar Invite").Range("B11")
On Error Resume Next
With objMyApptItem
.MeetingStatus = olMeeting
.recipients.Add recipients
.Location = " Phone Call"
.Subject = Worksheets("Calendar Invite").Range("B13")
.Start = Worksheets("Calendar Invite").Range("B15")
.AllDayEvent = "False"
.HTMLBody = RangetoHTML(rng)
.Display 'or use .Send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2016
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
It IS a meeting request. The MeetingItem object cannot be created, it is automatically created when you set the MeetingStatus property of an AppointmentItem object to olMeeting and send it to one or more users. Recipients will receive them as MeetingItem items.
For your second problem, the AppointmentItem object doesn't support an HTMLBody property; only Body and RTFBody.
I figured it out, so posting the solution in case others wish to use the same. Basically as you can't use HTMLBody, you can compose in Word. So this will copy and paste in the word editor.
I still can't get it to display the invitees by default... but clicking the "Invite Attendees" button isn't such a bit deal.
Sub Consolidation_Invite()
Dim olApp As Object
Dim olApt As Object
Dim RCP As Range
Const wdPASTERTF As Long = 1
Set olApp = CreateObject("Outlook.Application")
Set olApt = olApp.CreateItem(1)
Set RCP = Worksheets("Calendar Invite").Range("B11")
With olApt
.MeetingStatus = olMeeting
.Start = Worksheets("Calendar Invite").Range("B15")
.AllDayEvent = "False"
.recipients.Add RCP
.Location = "Phone Call (please be at your computer)"
.Subject = Worksheets("Calendar Invite").Range("B13")
Sheets("Calendar Invite").Range("A21:B50").Copy
.Display
.GetInspector.WordEditor.Windows(1).Selection.PasteAndFormat wdPASTERTF
End With
End Sub

VBA '1004' error at ActiveWorkbook.Save

I have created a VBA module that :
searches for a specific email in outlook
grabs the excel file attachment from the email it finds
formats the excel file attachment (adds colors and grid to make it look more presentable)
saves the formatted excel file to my desktop
sends email(s) to our client with the formatted excel file as an attachment (and pastes the excel file into the body of the email)
** I use multiple arrays to send to individual clients
My code works pretty well and has worked without issues many times. However, every now and again it will have a '1004 run time error' pop up randomly while processing. When I debug, it takes me to 'ActiveWorkbook.Save'. Usually if I run it again it works just fine, but I need it to be more user friendly for others to use. Code is as follows.
Public f As Integer 'format integer
Sub Clients()
'Array([file destination to be saved], [subject of file being searched in outlook], [file name given when saved], [emails the report is going to])
f = 0
email_1 = Array("C:\User\Desktop\", "FL Test Results", "FL_Reports", "client1#email.com")
Call Reports(email_1)
f = 1
email_2 = Array("C:\User\Desktop\", "CA Test Results", "CA_Reports", "client2#email.com")
Call Reports(email_2)
f = 2
email_3 = Array("C:\User\Desktop\", "NY Test Results", "NY_Reports", "client3#email.com")
Call Reports(email_3)
email_4 = Array("C:\User\Desktop\", "TX Test Results", "TX_Reports", "client4#email.com")
Call Reports(email_4)
End Sub
Function Reports(a As Variant)
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim olApp As Outlook.Application
Dim olNs As Namespace
Dim olFldr As MAPIFolder
Dim olItms As Items
Dim olMi As MailItem
Dim olEmail As Outlook.MailItem
Dim olAtt As Attachment
Dim subj As String
Dim saveAs As String
Dim emails As String
Dim FilePath As String
FilePath = a(0)
subj = a(1)
saveAs = a(2)
emails = a(3)
Set olApp = GetObject(, "Outlook.Application")
Set olNs = olApp.GetNamespace("MAPI")
Set olFldr = olNs.GetDefaultFolder(olFolderInbox)
Set olItms = olFldr.Items
Set olEmail = olApp.CreateItem(olMailItem)
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set rng = Nothing
Set rng = ActiveSheet.UsedRange
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Set olMi = olItms.Find("[Subject] = " & Chr(34) & subj & Chr(34))
If Not (olMi Is Nothing) Then
For Each olAtt In olMi.Attachments
olAtt.SaveAsFile FilePath & saveAs & ".xls"
Workbooks.Open (FilePath & saveAs & ".xls")
Call format.Run 'Seperate file that formats the raw excel sheet to look more pretty
If f = 0 Then
Call format.DeleteOldClasses 'different ways clients want there excel file info sorted
ElseIf f = 1 Then
Call format.sortByDate
Else
End If
ActiveWorkbook.Save '#######This is where the error pops up
Set rng = Worksheets(saveAs).UsedRange
Next olAtt
End If
On Error Resume Next
With OutMail
.Attachments.Add FilePath & saveAs & ".xls"
.To = emails
.CC = ""
.BCC = ""
.subject = subj
.HTMLBody = RangetoHTML(rng)
.send
End With
On Error GoTo 0
ActiveWorkbook.Close
Kill (FilePath & saveAs & ".xls")
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
Set olAtt = Nothing
Set olMi = Nothing
Set olFldr = Nothing
Set olNs = Nothing
Set olApp = Nothing
End Function
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2013
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Thank you for your time and help.
So I found a solution that works for me but maybe not others with the same issue. I Set my workbooks as #findwidow and #R3uk suggested. I simply put "On Error Resume Next" and save an extra copy in a new place that I pull the attachment from to place in the email.
On Error Resume Next
wB.Save
wB.SaveCopyAs ("C:\Users\Ken\Desktop\" & saveAs & ".xls")
Set rng = Worksheets(saveAs).UsedRange
Next olAtt
End If
It wont save the formatted excel file at times during the error, however this rarely happens now and it is only for our own documentation. It now continues through the cycle of client arrays with ease (and actually seems faster). Thank you for the help.