Attach file with path based on cell value to email - excel

I am trying to send an email with the below code from my workbook. It works fine but only until I try to attach a file.
The file is created by another VBA code and the file name is defined by the cell values specified below, but I get a debug error when I try to run the code and it won't attach. I've tested with a named path eg C:test\test.docx and it works fine.
How can I get it to accept the path based on the cell values? I've set it to .Display whilst testing rather than send.
Option Explicit
Option Compare Text 'ignore case sensitivity when comparing strings
Sub SendEmail()
Dim objOutlook As Object
Dim objMail As Object
Dim OL As Outlook.Application, ES As Worksheet, r As Long, i As Long
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
Dim path As String
path = "\\Wbcphfil01.wbc.lan\dts\Groups\Operational_Services\opserv_group\Enforcement\NRSWA\Licences\Mobile Plant\Applications 2019-20\" & Cells(i, 4) & " (" & Cells(i, 13) & ").docx"
r = Cells(Rows.Count, 1).End(xlUp).Row
For i = 5 To r
With Cells(i, 7)
If .Value <> "" And Cells(i, 5) = "Mobile Plant" Then
With objMail
.To = Cells(i, 11).Value
.Subject = "Your " & Cells(i, 5).Value & " licence - " & Cells(i, 4).Value
.Body = "abc"
.Attachments.Add path
.Display
End With
End If
End With
Next i
Set objOutlook = Nothing
Set objMail = Nothing
End Sub

You are using Cells(i, 4) on the path to the file before you defined what the variable i actually is! Maybe move the path inside your For Loop?
Option Explicit
Option Compare Text 'ignore case sensitivity when comparing strings
Sub SendEmail()
Dim objOutlook As Object
Dim objMail As Object
Dim OL As Outlook.Application, ES As Worksheet, r As Long, i As Long
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
Dim path As String
r = Cells(Rows.Count, 1).End(xlUp).Row
For i = 5 To r
path = "\\Wbcphfil01.wbc.lan\dts\Groups\Operational_Services\opserv_group\Enforcement\NRSWA\Licences\Mobile Plant\Applications 2019-20\" & Cells(i, 4) & " (" & Cells(i, 13) & ").docx"
With Cells(i, 7)
If .Value <> "" And Cells(i, 5) = "Mobile Plant" Then
With objMail
.To = Cells(i, 11).Value
.Subject = "Your " & Cells(i, 5).Value & " licence - " & Cells(i, 4).Value
.Body = "abc"
.Attachments.Add path
.Display
End With
End If
End With
Next i
Set objOutlook = Nothing
Set objMail = Nothing
End Sub

Related

Excel - Run-time error 13 in vba macro created

I am trying to create a macro to send automated reminders.
I am sending below the two macros:
Sub Auto_Open()
Dim vResp As Variant, dTime As Date
vResp = MsgBox("Inviare email ora?", vbYesNo)
If vResp = 6 Then 'YES
Call EmailReminder
ElseIf vResp = 7 Then 'NO
dTime = CDate(InputBox("Send email at:", , Time + TimeValue("00:00:10")))
Do Until Time = dTime 'OR = #8:00:00 AM#
DoEvents
Loop
Call EmailReminder
End If
End Sub
Sub EmailReminder()
Dim oOL As Outlook.Application, oMail As Outlook.MailItem, oNS As Outlook.Namespace
Dim oMapi As Outlook.MAPIFolder, oExpl As Outlook.Explorer
Dim sBody As String, dDate As Date
Dim oWS As Worksheet, r As Long, i As Long, sStart As String
Set oWS = Foglio1
Set oOL = New Outlook.Application
Set oExpl = oOL.ActiveExplorer
If TypeName(oExpl) = "Nothing" Then
Set oNS = oOL.GetNamespace("MAPI")
Set oMapi = oNS.GetDefaultFolder(olFolderInbox)
Set oExpl = oMapi.GetExplorer
End If
With oWS.Range("E1")
r = .CurrentRegion.Rows.Count
For i = 1 To r
dDate = .Cells(i, 1)
sBody = "Oggi è il compleanno di" & .Cells(i, 2) & dDate & .Cells(i, -4) & " " & .Cells(i, -3) & vbCrLf & "Facciamo i nostri auguri!"
If Date = dDate Or Date = Int(dDate) Then ' Use INT to eliminate time info
Set oMail = oOL.CreateItem(oIMailItem)
With oMail
.Recipients.Add "umberto.roselli#openfiber.it" 'Indirizzo ricevente
.Subject = "Nuovo compleanno oggi:" & .Cells(i, -4) & " " & .Cells(i, -3) & .Body = sBody: .Send
End With
End If
Next i
End With
MsgBox "Messaggio email inviato correttamente!"
End Sub
I keep getting, however, on the second macro the error Run-Time 13: Type not matching but it doesn't give me any indication where the error is.
Can you help me out?
Thank you very much in advance
Fyi
Private Sub Workbook_Open()
Dim i As Long
Dim OutApp, OutMail As Object
Dim strto, strcc, strbcc, strsub, strbody As String
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
For i = 2 To Range("e65536").End(xlUp).Row
If Cells(i, 8) <> "Y" Then
If Cells(i, 5) - 7 < Date Then
strto = Cells(i, 7).Value 'email address
strsub = Cells(i, 1).Value & " " & Cells(i, 2).Value & " compleanno il " & Cells(i, 5).Value 'email subject
strbody = "Il compleanno di " & Cells(i, 1).Value & " " & Cells(i, 2).Value & " sarà il " & Cells(i, 5).Value & vbNewLine 'email body
With OutMail
.To = strto
.Subject = strsub
.Body = strbody
.Send
End With
Cells(i, 8) = "Mail Sent " & Now()
Cells(i, 9) = "Y"
End If
End If
Next
Set OutMail = Nothing
Set OutApp = Nothing
End Sub

