Add a new line in message body using the following vbscript - email

I have created a txt file to support the message body of the vbscript but it only reads the last line of the messagebody.txt
WScript.Sleep 100
Set WshShell=WScript.CreateObject("WScript.Shell")
Set objShell=WScript.CreateObject("WScript.Shell")
set objOutlook=CreateObject("Outlook.Application")
Set objMail=CreateObject("CDO.Message")
Set objMail=objOutlook.CreateItem(0)
strDesktop = WshShell.SpecialFolders("Desktop")
Set objFileToReadTo = CreateObject("Scripting.FileSystemObject").OpenTextFile(strDesktop + "\\send email with attachment\List_To.txt",1)
Set objFileToReadCC = CreateObject("Scripting.FileSystemObject").OpenTextFile(strDesktop + "\\send email with attachment\List_CC.txt",1)
Set objFileToReadSubject = CreateObject("Scripting.FileSystemObject").OpenTextFile(strDesktop + "\\send email with attachment\List_Subject.txt",1)
Set objFileToReadBody = CreateObject("Scripting.FileSystemObject").OpenTextFile(strDesktop + "\\send email with attachment\Email Body.txt",1)
Set objFileToReadAttachments = CreateObject("Scripting.FileSystemObject").OpenTextFile(strDesktop + "\\send email with attachment\List_Attachments_withFileExtension.txt",1)
Dim strLineTo
Dim strLineCC
Dim strLineSubject
Dim strLineBody
Dim strLineAttachments
objMail.Display
WScript.Sleep 10
do while not objFileToReadTo.AtEndOfStream
strLineTo = objFileToReadTo.ReadLine()
objMail.To=strLineTo
loop
objFileToReadTo.Close
WScript.Sleep 10
do while not objFileToReadCC.AtEndOfStream
strLineCC = objFileToReadCC.ReadLine()
objMail.cc = strLineCC
loop
objFileToReadCC.Close
'41
WScript.Sleep 10
do while not objFileToReadSubject.AtEndOfStream
strLineSubject = objFileToReadSubject.ReadLine()
objMail.Subject = strLineSubject
loop
objFileToReadSubject.Close
'48
WScript.Sleep 10
do while not objFileToReadBody.AtEndOfStream
strLineBody = objFileToReadBody.ReadLine()
objMail.Body = strLineBody & vbCRLF
loop
objFileToReadBody.Close
'55
WScript.Sleep 10
do while not objFileToReadAttachments.AtEndOfStream
strLineAttachments = objFileToReadAttachments.ReadLine()
objMail.Attachments.Add(strLineAttachments)
loop
objFileToReadAttachments.Close
'62
'objShell.Sendkeys "%s"
WScript.Sleep 40
'objShell.SendKeys "{TAB}"
'objShell.SendKeys "{UP}"
'objShell.SendKeys "{Enter}"
'set MyEmail=nothing
'objOutlook.Quit
'Set objMail = Nothing
'Set objOutlook = Nothing
and here is my messagebody.txt
Hi,
Testing vbscript
Regards,
abcd
It only reads the last ABCD and displays the same on the oulook window.
How do I make the scipt understand multiple lines?

I really don't know why you have used different text files for storing ToList, CCList, body etc. but if you are sure about using this approach, I won't change it.
I am just pointing out why you are not getting the full text in the email body. Replace the following code:
do while not objFileToReadBody.AtEndOfStream
strLineBody = objFileToReadBody.ReadLine() 'Here you are just overwriting the value contained in strLineBody in each loop iteration. Hence, in the end, only last line is left in this variable
objMail.Body = strLineBody & vbCRLF
loop
WITH
objMail.Body = objFileToReadBody.readAll

