How to loop and create an Outlook message body - vba

I am trying to loop a list from a sheet into a Outlook Body, but I just loops through until the end and show the last one...
Any ideas?
Sub SendEmail()
Dim ws As Worksheet
Set ws = Worksheets("PrestageData")
strUsed = ws.UsedRange.Rows.Count
Dim EmailApp As Outlook.Application
Dim Source As String
Set EmailApp = New Outlook.Application
Dim EmailItem As Outlook.MailItem
Set EmailItem = EmailApp.CreateItem(olMailItem)
EmailItem.To = frmForm.txtCollector.Value & "mail.dk"
'EmailItem.CC = "hello#gmail.com"
'EmailItem.BCC = "hhhh#gmail.com"
EmailItem.Subject = "Din FAP er klar til afhentning"
For i = 2 To strUsed
If ws.Cells(i, 4).Value = "KLAR" Then
strReady = ws.Cells(i, 1).Value
EmailItem.HTMLBody = "Hej," & frmForm.txtCollector.Value & "<br><br>" & "Følgende FAP er klar: " & strReady
'Source = ThisWorkbook.FullName
'EmailItem.Attachments.Add Source
End If
Next
EmailItem.Display
End Sub

You are missing an Exit For to leave the loop after the first find:
For i = 2 To strUsed
If ws.Cells(i, 4).Value = "KLAR" Then
strReady = ws.Cells(i, 1).Value
EmailItem.HTMLBody = "Hej," & frmForm.txtCollector.Value & "<br><br>" & "Følgende FAP er klar: " & strReady
Exit For
End If
Next
In case you want to capture multiple matching entries, you have to extend the body rather than replacing it in full. You could append an extra line per entry.

It seems every time in the loop you overwrite the message body. Instead, you need to append the message body with a content found in the worksheet:
EmailItem.HTMLBody = "Hej," & frmForm.txtCollector.Value
For i = 2 To strUsed
If ws.Cells(i, 4).Value = "KLAR" Then
strReady = ws.Cells(i, 1).Value
EmailItem.HTMLBody = EmailItem.HTMLBody & "<br><br>" & "Følgende FAP er klar: " & strReady
'Source = ThisWorkbook.FullName
'EmailItem.Attachments.Add Source
End If
Next
But I'd suggest playing a well-formed HTML markup in the code and find the closing tag in the HTMLBody string and paste your add-in there. For example, you could use the Replace function available in VBA:
EmailItem.HTMLBody = Replace(EmailItem.HTMLBody, "</body>", "<br><br>" & "Følgende FAP er klar: " & strReady & "</body>")

Related

Runtime Error - Cannot find this file; verify name & file path correct (Excel / VBA)

