Emailing HTML file contents with VBS script - vbscript

How can I get this script to load the contents of a HTML file and send it as the email body.
I keep getting an error that says
Line 8
Invalid procedure call or argument
Code: 800A0005
I have tried that and it works thanks.
But when it reads the htm file the script breaks because there are more than one “ in the file.
I am getting this error
Line: 13
Object doesn't support this property or method: 'objEmail.CreateMHTMLBody'
code: 800A01B6
What can I do to fix it.
Dim fso
Set objEmail = CreateObject("CDO.Message")
objEmail.From = "user#Example.com"
objEmail.Subject = "Test Email"
Const ForReading=1
Set fso = CreateObject("Scripting.FileSystemObject")
Set dict = CreateObject("Scripting.Dictionary")
BodyText = fso.OpenTextFile("C:\Users\user\Desktop\Email.htm",ForReading).ReadAll
objEmail.CreateMHTMLBody = BodyText
objEmail.AddAttachment "C:\Users\user\Desktop\test.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set dict = CreateObject("Scripting.Dictionary")
Set file = fso.OpenTextFile ("C:\Users\user\Desktop\address.txt", 1)
row = 0
Do Until file.AtEndOfStream
line = file.Readline
dict.Add row, line
row = row + 1
objEmail.To = line
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
"127.0.0.1"
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Update
objEmail.Send
Loop

Set statement assigns an object reference to a variable or property;
ReadAll method reads an entire TextStream file and returns the resulting string.
Hence, next code snippet should work:
Const ForReading=1
Set fso = CreateObject("Scripting.FileSystemObject")
Set dict = CreateObject("Scripting.Dictionary")
BodyText = fso.OpenTextFile("C:\Users\user\Desktop\Email.htm",ForReading).ReadAll
' superabundant Set fso = CreateObject("Scripting.FileSystemObject")
' superabundant Set dict = CreateObject("Scripting.Dictionary")
Set file = fso.OpenTextFile ("C:\Users\user\Desktop\address.txt", 1)
' …
'
objEmail.Subject = "Test Email"
objEmail.HtmlBody = BodyText
'…
Please read Paul R. Sadowski's article VBScript To Send Email Using CDO. There is a hint how to send a webpage from a file on your machine using CreateMHTMLBody method instead of setting HTMLBody property.

Related

variable isnt updating as the code loops through