Can I add a file path from a cell in Attachments.Add?

I'm trying to create an email for every row of data on my sheet.
It seems to be working until I add the .Attachments.Add line.
I am trying to identify the file path from a cell.
Sub CreateEmails()
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
Dim objEmail As Object
Dim eBody As String
Range("A2").Select
Do Until IsEmpty(ActiveCell)
Set objEmail = objOutlook.CreateItem(olMailItem)
eBody = "<p>Hi " & ActiveCell(0, 1).Value & ", </p>" _
& "<p>Message Body</p>" & _
"<p>Thank you!</p><br>"
With objEmail
.to = ActiveCell(0, 2).Value
.Subject = ActiveCell(0, 3).Value
.HTMLBody = "<html><head></head><body>" & eBody & "</body></html>"
.Attachments.Add ActiveCell(0, 5).Value
.Display
End With
ActiveCell.Offset(1, 0).Select
Loop
End Sub
The Attachments.Add method requires the source of the attachment which can be a file (represented by the full file system path with a file name) or an Outlook item that constitutes the attachment. It is not clear what value is passed in your sample code, so I'd suggest debugging the code more carefully and making sure a valid value is passed. For example:
Sub AddAttachment()
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Set myItem = Application.CreateItem(olMailItem)
Set myAttachments = myItem.Attachments
myAttachments.Add "C:\Test.doc", _
olByValue, 1, "Test"
myItem.Display
End Sub
Instead of using something like this,
ActiveCell(0,1).Value
you should use something like this.
ActiveCell.Offset(0,1).Value
Even better would be not to use ActiveCell, declare and use a variable for the range.
Sub CreateEmails()
Dim objOutlook As Object
Dim objEmail As Object
Dim rng As Range
Dim eBody As String
Set objOutlook = CreateObject("Outlook.Application")
Set rng = Range("A2")
Do Until rng.Value <> ""
Set objEmail = objOutlook.CreateItem(olMailItem)
eBody = "<p>Hi " & rng.Offset(0, 1).Value & ", </p>" _
& "<p>Message Body</p>" & _
"<p>Thank you!</p><br>"
With objEmail
.to = rng.Offset(0, 2).Value
.Subject = rng.Offset(0, 3).Value
.HTMLBody = "<html><head></head><body>" & eBody & "</body></html>"
.Attachments.Add rng.Offset(0, 5).Value
.Display
End With
Set rng = rng.Offset(1, 0)
Loop
End Sub

Add hyperlink from excel VBA to outlook appointment

