So I'm trying to send an e-mail with VBscripting and otherwise it works fine, but nothing I try to write to the txt or html body, appear on the message. Here is the function I'm using:
Function EMail( myFrom, myTo, mySubject, myTextBody, myHTMLBody, myAttachment, mySMTPServer, mySMTPPort )
' This function sends an e-mail message using CDOSYS
'
' Arguments:
' myFrom = Sender's e-mail address ("John Doe <jdoe#mydomain.org>" or "jdoe#mydomain.org")
' myTo = Receiver's e-mail address ("John Doe <jdoe#mydomain.org>" or "jdoe#mydomain.org")
' mySubject = Message subject (optional)
' myTextBody = Actual message (text only, optional)
' myHTMLBody = Actual message (HTML, optional)
' myAttachment = Attachment as fully qualified file name, either string or array of strings (optional)
' mySMTPServer = SMTP server (IP address or host name)
' mySMTPPort = SMTP server port (optional, default 25)
'
' Returns:
' status message
'
' Standard housekeeping
Dim i, objEmail
' Use custom error handling
On Error Resume Next
' Create an e-mail message object
Set objEmail = CreateObject( "CDO.Message" )
' Fill in the field values
With objEmail
.From = myFrom
.To = myTo
' Other options you might want to add:
' .Cc = ...
' .Bcc = ...
.Subject = mySubject
.TextBody = myTextBody
.HTMLBody = myHTMLBody
If IsArray( myAttachment ) Then
For i = 0 To UBound( myAttachment )
.AddAttachment Replace( myAttachment( i ), "\", "\\" ),"",""
Next
ElseIf myAttachment <> "" Then
.AddAttachment Replace( myAttachment, "\", "\\" ),"",""
End If
If mySMTPPort = "" Then
mySMTPPort = 25
End If
With .Configuration.Fields
.Item( "http://schemas.microsoft.com/cdo/configuration/sendusing" ) = 2
.Item( "http://schemas.microsoft.com/cdo/configuration/smtpserver" ) = mySMTPServer
.Item( "http://schemas.microsoft.com/cdo/configuration/smtpserverport" ) = mySMTPPort
.Update
End With
End With
' Return status message
If Err Then
EMail = "ERROR " & Err.Number & ": " & Err.Description
Err.Clear
Else
objEmail.send
If Err Then
EMail = "ERROR " & Err.Number & ": " & Err.Description
Err.Clear
Else
EMail = "ok"
End If
End If
' Release the e-mail message object
Set objEmail = Nothing
' Restore default error handling
On Error Goto 0
End Function
And here is how I'm calling it:
MsgBox Email ( "address#sender.com", _
address#receiver.com, _
"This subject appears on the email correctly", _
"But this txt body does not", _
"", _
"", _
"mail.smtp-server.com", _
25 )
Like I said, the e-mail goes through alright, attachments work, subject works but for whatever reason the body never appears in the message! What is the problem?
For text use TextBody, for HTML use HTMLBody don't set both, currently you set HTMLBody to "" which will override TextBody.
You could use a flag argument;
Function EMail( myFrom, myTo, mySubject, myBody, isHTML, myAttachment...
Then
if isHTML then
.HTMLBody = myBody
else
.TextBody = myBody
end if
Related
I need to send an up arrow ↑ to an iPhone with SMS using VBA and a CDO mail object.
My attempts are as follows:
Unicode:
subj = ChrW(8593) & " Up " & ChrW(8593)
HTML:
subj = "↑ Up ↑"
Both of the above methods result in the iPhone receiving either a ? Up ? for the Unicode or ↑ Up ↑ as a string literal.
Does anyone know the correct syntax for an up arrow ↑?
Solution:
I was looking for some 'special character' syntax but the problem was not in the construction of the message. I needed to add .BodyPart.Charset = "utf-8" to the CDO.Message object and use the Unicode Chrw(8593) where I needed it.
Sub sendMSSG(sbj As String, mssg As String)
Dim cdoMail As New CDO.Message
On Error GoTo err_Report
With cdoMail
With .Configuration.Fields
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort '2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "my.smtpserverserver.net"
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic '1
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = sFROM
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = sFROMPWD
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 6
.Update
End With
.BodyPart.Charset = "utf-8" '<~~ THIS WAS REQUIRED
.Subject = sbj
.From = sFROM
.To = sPHONEMSSGNO
.Bcc = vbNullString
.Cc = vbNullString
.TextBody = mssg
.Send
End With
Exit Sub
err_Report:
Debug.Print Err.Number & ": " & Err.Description
End Sub
Apparently, .BodyPart.Charset covers both the subject and the message body as I was able to use unicode in both.
Anyone planning to use this code for their own purposes needs to add the Microsoft CDO for Windows 2000 library to their project via Tools, References.
Server: Windows 2003 r3
Program is supposed to automatically send out emails when they appear in a folder.
The issue that I am having is I can't find any support for the object that is being created.
I am trying to send a email using the text/html content-type and the emails being sent keep being received with the text/plain and the html is just normally displaying as text
The object being created is:
oMail As SMTP
I've tried
oMail.IsBodyHtml = True
And
oMail.MessageFormat = 1
All the tutorials online i've seen use
Dim oSmtp As EASendMailObjLib.Mail
Below is the entire function
Public Function sEnd(oMail As SMTP, MailToSend() As OutMail, ByVal i As Integer) As Boolean
On Error GoTo SendEmail_Err
Dim result
' Reset Smtp err code
iSmtpErr = 0
' Go thru the list of Mail to send
With MailToSend(i)
If .Status = EMO_TO_SEND Then
DoEvents
''''''''''''''''''''''''''''''''''''''
' Load Winsock
oMail.WinsockLoaded = True
' Specify Domain, Host and Mail Port
oMail.MailServer = sOutboundDomain
oMail.MailPort = iOutboundMailPort
DoEvents
'oMail.Action = a_ConnectToServer
oMail.Action = a_ResetHeaders
' oMail.IsBodyHtml = True
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Specify Mail contents: Sender, Recipient, subject, body, ..
oMail.From = .SenderEmailAddr
oMail.To = .RecipientEmailAddr
oMail.SUBJECT = .SUBJECT
oMail.Date = Format(Now, "ddd, dd mmm yyyy hh:mm:ss") & Space(1) & sTimeZone
oMail.MessageText = .Body
' oMail.MessageFormat = 1
oMail.OtherHeaders = X_MAILER & Space(1) & sXMailer
' Send Message
oMail.Action = a_SendMessage
.Status = EMO_SENT
.TimeSent = Now
DoEvents
' Quit
oMail.Action = a_DisconnectFromServer
End If
End With
sEnd = True
Exit Function
SendEmail_Err:
On Error Resume Next
If iSmtpErr >= 25005 And iSmtpErr <= 26005 Or _
iSmtpErr = 20302 Or iSmtpErr = 20163 Or _
iSmtpErr = 20162 Then
' Changed to handle invalid email address error - July 20, 1999
' Or iSmtpErr = 0 Then
' Winsock/connection error
MailToSend(i).Status = EMO_NO_CONNECTION
RaiseAlert USER_CONNECTION_ERR, ""
Else
MailToSend(i).Status = EMO_FAILED_TO_SEND
End If
' Log error
Call LogError(CLng(iSmtpErr), MailToSend(i).FileName & ":" & Error, "Send")
' Put in to handle invalid email address error - July 20, 1999
oMail.Action = a_DisconnectFromServer
oMail.Action = a_Idle
sEnd = True
Exit Function
End Function
Thanks a lot for any input!
I used this script on my website to collect enquiry form information from visitors. One of my clients reports that when he receives the email that's generated, Outlook is manipulating the line:
email=myclient#myclientsdomain.com
...to include the prefix "email=" as if that's part of the email! (Silly Outlook!)
I need to alter my code so a leading space is inserted immediately before the email address so it looks more like this:
email= myclient#clientsdomain.com
That way, when my client clicks on the email to reply to the user, the correct email is used (the one without the prefix attached to the front of the email!)
In summary Outlook is including the prefix when it creates an email link because of the absence of any space between the email and the prefix.
I'm not much of a coder and extensive searching has failed me. I tried lots of suggestions but my form seems to either fail or no fix happens.
<!--START CODE FOR SENDFORM.ASP -->
<%# LANGUAGE="VBScript" %>
<%
Dim sFormTitle, sFormSender, sFormSubject, sFormDestination
'============================================
' You only need to change the details below!
'============================================
sFormTitle = "enquiries"
sFormSender = “myemail#mydomain.com"
sFormDomain = “mydomain.com"
sFormSubject = "Enquiry From Website."
sFormDestination = “me#mydomain.com"
'sFormDestination = “mail#mydomain.com"
'============================================
' And that's it!
'============================================
Dim sRawForm, aFormArray, sElement, sFormData
sRawForm = request.form
aFormArray = Split(sRawForm, "&")
for i = 0 to UBOUND(aFormArray)
sElement = Unescape(aFormArray(i))
sElement = Replace( sElement, "+", " " )
sFormData = sFormData & sElement & vbCrLf
next
%>
<%
Dim sRecipients, sBody, sSubject
sRecipients = Request.Form( sFormDestination )
sBody = sFormData
sSubject = sFormSubject
dim msg
set msg = Server.CreateOBject( "JMail.SMTPMail" )
msg.Logging = true
msg.silent = true
msg.Sender = sFormSender
msg.SenderName = sFormTitle
msg.AddRecipient sFormDestination
msg.Subject = sSubject
msg.Body = sBody
msg.ServerAddress = "IP GOES HERE - REMOVED IT FOR THIS POSTING"
if not msg.Execute then
Response.redirect "http://mydomain.co.uk/sorry.html"
else
Response.redirect "http://mydomain.co.uk/thanks.html"
end if
%>
<!--END CODE FOR SENDFORM.ASP -->
EDIT BELOW IN RESPONSE TO LANKYMART'S SUGGESTIONS:
Lankymart - Outlooks sees the text string email=myclient#myclientsdomain.com contains an # symbol in the middle and interprets the whole thing to be the email address - as such it makes the whole thing a clickable email link. If my form could generate a non breaking space, Outlook would still make that an email link but without the unwanted prefix included.
I can't use   - I don't know how to automatically insert it using the script (this is what I'm asking). Perhaps you meant on my html form page - this won't "carry through" to the email that's batched up and sent.
The square brackets have the same issue - if the asp form could somehow automatically insert these for me, the email will arrive and Outlook might display it correctly - getting my form to do this is the part I need to know. (I feel a leading space might be better as this will definitely work)
Any other ideas?
It's simple just use Replace() to identify the equals and add the   (Non-breaking space).
sRawForm = Request.Form
aFormArray = Split(sRawForm, "&")
For i = 0 To UBound(aFormArray)
sElement = Unescape(aFormArray(i))
sElement = Replace(sElement, "=", " =")
sElement = Replace(sElement, "+", " " )
sFormData = sFormData & sElement & vbCrLf
Next
Or to try the < > method using Replace();
sRawForm = Request.Form
aFormArray = Split(sRawForm, "&")
For i = 0 To UBound(aFormArray)
sElement = Unescape(aFormArray(i))
sElement = Replace(sElement, "=", "=<") & ">"
sElement = Replace(sElement, "+", " " )
sFormData = sFormData & sElement & vbCrLf
Next
If you just want the form values without outputting name=value just iterate through the Request.Form collection like;
Dim element
For Each element In Request.Form
sFormData = sFormData & element.Value & vbCrLf
Next
This would be my preferred method for iterating through the Request.Form collection, if you want the key value pair approach name=value you can still do that like this;
Dim element
For Each element In Request.Form
'Both and < > methods shown but < > preferred.
'sFormData = sFormData & element.Name & "= " & element.Value & vbCrLf
sFormData = sFormData & element.Name
'Only add < > if it's the email element.
If element.Name = "email" Then
sFormData = sFormData & "=<" & element.Value & ">" & vbCrLf
Else
sFormData = sFormData & "=" & element.Value & vbCrLf
End If
Next
Update:
In reply to the question in the comments the above code should replace;
sRawForm = request.form
aFormArray = Split(sRawForm, "&")
for i = 0 to UBOUND(aFormArray)
sElement = Unescape(aFormArray(i))
sElement = Replace( sElement, "+", " " )
sFormData = sFormData & sElement & vbCrLf
next
Because your iterating through the Request.Form collection instead of using Split() to build an Array and loop through that, you no longer have to do all the string clean-up, this is one of the benefits of using the For Each approach.
I am writing an application that sends emails to an admin when there is a problem with the data. The account it's sending through is a Network Solutions SMTP server.
The code works most of the time, but about 1 out of 10 sends fail with the error -2147220973 "The transport failed to connect to the server".
Any suggestions on how to handle this?
Set imsg = CreateObject("cdo.message")
Set iconf = CreateObject("cdo.configuration")
Set Flds = iconf.Fields
With Flds
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.OurCompany.com"
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 2525
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "me#OurCompany.com"
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
.Update
End With
With imsg
Set .Configuration = iconf
.To = "me#MyEmail.com" 'CMemail
.From = "resupport#OurCompanycom"
.Subject = ACT
.HTMLBody = "Notification for " & CTName & " of " & CTCname & " " & ACT & ". You must manually Notify them about new docs for " & pname & ". " _
& "<br>Tell " & CTName & " to '" & Nz(DLookup("Notify", "TBLINVOICESETTINGS"), "") & " " & PRName & "_" & pname & ".pdf'"
.Send
End With
Set imsg = Nothing
Set iconf = Nothing
Should the smtpserverport be 25, is it being blocked by firewall?
This piece of code executes correctly :
Sub SMail(pTO As String, pSB As String, pBO As String, pAT As String)
On Error GoTo ErrH: Dim mm As CDO.Message: Set mm = New CDO.Message
mm.Configuration.Fields(cdoSMTPUseSSL) = "True"
mm.Configuration.Fields(cdoSendUsingMethod) = 2
mm.Configuration.Fields(cdoSMTPAuthenticate) = 1
mm.Configuration.Fields(cdoSMTPServer) = "smtp.gmail.com"
mm.Configuration.Fields(cdoSendUserName) = "MyID"
mm.Configuration.Fields(cdoSendPassword) = "MyPW"
'mm.Configuration.Fields(cdoSMTPConnectionTimeout) = 20
'mm.Configuration.Fields(cdoSMTPServerPort) = 25
mm.Configuration.Fields.Update
mm.From = "MyID"
mm.To = pTO
mm.Subject = pSB
mm.TextBody = pBO
mm.AddAttachment (pAT)
mm.send
ErrH: If Err Then MsgBox (Err.Number & " : " & Err.Description)
Set mm = Nothing
End Sub
I am struggling with the above error when trying to write the Visual Basic code for a 2010 Access Form. I am trying to get ensure that the associate and the Team Lead get the same email. When I first wrote the code, it worked initially. I have since added an "issue date" to the form, but not to the email. I attempted to add the issue date to the Script, but that did not work. I have since removed both the issue date from the form and the script. Any help would appreciated:
Private Sub cmdEmail_Click()
Dim objOutlook As Object
Dim objMailItem As Object
Const olMailItem As Integer = 0
Dim objMailItem1 As Object
Const olMailItem1 As Integer = 0
Set objOutlook = CreateObject("Outlook.Application")
Set objMailItem = objOutlook.CreateItem(olMailItem)
Set objMailItem1 = objOutlook.CreateItem(olMailItem1)
Dim strPathAttach As String
On Error GoTo err_Error_handler
'set receipient, you can use a DLookup() to retrieve your associate Email address
objMailItem.To = DLookup("Email_ID", "dbo_Noble_Associates", "[Fullname]='" & Me.cboAssociate & "'")
objMailItem1.To = DLookup("Email_ID", "dbo_TeamLeads$", "[Fullname]='" & Me.txtTeamLead & "'")
'set subject with text and Form values
objMailItem.Subject = "Attendance Violation " & Me.cboAssociate
objMailItem1.Subject = "Attendance Violation " & Me.cboAssociate
'set body content with text and Form values etc.
objMailItem.htmlBody = "Date of Occurrence: " & Format(Me.Occurrence_Date, "mm/dd/yyyy") & "<br>" & "Attendance Points: " & Me.CboType & "<br>" & "Total Points: " & Me.txtTotalpoints & "<br>" & "Notes: " & Me.txtNotes
objMailItem1.htmlBody = "Date of Occurrence: " & Format(Me.Occurrence_Date, "mm/dd/yyyy") & "<br>" & "Attendance Points: " & Me.CboType & "<br>" & "Total Points: " & Me.txtTotalpoints & "<br>" & "Notes: " & Me.txtNotes
' display email
' objMailItem.Display
' sending mail automaticly
objMailItem.Send
objMailItem1.Send
Set objOutlook = Nothing
Set objMailItem = Nothing
Set objMailItem1 = Nothing
exit_Error_handler:
On Error Resume Next
Set objOutlook = Nothing
Set objMailItem = Nothing
Set objMailItem1 = Nothing
Exit Sub
err_Error_handler:
Select Case Err.Number
'trap error 287
Case 287
MsgBox "Canceled by user.", vbInformation
Case Else
MsgBox "Error " & Err.Number & " " & Err.Description
End Select
Resume exit_Error_handler
End Sub
Private Sub CheckEmail_Click()
End Sub
Private Sub cmdSaveandNew_Click()
If Me.txtOccurrence_Date & "" = "" Then
MsgBox "Please enter the date."
Me.txtOccurrence_Date.SetFocus
Exit Sub
ElseIf Me.cboAssociate & "" = "" Then
MsgBox "Please select the associate's name."
Me.cboAssociate.SetFocus
Exit Sub
ElseIf Me.txtPoints & "" = "" Then
MsgBox "Please enter the number of Points."
Me.txtPoints.SetFocus
Exit Sub
End If
If Me.CheckEmail = True Then
cmdEmail_Click
End If
DoCmd.Close acForm, Me.Name
End Sub
Private Sub cmd_Cancel_Click()
Me.Undo
DoCmd.Close acForm, Me.Name
End Sub
Private Sub cboassociate_AfterUpdate()
Me.txtTeamLead.Value = Me.cboAssociate.Column(1)
End Sub
Private Sub cboFullname_AfterUpdate()
Me.txtCurrentpoints.Value = Me.cbofullname.Column(1)
End Sub
Private Sub CboType_AfterUpdate()
Me.txtPoints.Value = Me.CboType.Column(1)
End Sub
I am open to any suggestions.