Ive written some code that loops through text files in a folder and updates them with an addiotnal header "TREATMENT_CODE" and then appends a code to the end of each line within each text file. The code is taken from the txt file name. Ive set this as a variable called TCode. The problem Im having is that the TCode variable isn't changing after the first loop through. Can anybody help? Thanks
Please excuse all of the msgbox lines, just me using them to figure out whats going on.
Code:
Option Explicit
Dim FSO, FLD, FIL, TS
Dim strFolder, strContent, strPath, FileName, PosA, TCode, rfile, Temp, dataToAppend, fulldata, wfile, TempArr, i
Const ForReading = 1, ForWriting = 2, ForAppending = 8
'Change as needed - this names a folder at the same location as this script
strFolder = "C:\Users\User1\OneDrive - Company/Documents\Temporary_delete_every_month\CRM_combiner_macro\Looping_test\files to amend"
'Create the filesystem object
Set FSO = CreateObject("Scripting.FileSystemObject")
'Get a reference to the folder you want to search
set FLD = FSO.GetFolder(strFolder)
'loop through the folder and get the file names
For Each Fil In FLD.Files
'MsgBox Fil.Path
'If UCase(FSO.GetExtensionName(Fil.Name)) = ".txt" Then
strPath = Fil.Path
'msgbox strPath
'strPath = Replace(strPath,"""","")
'msgbox strPath
posA = InStrRev(strPath, "\") +1
TCode = "|" & Mid(strPath, posA, 11)
msgbox "this is TCode " & TCode
Set fso = CreateObject("scripting.filesystemobject")
'msgbox "next file to amend" & strPath
Set rfile = fso.OpenTextFile(strPath, ForReading) 'File opened in Read-only mode
While Not rfile.AtEndOfStream
temp=rfile.ReadLine()
If rfile.Line=2 Then
dataToAppend = "|TREATMENTCODE"
ElseIf rfile.Line=3 Then
dataToAppend = TCode
End If
fulldata = fulldata & temp & dataToAppend & "|||"
Wend
rfile.Close
fulldata = Left(fulldata,Len(fulldata)-2)
Set wfile = fso.OpenTextFile(strPath, ForWriting) 'File opened in write mode
tempArr = Split(fulldata,"|||")
For i=0 To UBound(tempArr)
wfile.WriteLine tempArr(i)
Next
wfile.Close
Set fso= Nothing
'End If
'Clean up
Set TS = Nothing
Set FLD = Nothing
Set FSO = Nothing
set rfile = Nothing
set wfile = Nothing
set tempArr = Nothing
set Temp = Nothing
set TCode = Nothing
Next
MsgBox "Done!"

How to correct VBscript runtime error: input past end of file

I'm getting the following error for this code. Please could you advise where it is wrong? Line 71 is "urls2 = objInputFile.ReadAll".
Line 71
Character 1
Error: Input past end of file
Code: 800A003E
Source: Microsoft VBScript runtime error.
inputfile = "C:\Evernote.html"
outputfolder = "c:\"
msgbox("launched. press ok to continue")
'create urls1.txt
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objOutputFile = objFileSystem.CreateTextFile(outputfolder & "urls1.txt", TRUE)
'read inputfile (evernote exported html)
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objInputFile = objFileSystem.OpenTextFile(inputfile, 1)
html = objInputFile.ReadAll
objInputFile.Close
'split html var
html = Split(html, "<tr><td><b>Source:</b></td><td><a href=""")
'loop through html array and clean up the results so you get just the urls
'and write them to urls1.txt
For i = 1 To UBound(html)
checkA = InStr(html(i), """")
if checkA > 1 then
html(i) = Split(html(i), """")
urls = html(i)(0)
objOutputFile.WriteLine(urls)
end if
Next
'remove duplicates
'create urls2.txt
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objOutputFile = objFileSystem.CreateTextFile(outputfolder & "urls2.txt", TRUE)
'read urls1.txt and remove duplicates and write results to urls2.txt
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = outputfolder & "urls1.txt"
Set objFile = objFS.OpenTextFile(strFile)
Set d = CreateObject("Scripting.Dictionary")
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If Not InStr(strLine,"--------") >0 Then
If Not d.Exists(strLine) Then
d.Add strLine , 0
End If
End If
Loop
x=d.Items
For Each strKey In d.keys
objOutputFile.WriteLine(strKey)
Next
'sort alphabetically
'read urls2.txt and sort everything alphabetically
'read urls2.txt
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objInputFile = objFileSystem.OpenTextFile(outputfolder & "urls2.txt", 1)
urls2 = objInputFile.ReadAll
objInputFile.Close
'split each line into array
urls2 = Split(urls2, VBCrLf)
'sort urls2 array by alphabet with bubble sort method
For i = (UBound(urls2) - 1) to 0 Step -1
For j= 0 to i
If UCase(urls2(j)) > UCase(urls2(j+1)) Then
strHolder = urls2(j+1)
urls2(j+1) = urls2(j)
urls2(j) = strHolder
End If
Next
Next
'write the sorted version of urls2.txt in urlsfinal.txt
'create urlsfinal.txt
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objOutputFile = objFileSystem.CreateTextFile(outputfolder & "urlsfinal.txt", TRUE)
'write all sorted vars from urls2 array to urlsfinal.txt
For i = 0 to UBound(urls2)
objOutputFile.WriteLine(urls2(i))
next
msgbox("all done")
The problem is your source file urls2.txt is empty. The reason for this is you are not closing your files after you write to them. You need to add this after you have finished writing out to urls1.txt and urls2.txt.
objOutputFile.Close
Also, you don't need to continually recreate the instance of objFileSystem every time you access the files. You can instantiate it once at the top.
Be sure to be a good memory citizen and destroy all objects you set in your code.
Set objFileSystem = Nothing

Put new text on the same line in the output file

I'm trying to make a settings file for my. Vbs happens that it also creates settings for my. Bat file and add new text to invest the same place the text on the same line the file creates a new line.
Ex:
CBNC-Blacklist =TEST
When I add a new text with the old it is well
CBNC-Blacklist =TEST
SDSADADA
Sub Main()
Dim Blist
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile("A\a00_Blacklist.ini")
If objFile.Size > 0 Then
Set objReadFile = objFSO.OpenTextFile("A\a00_Blacklist.ini", 1)
strContents = objReadFile.ReadAll
objReadFile.Close
End if
Set WshShell = CreateObject("WScript.Shell")
Const ForReading = 1, ForWriting = 2, ForAppending = 8, CreateIfNeeded = True
Blist = Inputbox(vbcrlf & "Digite abaixo os itens que você deseja adicionar" & vbcrlf & "na Blacklist separando os mesmos com espaços:", "NoCheating", strContents)
If Blist = "" Then
msgbox "A Blacklist NÃO foi alterada!",vbExclamation,"NoCheating"
Else
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objMiFichero = objFSO.OpenTextFile("A\a00_Blacklist.ini", ForWriting, CreateIfNeeded)
objMiFichero.WriteLine( Blist )
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objMiFichero = objFSO.OpenTextFile("A\a00_Config_2.ini", ForWriting, CreateIfNeeded)
objMiFichero.WriteLine( "CBNC-Blacklist="&Blist )
msgbox "A Blacklist foi atualizada!",vbInformation,"NoCheating"
End if
End Sub
On Error Resume Next
Main
If Err.Number Then
WScript.Quit 4711
End If
Unfortunately, VBScript doesn't have a "seek" statement to position a file pointer. And you can't combine any of the file modes (ForReading, ForWriting, ForAppending) so that prevents you from "reading" the file until you get to a certain position and then writing at that position. (I've always wondered why they chose bit-position values (1, 2, 8) when you can't combine the values anyway. They could have just used 1, 2, 3).
What you can do, however, is parse your original ini file and write to a new one. If nothing should change, just write the original line to the new file. If the value should change, write a new value to your new file. For example, if you wanted to change the value of CBNC-Blacklist from TEST to NEW:
Set FileIn = objFSO.OpenTextFile("c:\settings.ini", ForReading)
Set FileOut = objFSO.CreateTextFile("c:\settings-new.ini", True)
Do Until FileIn.AtEndOfStream
' Read a line from the original file...
strLine = FileIn.ReadLine()
' Is this the line we want to change?
If Left(strLine, 15) = "CBNC-Blacklist=" Then
' Write the new value to the new file.
FileOut.WriteLine "CBNC-Blacklist=NEW"
Else
' Just write the original line to the new file.
FileOut.WriteLine strLine
End If
Loop
FileIn.Close
FileOut.Close
' Finally, replace the original settings file with the new one...
objFSO.CopyFile "c:\settings-new.ini", "c:\settings.ini", True
Of course you could make this more modular by creating a subroutine that accepts the "key" and "value" as parameters. I just wanted to keep things simple for this example.
I got what I wanted and I have to say it was very difficult anyway thanks for the help and the code below is the code ... I could always read the first line. Ini file and always writes in the first well.
Sub Main()
Dim Blist
Const ForReading = 1, ForWriting = 2, ForAppending = 8, CreateIfNeeded = True
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("A\a00_Blacklist.ini", ForReading)
For i = 4 to 3
objTextFile.ReadLine
Next
strLine = objTextFile.ReadLine
Set WshShell = CreateObject("WScript.Shell")
Blist = Inputbox(vbcrlf & "Digite abaixo os itens que você deseja adicionar" & vbcrlf & "na Blacklist separando os mesmos com espaços:","NoCheating",strLine)
If Blist = "" Then
msgbox "A Blacklist NÃO foi alterada!",vbExclamation,"NoCheating"
Else
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objMiFichero = objFSO.OpenTextFile("A\a00_Blacklist.ini", ForWriting, CreateIfNeeded)
objMiFichero.WriteLine( Blist )
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objMiFichero = objFSO.OpenTextFile("A\a00_Config_2.ini", ForWriting, CreateIfNeeded)
objMiFichero.WriteLine( "CBNC-Blacklist="&Blist )
msgbox "A Blacklist foi atualizada!",vbInformation,"NoCheating"
End if
End Sub
On Error Resume Next
Main
If Err.Number Then
WScript.Quit 4711
End If

Reading data from a file with a variable name - VBScript

I'm trying to count the number of lines in a text file using VBScript. I have managed to do this without a problem for a text file with a fixed name. EG: "C:\Orig\sample.txt"
However, our filenames change daily, EG: "C:\Orig\sample*todaysdate*.txt"
I have looked high and low for a way to 'read' a file with a variable name and have had no luck.
What I have so far for a fixed file name is:
Dim oFso, oReg, sData, lCount, linesum
Const ForReading = 1, sPath = "C:\Orig\sample.txt"
Set oReg = New RegExp
Set oFso = CreateObject("Scripting.FileSystemObject")
sData = oFso.OpenTextFile(sPath, ForReading).ReadAll
With oReg
.Global = True
.Pattern = "\r\n" 'vbCrLf
lCount = .Execute(sData).Count + 1
End With
WScript.Echo("The total number of lines including the header is " & lCount)
Set oFso = Nothing
Set oReg = Nothing
This works perfectly well, but I just cannot find the correct syntax for a variable file name.
If it is of any help, the file I'm looking to interrogate will be the ONLY file in the containing folder.
Is anybody able to offer any assistance? Many thanks.
I have now tried the following:
Dim objFso, objReg, sData, lCount
Const ForReading = 1
sPath = "C:\Orig"
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFso.GetFolder(sPath)
For Each objFile in objFolder.Files
Set objReg = New RegExp
sData = objFso.OpenTextFile(sPath, ForReading).ReadAll
With objReg
.Global = True
.Pattern = "\r\n" 'vbCrLf
lCount = .Execute(sData).Count + 1
End With
WScript.Echo("The total number of lines including the header is " & lCount)
Set objFso = Nothing
Set objReg = Nothing
Set objFolder = Nothing
set sData = Nothing
Next
But on line 9 I am getting a 'Permission denied' error. I have checked folder permissions and file permissions and I have full rights.
Does anybody have any ideas?
Thanks in advance.
Loop through the files in the folder instead. There's no need to name the file directly.
Dim oFso, oReg, sData, lCount, linesum
Const ForReading = 1
sPath = "C:\Orig\sample\"
Set oFso = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFso.GetFolder(sPath)
For Each objFile in objFolder.Files
Set oReg = New RegExp
sData = oFso.OpenTextFile(sPath, ForReading).ReadAll
With oReg
.Global = True
.Pattern = "\r\n" 'vbCrLf
lCount = .Execute(sData).Count + 1
End With
WScript.Echo("The total number of lines including the header is " & lCount)
Set oFso = Nothing
Set oReg = Nothing
Next

VB Script - Undefined variable

I'm getting 'variable is undefined', I'm guessing this has something to do with the scope of variables in vbscript, but my knowledge is limited with this.
I know the loading of the email addresses works and the actual emailing because I have checked these separately. I'm trying to loop through a list of email addresses and send the log file to each..
Any additional information would be great!
First, there is a var array at the top of the file:
dim emails()
function getEmailAddresses()
dim objFSO
dim objConfigFile
dim strLine
dim iCounter
const ForReading = 1, ForWriting = 2, ForAppending = 8
set objFSO = createobject("Scripting.FileSystemObject")
set objConfigFile = objFSO.OpenTextFile("emailAddresses.config", ForReading)
iCounter = 0
do while not objConfigFile.AtEndOfStream
redim preserve emails(iCounter)
strLine = trim(objConfigFile.ReadLine)
emails(iCounter) = strLine
iCounter = iCounter + 1
loop
objConfigFile.Close
end function
function writetolog(strLogtext)
dim objFSO
dim objLogfile
const ForReading = 1, ForWriting = 2, ForAppending = 8
set objFSO = createobject("Scripting.FileSystemObject")
set objLogfile = objFSO.OpenTextFile("xxx.log", ForAppending, true)
objLogfile.Writeline now() & " - " & strLogText
objLogfile.Close
call EmailLogFile(strLogText)
end function
function EmailLogFile(bodyText)
for each emailAddress in emails
set objEmail = CreateObject("CDO.Message")
objEmail.From = "File.Mover#xxxxxxx.xxx"
objEmail.To = emailAddress
objEmail.Subject = "File Move Log"
objEmail.Textbody = bodyText
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
"xxxxxx"
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Update
objEmail.Send
next
end function
It doesn't look like you're calling getEmailAddresses() anywhere so your file won't be read and your emails array won't be populated
What line is the undefined var at? Or what is the var name?
Either way, 'strLogText' is not defined anywhere. Also, if this is a classic ASP page put an Option Explicit statement at the top.

Resources