Running into error message in title when attempting to link attachments to email. The attachments are stored in Folder Names respective to the "type" of company, which is why I'm attempting to add a for loop to retrieve "type" from spreadsheet.
Sub mailTest()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim olAttachmentLetter As Outlook.Attachments
Dim fileLocationLetter As String
Dim dType As String
For i = 2 To 3
Set olApp = New Outlook.Application
Set olMail = olApp.CreateItem(olMailItem)
Set olAttachmentLetter = olMail.Attachments
fileLocationLetter = "C:\...\user\Desktop\FileLocation"
letterName = "TestLetter1"
dType = Worksheets("Test1").Cells(i, 2).Value
mailBody = "Hello " _
& Worksheets("Test1").Cells(i, 4) _
& "," _
& Worksheets("BODY").Cells(2, 1).Value _
& Worksheets("BODY").Cells(3, 1).Value _
& Worksheets("BODY").Cells(4, 1).Value & " " & dType _
& Worksheets("BODY").Cells(5, 1).Value & " TTT" & dType & "xx18" _
& Worksheets("BODY").Cells(6, 1).Value _
& Worksheets("BODY").Cells(7, 1).Value
With olMail
.To = Worksheets("Test1").Cells(i, 5).Value
.Subject = Worksheets("Test1").Cells(i, 3).Value & " - "
.HTMLBody = "<!DOCTYPE html><html><head><style>"
.HTMLBody = .HTMLBody & "body{font-family: Calibri, ""Times New Roman"", sans-serif; font-size: 13px}"
.HTMLBody = .HTMLBody & "</style></head><body>"
.HTMLBody = .HTMLBody & mailBody & "</body></html>"
''Adding attachment
.Attachments.Add fileLocationLetter & letterName & ".pdf"
.Display
'' .Send (Once ready to send)
End With
Set olMail = Nothing
Set olApp = Nothing
Next
End Sub
What am I doing wrong here? The file is stored in 'C:...\user\Desktop\FileLocation\TestLetter1.pdf'
Thank you kindly.
You are missing the \ between the fileLocation and the letterName. Thus, either write this:
.Attachments.Add fileLocationLetter & "\" & letterName & ".pdf"
or this:
fileLocationLetter = "C:\...\user\Desktop\FileLocation\"
With much help from #Vityata, figured it out.
Essentially being able to make two attachments, one is static with known file name, the second attachment's name is dependent on stored cell value. The workaround was to break the path/name of the file as stored strings. Maybe there's an easier way, but this worked for me!
Code used:
Sub mailTest()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
'' Identify Attachments
Dim olAttachmentLetter As Outlook.Attachments
Dim olAttachmentSSH As Outlook.Attachments
'' Identify Attachment Locations / Paths
Dim fileLocationLetter As String
Dim fileLocationSSH As String
Dim fileLocationSSHi As String
Dim fileLocationSSHii As String
'' Type Variable, referencing cell in worksheet where "Type" is stored (in loop below)
Dim dType As String
'' Creating the loop - Replace 4 with end of rows. Will eventually create code to automatically identify the last cell with stored value
For i = 2 To 4
Set olApp = New Outlook.Application
Set olMail = olApp.CreateItem(olMailItem)
Set olAttachmentLetter = olMail.Attachments
Set olAttachmentSSH = olMail.Attachments
''File Location for Letter
fileLocationLetter = "C:\...\Directory"
''File Location for Excel sheet - Need 3 fields as file name is dynamic based on loop value
fileLocationSSH = "C:\...\Directory\Excel Files"
fileLocationSSHi = "Beginning of File name..."
fileLocationSSHii = " ... End of File name"
letterName = "Name of PDF attachment"
dType = Worksheets("Test1").Cells(i, 2).Value
''Body of Email - Each new line represents new value (linking to hidden worksheet in Excel doc)
mailBody = "Hello " _
& Worksheets("Test1").Cells(i, 4) _
& "," _
& Worksheets("BODY").Cells(2, 1).Value _
& Worksheets("BODY").Cells(3, 1).Value _
& Worksheets("BODY").Cells(4, 1).Value & " " & dType _
& Worksheets("BODY").Cells(5, 1).Value _
& Worksheets("BODY").Cells(6, 1).Value _
& Worksheets("BODY").Cells(7, 1).Value
With olMail
.To = Worksheets("Test1").Cells(i, 5).Value
.Subject = Worksheets("Test1").Cells(i, 3).Value
.HTMLBody = "<!DOCTYPE html><html><head><style>"
.HTMLBody = .HTMLBody & "body{font-family: Calibri, ""Times New Roman"", sans-serif; font-size: 13px}"
.HTMLBody = .HTMLBody & "</style></head><body>"
.HTMLBody = .HTMLBody & mailBody & "</body></html>"
'' Adding attachments, referencing file locations and amending file name if needed
.Attachments.Add fileLocationLetter & "\" & letterName & ".pdf"
.Attachments.Add fileLocationSSH & "\" & dType & "\" & fileLocationSSHi & dType & fileLocationSSHii & ".xlsx"
.Display
'' .Send (Once ready to send)
End With
Set olMail = Nothing
Set olApp = Nothing
Next
End Sub

Saving data in a cell in the next empty row