In the loop you replace the Body with each line you read, when you should be appending to it. Switch this line;
objMail.Body = strLineBody & vbCRLF
to be;
objMail.Body = objMail.Body & strLineBody & vbNewLine
If you forgo the loop and use ReadAll (as #Gurman has suggested), bear in mind that while this will be fine for minimal text, larger text files will make the process less efficient then looping through each line as you have started to do already.

Related

Why does it take so long to copy MailItems in Outlook?

I want to copy MailItems from one Outlook folder to another.
When I run the following code it takes a long time like i.e. 5 seconds per MailItem even if the MailItems are only mails with few lines < 5kB.
I do this in the folders of an IMAP EMail account.
Sometimes I also get an error that an item can not be moved but only be copied.
What do I do wrong? This should be simple.
Currently the code creates first a copy of the mail in the original folder and then I move this copy. I would prefer to create a copy directly in the destination folder.
If I do this manually by dragging and dropping the mails (holding Ctrl to make a copy) this works fast like maybe 1s for 3 mails.
Sub CopyMailsToOtherFolder()
On Error GoTo CopyMailsToOtherFolder_Err
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Dim TestFolder As Outlook.Folder
Dim OutFolder As Outlook.Folder
Dim objItem As Object 'Note that myItem is declared as type Object so that it can represent all types of Outlook items including meeting request and task request items.
Dim MsgOrg As Outlook.MailItem
Dim MsgCopy As Outlook.MailItem
Dim lngI As Long
Set TestFolder = objNS.Folders("Edgar").Folders("Inbox")
Set OutFolder = objNS.Folders("Edgar").Folders("Inbox").Folders("TestOut")
Debug.Print "Start: " & Time()
'For lngI = 1 To TestFolder.Items.Count
For lngI = 1 To 3
Set objItem = TestFolder.Items(lngI)
If TypeName(objItem) = "MailItem" Then
Set MsgOrg = objItem
Debug.Print " Org: " & MsgOrg.Subject
Set MsgCopy = MsgOrg.Copy 'Creates copy in original folder
MsgCopy.Move OutFolder
End If
Next
Debug.Print "Done"
CopyMailsToOtherFolder_Exit:
Debug.Print "Exit: " & Time()
Exit Sub
CopyMailsToOtherFolder_Err:
Debug.Print "Error " & Err.Number & " - " & Err.Description
Resume CopyMailsToOtherFolder_Exit
End Sub

using Windows send-to for creating a one step send to>zip>to email

In another post on Stack Overflow a user named James L. presented a useful script for adding 7-Zip to the Send to Options in Windows. I was wondering how hard it would be to take that same principle one more step by sending the results on to be attached to an email?
Most of the zips I create are done in order to email them and this would cut that down to one click. The only obstacle being that it could not create a self-extracting ".exe" file to be attached.
Here are three scripts you can stich together.
CreateBlankZip.vbs Zipname passed as a parameter, use quotes if spaces in name.
Set Ag=Wscript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Ag(0), 8, vbtrue)
BlankZip = "PK" & Chr(5) & Chr(6)
For x = 0 to 17
BlankZip = BlankZip & Chr(0)
Next
ts.Write BlankZip
Add folder to zip. DestinationZip SourceFolder
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set SrcFldr=objShell.NameSpace(Ag(1))
Set DestFldr=objShell.NameSpace(Ag(0))
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Msgbox "Finished"
Send mail and attach file.
Set emailObj = CreateObject("CDO.Message")
emailObj.From = "dc#gmail.com"
emailObj.To = "dc#gmail.com"
emailObj.Subject = "Test CDO"
emailObj.TextBody = "Test CDO"
emailObj.AddAttachment "c:\windows\win.ini"
Set emailConfig = emailObj.Configuration
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = true
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "MyName"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "Ppassword1"
emailConfig.Fields.Update
emailObj.Send
If err.number = 0 then Msgbox "Done"

Using VBScript, how do I update Microsoft Outlook Inbox folder before accessing it in VBS?

