IF loop to check if file exists in VBS - vbscript

I'm doing a lab, and the instructions say to check if a file exists. It suggests using the boolean Not to do it.
Here's my code, but no matter what I do, I can't get past the end of the loop. I keep getting the error message that says the file doesn't exist.
Const Read = 1, Write = 2, Append = 8, ASCII = 0
FileName = "C:\users\gryphon\IP_Addresses.csv"
ipAddrStr = ""
NewRoom = 106
Comp1_IP = "192.168.10.59"
Comp2_IP = "192.168.10.60"
Comp3_IP = "192.168.10.61"
Comp4_IP = "192.168.10.61"
Set fso = CreateObject("Scripting.FileSystemObject")
ipAddrStr = CStr(NewRoom) & "1," & CStr(Comp1_IP) & CStr(NewRoom) & "2," & _
CStr(Comp2_IP) & CStr(NewRoom) & "3," & CStr(Comp3_IP) & _
CStr(NewRoom) & "4," & CStr(Comp4_IP)
If Not fso.FileExists("FileName") Then
WScript.StdOut.WriteLine(Chr(7) & Chr(7))
WScript.Echo "File Does Not Exist." & vbCrLf & _
"You Must Create the File Before You can Read the File."
WScript.Quit
End If
What am I doing wrong, and how do I fix it? This has to be done by 04DEC2016 at 11PM PST. I asked my instructor for help last Monday, and I'm still waiting to hear back.

remove the double quotes from fso.fileExists("FileName"),because of that it is taking the string Filename instead of the value of Filename variable
If NOT fso.FileExists(FileName) Then
WScript.StdOut.WriteLine(Chr(7) & chr(7))
WScript.Echo "File Does Not Exist." & vbcrlf & _
"You Must Create the File Before You can Read the File."
WScript.Quit
End If

Related

VBScript Macro getParentFolder Name

