I'm trying to retrieve data from archieved outlook emails from Enterprise Vault using excel vba. but it searching through only 1005 mail. but actually mail should be more than 10000. but actually looping through only 1005 mail. but should go to more than 10000 mail. I think problem happening due Enterprise Vault archived mail. because this emails are not showing in outlook but showing while going through below wesite
http://arlev4cls.india.eclerx.com/EnterpriseVault/search/shell.aspx?server=ARLMSEXCH07&mbx=SMTP:Pravin.Angane#eclerx.com#
Sub OnlineJapan_Email()
Dim outlookApp
Dim olNs As Outlook.Namespace
Dim Fldr As Outlook.MAPIFolder
Dim olMail As Variant 'Outlook.MailItem
Dim olFMail As Outlook.MailItem
Dim myTasks
Dim sir() As String
Dim rng As Range
'Set outlookApp = New Outlook.Application
Set outlookApp = CreateObject("Outlook.Application")
Set olNs = outlookApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderInbox)
Set myTasks = Fldr.Items
Dim wb As Workbook
Dim obwb As Workbook
For Each wb In Workbooks
If wb.Name Like "Consolidated observation file*.xlsb" Then
Set obwb = wb
obwb.Activate
Exit For
End If
Next
lastrow = obwb.Sheets("Daily Observation").Range("bm50000").End(xlUp).Row
Set rng = obwb.Sheets("Daily Observation").Range(Cells(8, 60), Cells(lastrow, 65)).SpecialCells(xlCellTypeVisible)
'
'Set olMail = myTasks.Find("[Subject] = ""123456""")
'
For Each olMail In myTasks
'
If TypeName(olMail) = "MailItem" Then
If (InStr(1, olMail.Subject, "Japan Observations for ", vbTextCompare) > 0) Then
Set olFMail = olMail.Forward
With olFMail
.To = "Pravin.Angane#eclerx.com;Jaysing.Pardeshi#eclerx.com;Suhas.Bhange#eclerx.com;Dadasaheb.Kamble#eclerx.com"
.CC = "Jaysing.Pardeshi#eclerx.com;Suhas.Bhange#eclerx.com"
.HTMLBody = "<HTML><BODY>" & obwb.Sheets("AutoMail").Range("a40") & "<br><br>" & obwb.Sheets("AutoMail").Range("a41") & "</BODY></HTML>" & RangetoHTML(rng) & olFMail.HTMLBody
.Subject = obwb.Sheets("AutoMail").Range("i42")
End With
Set Myattachments = olFMail.Attachments
While Myattachments.Count > 0
Myattachments.Remove 1
Wend
olFMail.Attachments.Add "\\IPSAABACUS\CM_Shared$\SalesForce\Jyoti Sahay\VA-Training\Scrubbing feedback\Observations\Consolidated observation file - Dec-2022.rar"
olFMail.Display
Exit For
End If
End If
Next
'Dim outForward As Outlook.MailItem
'Set outForward = ActiveExplorer.Selection.Item(1).Forward
'outForward.Recipients.Add "pravin.angane#eclerx.com"
'outForward.Save
End Sub
Function RangetoHTML(rng As Range)
Dim obj As Object
Dim txtstr As Object
Dim File As String
Dim wb As Workbook
File = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
rng.Copy
Set wb = Workbooks.Add(1)
With wb.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
.Cells.EntireColumn.AutoFit
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
With wb.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=File, _
Sheet:=wb.Sheets(1).Name, _
Source:=wb.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
Set obj = CreateObject("Scripting.FileSystemObject")
Set txtstr = obj.GetFile(File).OpenAsTextStream(1, -2)
RangetoHTML = txtstr.readall
txtstr.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
wb.Close savechanges:=False
Kill File
Set txtstr = Nothing
Set obj = Nothing
Set wb = Nothing
End Function
Sub OnlineJapan_Email()
Dim outlookApp
Dim olNs As Outlook.Namespace
Dim Fldr As Outlook.MAPIFolder
Dim olMail As Variant 'Outlook.MailItem
Dim olFMail As Outlook.MailItem
Dim myTasks
Dim sir() As String
Dim rng As Range
'Set outlookApp = New Outlook.Application
Set outlookApp = CreateObject("Outlook.Application")
Set olNs = outlookApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderInbox)
Set myTasks = Fldr.Items
Dim wb As Workbook
Dim obwb As Workbook
For Each wb In Workbooks
If wb.Name Like "Consolidated observation file*.xlsb" Then
Set obwb = wb
obwb.Activate
Exit For
End If
Next
lastrow = obwb.Sheets("Daily Observation").Range("bm50000").End(xlUp).Row
Set rng = obwb.Sheets("Daily Observation").Range(Cells(8, 60), Cells(lastrow, 65)).SpecialCells(xlCellTypeVisible)
'
'Set olMail = myTasks.Find("[Subject] = ""123456""")
'
For Each olMail In myTasks
'
If TypeName(olMail) = "MailItem" Then
If (InStr(1, olMail.Subject, "Japan Observations for ", vbTextCompare) > 0) Then
Set olFMail = olMail.Forward
With olFMail
.To = "Pravin.Angane#eclerx.com;Jaysing.Pardeshi#eclerx.com;Suhas.Bhange#eclerx.com;Dadasaheb.Kamble#eclerx.com"
.CC = "Jaysing.Pardeshi#eclerx.com;Suhas.Bhange#eclerx.com"
.HTMLBody = "<HTML><BODY>" & obwb.Sheets("AutoMail").Range("a40") & "<br><br>" & obwb.Sheets("AutoMail").Range("a41") & "</BODY></HTML>" & RangetoHTML(rng) & olFMail.HTMLBody
.Subject = obwb.Sheets("AutoMail").Range("i42")
End With
Set Myattachments = olFMail.Attachments
While Myattachments.Count > 0
Myattachments.Remove 1
Wend
olFMail.Attachments.Add "\\IPSAABACUS\CM_Shared$\SalesForce\Jyoti Sahay\VA-Training\Scrubbing feedback\Observations\Consolidated observation file - Dec-2022.rar"
olFMail.Display
Exit For
End If
End If
Next
'Dim outForward As Outlook.MailItem
'Set outForward = ActiveExplorer.Selection.Item(1).Forward
'outForward.Recipients.Add "pravin.angane#eclerx.com"
'outForward.Save
End Sub
Function RangetoHTML(rng As Range)
Dim obj As Object
Dim txtstr As Object
Dim File As String
Dim wb As Workbook
File = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
rng.Copy
Set wb = Workbooks.Add(1)
With wb.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
.Cells.EntireColumn.AutoFit
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
With wb.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=File, _
Sheet:=wb.Sheets(1).Name, _
Source:=wb.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
Set obj = CreateObject("Scripting.FileSystemObject")
Set txtstr = obj.GetFile(File).OpenAsTextStream(1, -2)
RangetoHTML = txtstr.readall
txtstr.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
wb.Close savechanges:=False
Kill File
Set txtstr = Nothing
Set obj = Nothing
Set wb = Nothing
End Function
Related
Im trying to generate an email using Ron de Bruin's RangeToHTML and its working perfectly so far however one of my cells ("B26") contains an image and this wont copy into the email.
I've tried and succeded in adding in the image before or after the range but I need this image to appear in this specific cell. Any Ideas how I can get this to work if its at all possible?
Sub SendEmail()
Dim OutlookApp As Outlook.Application
Dim MItem As Outlook.MailItem
Dim cell As Range
Dim Subj As String
Dim EmailAddr As String
Dim Recipient As String
Dim rng As Range
Dim rng2 As Range
Dim StrBody As String
Set rng = Sheets("Email Templates").Range("A1:D29")
'Set rng2 = Sheets("Email Templates").Range("A6:D32").SpecialCells(xlCellTypeVisible)
'Create Outlook object
Set OutlookApp = New Outlook.Application
'Operations Contacts
For Each cell In Sheets("Contacts").Columns("A").Cells.SpecialCells(xlCellTypeVisible)
If cell.Value Like "*#*" Then
EmailAddr = EmailAddr & ";" & cell.Value
End If
Next
'Systems Contacts
For Each cell In Sheets("Contacts").Columns("B").Cells.SpecialCells(xlCellTypeVisible)
If cell.Value Like "*#*" Then
EmailAddr = EmailAddr & ";" & cell.Value
End If
Next
Subj = "Systems Notification | System Outage | " & Sheets("Email Templates").Range("C6") & " " & Sheets("Email Templates").Range("C4") & " " & Sheets("Email Templates").Range("C6")
'Create Mail Item and view before sending
Set MItem = OutlookApp.CreateItem(olMailItem)
With MItem
.To = EmailAddr
.Subject = Subj
.HTMLBody = RangetoHTML(rng)
.Display
End With
End Sub
Function RangetoHTML(rng As Range)
' By Ron de Bruin.
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
Dim r As Long
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).PasteSpecial xlPasteAllUsingSourceTheme, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
For r = 1 To rng.Rows.Count
.Rows(r).RowHeight = rng.Rows(r).RowHeight
Next r
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=")
RangetoHTML = Replace(RangetoHTML, "<!--[if !excel]> <![endif]-->", "")
'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
You can achieve it by taking a screenshot(using VBA Code) of the relevant range (Has to be visible in the screen) and then save and import that image in Outlook..
This will get you started. I have added the comments so you should not have a problem understanding it. If you still do then simply ask.
Option Explicit
Sub SaveRngAsImage()
Dim flName As String
Dim ws As Worksheet
Dim shp As Shape
Dim objChart As ChartObject
Dim chrt As Chart
Set ws = ActiveSheet
'~~> Change as applicable
flName = "C:\Users\routs\Desktop\MyRng.jpg"
'~~> Delete the above image
If Dir(flName) <> "" Then Kill flName
'~~> Check if what the user selected is a valid range
If TypeName(Selection) <> "Range" Then
MsgBox "Select a range first."
Exit Sub
End If
'~~> Take a screenshot of the range
Selection.CopyPicture xlScreen, xlBitmap
DoEvents
'~~> Paste the screenshot in the worksheet and assign it to
'~~> a shape object so that we can use it's approx width and
'~~> Height to create the chart object
With ws
.Paste
DoEvents
Set shp = .Shapes(.Shapes.Count)
Set objChart = ActiveSheet.ChartObjects.Add(0, 0, shp.Width, shp.Height)
Set chrt = objChart.Chart
With chrt
shp.Copy '~~> Copy the shape (in case the clipboard is cleared)
.ChartArea.Select
.Paste
'~~> Save the image
.Export ("C:\Users\routs\Desktop\MyRng.jpg")
End With
shp.Delete
objChart.Delete
End With
'~~> Attaching the above image to outlook email body
'https://stackoverflow.com/questions/44869790/embed-picture-in-outlook-mail-body-excel-vba
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "SomeEmail#SomeServer.com"
.Subject = "Attaching an image"
.Attachments.Add flName, 1, 0
.HtmlBody = "<html><p>Dear XYZ</p>" & _
"<img src=""cid:MyRng.jpg"">"
.Display
End With
End Sub
Screenshot
I have the below code. I wish to place a table in the body of an HTML email where I want negative values to be color-coded in red, positive values in green and unchanged values to display a dash. I can make it work for a single cell reference, however I can't figure out how to incorporate a For Each...Next command so that the code runs through an entire column and color codes all values accordingly. Any help is greatly appreciated.
Sub Test()
Dim oApp As Object
Dim oEmail As Object
Set oApp = CreateObject("Outlook.Application")
Set oEmail = oApp.CreateItem(0)
rng = Range("A1")
If Range("A1") < 0 Then
rng = "<font color=""red"">" & "<b>" & rng & "</font>" & "</b>"
ElseIf Range("A1") > 0 Then
rng = "<font color=""green"">" & "<b>" & rng & "</font>" & "</b>"
Else: rng = "<b>" & "-" & "</b>"
End If
Set oApp = CreateObject("Outlook.Application")
Set oEmail = oApp.CreateItem(olMailItem)
oEmail.Close olSave
oEmail.Save
oEmail.BCC = ""
oEmail.Subject = "Test"
oEmail.SentOnBehalfOfName = """Hello"" <xxx#xxx>"
oEmail.HTMLBody = rng
oEmail.Display
Set oEmail = Nothing
Set oApp = Nothing
Set colAttach = Nothing
Set oAttach = Nothing
cleanup:
Set oApp = Nothing
End Sub
You can implement a For Each loop like this:
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1") '<-- Update
Dim myCell As Range, rng As Range
Set rng = ws.Range("A1:A10", "A12:A17")
For Each myCell In rng
If myCell < 0 Then
myCell.[Format]
ElseIf myCell > 0 Then
myCell.[Format]
Else
myCell.[Format]
End If
Next myCell
The main problem was that I used rng in the .HTMLBody section instead of RangetoHTML(rng) which had to be created as a function. Code is below.
Sub Test()
Dim oApp As Object
Dim oEmail As Object
Dim ws As Worksheet
Dim myCell As Range
Dim rng As Range
Set oApp = CreateObject("Outlook.Application")
Set oEmail = oApp.CreateItem(0)
Set ws = ThisWorkbook.Sheets("Sheet1")
Set rng = Sheets("Sheet1").Range("A1:A10, "A12:A17"")
For Each myCell In rng
If myCell < 0 Then
myCell.Font.Color = vbRed
ElseIf myCell > 0 Then
myCell.Font.Color = vbGreen
Else: myCell.Font.Color = vbBlack
End If
Next myCell
Set oApp = CreateObject("Outlook.Application")
Set oEmail = oApp.CreateItem(olMailItem)
oEmail.BCC = ""
oEmail.Subject = "Test"
oEmail.SentOnBehalfOfName = """FBN Markets"" <xxx#xxx>"
oEmail.HTMLBody = RangetoHTML(rng)
oEmail.Send
Set oEmail = Nothing
Set oApp = Nothing
Set colAttach = Nothing
Set oAttach = Nothing
cleanup:
Set oApp = Nothing
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
How can I use the command "Paste Special - As Picture" that you access in Excel from the right-click menu?
I have viewed various posts, but they seem to be outdated when using Excel 2016. It seems it has to be in this section,
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
How do I alter to allow copy and paste as picture?
When using the original code below, I lose all column and row sizing in the email body.
Dim rng As Range
Dim OutApp As Object
Dim outMail As Object
Set rng = Nothing
' Only send the visible cells in the selection.
Set rng = Sheets("Dashboard").Range("B4:L17").SpecialCells(xlCellTypeVisible)
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set outMail = OutApp.CreateItem(0)
With outMail
.To = ""
.CC = ""
.BCC = ""
.Subject = ""
.HTMLBody = RangetoHTML(rng)
.Display
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)
' By Ron de Bruin.
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
To get better picture on Outlook, work with Word object model with MailItem.GetInspector Property (Outlook)
Example
Option Explicit
Public Sub Example()
Dim rng As Range
Dim olApp As Object
Dim Email As Object
Dim Sht As Excel.Worksheet
Dim wdDoc As Word.Document
Set Sht = ActiveWorkbook.Sheets("Dashboard")
Set rng = Sht.Range("B4:L17")
rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set olApp = CreateObject("Outlook.Application")
Set Email = olApp.CreateItem(0)
Set wdDoc = Email.GetInspector.WordEditor
With Email
.To = ""
.CC = ""
.BCC = ""
.Subject = ""
.Attachments.Add ActiveWorkbook.FullName
wdDoc.Range.PasteAndFormat Type:=wdChartPicture
' if need setup inlineshapes hight & width
With wdDoc
.InlineShapes(1).Height = 130
End With
.Display
End With
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set Email = Nothing
Set olApp = Nothing
End Sub
Something like this should work:
Dim ol As Object 'Outlook.Application
Dim olEmail As Object 'Outlook.MailItem
Dim olInsp As Object 'Outlook.Inspector
Dim wd As Object 'Word.Document
Sheets("Dashboard").Range("B4:L17").SpecialCells(xlCellTypeVisible).Copy
Set ol = GetObject(, "Outlook.Application") '/* if outlook is running, create otherwise */
Set olEmail = ol.CreateItem(0) 'olMailItem
With olEmail
Set olInsp = .GetInspector
If olInsp.EditorType = 4 Then 'olEditorWord
Set wd = olInsp.WordEditor
wd.Range.PasteAndFormat 13 'wdChartPicture
End If
.Display
End With
If sure that your version of Outlook uses Word Editor, you can do it like:
With olEmail
.GetInspector.WordEditor.Range.PasteAndFormat 13
.Display
End With
If you want to add Text, use this code.
Dim ol As Object 'Outlook.Application
Dim olEmail As Object 'Outlook.MailItem
Dim olInsp As Object 'Outlook.Inspector
Dim wd As Object 'Word.Document
Sheets("Dashboard").Range("B4:L17").SpecialCells(xlCellTypeVisible).Copy
Set ol = GetObject(, "Outlook.Application") '/* if outlook is running, create otherwise */
Set olEmail = ol.CreateItem(0) 'olMailItem
With olEmail
Set olInsp = .GetInspector
If olInsp.EditorType = 4 Then 'olEditorWord
Set wd = olInsp.WordEditor
wd.Range.PasteAndFormat 13 'wdChartPicture
End If
wd.Paragraphs(1).Range.InsertAfter "Hi, There" & Chr(10)
Sheets("chart").Range("B4:L17").SpecialCells(xlCellTypeVisible).Copy
wd.Paragraphs(wd.Paragraphs.Count).Range.Characters.First.PasteAndFormat 13
wd.Paragraphs.Add
Sheets("chart").Range("B4:L17").SpecialCells(xlCellTypeVisible).Copy
wd.Paragraphs(wd.Paragraphs.Count).Range.Characters.First.PasteAndFormat 13
wd.Paragraphs.Add
wd.Paragraphs(wd.Paragraphs.Count).Range.InsertAfter Chr(10) & Chr(10) & "BR"
.Display
End With
This is the sample email which is saved in Excel worksheet.
Hi All,
This is the test email
Regards,
Xyz
I want to copy this email as it is & paste it to Outlook.
With the help of online forums I have written a code but the output is not the same as the input.
Global Email_Subject, Email_Send_From, Email_Send_To, _
Email_Cc, Email_Bcc, Email_Body As String
Global Mail_Object, Mail_Single As Variant
Global wb As Workbook
Sub India_BB()
Dim i As Integer
Dim ShtToSend As Worksheet
Dim strSendTo, strbody As String
Dim strSheetName As String
Dim strSubject As String
Dim rng As Range
Set Mail_Object = CreateObject("Outlook.Application")
Set Mail_Single = Mail_Object.CreateItem(0)
For i = 1 To ThisWorkbook.Sheets.Count
If Sheets(i).Name = "India_BB" Then
Sheets(i).Select
Set rng = Nothing
strSheetName = Sheets(i).Name
strSendTo = Sheet1.Range("A1").Text
strSubject = Sheet1.Range("B1").Text
Set rng = Sheets(strSheetName).Range("body").SpecialCells(xlCellTypeVisible)
With Mail_Single
.To = strSendTo
.CC = ""
.BCC = ""
.Subject = strSubject
.HTMLBody = RangetoHTML(rng)
.Display
End With
End If
Next i
End Sub
Function RangetoHTML(rng As Range)
' By Ron de Bruin.
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 xlPasteAll, , 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
Below is the Output I am getting with above code.
Link for excel file : https://drive.google.com/open?id=0Byy709uTvWRoTnRYaVJQNWNNR1E
Use GetInspector.WordEditor
See Example...
Sub India_BB()
Dim i As Integer
Dim ShtToSend As Worksheet
Dim strSendTo, strbody As String
Dim strSheetName As String
Dim strSubject As String
Dim rng As Range
' add ref - tool -> references - > Microsoft Word XX.X Object Library
Dim wdDoc As Word.Document '<=========
Set Mail_Object = CreateObject("Outlook.Application")
Set Mail_Single = Mail_Object.CreateItem(0)
Set wdDoc = Mail_Single.GetInspector.WordEditor '<========
For i = 1 To ThisWorkbook.Sheets.Count
If Sheets(i).Name = "India_BB" Then
Sheets(i).Select
Set rng = Nothing
strSheetName = Sheets(i).Name
strSendTo = Sheet1.Range("A1").Text
strSubject = Sheet1.Range("B1").Text
Set rng = Sheets(strSheetName).Range("body").SpecialCells(xlCellTypeVisible)
rng.Copy
With Mail_Single
.To = strSendTo
.CC = ""
.BCC = ""
.Subject = strSubject
' .HTMLBody = RangetoHTML(rng)
.Display
wdDoc.Range.PasteAndFormat wdChartPicture & .HTMLBody = " " '<=======
End With
End If
Next i
End Sub
I've been looking for an answer for this for a few weeks, and it's driving me crazy:
I have a macro that copies specific cells to a new email in Outlook. It works perfectly if the IDE is open, but typically if it isn't it pastes the content into the current sheet instead of the new email. Even weirder is that sometimes it WILL work while the IDE is closed, but 99% of the time it won't, making this a nightmare to diagnose.
It's driving me crazy, you guys are my only hope!
Sub EmailReports()
Dim rngSubject As Range
Dim rngTo As Range
Dim rngBody As Range
Dim objOutlook As Object
Dim objMail As Object
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
xRow = ActiveCell.Row
RMName = Sheets("Dashboard").Range("B" & xRow)
LastTaskRow = Sheets(RMName).Range("A1")
With Target
Range("E" & xRow) = Format(Now(), "MM/DD/YYYY")
End With
Set rngTo = Range("C" & xRow)
Set rngSubject = Worksheets("Dashboard").Range("K4")
Set rngBody = Worksheets(RMName).Range("D4:E" & LastTaskRow)
rngBody.Copy
With objMail
.To = rngTo
.Subject = rngSubject
.Display
End With
SendKeys "^({v})", True
Set objOutlook = Nothing
Set objMail = Nothing
End Sub
I tried adding Dmitry's suggestion, though I'm not sure I added it properly.
Sub EmailReports()
Dim rngSubject As Range
Dim rngTo As Range
Dim rngBody As Range
Dim objOutlook As Object
Dim objMail As Object
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
xRow = ActiveCell.Row
RMName = Sheets("Dashboard").Range("B" & xRow)
LastTaskRow = Sheets(RMName).Range("A1")
With Target
Range("E" & xRow) = Format(Now(), "MM/DD/YYYY")
End With
Set rngTo = Range("C" & xRow)
Set rngSubject = Worksheets("Dashboard").Range("K4")
Set rngBody = Worksheets(RMName).Range("D4:E" & LastTaskRow)
rngBody.Copy
With objMail
.To = rngTo
.Subject = rngSubject
.Display
End With
Set objHTML = CreateObject("htmlfile")
ClipboardText = objHTML.ParentWindow.ClipboardData.GetData("text")
objMail.Body = rngBody.Text
Set objOutlook = Nothing
Set objMail = Nothing
End Sub
Instead of using SendKeys (which will send the specified input to the foreground window, whatever it happens to be), paste the text using
Set objHTML = CreateObject("htmlfile")
ClipboardText = objHTML.ParentWindow.ClipboardData.GetData("text")
objMail.Body = ClipboardText
Or, even better, do not use clipboard at all and read the text of the current selection in Excel explicitly and set the Body property in Outlook:
objMail.Body = rngBody.Text
I finally figured it out. Dmitry was on the right track by using an HTML file instead of a simple copy/SendKeys.
Here is the new code:
Sub EmailReports()
Dim rngSubject As Range
Dim rngTo As Range
Dim rngBody As Range
Dim objOutlook As Object
Dim objMail As Object
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
xRow = ActiveCell.Row
RMName = Sheets("Dashboard").Range("B" & xRow)
LastTaskRow = Sheets(RMName).Range("A1")
With Target
Range("E" & xRow) = Format(Now(), "MM/DD/YYYY")
End With
Set rngTo = Range("C" & xRow)
Set rngSubject = Worksheets("Dashboard").Range("K4")
Set rngBody = Worksheets(RMName).Range("D4:E" & LastTaskRow)
With objMail
.To = rngTo
.Subject = rngSubject
.HTMLBody = RangetoHTML(rngBody)
.Display
End With
Set objOutlook = Nothing
Set objMail = Nothing
End Sub
It is calling a function I found on Microsoft's website called "RangetoHTML":
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
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