The following is a VBScript (VBS) that I use the check for and process certain Outlook emails and attachments. The script finds the emails via their email address and subject. It then saves the attachment in a folder and moves the email to a folder within Outlook. (Most of this code was adapted from a stackoverflow.com post, but I have since forgotten which one.)
My issue: Sometimes this script has to be run before the user has opened Outlook for the day; therefore, none of the Outlook folders have been updated and the script can't find emails that have been sent to the user since the user shut Outlook down last.
My question: How do I update the Outlook inbox then proceed with the rest of the script ensuring that the Inbox is (or all Outlook folders are) completely updated? I'm not sure if VBS will wait for the folder update to happen, but if it won't, I, of course, need it to. I don't know how to update the inbox or wait for it to update if waiting is applicable.
Other tips on how to make the script better are welcome.
My VBScript:
Const olFolderInbox = 6
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
Call SaveAndMoveAttachment("'subject 1'", objFolder)
Call SaveAndMoveAttachment("'subject 2'", objFolder)
Call SaveAndMoveAttachment("'subject 3'", objFolder)
Set objFSO = Nothing
Set objOutlook = Nothing
Set objNamespace = Nothing
WScript.Quit
Sub SaveAndMoveAttachment(sSubject, objFolder)
Set colItems = objFolder.Items
Set colFilteredItems = colItems.Restrict("[Subject] = " & sSubject)
If colFilteredItems.count = 0 then
Msgbox "An email with subject " & sSubject & " in it was not found in your Outlook Inbox"
WScript.Quit
end if
For Each objMessage In colFilteredItems
Set colAttachments = objMessage.Attachments
intCount = colAttachments.Count
If intCount <> 0 and objMessage.Sender.Address = "support#somesite.com" Then
For i = 1 To intCount
strFileName = "Z:\somepath\" & objMessage.Attachments.Item(i).FileName
objMessage.Attachments.Item(i).SaveAsFile strFileName
'move the message to somefolder folder
Set objFoldersomefolder = objNamespace.GetDefaultFolder(olFolderInbox).Folders("somefolder")
objMessage.Move objFoldersomefolder
Next
End If
Next
Set colFilteredItems = Nothing
Set colAttachments = Nothing
Set colItems = Nothing
End Sub
Add logon step between above 2 lines
WSCript.Sleep 2000
objNamespace.Logon
objNamespace.SendAndReceive(True)
Below this line:
Set objNamespace = objOutlook.GetNamespace("MAPI")
Add this:
WSCript.Sleep 2000
objNamespace.SendAndReceive(True)
I found it here:
http://www.experts-exchange.com/Software/Office_Productivity/Groupware/Outlook/Q_28215854.html

Vbscript Wscript.Run method stuck because of space character

Error System can't find the file specified
strCline = Document.getElementById("head").innerHtml
msgbox strCline
strCline = replace(strCline, " ",Chr(32))
oShell.run strCline
Set oShell = Nothing
Above code produces error because it can't read file name properly. It's all because of space characters in file name. After reading, i found chr(32) would replace space character but it won't. How do I make it take space character.
Edit:
My final code looked like this which worked. I made mistake while creating object.
Sub funEdit
set oShell=createobject("Wscript.shell")
strCline = Document.getElementById("head").innerHtml
msgbox strCline
strCline = replace(strCline, " ",Chr(32))
oShell.run strCline
Set oShell = Nothing
End Sub
The shell splits a command line into parameters using blank(s) for a delimiter. If you want to send text file specifications to .Run to display them automagically in the default editor, you must double quote the (logically) single parameter. This demo code:
Option Explicit
Dim sFSpec : sFSpec = "C:\Documents and Settings\eh\tmp.txt"
Dim sCmd : sCmd = sFSpec
Dim oWSH : Set oWSH = CreateObject("WScript.Shell")
On Error Resume Next
oWSH.Run sCmd
WScript.Echo qq(sCmd), "=>", Err.Number, Err.Description
Err.Clear
sCmd = qq(sFSpec)
oWSH.Run sCmd
WScript.Echo qq(sCmd), "=>", Err.Number, Err.Description
On Error GoTo 0
Function qq(s)
qq = """" & s & """"
End Function
will output:
"C:\Documents and Settings\eh\tmp.txt" => -2147024894
""C:\Documents and Settings\eh\tmp.txt"" => 0
and open only one Notepad.
See here for some context.