I am trying to create a vbscript macro which would get the folder location in which the macro is stored and create the output files into the same folder. I am using the below code but its not getting the correct location
Set obj1FSO = CreateObject("Scripting.FileSystemObject")
folderLoc = obj1FSO.GetParentFolderName("\Cubes_Macro_V5.zmc")
It would then use the folderLoc variable and append the output file name to it in order to create the output file in the same folder as where the macro is stored.
Set repFso = CreateObject("Scripting.FileSystemObject")
Set repFile = repFso.CreateTextFile(folderLoc & "RCHT_OPTION4_REPORT.txt", True)
The Macro is stored in a folder in the D:\ drive but when I run the above segment of code it get the location for the desktop.
https://msdn.microsoft.com/en-us/library/22dyy47c%28v=vs.84%29.aspx
That is not how the method works - it extracts the "parent" from the string provided.
Option Explicit
Dim fso,GetTheParent
Set fso = CreateObject("Scripting.FileSystemObject")
GetTheParent = fso.GetParentFolderName("C:\Windows")
wscript.echo "Attempt 1:" & "'" & GetTheParent & "'"
GetTheParent = fso.GetParentFolderName("\Windows")
wscript.echo "Attempt 2:" & "'" & GetTheParent & "'"
GetTheParent = fso.GetParentFolderName("Windows")
wscript.echo "Attempt 3:" & "'" & GetTheParent & "'"
GetTheParent = fso.GetParentFolderName("C:\WINDOWS\system32")
wscript.echo "Attempt 4:" & "'" & GetTheParent & "'"
GetTheParent = fso.GetParentFolderName("\WINDOWS\system32")
wscript.echo "Attempt 5:" & "'" & GetTheParent & "'"
Results:
Attempt 1:'C:\'
Attempt 2:''
Attempt 3:''
Attempt 4:'C:\WINDOWS'
Attempt 5:'\WINDOWS'
There is a difference between the current directory ('where you are when you start the process') and the script's directory:
>> WScript.Echo 0, goFS.GetAbsolutePathName(".\")
>> WScript.Echo 1, goWS.CurrentDirectory
>> WScript.Echo 2, goFS.GetParentFolderName(WScript.ScriptFullName)
>>
0 C:\Documents and Settings\eh
1 C:\Documents and Settings\eh
2 M:\bin
(I called my REPL/Interactive VBS shell that resides in m:\bin from my home directory)
I don't know if "Cubes_Macro_V5.zmc" is a VBScript file (with a special extension that is loaded by whatever agent you use via w|cscript.exe), but check if WScript.ScriptFullName has the expected content and apply .GetParentFolderName.
If that fails, you need to determine the folder that your agent uses for macros and feed that directory to .BuildPath.
On second thought:
Voodoo but easy to test: Does
WScript.Echo 0, goFS.GetAbsolutePathName(".\Cubes_Macro_V5.zmc")
deliver the desired result?

Trying to use Shell object and FileSystemObject in VBScript for file manipulation

I am trying to recursively loop through hundreds of directories, and thousands of JPG files to gather sort the files in new folders by date. So far, I am able to individually GetDetailsOf the files using the Shell NameSpace object, and I am also able to recursively loop through directories using the FileSystemObject. However, when I try to put them together in functions, etc, I am getting nothing back when I try to get the DateTaken attribute from the photo.
Here is my code so far:
sFolderPathspec = "C:\LocationOfFiles"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDir = objFSO.GetFolder(sFolderPathspec)
Dim arrFiles()
getInfo(objDir)
Sub getInfo(pCurrentDir)
fileCount = 0
For Each strFileName In pCurrentDir.Files
fileCount = fileCount + 1
Next
ReDim arrFiles(fileCount,2)
i=0
For Each aItem In pCurrentDir.Files
wscript.Echo aItem.Name
arrFiles(i,0) = aItem.Name
strFileName = aItem.Name
strDir = pCurrentDir.Path
wscript.echo strDir
dateVar = GetDatePictureTaken(strFileName, strDir)
'dateVar = Temp2 & "_" & Temp3 & "_" & Temp1
arrFiles(i,1) = dateVar
WScript.echo i & "." & "M:" & monthVar & " Y:" & yearVar
WScript.echo i & "." & strFileName & " : " & arrFiles(i,1) & " : " & dateVar
i=i+1
Next
For Each aItem In pCurrentDir.SubFolders
'wscript.Echo aItem.Name & " passing recursively"
getInfo(aItem)
Next
End Sub
Function GetDatePictureTaken(strFileName, strDir)
Set objShell = CreateObject ("Shell.Application")
Set objCurrFolder = objShell.Namespace(strDir)
'wscript.Echo cstr(objCurrFolder.GetDetailsOf(strFileName, 12))
strFileNameDate = cstr(objCurrFolder.GetDetailsOf(strFileName, 12))
strFileNameDate = CleanNonDisplayableCharacters(strFileNameDate)
arrDate = split(strFileNameDate, "/")
'''FAILS HERE WITH A SUBSCRIPT OUT OF RANGE ERROR SINCE IT GETS NULL VALUES BACK FROM THE GET DETAILS OF FUNCTION'''
monthVar = arrDate(0)
yearVar = arrDate(1)
dayVar = arrDate(2)
GetDatePictureTaken = monthVar & "\" & dayVar & "\" & yearVar
End Function
Function CleanNonDisplayableCharacters(strInput)
strTemp = ""
For i = 1 to len(strInput)
strChar = Mid(strInput,i,1)
If Asc(strChar) < 126 and not Asc(strChar) = 63 Then
strTemp = strTemp & strChar
End If
Next
CleanNonDisplayableCharacters = strTemp
End Function
The "Subscript out of range" error when accessing arrDate(0) is caused by arrDate being empty (UBound(arrDate) == -1). As a Split on a non-empty string will return an array, even if the separator is not found, and an attempt to Split Null will raise an "Invalid use of Null" error, we can be sure that strFileNameDate is "".
Possible reason for that:
The index of "Date Picture Taken" is 25 (XP) and not 12 (Win 7) - or whatever came to Mr. Gates' mind for Win 8.
The DPT property is not filled in.
Your cleaning function messed it up.
You have to test for strFileNameDate containing a valid date and decide where to put the files without a valid DPT.
P.S. Instead of doing the recursive loopings, you should consider to use
dir /s/b path\*.jpg > pictures.txt
and to process that file.

Autogenerate an email in an outlook and attach the currently open word document with VBS

I want to write a VBS macro to auto generate an email in outlook and attach a word document. I currently have a macro that does this for excel, but I can't get it to work for Word. I can't figure out for the life of me what my "FName= " should be. Any suggestions or help would be greatly appreciated. Here is what I have:
Sub AutoEmail()
On Error GoTo Cancel
Dim Resp As Integer
Resp = MsgBox(prompt:=vbCr & "Yes = Review Email" & vbCr & "No = Immediately Send" & vbCr & "Cancel = Cancel" & vbCr, _
Title:="Review email before sending?", _
Buttons:=3 + 32)
Select Case Resp
'Yes was clicked, user wants to review email first
Case Is = 6
Dim myOutlook As Object
Dim myMailItem As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = ActiveWord & "\" & ActiveWord.Name
With otlNewMail
.To = ""
.CC = ""
.Subject = ""
.Body = "Good Morning," & vbCr & vbCr & "" & Format(Date, "MM/DD") & "."
.Attachments.Add FName
.Display
End With
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If no is clicked
Case Is = 7
Dim myOutlok As Object
Dim myMailItm As Object
Set otlApp = CreateObject("Outlook.Application")
Set otlNewMail = otlApp.CreateItem(olMailItem)
FName = ActiveWorkbook.Path & "\" & ActiveWorkbook.Name
With otlNewMail
.To = ""
.CC = ""
.Subject = ""
.Body = "Good Morning," & vbCr & vbCr & " " & Format(Date, "MM/DD") & "."
.Attachments.Add FName
.Send
'.Display
'Application.Wait (Now + TimeValue("0:00:01"))
'Application.SendKeys "%s"
End With
'otlApp.Quit
Set otlNewMail = Nothing
Set otlApp = Nothing
Set otlAttach = Nothing
Set otlMess = Nothing
Set otlNSpace = Nothing
'If Cancel is clicked
Case Is = 2
Cancel:
MsgBox prompt:="No Email has been sent.", _
Title:="EMAIL CANCELLED", _
Buttons:=64
End Select
End Sub
May it is a bit late, but I want to solve it for future use.
You want to have the active document as your file name (FName).
FName = Application.ActiveDocument.Path + "\" + Application.ActiveDocument.Name
' .Path returns only the Path where the file is saved without the file name like "C:\Test"
' .Name returns only the Name of the file, including the current type like "example.doc"
' Backslash is needed because of the missing backslash from .Path
otlNewMail.Attachements.Add FName
May you also want to save your current document before sending it via outlook, otherwise you will send the document without the changes made.
Function SaveDoc()
ActiveDocument.Save
End Function
I hope that this will help others, because the code from the question helped me a lot while scripting a similar script.

File Folder copy

Below is the VBScript code. If the file/s or folder exist I get scripting error, "File already exists".
How to fix that?
How to create folder only if it does not exist and copy files only that are new or do not exist in source path?
How to insert the username (Point 1) after "Welcome" and at (Poin 3) instead of user cancelled?
Can the buttons be changed to Copy,Update,Cancel instead of Yes,No,Cancel? (Point 2)
The code:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set wshShell = WScript.CreateObject( "WScript.Shell" )
strUserName = wshShell.ExpandEnvironmentStrings( "%USERNAME%" )
Message = " Welcome to the AVG Update Module" & vbCR '1*
Message = Message & " *****************************" & vbCR & vbCR
Message = Message & " Click Yes to Copy Definition Files" & vbCR & vbCR
Message = Message & " OR " & vbCR & vbCR
Message = Message & " Click No to Update Definition Files." & vbCR & vbCR
Message = Message & " Click Cancel (ESC) to Exit." & vbCR & vbCR
X = MsgBox(Message, vbYesNoCancel, "AVG Update Module") '2*
'Yes Selected Script
If X = 6 then
objFSO.FolderExists("E:\Updates")
if TRUE then objFSO.CreateFolder ("E:\Updates")
objFSO.CopyFile "c:\Docume~1\alluse~1\applic~1\avg8\update\download\*.*",
"E:\Updates\" , OverwriteFiles
MsgBox "Files Copied Succesfully.", vbInformation, "Copy Success"
End If
'No Selected Script
If X = 7 then
objFSO.FolderExists("Updates")
if TRUE then objFSO.CreateFolder("Updates")
objFSO.CopyFile "E:\Updates\*.*", "Updates", OverwriteFiles
Message = "Files Updated Successfully." & vbCR & vbCR
Message = Message & "Click OK to Launch AVG GUI." & vbCR & vbCR
Message = Message & "Click Cancel (ESC) to Exit." & vbCR & vbCR
Y = MsgBox(Message, vbOKCancel, "Update Success")
If Y = 1 then
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\Progra~1\avg\avg8\avgui.exe" & Chr(34), 0
Set WshShell = Nothing
End if
If Y = 3 then WScript.Quit
End IF
'Cancel Selection Script
If X = 2 then
MsgBox "No Files have been Copied/Updated.", vbExclamation, "User Cancelled" '3*
End if
How to create folder only if it does not exist
This your code:
objFSO.FolderExists("E:\Updates")
if TRUE then objFSO.CreateFolder ("E:\Updates")
simply calls the FolderExists and CreateFolder methods in sequence (CreateFolder is always called because the if TRUE condition evaluates to True) and is equal to:
objFSO.FolderExists("E:\Updates")
objFSO.CreateFolder ("E:\Updates")
You want to call CreateFolder depending on the return value of the FolderExists method:
If Not objFSO.FolderExists("E:\Updates") Then
objFSO.CreateFolder "E:\Updates"
and copy files only that are new or do not exist in source path?
Neither VBScript nor the FileSystemObject object have this functionality. However, it is possible to call an external tool that can do that, such as xcopy, from your script using the WshShell.Run method. I guess you need something like this:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "xcopy c:\Docume~1\alluse~1\applic~1\avg8\update\download\*.* E:\Updates\ /D", , True
How to insert the username (Point 1)
Concatenate the message text with the strUserName variable value:
Message = " Welcome " & strUserName & " to the AVG Update Module" & vbCR
...
MsgBox "No Files have been Copied/Updated.", vbExclamation, strUserName & " Cancelled"
Can the buttons be changed to Copy,Update,Cancel Instead of Yes,No,Cancel?(Point 2)
No, VBScript's built-in MsgBox function does not support custom buttons. There're workarounds though: you could create your custom message box using an HTA (HTML application) or use the InputBox function to prompt the user for the task they wish to perform. You can find examples here.
I'd also like to note that you can improve your script by using the Select Case statement to check the MsgBox return value instead of multiple If...Then...End If statements. Also, it's a bad practice to use "magic numbers" like 6 or 7 - use the appropriate constants instead. For example:
Select Case X
Case vbYes
...
Case vbNo
...
Case Else ' vbCancel
...
End Select
When you say
"copy files only that are new or do
not exist in source path?"
do you mean you only want to copy files from the source directory to the destination directory if they do not exist in the destination? If so this will accomplish that
Const SourceFolder = "C:\Test1\"
Const DestinationFolder = "C:\Test2\"
Set fso = CreateObject("Scripting.FileSystemObject")
'Get a collection of al the files in the source directory
Set fileCol = fso.GetFolder(SourceFolder).Files
'Loop through each file and check to see if it exists in the destination directory
For Each objFile in fileCol
If NOT fso.FileExists(DestinationFolder & objFile.Name) Then
'If the file does not exist in the destination directory copy it there.
objFile.Copy DestinationFolder
Else
If objFile.DateLastModified > fso.GetFile(DestinationFolder & objFile.Name).DateLastModified Then
'If the file is newer than the destination file copy it there
objFile.Copy DestinationFolder, True
End If
End If
Next
Set fileCol = Nothing
Set fso = Nothing
Added the requested date check.

VBScript FTP Login with Username and Password

I am trying to update a VBScript (very little experience with this, I do a lot of VB.NET), that reads an FTP directory and moves certain files to a new local directory on a daily basis. I have old code that works on an FTP site that uses anonymous logins, but I now need it to access an FTP site that requires username and password.
Here is my current code -
Sub MoveNSPurolatorFile()
Dim NSPurolatorFTPSite, NSPurolatorMoveFilePath, NSPurolatorFTPFolder, NSPurolatorFTPFileName
Dim folder, files
Dim fso
set fso = CreateObject("Scripting.FileSystemObject")
NSPurolatorFTPSite="\\xxx.xxx.x.xx\"
NSPurolatorMoveFilePath = "F:\TestDirectory"
NSPurolatorFTPFolder = "TestFolder"
NSPurolatorFTPFileName = "MAN0201.CSV"
If InStr(NSPurolatorFTPFileName, "_processed") = 0 and InStr(NSPurolatorFTPFileName, ".CSV") > 0 Then
If fso.FolderExists(NSPurolatorFTPSite & NSPurolatorFTPFolder) Then
If fso.FileExists(NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName) Then
objfile.writeline "NS Purolator File Found: " & NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName
fso.copyFile NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName, NSPurolatorMoveFilePath & "\"
Else
objfile.writeline "File does not exist: " & NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName
End If
End If
End If
Next
End Sub
It says the folder does not exist, but I know it does and when I run this code against an ftp site that does not require username and password it works fine. I guess my question is - How do I pass in the username and password using VBScript to the ftp site before trying to access folders, etc?
Thanks.
This really is an incredibly bad way to do this. You can't just treat folders on a remote FTP site as local folders.
You really should be using InetCtrls.Inet.1
Here's an example I lifted from somewhere else that does not do what you want, but contains all the parts you need - you need to pick it apart to suit your needs.
'Option Explicit
'const progname="FTP upload script by Richard Finegold"
'const url = "ftp://ftp.myftpsite.com"
'const rdir = "mydir"
'const user = "anonymous"
'const pass = "myname#mymailsite.com"
'This is an example of ftp'ing without calling the external "FTP" command
'It uses InetCtrls.Inet.1 instead
'Included is a "hint" for simple downloading
'Sources:
'http://msdn.microsoft.com/library/partbook/ipwvb5/loggingontoftpserver.htm
'http://msdn.microsoft.com/library/partbook/egvb6/addinginternettransfercontrol.htm
'http://cwashington.netreach.net/ - search on "ftp" - inspiration only!
'Insist on arguments
dim objArgs
Set objArgs = Wscript.Arguments
If 0=objArgs.Count Then
MsgBox "No files selected for operation!", vbOkOnly + vbCritical, progname
WScript.Quit
End If
'Force console mode - csforce.vbs (with some reorganization for efficiency)
dim i
if right(ucase(wscript.FullName),11)="WSCRIPT.EXE" then
dim args, y
For i = 0 to objArgs.Count - 1
args = args + " " + objArgs(i)
Next
Set y = WScript.CreateObject("WScript.Shell")
y.Run "cscript.exe " & wscript.ScriptFullName + " " + args, 1
wscript.quit
end if
'Do actual work
dim fso, ftpo
set fso = WScript.CreateObject("Scripting.FileSystemObject")
set ftpo = WScript.CreateObject("InetCtls.Inet.1") 'Msinet.ocx
ftpo.URL = url
ftpo.UserName = user
ftpo.Password = pass
WScript.Echo "Connecting..."
ftpo.Execute , "CD " & rdir
do
' WScript.Echo "."
WScript.Sleep 100 'This can take a while loop while ftpo.StillExecuting
for i = 0 to objArgs.Count - 1
dim sLFile
sLFile = objArgs(i)
if (fso.FileExists(sLFile)) then
WScript.Echo "Uploading " & sLFile & " as " & FSO.GetFileName(sLFile) & " "
ftpo.Execute , "Put " & sLFile & " " & FSO.GetFileName(sLFile)
'ftpo.Execute , "Get " & sRemoteFile & " C:\" & sLFile
do
'WScript.Echo "."
WScript.Sleep 100 'This can take a while
loop while ftpo.StillExecuting
else
MsgBox Chr(34) & sLFile & Chr(34) & " does not exist!", _
vbOkOnly, progname
end if
next
WScript.Echo "Closing"
ftpo.Execute , "Close"
WScript.Echo "Done!"
Here's a pretty nice way to do it - I'm sure this could be improved upon, but I just got it going.. :-)
Dim fso, folder1, folder2, folder2a
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder2a = fso.GetFolder("C:\temp")
ftpFolderString = "ftp://username:password#ftp.ftpsite.com/folderpath"
targetFoldder = "C:\temp"
fileSearchStr = "searchstring"
Dim SH, txtFolderToOpen, thing
Set SH = CreateObject("Shell.Application")
'SH.Open txtFolderToOpen
Set folder1 = SH.NameSpace(ftpFolderString)
Set folder2 = SH.NameSpace(targetFoldder)
For Each item In folder1.items
If InStr(LCase(item.Name),fileSearchStr) > 0 Then
Debug.WriteLine item.Name
folder2.CopyHere item,4
WScript.Sleep(200)
For Each item2 In folder2a.Files
If item2.Name = item.Name Then
While item2.Size < item.Size
WScript.Sleep(200)
Wend
End If
Next
WScript.Sleep(200)
End If
Next
Set SH = Nothing
Debug.WriteLine "Done"
How is the script being run? Manually, automatically? By a service?
Mapped-letter drives are not always available when running as a service.
Experiment with the script to ensure that it even able to see the F:\ drive, and then see what else is visible.
Is the FTP site accessed by a UNC path (looks like it is)? If it is just a standard FTP address then you can incorporate the username / password in the URL e.g. ftp://user:pass#myftpsite.com. If it is a UNC path that you are trying to access using different credentials then the easiest way would probably be to map a drive, do the work and then unmap the drive. 2 different approaches can be found here

Resources