Error -2147220975 when sending an email by an Excel VBA - vba

I've set up a button in my Excel Sheet that should be able so save a picture of the sheet to my hard drive and then send an Email to a specific address with the picture attached to it, the saving of the picture works fine, but when I try and send the Email using a piece of code I found at http://www.exceltoolset.com/sending-email-with-vba/ it returns the error: -2147220975
Here is the whole sub:
Sub SendKnap_Klik()
Set Sheet = ActiveSheet
Ret = IIf(Environ$("tmp") <> "", Environ$("tmp"), Environ$("temp"))
Output = Ret & "\SkemaSend.png"
zoom_coef = 100 / Sheet.Parent.Windows(1).Zoom
Set area = Sheet.Range(Sheet.PageSetup.PrintArea)
area.CopyPicture xlPrinter
Set chartobj = Sheet.ChartObjects.Add(0, 0, area.Width * zoom_coef, area.Height * zoom_coef)
chartobj.Chart.Paste
chartobj.Chart.Export Output, "png"
chartobj.Delete
ReturnValue = SendEMail("Subject", "MyMail#gmail.com", Range("J25").Value, "Body", "smtp.gmail.com", "", Output)
If ReturnValue = True Then
MsgBox "Emailen sent to " & Range("J25") & " was successfull!"
Else
MsgBox "Emailen sent to " & Range("J25") & " was not sent" & vbNewLine & "Error: " & Err.Number
End If
End Sub
Function SendEMail(Subject As String, _
FromAddress As String, _
ToAddress As String, _
MailBody As String, _
SMTP_Server As String, _
BodyFileName As String, _
Optional Attachments As Variant = Empty) As Boolean
Dim MailMessage As CDO.Message
Dim N As Long
Dim FNum As Integer
Dim S As String
Dim Body As String
Dim Recips() As String
Dim Recip As String
Dim NRecip As Long
' ensure required parameters are present and valid.
If Len(Trim(Subject)) = 0 Then
SendEMail = False
Exit Function
End If
If Len(Trim(FromAddress)) = 0 Then
SendEMail = False
Exit Function
End If
If Len(Trim(SMTP_Server)) = 0 Then
SendEMail = False
Exit Function
End If
' Clean up the addresses
Recip = Replace(ToAddress, Space(1), vbNullString)
If Right(Recip, 1) = ";" Then
Recip = Left(Recip, Len(Recip) - 1)
End If
Recips = Split(Recip, ";")
For NRecip = LBound(Recips) To UBound(Recips)
On Error Resume Next
' Create a CDO Message object.
Set MailMessage = CreateObject("CDO.Message")
If Err.Number <> 0 Then
SendEMail = False
Exit Function
End If
Err.Clear
On Error GoTo 0
With MailMessage
.Subject = Subject
.From = FromAddress
.To = Recips(NRecip)
If MailBody <> vbNullString Then
.TextBody = MailBody
Else
If BodyFileName <> vbNullString Then
If Dir(BodyFileName, vbNormal) <> vbNullString Then
' import the text of the body from file BodyFileName
FNum = FreeFile
S = vbNullString
Body = vbNullString
Open BodyFileName For Input Access Read As #FNum
Do Until EOF(FNum)
Line Input #FNum, S
Body = Body & vbNewLine & S
Loop
Close #FNum
.TextBody = Body
Else
' BodyFileName not found.
SendEMail = False
Exit Function
End If
End If ' MailBody and BodyFileName are both vbNullString.
End If
If IsArray(Attachments) = True Then
' attach all the files in the array.
For N = LBound(Attachments) To UBound(Attachments)
' ensure the attachment file exists and attach it.
If Attachments(N) <> vbNullString Then
If Dir(Attachments(N), vbNormal) <> vbNullString Then
.AddAttachment Attachments(N)
End If
End If
Next N
Else
' ensure the file exists and if so, attach it to the message.
If Attachments <> vbNullString Then
If Dir(CStr(Attachments), vbNormal) <> vbNullString Then
.AddAttachment Attachments
End If
End If
End If
With .Configuration.Fields
' set up the SMTP configuration
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = SMTP_Server
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "mymail#gmail.com"
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "pass"
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Update
End With
On Error Resume Next
Err.Clear
' Send the message
.Send
If Err.Number = 0 Then
SendEMail = True
Else
SendEMail = False
Exit Function
End If
End With
Next NRecip
SendEMail = True
End Function
I also changed settings on my Gmail account to allow unsecured programs to access the account
What am I doing wrong, should something be changed?