I have code that works fine in all aspects, but I can not find a way to create a hyperlink in an Outlook appointment. The address is placed in column H in Excel, and I want to use VBA to export it to a certain calendar. Any help would greatly be appriciated.
My code is as follows:
Sub Appointments()
Const olAppointmentItem As Long = 1
Dim OLApp As Object
Dim OLNS As Object
Dim OLAppointment As Object
Dim miCalendario As Object
Dim r As Long
On Error Resume Next
Set OLApp = GetObject(, "Outlook.Application")
If OLApp Is Nothing Then Set OLApp = CreateObject("Outlook.Application")
On Error GoTo 0
If Not OLApp Is Nothing Then
Set OLNS = OLApp.GetNamespace("MAPI")
OLNS.Logon "Outlook"
b = 1
r = 2
Dim mysub, myStart, myEnd, mydes, myallday
While Len(Cells(r, 5).Text) <> 0
mysub = Cells(r, 7)
If Not Cells(r, 13).Value = 0 Then
mysub = mysub & "(s. " & Cells(r, 13).Value & ")" & vbCrLf
End If
'& ", " & Cells(r, 3)
myStart = DateValue(Cells(r, 1).Value) + Cells(r, 2).Value
myEnd = DateValue(Cells(r, 1).Value) + Cells(r, 3).Value
mydes = ""
Set miCalendario = OLApp.Session.GetDefaultFolder(9).Folders(ActiveSheet.Name)
Set OLAppointment = miCalendario.Items.Add(olAppointmentItem)
Dim olItems As Items
Dim olApptItem As Outlook.AppointmentItem
Set olItems = miCalendario.Items
Set olApptItem = miCalendario.Items.GetFirst
'add appointments
On Error Resume Next
With OLAppointment
.Subject = mysub
.Start = myStart
.End = myEnd
.Body = mydes
If Not Cells(r, 1).Value = 0 Then
If Not Cells(r, 8).Value = 0 Then
mydes = mydes & Cells(1, 8).Value & " - " & Cells(r, 8).Value & vbCrLf
End If
.Body = mydes
End If
.Location = Cells(r, 4).Value .Save
End With
r = r + 1
b = b + 1
Wend
Set OLAppointment = Nothing
Set OLNS = Nothing
Set OLApp = Nothing
End If
End Sub
You need to use .HTMLBody insted .Body
.HTMLbody = "link_Mask"
I hope it'll help

Sending Email Based on Cell Value within a Loop

I have a sample sheet
I have a module that runs through the list in a loop within another loop, checking for duplicate names and then grouping the names together to send an email with an attachment based on Column D (Division).
Sample 4 would get one email with 3 attachments.
I have been asked to build in the ability to exclude people based on a value (I chose yes or no, column C) before running the module.
Reason being that if the list is long (over 1000 names) to set it before generating the emails. I would build in a trigger to set that value, but it is apparently an arbitrary decision made by the senders in a dept.
I have tried to build an IF statement into the loop as shown below but it is as if the If statement is coming out as not being true (I stepped through).
Which means all the With Outmail objects will not work.
I was able to get it to work by using the if statement with a for/next setup on its own (no loops), but cannot get it to work with the loop, which is the more important piece.
Here is the main piece of code. The main loop and then the if statement to account for the yes or no values:
Do While r <= rng.Rows.Count
If rng.Cells(r, 3).Value Like "?*#?*.?*" And LCase(rng.Cells(r, 3)) = "yes" Then
Set OutMail = OutApp.CreateItem(0)
End If
And here is the full sub:
Sub EmailDivisions()
Dim OutApp As Object
Dim OutMail As Object
Dim cell, lookrng As Range
Dim strDir As String
Dim strFilename As String
Dim sigString As String
Dim strBody As String
Dim strName As Variant
Dim strName1 As Variant
Dim strDept As Variant
Dim strName2 As String
Dim strName3 As Variant
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
sigString = Environ("appdata") & _
"\Microsoft\Signatures\Divisions.htm"
If Dir(sigString) <> "" Then
signature = GetBoiler(sigString)
Else
signature = ""
End If
Set rng = ActiveSheet.UsedRange
r = 2
Do While r <= rng.Rows.Count
If rng.Cells(r, 3).Value Like "?*#?*.?*" And LCase(rng.Cells(r, 3)) = "yes" Then
Set OutMail = OutApp.CreateItem(0)
End If
Set strName = rng.Cells(r, 1)
Set strDept = rng.Cells(r, 4)
strName2 = Left(strName, InStr(strName & " ", " ") - 1)
With OutMail
strFilename = Dir("\\Divisons\1a*" & strDept & "*")
.SentOnBehalfOfName = "divisionalsend#xyz.org"
.To = rng.Cells(r, 2).Value
.Subject = "Monthly Divisional Report for " & strDept
.HTMLBody = "<Font Face=calibri>" & "Dear " & strName2 & ",<br><br>" & signature
.Attachments.Add strDir & strFilename
'See if the next row is for the same sender. If so, process that
'row as well. And then keep doing it until no more rows match
Do While rng.Cells(r, 2).Value = rng.Cells(r + 1, 2)
r = r + 1
Set strDept = rng.Cells(r, 4)
strfilename1 = Dir("\\Divisions\1a*" & strDept & "*")
.Subject = "Monthly Divisional Report for Your Departments"
.Attachments.Add strDir & strfilename1
Loop
.Display
End With
Set OutMail = Nothing
r = r + 1
Loop
Set OutApp = Nothing
End Sub
Function GetBoiler(ByVal sFile As String) As String
Dim FSO As Object
Dim ts As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Set ts = FSO.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.ReadAll
ts.Close
End Function
Figured it out, here is the final sub:
Sub EmailDivisions()
Dim OutApp As Object
Dim OutMail As Object
Dim cell, lookrng As Range
Dim strDir As String
Dim strFilename As String
Dim sigString As String
Dim strBody As String
Dim strName As Variant
Dim strName1 As Variant
Dim strDept As Variant
Dim strName2 As String
Dim strName3 As Variant
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
sigString = Environ("appdata") & _
"\Microsoft\Signatures\Divisions.htm"
If Dir(sigString) <> "" Then
signature = GetBoiler(sigString)
Else
signature = ""
End If
Set rng = ActiveSheet.UsedRange
r = 2
Do While r <= rng.Rows.Count
Debug.Print LCase(rng.Cells(r, 2))
If Cells(r, 2).Value Like "?*#?*.?*" And LCase(Cells(r, 3)) = "yes" Then
Set OutMail = OutApp.CreateItem(0)
ElseIf Cells(r, 2).Value Like "?*#?*.?*" And LCase(Cells(r, 3)) = "no" Then GoTo ContinueLoop
End If
Set strName = Cells(r, 1)
Set strDept = Cells(r, 4)
strName2 = Left(strName, InStr(strName & " ", " ") - 1)
With OutMail
strFilename = Dir("\\Divisons\1a*" & strDept & "*")
.SentOnBehalfOfName = "divisionalsend#xyz.org"
.To = Cells(r, 2).Value
.Subject = "Monthly Divisional Report for " & strDept
.HTMLBody = "<Font Face=calibri>" & "Dear " & strName2 & ",<br><br>" & signature
.Attachments.Add strDir & strFilename
.display
'See if the next row is for the same sender. If so, process that
'row as well. And then keep doing it until no more rows match
Do While rng.Cells(r, 2).Value = rng.Cells(r + 1, 2)
r = r + 1
Set strDept = Cells(r, 4)
strfilename1 = Dir("\\Divisions\1a*" & strDept & "*")
.Subject = "Monthly Divisional Report for Your Departments"
.Attachments.Add strDir & strfilename1
.Display
ContinueLoop:
Loop
End With
Set OutMail = Nothing
r = r + 1
Loop
Set OutApp = Nothing
End Sub
Function GetBoiler(ByVal sFile As String) As String
Dim FSO As Object
Dim ts As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Set ts = FSO.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.ReadAll
ts.Close
End Function

