Send email notification with attachment - vbscript

I'm writing a VBScript to send email notification when a file arrives in Test folder. I want to attach that file to my email. The file name is not constant. Each time a file arrives with different name.
Below is my code:
Const PATH = "F:\Test"
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim folder: Set folder = fso.GetFolder(PATH)
If folder.Files.Count <> 0 Then
strSMTPFrom = "errorfile#test.com"
strSMTPTo = "test#test.com"
strSMTPRelay = "127.0.0.1"
strTextBody = "The attached file arrived in Test folder"
strSubject = "File arrived in Test folder"
strAttachment =
Set oMessage = CreateObject("CDO.Message")
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTPRelay
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
oMessage.Configuration.Fields.Update
oMessage.Subject = strSubject
oMessage.From = strSMTPFrom
oMessage.To = strSMTPTo
oMessage.TextBody = strTextBody
oMessage.AddAttachment strAttachment
oMessage.Send
End If

I'd say what you actually want is a filesystem monitor. Something like this:
Sub SendNotification(filename)
'your mail sending code goes here
End Sub
Function CreateMonitor(path)
Set wmi = GetObject("winmgmts://./root/cimv2")
Set fso = CreateObject("Scripting.FileSystemObject")
path = Split(fso.GetAbsolutePathName(path), ":")
drv = path(0) & ":"
dir = Replace(path(1), "\", "\\")
If Right(dir, 2) <> "\\" Then dir = dir & "\\"
query = "SELECT * FROM __InstanceOperationEvent" & _
" WITHIN 1" _
" WHERE Targetinstance ISA 'CIM_DataFile'" & _
" AND TargetInstance.Drive=""" & drv & """" & _
" AND TargetInstance.Path=""" & dir & """"
Set CreateMonitor = wmi.ExecNotificationQuery(query)
End Function
Set monitor = CreateMonitor("F:\Test")
Do
Set evt = monitor.NextEvent()
If evt.Path_.Class = "__InstanceCreationEvent" Then
SendNotification evt.TargetInstance.Name
End If
Loop
The Name property of the TargetInstance object contains the full path to the new file. Put your mail sending code into the SendNotification function and have it attach filename to the mail.

To find the newest file in a folder, use this code:
Const PATH = "F:\Test"
dim fso: set fso = CreateObject("Scripting.FileSystemObject")
dim myFolder: set myFolder = fso.getFolder(PATH)
dim myFile
dim recentFile
For Each myFile in myFolder.Files
If (isempty(recentFile)) Then
Set recentFile = myFile
ElseIf (myFile.DateLastModified > recentFile.DateLastModified) Then
Set recentFile = myFile
End If
Next
Then just use its path to attach the file.
strAttachment = recentFile.path

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!"

Receiving error code 424 in VBA when attempting to use CopyHere method with built in Windows Zip

I am receiving the object required error on the following line, although fl4 is a defined variant/object/file:
oFold.CopyHere (fl4)
Any thoughts would be appreciated.
Below is an applicable excerpt of code. I have excluded the recursive loop and directory sub folder iteration:
srcpth = rs1.Fields("Src_File_Path").Value
destpth = rs1.Fields("Zip_File_Path").Value
var = 0
Set FS2 = New FileSystemObject
Set FS2 = CreateObject("Scripting.FileSystemObject")
Set fl1 = FS2.GetFolder(srcpth)
For Each fl2 In FS2.GetFolder(srcpth).SubFolders
var = 2
ZipFile = Application.CurrentProject.Path & "\tmp\" & fl2.Name & ".zip"
Set FS3 = CreateObject("Scripting.FileSystemObject")
FS3.CreateTextFile(ZipFile, True).Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)
Set FS3 = Nothing
Set FS4 = New FileSystemObject
Set FS4 = CreateObject("Scripting.FileSystemObject")
Set fl3 = FS4.GetFolder(fl2)
For Each fl4 In FS4.GetFolder(fl2).Files
var = 2
GoTo Zipxchg
zipxchg_2:
Next
Next
Set FS1 = Nothing
Set oFld = Nothing
Set oApp = Nothing
Set oShl = Nothing
Exit Sub
Zipxchg:
If var = 2 Then
ZipFile = Application.CurrentProject.Path & "\tmp\" & fl2.Name & ".zip"
Set oApp = CreateObject("Shell.Application")
Set oFld = oApp.NameSpace(CVar(ZipFile))
Set FilestoZip = objShell.File(fl4)
i = oFld.Items.Count
oFold.CopyHere (fl4)
Set oShl = CreateObject("WScript.Shell")
GoTo zipxchg_2
End Sub
remove the brackets .... use oFold.CopyHere fl4 .... brackets cause a value to be returned, but there is no variable (object) to receive it

Using VBS to read from one text file and compare to CSV to create condition dependent shortcut

Trying to read a single value in a text file and use that value to match a position on a csv in order to generate a unique shortcut with arguments. I'm having trouble finding the error in my VBS logic in the script below:
dim objFS,objFileToRead,objTextFile, strSiteCode, strServerFQDN, strPort, mySiteCode
dim arrStr
strComputer = "."
Set objFS = CreateObject("Scripting.FileSystemObject")
set objTextFile = objFS.OpenTextFile("Servers.csv")
Set objFileToRead = objFS.OpenTextFile("code.txt",1)
Set mySiteCode = objFileToRead.ReadAll()
Set WSHShell = CreateObject("WScript.Shell")
Do while NOT objTextFile.AtEndOfStream
arrStr = Split(objTextFile.ReadLine,",")
strSiteCode = arrStr(0)
strServerFQDN = arrStr(1)
strPort = arrStr(2)
if mySiteCode = strSiteCode then
'wscript.echo "Site Code: " & strSiteCode & " - Server FQDN: " & strServerFQDN & " - Port #: " & strPort
fullname = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Generic\Generic.lnk"
TargetPath = "%SystemRoot%\Generic\Generic.exe"
Set shortcut = WSHShell.CreateShortcut(fullname)
shortTarget = shortcut.TargetPath
shortcut.Arguments = "s=" & strServerFQDN & " p=" & strPort
shortcut.save
fullname = "C:\Users\Public\Desktop\Generic.lnk"
TargetPath = "%SystemRoot%\Generic\Generic.exe"
Set shortcut = WSHShell.CreateShortcut(fullname)
shortTarget = shortcut.TargetPath
shortcut.Arguments = "s=" & strServerFQDN & " p=" & strPort
shortcut.save
end if
Loop
I'm wondering if I need to load both the csv and txt file in to an array in order to create the shortcut with the correct information.
Resources:
servers.csv (file contains info in format below)
Site1,10.0.0.1,12345
Site2,10.0.0.2,23456
...
code.txt (file contains only one line which is site identifier)
Site1
If you'd execute the script from an open cmd window with
cscript YourScriptName.vbs
you will see the error message. I think you should change the lines
shortTarget = shortcut.TargetPath
to
shortcut.Target = TargetPath
or better directly to
shortcut.Target = "%SystemRoot%\Generic\Generic.exe"
As stated in a reply to LotPings (thanks for your feedback!) the issue was that the readall command was picking up the contents of the text file to include the CRLF at the end of the Site1 value. It was not obvious that these characters were present until opening the txt file in an editor that would display all characters.
Corrected and functional code is:
dim objFS,objFileToRead,objTextFile, strSiteCode, strServerFQDN, strPort, mySiteCode
dim arrStr
strComputer = "."
Set objFS = CreateObject("Scripting.FileSystemObject")
set objTextFile = objFS.OpenTextFile("Servers.csv")
Set objFileToRead = objFS.OpenTextFile("code.txt",1)
mySiteCode = objFileToRead.ReadLine()
Set WSHShell = CreateObject("WScript.Shell")
Do while NOT objTextFile.AtEndOfStream
arrStr = Split(objTextFile.ReadLine,",")
strSiteCode = arrStr(0)
strServerFQDN = arrStr(1)
strPort = arrStr(2)
if trim(mySiteCode) = trim(strSiteCode) then
'Start Menu Icon Creation Here
fullname = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Generic\Generic.lnk"
Set shortcut = WSHShell.CreateShortcut(fullname)
shortcut.TargetPath = "%SystemRoot%\Generic\Generic.exe"
shortcut.Arguments = "s=" & strServerFQDN & " p=" & strPort
shortcut.WorkingDirectory = "%SystemRoot%\Generic"
shortcut.save
'Desktop Icon Creation Here
fullname = "C:\Users\Public\Desktop\Generic.lnk"
Set shortcut = WSHShell.CreateShortcut(fullname)
shortcut.TargetPath = "%SystemRoot%\Generic\Generic.exe"
shortcut.Arguments = "s=" & strServerFQDN & " p=" & strPort
shortcut.WorkingDirectory = "%SystemRoot%\Generic"
shortcut.save
Exit Do
end if
Loop

VB Script referencing a Variable which is defined from a macro

I need some help with this VB script (edit: it is being used in QlikView)- it is copying a file to a different location (checks if the file already exists in the destination folder).
It works when the source filename and location is hardcoded but this is going to be a variable which is defined in a different macro.
So the source filename and location will be defined by varFileOpen.
Basically in the code, instead of:
SourceFile = "C:\file_path\file_name.txt"
to be like this:
SourceFile = varFileOpen
where varFileOpen has been defined from a different SUB (it is the full file path).... I can't get it to work?
Sub that creates the varFileOpen:
'Sub to get open file dialog
SUB ShowOpen
OpenSave "varFileOpen", 0, "Text file (*.txt)|*.txt|All files (*.*)|*.*", "h:\", "Select a file to open"
END SUB
' Sub to show browse folder dialog
SUB Folder (objVariable)
ON ERROR RESUME NEXT
SET objShell = CREATEOBJECT("Shell.Application")
SET objFolder = objShell.BrowseForFolder (WINDOW_HANDLE, TITLE, OPTIONS, ROOT)
SET objFolderItem = objFolder.Self
strPathAndFile = objFolderItem.Path
SET objSavePath = ActiveDocument.Variables(objVariable)
objSavePath.SetContent strPathAndFile, TRUE
ON ERROR GOTO 0
END SUB
' Sub to show open/save dialog
SUB OpenSave (objVariable, intType, strFilter, strInitialDirectory, strDialogText)
' Create objects
SET objShell = CREATEOBJECT("WScript.Shell")
SET objFSO = CREATEOBJECT("Scripting.FileSystemObject")
strTempDir = objShell.ExpandEnvironmentStrings("%TEMP%")
strTempFile = strTempDir & "\" & objFSO.GetTempName
' Temporary powershell script file to be invoked
strPSFile = tempFile & ".ps1"
' Temporary file to store standard output from command
strPSOutFile = tempFile & ".txt"
' Create script to run
strPSScript = strPSScript & "[System.Reflection.Assembly]::LoadWithPartialName(""System.windows.forms"") | Out-Null" & vbCRLF
' Check type (Open (0) or Save (1))
IF intType = 1 THEN
strPSScript = strPSScript & "$dlg = New-Object System.Windows.Forms.SaveFileDialog" & vbCRLF
ELSE
strPSScript = strPSScript & "$dlg = New-Object System.Windows.Forms.OpenFileDialog" & vbCRLF
END IF
' Set initial directory
strPSScript = strPSScript & "$dlg.initialDirectory = " & CHR(34) & strInitialDirectory & CHR(34) & vbCRLF
' Set file filter/s
strPSScript = strPSScript & "$dlg.filter = " & CHR(34) & strFilter & CHR(34) & vbCRLF
strPSScript = strPSScript & "$dlg.FilterIndex = 1" & vbCRLF
' Set dialog text
strPSScript = strPSScript & "$dlg.Title = " & CHR(34) & strDialogText & CHR(34) & vbCRLF
' Show help (seems it must be set to true)
strPSScript = strPSScript & "$dlg.ShowHelp = $True" & vbCRLF
' Show the dialog
strPSScript = strPSScript & "$dlg.ShowDialog() | Out-Null" & vbCRLF
strPSScript = strPSScript & "Set-Content """ &strPSOutFile & """ $dlg.FileName" & vbCRLF
' Write result
SET objResultFile = objFSO.CreateTextFile(strPSFile, TRUE)
objResultFile.WriteLine(strPSScript)
objResultFile.Close
SET objResultFile = NOTHING
' Run command in PowerShell
strPSCMD = "powershell -ExecutionPolicy unrestricted &'" & strPSFile & "'"
objShell.Run strPSCMD, 0, TRUE
' Open result file and read result
SET objResultFile = objFSO.OpenTextFile(strPSOutFile, 1, 0, -2)
strPathAndFile = objResultFile.ReadLine
objResultFile.Close
SET objResultFile = NOTHING
' Add to result to variable
SET objSavePath = ActiveDocument.Variables(objVariable)
objSavePath.SetContent strPathAndFile, TRUE
' Delete temp-files
objFSO.DeleteFile(strPSFile)
objFSO.DeleteFile(strPSOutFile)
END SUB
The above code opens explorer & you are able to select a file and the path is copied - varFileOpen.
The following SUB moves the file:
SUB movefile
Const DestinationFile = "c:\destfolder\anyfile.txt"
Const SourceFile = "C:\file_path\file_name.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
'Check to see if the file already exists in the destination folder
If fso.FileExists(DestinationFile) Then
'Check to see if the file is read-only
If Not fso.GetFile(DestinationFile).Attributes And 1 Then
'The file exists and is not read-only. Safe to replace the file.
fso.CopyFile SourceFile, "C:\destfolder\", True
Else
'The file exists and is read-only.
'Remove the read-only attribute
fso.GetFile(DestinationFile).Attributes = fso.GetFile(DestinationFile).Attributes - 1
'Replace the file
fso.CopyFile SourceFile, "C:\destfolder\", True
'Reapply the read-only attribute
fso.GetFile(DestinationFile).Attributes = fso.GetFile(DestinationFile).Attributes + 1
End If
Else
'The file does not exist in the destination folder. Safe to copy file to this folder.
fso.CopyFile SourceFile, "C:\destfolder\", True
End If
Set fso = Nothing
END SUB
You will need to pass the value into the Sub for it to have scope, which means you will need to define the sub like this so that it accepts a parameter
Public Sub MySub(byVal SourceFile)
ByVal just means you pass the Value of the variable rather than the actual variable itself.
And you would call it from the other sub with
MySub varFileOpen
EDIT: Based on the code displayed above, you would need to change Sub movefile to Sub movefile(byVal SourceFile) and remove the Const delaration of SourceFile. Once that was done, all you would have to do is change whatever is calling movefile (I can't see anything in the code you've posted doing this?) to call it with movefile varToOpen instead
Try my CustomFileDialog.
Usage:
Dim fDialog
Set fDialog = New CustomFileDialog
fDialog.FilterString = "Text Files (*.txt)|*.txt"
fDialog.InitialDirectory = "C:\"
fDialog.DialogText = "Select a file to open"
fDialog.Show
fDialog.MoveFile "C:\stackoverflow\temp\New File Name.TXT"
CustomFileDialog
Class CustomFileDialog
Public SourceFile
Public FilterString
Public InitialDirectory
Public DialogText
Public Sub Show
Set toolkit = CreateObject("Vbsedit.toolkit")
Files = toolkit.OpenFileDialog(InitialDirectory, FilterString, False, DialogText)
If UBound(Files) >= 0 Then
SourceFile = Files(0)
Else
SourceFile = ""
End If
End Sub
Public Sub MoveFile(DestinationFile)
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(DestinationFile) Then fso.DeleteFile DestinationFile, True
fso.CopyFile SourceFile, DestinationFile, True
End Sub
End Class

vbscript search string in multiple files

Please advice how changes the current single incoming log file to search multiple files.
Dim strTextToFind, strInputFile, strOutputFile, boolMatchCaseSensitive
Dim objFSO, objInputFile, strFoundText, strLine, objOutputFile
strTextToFind = Inputbox("Enter the text you would like to search for.")
strInputFile = "C:\Users\mmmanima\Desktop\mani\Day_16.txt"
iF YOU CAN NOTICED, IM ONLY ACCESS THE day_16 FILE
strOutputFile = "C:\Users\mmmanima\Desktop\texting As\result.txt"
Set objFSO = CreateObject("Scripting.FilesystemObject")
Const intForReading = 1
Const intForWriting = 2
Const intForAppending = 8
Set objInputFile = objFSO.OpenTextFile(strInputFile, intForReading, False)
Do until objInputFile.atEndOfStream
strLine = objInputFile.ReadLine
If InStr(strLine,strTextToFind) > 0 Then
strFoundText = strLine
If strFoundText <> "" Then
Set objOutputFile = objFSO.OpenTextFile(strOutputFile,intForAppending, True)
objOutputFile.WriteLine strFoundText
objOutputFile.Close
Set objOutputFile = Nothing
End If
End If
loop
objInputFile.Close
Set objInputFile = Nothing
WScript.Quit
VBScript required to search userinput string into the share folder and there is 60 files.
As I believe you want to search through the all files in a particular folder. Then I suggest you to loop you action while all files are read
to do that it's easier to maintain sub or function
pseudo:
var inputFolder = ".\myfolder"
foreach file in the inputFolder
{
inputFile = file
searchIn(inputFile)
}
sub searchIn(inputFile)
{
'do your current works here
}
code:
This part will give you the all file names
Set fso = CreateObject("Scripting.FileSystemObject")
inputFldr = Replace(wscript.scriptfullname,wscript.scriptname,".\")
Set fldr = fso.getFolder(inputFldr)
For Each file In fldr.Files
'call to your function
Next
----------plese aware of typos------
Dim strTextToFind, strInputFile, strOutputFile, boolMatchCaseSensitive
Dim objFSO, objInputFile, strFoundText, strLine, objOutputFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
inputFldr = Replace(wscript.scriptfullname,wscript.scriptname,".\")
Set fldr = objFSO.getFolder(inputFldr)
strTextToFind = Inputbox("Enter the text you would like to search for.")
For Each file In fldr.Files
yourFunctionName(file )
Next
sub yourFunctionName(inputFile)
strInputFile = inputFile
strOutputFile = ".\result.txt"
Const intForReading = 1
Const intForWriting = 2
Const intForAppending = 8
Set objInputFile = objFSO.OpenTextFile(strInputFile, intForReading, False)
Do until objInputFile.atEndOfStream
strLine = objInputFile.ReadLine
If InStr(strLine,strTextToFind) > 0 Then
strFoundText = strLine
If strFoundText <> "" Then
Set objOutputFile = objFSO.OpenTextFile(strOutputFile,intForAppending, True)
objOutputFile.WriteLine strFoundText
objOutputFile.Close
Set objOutputFile = Nothing
End If
End If
loop
objInputFile.Close
Set objInputFile = Nothing
end sub
WScript.echo "done"
WScript.Quit
You can try this vbscript, i added a function BrowseForFolder()
Option Explicit
Dim strTextToFind,inputFldr,strInputFile,strOutputFile,path,fldr
Dim objFSO, objInputFile,strFoundText,strLine,objOutputFile,file,ws
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set ws = CreateObject("wscript.Shell")
path = objFSO.GetParentFolderName(wscript.ScriptFullName)
strOutputFile = path & "\result.txt"
If objFSO.FileExists(strOutputFile) Then
objFSO.DeleteFile(strOutputFile)
End if
inputFldr = BrowseForFolder()
Set fldr = objFSO.getFolder(inputFldr)
strTextToFind = Inputbox("Enter the text you would like to search for it !","Enter the text you would like to search for it !","wscript")
For Each file In fldr.Files
Call Search(file,strTextToFind)
Next
ws.run strOutputFile
'***************************************************************************************************************
Sub Search(inputFile,strTextToFind)
strInputFile = inputFile
Const intForReading = 1
Const intForWriting = 2
Const intForAppending = 8
Set objInputFile = objFSO.OpenTextFile(strInputFile,intForReading, False)
Do until objInputFile.atEndOfStream
strLine = objInputFile.ReadLine
If InStr(strLine,strTextToFind) > 0 Then
strFoundText = strLine
If strFoundText <> "" Then
Set objOutputFile = objFSO.OpenTextFile(strOutputFile,intForAppending, True)
objOutputFile.WriteLine "The Path of file ===> "& DblQuote(strInputFile) & VbCRLF &_
"String found "& DblQuote(strTextToFind) & " ===> "& DblQuote(strFoundText) & VbCRLF & String(100,"*")
objOutputFile.Close
Set objOutputFile = Nothing
End If
End If
loop
objInputFile.Close
Set objInputFile = Nothing
End sub
'***************************************************************************************************************
Function BrowseForFolder()
Dim ws,objFolder,Copyright
Set ws = CreateObject("Shell.Application")
Set objFolder = ws.BrowseForFolder(0,"Choose the folder to search on it ",1,"c:\Programs")
If objFolder Is Nothing Then
Wscript.Quit
End If
BrowseForFolder = objFolder.self.path
end Function
'****************************************************************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'*****************************************************
A bit late in the day after such a long time gap to address Mara Raj's problem with Hackoo's script but here it is for any others who may be interested. On starting the script it automatically deletes any existing result.txt file. Should the script subsequently go on to find "no match" it fails to generate a results.txt file as it would normally do if there were a match. The simplest way to correct this is to insert:
If objFSO.FileExists(strOutputFile) Then
else
wscript.echo "No Matches Found"
wscript.Quit
end if
between "next" and "ws.run strOutputFile"

Resources