//
// MessageId: CDO_E_SMTP_SEND_FAILED
//
// MessageText:
//
// The message could not be sent to the SMTP server. The transport error code was %2. The server response was %1
//
#define CDO_E_SMTP_SEND_FAILED 0x80040211L
CDO takes it's default settings from Windows Mail/Outlook Express/Microsoft Internet Mail and News.
This VBA code list your configuration:
Set emailConfig = emailObj.Configuration
On Error Resume Next
For Each fld in emailConfig.Fields
Text = Text & vbcrlf & fld.name & " = " & fld
If err.number <> 0 then
Text = Text & vbcrlf & fld.name & " = Error - probably trying to read password - not allowed"
err.clear
End If
Next
Msgbox Replace(Text, "http://schemas.microsoft.com", "")

Related

Check which worksheets to export as pdf

I am a beginner in Excel VBA but I would like to create a file where I can select certain worksheets by means of a userform with checkboxes. In principle, it is then intended that only the check boxes where the value is true should be exported.
Below I have 2 codes that work well separately from each other but I have not yet been able to get them to work together.
Note: both codes come from the internet.
If possible I would like to write a loop to keep the overview.
the code to export sheets as pdf and put them in a outlook
Sub Saveaspdfandsend1()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo, I, xNum As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim xArrShetts As Variant
Dim xPDFNameAddress As String
Dim xStr As String
xArrShetts = Array("test", "Sheet1", "Sheet2") 'Enter the sheet names you will send as pdf files enclosed with quotation marks and separate them with comma. Make sure there is no special characters such as \/:"*<>| in the file name.
For I = 0 To UBound(xArrShetts)
On Error Resume Next
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
If xSht.Name <> xArrShetts(I) Then
MsgBox "Worksheet no found, exit operation:" & vbCrLf & vbCrLf & xArrShetts(I), vbInformation, "Kutools for Excel"
Exit Sub
End If
Next
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
'Check if file already exist
xYesorNo = MsgBox("If same name files exist in the destination folder, number suffix will be added to the file name automatically to distinguish the duplicates" & vbCrLf & vbCrLf & "Click Yes to continue, click No to cancel", _
vbYesNo + vbQuestion, "File Exists")
If xYesorNo <> vbYes Then Exit Sub
For I = 0 To UBound(xArrShetts)
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
xStr = xFolder & "\" & xSht.Name & ".pdf"
xNum = 1
While Not (Dir(xStr, vbDirectory) = vbNullString)
xStr = xFolder & "\" & xSht.Name & "_" & xNum & ".pdf"
xNum = xNum + 1
Wend
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
xSht.ExportAsFixedFormat Type:=xlTypePDF, Filename:=xStr, Quality:=xlQualityStandard
Else
End If
xArrShetts(I) = xStr
Next
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
With xEmailObj
.Display
.To = ""
.CC = ""
.Subject = "????"
For I = 0 To UBound(xArrShetts)
.Attachments.Add xArrShetts(I)
Next
If DisplayEmail = False Then
'.Send
End If
End With
End Sub
the other code i tried I can see which checkbox is checked unfortunately I can't rewrite it so only the checked boxes will be exported to pdf.
Private Sub CommandButton100_Click()
For i = 100 To 113
If UserForm2.Controls("CheckBox" & i).Value = True Then
a = a + 1
End If
Next i
k = 1
For i = 100 To 113
If UserForm2.Controls("CheckBox" & i).Value = True And a = 1 Then
b = UserForm2.Controls("CheckBox" & i).Caption & "."
ElseIf UserForm2.Controls("CheckBox" & i).Value = True And k <> a Then
b = b & UserForm2.Controls("CheckBox" & i).Caption & ", "
k = k + 1
ElseIf UserForm2.Controls("CheckBox" & i).Value = True And k = a Then
b = b & "and " & UserForm2.Controls("CheckBox" & i).Caption & "."
End If
Next i
MsgBox ("You have selected " & b)
End Sub
Can someone help me please I am struggling for some time now?
Please, try the next function:
Private Function sheetsArr(uF As UserForm) As Variant
Dim c As MSForms.Control, strCBX As String, arrSh
For Each c In uF.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.value = True Then strCBX = strCBX & "," & c.Caption
End If
Next
sheetsArr = Split(Mid(strCBX, 2), ",") 'Mid(strCBX, 2) eliminates the first string character (",")
End Function
It will return an array composed from the ticked check boxes caption.
It can be used demonstratively, in this way:
Sub testSheetsArrFunction()
Debug.Print Join(sheetsArr(UserForm2), ",")
End Sub
The above code will return in Immediate Window a string containing the checked check boxes caption (separated by comma). It may be run from a standard module, too. Of course, the function must be copied in that module. And the form to be loaded, having some check boxes ticked.
Now, you have to change a single code line in your (working) code:
Replace:
xArrShetts = Array("test", "Sheet1", "Sheet2")
with:
xArrShetts = sheetsArr(UserForm2)
It should use the array built in the above function. Of course the function have to be copied in the module where to be called. If placed in the form code module, it can be simple called as:
xArrShetts = sheetsArr(Me)
Edited:
You should only paste the next code in the form code module and show the form:
Private Sub CommandButton1_Click()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo, I, xNum As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim xArrShetts As Variant
Dim xPDFNameAddress As String
Dim xStr As String
'xArrShetts = Array("test", "Sheet1", "Sheet2") 'Enter the sheet names you will send as pdf files enclosed with quotation marks and separate them with comma. Make sure there is no special characters such as \/:"*<>| in the file name.
xArrShetts = sheetsArr(Me)
For I = 0 To UBound(xArrShetts)
On Error Resume Next
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
If xSht.Name <> xArrShetts(I) Then
MsgBox "Worksheet no found, exit operation:" & vbCrLf & vbCrLf & xArrShetts(I), vbInformation, "Kutools for Excel"
Exit Sub
End If
Next
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
'Check if file already exist
xYesorNo = MsgBox("If same name files exist in the destination folder, number suffix will be added to the file name automatically to distinguish the duplicates" & vbCrLf & vbCrLf & "Click Yes to continue, click No to cancel", _
vbYesNo + vbQuestion, "File Exists")
If xYesorNo <> vbYes Then Exit Sub
For I = 0 To UBound(xArrShetts)
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
xStr = xFolder & "\" & xSht.Name & ".pdf"
xNum = 1
While Not (Dir(xStr, vbDirectory) = vbNullString)
xStr = xFolder & "\" & xSht.Name & "_" & xNum & ".pdf"
xNum = xNum + 1
Wend
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
xSht.ExportAsFixedFormat Type:=xlTypePDF, Filename:=xStr, Quality:=xlQualityStandard
End If
xArrShetts(I) = xStr
Next
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
With xEmailObj
.Display
.To = ""
.CC = ""
.Subject = "????"
For I = 0 To UBound(xArrShetts)
.Attachments.Add xArrShetts(I)
Next
If DisplayEmail = False Then
'.Send
End If
End With
End Sub
Private Function sheetsArr(uF As UserForm) As Variant
Dim c As MSForms.Control, strCBX As String, arrSh
For Each c In uF.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.Value = True Then strCBX = strCBX & "," & c.Caption
End If
Next
sheetsArr = Split(Mid(strCBX, 2), ",") 'Mid(strCBX, 2) eliminates the first string character (",")
End Function