MultiAttachment Distribution of varing files to multiple recipients

I have researched this topic and found great code - but not quite what I need. I have created an Excel file to setup a range for email distribution of an attachment to 3 hundred recipients - which works fine. But I have multiple attachments which need to go to the same recipient. Column A is the field where the file name is chosen - which picks up a pdf for recipient 1. Is it possible to use Column B for the second pdf file for recipient 1 and how do I loop that in?
Sub Mail_Report()
Dim OutApp As Object
Dim OutMail As Object
'Use presence of a Path to determine if a mail is sent.
Set Rng = Range(Range("J2"), Range("J" & Rows.Count).End(xlUp))
For Each cell In Rng
Rw = cell.Row
Path = cell.Value
If Path <> "" Then
'Get Date info from Path
'Dte = Right(Path, Len(Path) - InStrRev(Path, "\"))
'Get Territory to check for filename (Column A)
FilNmeStr = cell.Offset(0, -9).Value
'Email Address
ToName = cell.Offset(0, -5).Value
'Subject Line
SL = Cells(1, "K")
'Create Recipient List
For x = 1 To 4
Recp = cell.Offset(0, -x).Value
If Recp <> "" Then
Recp = cell.Offset(0, -x).Value
End If
RecpList = RecpList & ";" & Recp
Next
ccTo = RecpList
'Get Name
FirstName = cell.Offset(0, -7).Value
LastName = cell.Offset(0, -6).Value
'Loop through files in Path to see if
ClientFile = Dir(Path & "\*.*")
Do While ClientFile <> ""
If InStr(ClientFile, FilNmeStr) > 0 Then
AttachFile = Path & "\" & ClientFile
MailBody = "Hi " & FirstName & "," & vbNewLine & vbNewLine _
End If
ClientFile = Dir
Loop
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(o)
With OutMail
.SentOnBehalfOfName = """TechSupport"" <TechSupport#anycompany.com>"
.To = ToName
.cc = ccTo
.Subject = SL & " - " & cell.Offset(0, -9).Value
.Body = MailBody
.Attachments.Add (AttachFile)
.Display
'.Send
End With
Set OutMail = Nothing
Set OutApp = Nothing
RecpList = ""
End If
Next
End Sub
Try it this way.
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
https://www.rondebruin.nl/win/s1/outlook/amail6.htm

Resources