I have code which sends a file via Outlook and gets-saves data into an Excel file.
For sending a file via Outlook, it works perfectly. However it saves data into the same row of the Excel file. Code should save data into the next empty row of the Excel file.
Sub AutoEmail()
On Error GoTo Cancel
Dim Resp As Integer
Resp = MsgBox(prompt:=vbCr & "Yes = Review Email" & vbCr & "No = Immediately Send" & vbCr & "Cancel = Cancel" & vbCr, _
Title:="Review email before sending?", _
Buttons:=3 + 32)
'dfsfsd
Range("S20").Copy
Range("T20").PasteSpecial xlPasteValues
'sdaasdf
Workbooks.Open ("C:\Users\computername\Desktop\New folder (2)\ff.xlsx")
ThisWorkbook.Activate
'1
Workbooks("1435250.xlsx").Worksheets("RFI").Range("T20").Copy _
Workbooks("ff.xlsx").Worksheets("Sayfa1").Range("P2")
'1
Select Case Resp
'Yes was clicked, user wants to review email first
Case Is = 6
Dim myOutlook As Object
Dim myMailItem As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = Application.ActiveWorkbook.FullName
With otlNewMail
.To = Cells(33, 10)
.CC = Cells(1, 1)
.Subject = Cells(23, 10) & ": " & Cells(21, 10)
.Body = "this is a text" & vbCr & vbCr & "" & Cells(23, 10) & "."
.Attachments.Add FName
.Display
End With
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If no is clicked
Case Is = 7
Dim myOutlok As Object
Dim myMailItm As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = ActiveWorkbook.Path & "\" & ActiveWorkbook.Name
With otlNewMail
.To = ""
.CC = ""
.Subject = ""
.Body = "Good Morning," & vbCr & vbCr & " " & Format(Date, "MM/DD") & "."
.Attachments.Add FName
.Send
'.Display
'Application.Wait (Now + TimeValue("0:00:01"))
'Application.SendKeys "%s"
End With
'otlApp.Quit
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If Cancel is clicked
Case Is = 2
Cancel:
MsgBox prompt:="No Email has been sent.", _
Title:="EMAIL CANCELLED", _
Buttons:=64
End Select
End Sub
How can I save data (End(xlUp).Row) into the next empty row of an Excel file?
Change:
Workbooks("1435250.xlsx").Worksheets("RFI").Range("T20").Copy _
Workbooks("ff.xlsx").Worksheets("Sayfa1").Range("P2")
To this:
With Workbooks("ff.xlsx").Worksheets("Sayfa1")
Workbooks("1435250.xlsx").Worksheets("RFI").Range("T20").Copy .Range("P" & .Range("P" & .Rows.count).End(xlUp).Row + 1)
End With

Writing Values Of Cells Into Another Excel In VBA

I have this code to send e-mail with attached via Outlook:
Sub AutoEmail()
On Error GoTo Cancel
Dim Resp As Integer
Resp = MsgBox(prompt:=vbCr & "Yes = Review Email" & vbCr & "No = Immediately Send" & vbCr & "Cancel = Cancel" & vbCr, _
Title:="Review email before sending?", _
Buttons:=3 + 32)
Select Case Resp
'Yes was clicked, user wants to review email first
Case Is = 6
Dim myOutlook As Object
Dim myMailItem As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = Application.ActiveWorkbook.FullName
With otlNewMail
.To = Cells(33, 10)
.CC = Cells(1, 1)
.Subject = Cells(23, 10) & ": " & Cells(21, 10)
.Body = "Good morning" & vbCr & vbCr & "" & Cells(23, 10) & "."
.Attachments.Add FName
.Display
End With
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If no is clicked
Case Is = 7
Dim myOutlok As Object
Dim myMailItm As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = ActiveWorkbook.Path & "\" & ActiveWorkbook.Name
With otlNewMail
.To = ""
.CC = ""
.Subject = ""
.Body = "Good Morning," & vbCr & vbCr & " " & Format(Date, "MM/DD") & "."
.Attachments.Add FName
.Send
'.Display
'Application.Wait (Now + TimeValue("0:00:01"))
'Application.SendKeys "%s"
End With
'otlApp.Quit
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If Cancel is clicked
Case Is = 2
Cancel:
MsgBox prompt:="No Email has been sent.", _
Title:="EMAIL CANCELLED", _
Buttons:=64
End Select
End Sub
However there is another thing that i want to add. I want to write some cells into another excel after sending e-mail via Outlook, lets say A2 to B15. The excel file which i want to write on is in C:\Users\Computername\Desktop\Savingdata.xlsx
Mert,
Try the following, add these two lines at the beginning of your code:
Dim wbThisWorkbook, wbTheOneToSaveTo As Workbook
Set wbThisWorkbook = Workbooks("TheNameOfYourCurrentWorkbook")
Then after your sending routine, add this:
Set wbTheOneToSaveTo = Workbooks.Open ("C:\Users\Computername\Desktop\Savingdata.xlsx")
wbThisWorkbook.Sheets("TheNameOfThe Worksheet").Range("A2").Copy
wbTheOneToSaveTo.Sheets("TheNameOfTheWorksheet").Range("B15").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False 'adjust parameters according to your needs
wbTheOneToSaveTo.Close True
wbThisWorkbook.Activate
Hope this helps!

Object does not support this property or method error