VBA wordapp.document.open and selection.WholeStory

Thank you in advance to looking and helping.
I'm trying to open a word document, then run some code on the document's contents, and save it. Here's what I have:
wordApp.Documents.Open (strFile)
wordApp.Visible = True
wordApp.Selection.WholeStory
strAll = wordApp.Selection.XML
This seems to get a handle to the contents of the document being opened. I can change search it, etc, and it appears to be changing the contents, however when I attempt to save it:
using this:
wordApp.ActiveDocument.Save NoPrompt:=True
or using this:
wordApp.ActiveDocument.SaveAs FileName:=folderName + "\test.xml", FileFormat:=wdFormatXML
the actual saved file isn't changed. If the actual document isn't being changed, and yet the changes are being made, where would the changes being made?
I can actually open the document, not as part of processing a folder, but opening it manually and run an action that has the same code in it and it makes the changes and prompts me to save when I close it. The ValidateFolder is the sub. It opens all .xml documents in a folder and validates contents, then I need to save any changes. The code for the whole things is:
Private Sub ValidateFolder_Click()
Dim wordApp
Dim folderName As Variant
Dim fileDir As String
Dim strAll As String
Dim strFile As String
Dim arrString() As String, occurInStr() As String, fldVal As String
Dim logResults As String
Dim dispVal As String
Dim i As Integer, v As Integer
Dim lnCount As Integer
Dim charPos As Long
folderName = BrowseForFolder("C:\")
lnCount = 0
If folderName <> "" Then
MsgBox ("check " + folderName)
fileDir = Dir$(folderName + "\*", 16)
Do While fileDir <> ""
If fileDir <> "." And fileDir <> ".." Then
Rem If entry is an xml file, then check the file.
If InStr(1, fileDir, ".xml", 5) > 0 Then
Set wordApp = CreateObject("word.Application")
strFile = folderName + "\" + fileDir
wordApp.Documents.Open strFile
wordApp.Visible = True
wordApp.Selection.WholeStory
strAll = wordApp.Selection.XML
arrString = Strings.Split(strAll, "»")
MsgBox ("Opened: " + strFile)
MsgBox (CStr(strAll))
For i = 0 To UBound(arrString)
'MsgBox (CStr(UBound(arrString)))
fldVal = strRight(arrString(i), "«")
'MsgBox (fldVal)
If fldVal <> "" Then
fldVal = fldVal & "»"
occurInStr = Split(fldVal, "»")
'MsgBox ("Match-" & CStr(i + 1) & ": " & fldVal & " occurances: " & CStr(UBound(occurInStr, 1)) & " error occur: " & CStr(InStrRegEx(fldVal, "«[A-Z_! ,d+0-9]*<.*»")))
If InStrRegEx(fldVal, "«[A-Z_! ,d+0-9]*<.*»") > 0 Then
Dim repVal As String
repVal = leftOfStrRightBack(fldVal, ">")
repVal = strRight(repVal, "<")
Dim newFldVal As String
newFldVal = Replace(fldVal, repVal, "")
Dim myRange As Range
Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:=newFldVal, Forward:=True
If myRange.Find.found = True Then
myRange.Find.Execute FindText:=newFldVal, ReplaceWith:="FLDSTART" & newFldVal, Format:=True, Replace:=wdReplaceAll
End If
Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="FLDSTART", Forward:=True
If myRange.Find.found = True Then
myRange.Find.Execute FindText:="FLDSTART", ReplaceWith:="", Format:=True, Replace:=wdReplaceAll
End If
logResults = "errors"
If logResults = "" Then
logResults = "The Following Fields had errors:" & Chr(10) & " " & newFldVal
MsgBox (logResults = "The Following Fields had errors:" & Chr(10) & " " & newFldVal)
Else
logResults = logResults & Chr(10) & " " & newFldVal
End If
End If
End If
Next
If logResults = "" Then
MsgBox ("No errors")
Else
MsgBox ("errors")
End If
If logResults = "" Then
logResults = "Success!" & Chr(10) & Chr(10) & "There were no detected errors in fields."
Else
logResults = logResults & Chr(10) & Chr(10) & "They have been fixed." & Chr(10) & "Please save this document."
End If
MsgBox (logResults)
Rem Saving and closing the document.
wordApp.ActiveDocument.Save NoPrompt:=True
MsgBox ("Save and Quit now")
'wordApp.ActiveDocument.SaveAs FileName:=folderName + "\test.xml", FileFormat:=wdFormatXML
'wordApp.ActiveDocument.SaveAs (folderName + "\" + fileDir
'MsgBox ("Saved")
Exit Sub 'Stop here so you process only one document for testing.
wordApp.Quit SaveChanges:=wdSaveChanges, OriginalFormat:=wdWordDocument
End If
End If
fileDir = Dir$()
Loop
End If
End Sub
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
Dim ShellApp As Object
'Create a file browser window at the default folder
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
'Set the folder to that selected. (On error in case cancelled)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
'Destroy the Shell Application
Set ShellApp = Nothing
'Check for invalid or non-entries and send to the Invalid error
'handler if found
'Valid selections can begin L: (where L is a letter) or
'\\ (as in \\servername\sharename. All others are invalid
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
'If it was determined that the selection was invalid, set to False
BrowseForFolder = False
End Function
Public Function GetFolder() As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
MsgBox (fldr)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = OpenAt 'Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Public Function leftOfStrRightBack(ByVal searchIn As String, ByVal searchFor As String) As String
Dim charPos As Long
Dim retStr As String
retStr = ""
If InStr(1, searchIn, searchFor, 5) > 0 Then
charPos = Len(searchIn)
While charPos > 0
If CStr(Mid(searchIn, charPos, 1)) = searchFor Then
'MsgBox ("Searched: " & searchIn & " found: " & searchFor & " at pos: " & charPos)
retStr = CStr(Mid(searchIn, 1, charPos))
'MsgBox ("Return: " & retStr)
GoTo BreakOut
End If
charPos = charPos - 1
Wend
BreakOut:
End If
leftOfStrRightBack = CStr(retStr)
End Function
Public Function strRight(ByVal searchIn As String, ByVal searchFor As String) As String
Dim charPos As Long
Dim retStr As String
retStr = ""
charPos = InStr(1, searchIn, searchFor, 5)
If charPos > 0 Then
retStr = CStr(Mid(searchIn, charPos, Len(searchIn)))
End If
'CStr(CStr(Mid(arrString(i), charPos, Len(arrString(i))) & "»"))
strRight = CStr(retStr)
End Function
Public Function InStrRegEx(ByVal searchIn As String, ByVal searchFor As String) As Long
Dim regEx As Object, found As Object
If Len(searchIn) > 0 And Len(searchFor) > 0 Then
Set regEx = CreateObject("VBScript.RegExp")
regEx.Pattern = searchFor
regEx.Global = True
regEx.IgnoreCase = True
Set found = regEx.Execute(searchIn)
If found.Count <> 0 Then InStrRegEx = found(0).FirstIndex + 1
End If
End Function
Public Function getText(ByVal searchIn As String, ByVal searchFor As String) As String
Dim regEx As Object, found As Object
If Len(searchIn) > 0 And Len(searchFor) > 0 Then
Set regEx = CreateObject("VBScript.RegExp")
regEx.Pattern = searchFor
regEx.Global = True
regEx.IgnoreCase = True
Set found = regEx.Execute(searchIn)
If found.Count <> 0 Then getText = CStr(found(0))
End If
End Function

Sending Emails with Attachments VBA

I am trying to add an attachment functionality to my emails. My email code is working however the attachments are being sent as ATT00001.bin files.
The variable Forms![frmMain]!TabCtl54.Pages("page56").Controls("subtblcontent").Form![attachmentlnk] is a textbox on a form which is where I would put my file name.
attachmentlnkvar = "file:///C:/Users/desktopname/Desktop/" & Forms![frmMain]!TabCtl54.Pages("page56").Controls("subtblcontent").Form![attachmentlnk] & ".pdf"
With cdomsg
.To = emailstr
.FROM = fromemailstr
.subject = Forms!frmMain.txtSubject
.Attachments.Add attachmentlnkvar
.HTMLBody = strHTML
.Send
End With
Set cdomsg = Nothing
Is there a way I can send my files as pdfs?
I am happy to share with you the function which I use to sent all my emails:
Public Sub SendMessage(Optional SubjectText = "", Optional BodyText = "", Optional AttachmentPath = "", Optional sendTo = "", Optional sendCC = "", Optional DeliveryConfirmation = True, Optional DisplayDoNotAutoSend = True, Optional SendHighPriority = True, Optional UseHTML = True)
Dim objOutlook As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
Dim objOutlookRecip As Outlook.Recipient
Dim objOutlookAttach As Outlook.Attachment
Dim MultipleAttachmentPath As String
Dim CurrentAttachment As Variant
Dim aAtachments() As String
On Error GoTo ErrorMsgs
DoCmd.Hourglass True
' Create the Outlook session.
Set objOutlook = New Outlook.Application
' Create the message.
Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
With objOutlookMsg
If UseHTML Then
.BodyFormat = olFormatHTML
End If
If Not isnull(sendTo) And InStr(sendTo, "#") > 0 Then
.To = sendTo
End If
If Not isnull(sendCC) And InStr(sendCC, "#") > 0 Then
.CC = sendCC
End If
.Subject = SubjectText
If UseHTML Then
.HTMLBody = "<div style='font-family:Calibri,sans-serif'>" & BodyText & GetThankYouSignature & "</div>"
Else
.Body = BodyText & vbCrLf & GetUserFullNameInASCIIText & vbCrLf & vbCrLf
End If
If SendHighPriority Then
.Importance = olImportanceHigh 'High importance
End If
If DeliveryConfirmation Then
.OriginatorDeliveryReportRequested = True
.ReadReceiptRequested = True
End If
On Error Resume Next
If AttachmentPath <> "" Then
' Add attachments to the message.
If Not IsMissing(AttachmentPath) And InStr(AttachmentPath, ";") = 0 Then
Set objOutlookAttach = .Attachments.add(AttachmentPath)
ElseIf Not IsMissing(AttachmentPath) And InStr(AttachmentPath, ";") > 0 Then
aAtachments = Split(AttachmentPath, ";")
For Each CurrentAttachment In aAtachments
.Attachments.add (CurrentAttachment)
Next
End If
End If
On Error GoTo ErrorMsgs
End With
If DisplayDoNotAutoSend Or isnull(sendTo) Then
objOutlookMsg.Display
Else
objOutlookMsg.Send
End If
Set objOutlookMsg = Nothing
Set objOutlook = Nothing
Set objOutlookRecip = Nothing
Set objOutlookAttach = Nothing
DoCmd.Hourglass False
Exit Sub
ErrorMsgs:
DoCmd.Hourglass False
If Err.Number = "287" Then
MsgBox "You clicked No to the Outlook security warning. " & _
"Rerun the procedure and click Yes to access e-mail" & _
"addresses to send your message. For more information," & _
"see the document at http://www.microsoft.com/office" & _
"/previous/outlook/downloads/security.asp. "
Else
Call LogError(Err.Number, Err.Description, "SystemUtilities", "SendMessage")
Resume Next
Resume
End If
End Sub
The variable AttachmentPath can contain multiple paths to attachments delimited by ";"
Don't use file:// etc., just the path. And backslashes.
attachmentlnkvar = "C:\Users\desktopname\Desktop\" & Forms![frmMain]!TabCtl54.Pages("page56").Controls("subtblcontent").Form![attachmentlnk] & ".pdf"
Instead of .Attachments.Add attachmentlnkvar have you tried .AddAttachment attachmentlnkvar? That's what I use to send PDF reports via an SMTP server instead of Outlook.
The problem is with your SMTP server. Try putting the attachment after the body to avoid this problem. If that doesn't work, try sending the message as plain text instead of HTML using:
.TextBody = bodyText
EXAMPLE:
attachmentlnkvar = "C:/Users/desktopname/Desktop/" & Forms![frmMain]!TabCtl54.Pages("page56").Controls("subtblcontent").Form![attachmentlnk] & ".pdf"
With cdomsg
.To = emailstr
.FROM = fromemailstr
.Subject = Forms!frmMain.txtSubject
.HTMLBody = strHTML
.AddAttachment attachmentlnkvar
.Send
End With
Set cdomsg = Nothing
EXPLANATION:
https://kb.mit.edu/confluence/pages/viewpage.action?pageId=4981187

Extract the values in a drop-down field

I would like to extract the values in a drop-down field with the title "email address".
I would like the name selected to appear in the email "To" line.
I'm adding the ActiveDocument details to the subject line but would like to remove the .docx portion of the subject line.
Do I need separate Outlook code?
Sub RunAll()
Call Save
Call sendeMail
End Sub
Sub Save()
Dim strPath As String
Dim strPlate As String
Dim strName As String
Dim strFilename As String
Dim oCC As ContentControl
strPath = "C:\Users\******x\Desktop\Test 4"
CreateFolders strPath
On Error GoTo err_Handler
Set oCC = ActiveDocument.SelectContentControlsByTitle("License Plate Number").Item(1)
If oCC.ShowingPlaceholderText Then
MsgBox "Complete the License plate number!"
oCC.Range.Select
GoTo lbl_Exit
Else
strPlate = oCC.Range.Text
End If
Set oCC = ActiveDocument.SelectContentControlsByTitle("Customer Name").Item(1)
If oCC.ShowingPlaceholderText Then
MsgBox "Complete the Customer Name!"
oCC.Range.Select
GoTo lbl_Exit
Else
strName = oCC.Range.Text
End If
strFilename = strPlate & "__" & strName & ".docx"
ActiveDocument.SaveAs2 FileName:=strPath & strFilename, FileFormat:=12
lbl_Exit:
Set oCC = Nothing
Exit Sub
err_Handler:
MsgBox Err.Number & vbCr & Err.Description
Err.Clear
GoTo lbl_Exit
End Sub
Private Sub CreateFolders(strPath As String)
Dim oFSO As Object
Dim lngPathSep As Long
Dim lngPS As Long
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
lngPathSep = InStr(3, strPath, "\")
If lngPathSep = 0 Then GoTo lbl_Exit
Set oFSO = CreateObject("Scripting.FileSystemObject")
Do
lngPS = lngPathSep
lngPathSep = InStr(lngPS + 1, strPath, "\")
If lngPathSep = 0 Then Exit Do
If Len(Dir(Left(strPath, lngPathSep), vbDirectory)) = 0 Then Exit Do
Loop
Do Until lngPathSep = 0
If Not oFSO.FolderExists(Left(strPath, lngPathSep)) Then
oFSO.CreateFolder Left(strPath, lngPathSep)
End If
lngPS = lngPathSep
lngPathSep = InStr(lngPS + 1, strPath, "\")
Loop
lbl_Exit:
Set oFSO = Nothing
Exit Sub
End Sub
Private Sub sendeMail()
Dim olkApp As Object
Dim strSubject As String
Dim strTo As String
Dim strBody As String
Dim strAtt As String
strSubject = "VR*** Request: " + ActiveDocument + " CUSTOMER IS xx xx xx"
strBody = ""
strTo = ""
If ActiveDocument.FullName = "" Then
MsgBox "activedocument not saved, exiting"
Exit Sub
Else
If ActiveDocument.Saved = False Then
If MsgBox("Activedocument NOT saved, Proceed?", vbYesNo, "Error") <> vbYes Then Exit Sub
End If
End If
strAtt = ActiveDocument.FullName
Set olkApp = CreateObject("outlook.application")
With olkApp.createitem(0)
.To = strTo
.Subject = strSubject
.body = strBody
.attachments.Add strAtt
'.send
.Display
End With
Set olkApp = Nothing
End Sub
To get the doc's name without the extension, you can use this:
Left(ActiveDocument.Name, InStrRev(ActiveDocument.Name, ".") - 1)
InStrRev finds the last "dot" .
Left truncates the name until that position
-1 applied to the found position is to also remove the . itself
For example,
strSubject = "VR*** Request: " & Left(ActiveDocument.Name, InStrRev(ActiveDocument.Name, ".") - 1) & " CUSTOMER IS xx xx xx"
Addendum
To get the email address from a content-control titled "email address", you can use this function:
Function getEmailAddress()
Dim sh As ContentControl
For Each sh In ThisDocument.Range.ContentControls
If sh.Title = "email address" Then
getEmailAddress = sh.Range.Text
Exit Function
End If
Next
End Function
i.e.
With olkApp.createitem(0)
.To = getEmailAddress
' etc...

VBA To send mail using Filesearch

I have this code to send mail to multiple recipients using Lotus Notes. Right now I need to mention the entire file path for the attachments. My requirement is to use FileSearch method - mention any part of the name of the attachment within * * - so that the files get attached.
Sub Send()
Dim oSess As Object
Dim oDB As Object
Dim oDoc As Object
Dim oItem As Object
Dim direct As Object
Dim Var As Variant
Dim flag As Boolean
Dim cell As Range
Dim r As Excel.Range
Dim Name As String
Dim Annex As String
Dim recp As Variant
Dim cc As Variant
Dim Resp As Long
Resp = MsgBox(prompt:="Do you wish to send to the mail?", Buttons:=vbYesNo + vbInformation + vbDefaultButton2, Title:=AppHeader)
If Resp = vbYes Then
Sheets("Sheet2").Activate
For Each cell In Columns("B").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" And _
LCase(Cells(cell.Row, "E").Value) = "yes" Then
Set oSess = CreateObject("Notes.NotesSession")
Set oDB = oSess.GETDATABASE("", "")
Call oDB.OPENMAIL
flag = True
If Not (oDB.IsOpen) Then flag = oDB.Open("", "")
If Not flag Then
MsgBox "Can't open mail file: " & oDB.SERVER & " " & oDB.FILEPATH
GoTo exit_SendAttachment
End If
On Error GoTo err_handler
'Building Message
recp = Cells(cell.Row, "B").Value
cc = Cells(cell.Row, "C").Value
Set oDoc = oDB.CREATEDOCUMENT
Set oItem = oDoc.CREATERICHTEXTITEM("BODY")
oDoc.Form = "Memo"
oDoc.Subject = "HI" & "-" & Cells(cell.Row, "D").Value
oDoc.sendto = Split(recp, ",")
oDoc.copyto = Split(cc, ",")
oDoc.body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please find attached "
oDoc.postdate = Date
oDoc.SaveMessageOnSend = True
Name = Cells(cell.Row, "F").Value
Annex = Cells(cell.Row, "G").Value
Call oItem.EmbedObject(1454, "", Name)
Call oItem.EmbedObject(1454, "", Annex)
oDoc.Send False
End If
Next cell
MsgBox prompt:="Mail Sent", Buttons:=vbOKOnly + vbInformation, Title:=AppHeader
Exit Sub
'Attaching DATABASE
For Each r In Range("Fpath") '// Change to suit
If r.Value <> vbNullString Then
Call Send
End If
Next
oDoc.visable = True
'Sending Message
exit_SendAttachment:
On Error Resume Next
Set oSess = Nothing
Set oDB = Nothing
Set oDoc = Nothing
Set oItem = Nothing
'Done
err_handler:
If Err.Number = 7225 Then
MsgBox "File doesn't exist"
Else
MsgBox Err.Number & " " & Err.Description
End If
On Error GoTo exit_SendAttachment
Else
Sheets("Sheet1").Activate
End If
End Sub
Any thoughts will be highly appreciated.
It's been years since I have worked with Lotus notes. The last question that I answered on Lotus notes was way back in July 26, 2011 So be gentle on me if I miss any syntax. :p
Application.FileSearch method is no longer supported from XL2007+
Reference: Error message when you run a macro to search for a file in an Office 2007 program: "Run-time error 5111"
In case the above link dies, here is the screenshot.
As mentioned in that link You can use the FileSystemObject object to recursively search directories and to find specific files. Here is how we do that
In case the above link dies, here is the code from that link.
'~~> COURTESY: http://support.microsoft.com/kb/185601
Option Explicit
Dim fso As New FileSystemObject
Dim fld As Folder
Private Sub Command1_Click()
Dim nDirs As Long, nFiles As Long, lSize As Currency
Dim sDir As String, sSrchString As String
sDir = InputBox("Type the directory that you want to search for", _
"FileSystemObjects example", "C:\")
sSrchString = InputBox("Type the file name that you want to search for", _
"FileSystemObjects example", "vb.ini")
MousePointer = vbHourglass
Label1.Caption = "Searching " & vbCrLf & UCase(sDir) & "..."
lSize = FindFile(sDir, sSrchString, nDirs, nFiles)
MousePointer = vbDefault
MsgBox Str(nFiles) & " files found in" & Str(nDirs) & _
" directories", vbInformation
MsgBox "Total Size = " & lSize & " bytes"
End Sub
Private Function FindFile(ByVal sFol As String, sFile As String, _
nDirs As Long, nFiles As Long) As Currency
Dim tFld As Folder, tFil As File, FileName As String
On Error GoTo Catch
Set fld = fso.GetFolder(sFol)
FileName = Dir(fso.BuildPath(fld.Path, sFile), vbNormal Or _
vbHidden Or vbSystem Or vbReadOnly)
While Len(FileName) <> 0
FindFile = FindFile + FileLen(fso.BuildPath(fld.Path, _
FileName))
nFiles = nFiles + 1
List1.AddItem fso.BuildPath(fld.Path, FileName) ' Load ListBox
FileName = Dir() ' Get next file
DoEvents
Wend
Label1 = "Searching " & vbCrLf & fld.Path & "..."
nDirs = nDirs + 1
If fld.SubFolders.Count > 0 Then
For Each tFld In fld.SubFolders
DoEvents
FindFile = FindFile + FindFile(tFld.Path, sFile, nDirs, nFiles)
Next
End If
Exit Function
Catch: FileName = ""
Resume Next
End Function
Once you are able to select the files you can use the below code in a loop to add the attachments
stAttachment = "Blah Blah.Txt"
Set obAttachment = oDoc.CreateRichTextItem("stAttachment")
Set EmbedObject = obAttachment.EmbedObject(EMBED_ATTACHMENT, "", stAttachment)