How to replace a special character in email body with a value in each row using Excel with VBA to multiple recipients

I am creating an Excel UserForm that creates a separate email for up to 500 recipients.
There are 4 columns on the worksheet: Name(Column A), Email(Column B), Value 1(Column C).
The code uses the For and Next loop style, where r is declared as an Integer (r = 2 To 500) and with the MailItem Object, .To =Cells(r,2).
The issue I have is attempting to incorporate values from a range (Column C) that replace special characters placed in the text box used to create the body of the email.
So if I were to type, Hello, There were ^&^ transactions that failed yesterday. and hit a command button used for "Send", it would send an email to the each email address listed in Column B and replace ^&^ with the value in Column C to each individual email address (each row).
Below is the VBA code as an example. There are a lot of other declared variables that I did not mention of course to keep this inquiry as short as possible.
Dim Signature As String, EmailSensitivity As String, EmailImportance As String
Dim Greeting As String, Punctuation As String, Security As String
Sub SendButton1_Click()
If SubjectText = vbNullString Then
If EmailBody1 = vbNullString Then
MsgBox "Form Incomplete:" & vbCrLf & vbCrLf & _
"No Subject or Email Text.", vbOKOnly
Exit Sub
End If
End If
If SubjectText = vbNullString Then
MsgBox "Form Incomplete:" & vbCrLf & vbCrLf & _
"Please enter Subject.", vbOKOnly
Exit Sub
End If
If EmailBody1 = vbNullString Then
MsgBox "Form Incomplete:" & vbCrLf & vbCrLf & _
"Please enter Email Text."
Exit Sub
End If
If SignatureText1 = vbNullString Then
Continue = MsgBox("Your email contains no signature." & vbCrLf & vbCrLf & _
"Are you sure you wish to proceed?", vbYesNo)
If Continue = vbNo Then
Exit Sub
End If
End If
Dim OutApp As Object, OutMail As Object
Dim r As Integer
Application.ScreenUpdating = False
For r = 2 To 501
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(olMailItem)
On Error Resume Next
With OutMail
.Subject = Security & SubjectText.Value
.Body = EmailBody1.Value & vbCrLf & vbCrLf & _
SignatureText1.Value
.To = Cells(r, 2)
.Attachements.Add AttachmentText1.Value
.Importance = EmailImportance
.Sensitivity = EmailSensitivity
.Send
End With
Next r
Set OutApp = Nothing
Application.ScreenUpdating = True
Sheet1.Range("A2:B501").Clear
Continue = MsgBox("You have successfully generated a mass email!" & vbCrLf & vbCrLf & _
"Would you like to generate another email?", vbYesNo)
If Continue = vbNo Then
Application.Quit
End If
End Sub
I am still an amateur, so I'm working on cleaning a lot of unnecessary code, but this inquiry is mainly on replacing the special character with the value listed in each row.
This is my first time actually posting an inquiry on a forum, so please let me know if I am not following the correct procedure as your help is much appreciated.
It might be as simple as this, using the Replace function:
...
With OutMail
.Subject = Security & SubjectText.Value
.Body = Replace(EmailBody1.Value,"^&^",Cells(r, 3)) & _
vbCrLf & vbCrLf & SignatureText1.Value
...
Unrelated to this, but importat: On Error Resume Next means the sending (and any operation after that) will silently fail. This will make future debugging more difficult, frustrating and expensive. You should at least log relevant details about what error occured, and for what row in the sheet. And be sure to re-enable error-checking with on error goto 0 or similar after the part of your program that might fail unexpectedly.