I'm trying to copy data from excel to fallible PDF form. with below code, I open fallible form and populate the data and I need to save using varibale 'pr' .
While saving it is throwing run time error
"Object doesn't support this property or method"
Dim fcount As Long
Dim sFieldName As String
Set AcrobatApplication = CreateObject("AcroExch.App")
Set AcrobatDocument = CreateObject("AcroExch.AVDoc")
If AcrobatDocument.Open("C:\Users\Desktop\Projects\Jan 2018\Excel to PDF\Test.pdf", "") Then
AcrobatApplication.Show
Set AcroForm = CreateObject("AFormAut.App")
Set Fields = AcroForm.Fields
fcount = Fields.Count ' Number of Fields
With ThisWorkbook.Sheets(1)
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 2 To LastRow
Fields("Enter county name").Value = Range("A" & i).Value
Fields("Enter county served").Value = Range("B" & i).Value
Fields("Parcel number").Value = Range("C" & i).Value
pr = Range("C" & i).Value
Fields("Property owner name").Value = Range("D" & i).Value
fname = "C:\Users\Desktop\Projects\Jan 2018\Excel to PDF\docs\" & pr & ".pdf"
If AcrobatDocument.Save(PDSaveFull, fname) = False Then
MsgBox ("Cannot save the modified document")
End If
Next
End With
Else
MsgBox "failure"
Dim pr as String
should be enough considering the fact that you are using it only here:
fname = "C:\Users\Desktop\Projects\Jan 2018\Excel to PDF\docs\" & pr & ".pdf"

Send e-mail dependant on specific cell contents

I am a novice VBA programmer and I have searched for this but am unable to find a solution that exactly matches what I need.
I have a code to ping out customer's IP address but I only need e-mail notifications for the pings that have timed out.
The ping results are in column D and the e-mails are in column E of my spreadsheet. I'd be grateful for any help.
Thanks in advance.
Dim OutlookApp
Dim objMail
Dim x As Long
Dim PingResults As range
lastrow = Sheets("Ping").Cells(Rows.Count, 1).End(xlUp).Row
For x = 2 To lastrow
Set PingResults = range("d2:D250")
Set OutlookApp = CreateObject("Outlook.Application")
Set objMail = OutlookApp.CreateItem(olMailItem)
If PingResults.Cells.Value = "Request timed out." Then
objMail.To = Cells(x, 5).Value
With objMail
.Subject = Cells(x, 1) & " " & "-" & " " & Cells(x, 2) & " " & "-" & " " & Cells(x, 3)
.Body = "Run Diagnostics. Customer's broadband appears to have issues" & vbCrLf & Cells(x, 4)
.Display
.Save
End With
SendKeys "%{s}", True
ElseIf PingResults.Cells.Value = "" Then
Set OutlookApp = Nothing
Set objMail = Nothing
End If
End Sub
you most probably are after this:
Option Explicit
Sub main()
Dim pingResults As Range, cell As Range
With Sheets("Ping")
With .Range("D1", .Cells(.Rows.Count, "D").End(xlUp))
.AutoFilter Field:=1, Criteria1:="Request timed out."
If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then Set pingResults = .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible)
End With
.AutoFilterMode = False
End With
If Not pingResults Is Nothing Then
With CreateObject("Outlook.Application")
For Each cell In pingResults
With .CreateItem(0) '<--| olMailItem is an item of an OutLook enumeration whose value is "zero"
.Display
.to = cell.Offset(, 1).Value
.Subject = cell.Offset(, -3) & " " & "-" & " " & cell.Offset(, -2) & " " & "-" & " " & cell.Offset(, -1)
.Body = "Run Diagnostics. Customer's broadband appears to have issues" & vbCrLf & cell.Value
.Save
End With
SendKeys "%{s}", True
Next
.Quit
End With
End If
End Sub
This should do it:
Dim OutlookApp
Dim objMail
Dim x As Long
Dim PingResults As Range
Set OutlookApp = CreateObject("Outlook.Application")
lastrow = Sheets("Ping").Cells(Rows.Count, 1).End(xlUp).Row
Set PingResults = Range("d1:D" & lastrow)
For x = 2 To lastrow
If PingResults.Cells(x, 1).Value = "Request timed out." Then
Set objMail = OutlookApp.CreateItem(olMailItem)
With objMail
.To = Cells(x, 5).Value
.Subject = Cells(x, 1) & " " & "-" & " " & Cells(x, 2) & " " & "-" & " " & Cells(x, 3)
.Body = "Run Diagnostics. Customer's broadband appears to have issues" & vbCrLf & Cells(x, 4)
.Display
.Save
End With
SendKeys "%{s}", True
Set objMail = Nothing
End If
Next x
Set OutlookApp = Nothing