Isolating numbers in folder names - vbscript

I have created a script, out of snip-its found all over this site and elsewhere, to assign job numbers. It (is supposed to) search the "Jobs" directory for the highest job number, increment by 1, prompt for a customer name and job name, copy a template dir and rename it with the information provided. I know my code is messy, but it worked wonderfully...until someone put numbers in the job name (09889KM-TCM-Vadata PDX50 - POD 3). It now does it's intended job, but then runs again with the next number it finds in the job name i.e. increments 09889 to 09890 then picks up on PDX50 and tries to make a new folder 00051. I have been looking all day to find how to isolate the numbers on my own and, but as this script is in production I have no choice to beg for help. Please assist on how to isolate the first 5 digits, or make it stop after one run.
Option Explicit
Dim objFSO
Dim objNewFolder
Dim fs
Dim MainFolder
DIM JobNumber, nJobNumber, EmplInit, CustName, JobName
Dim fldr, LastName, LastJob, r, x, y
Dim OldFolder, sFile
'Find Highest Job Number Folder
Set fs = CreateObject("Scripting.FileSystemObject")
Set MainFolder = fs.GetFolder("C:\Test\")
For Each fldr In MainFolder.SubFolders
If fldr.Name > LastName Then
LastJob = fldr.Name
LastName = fldr.Name
End If
Next
'Extract JobNumber from name and increment by 1, and format to five numbers
Set r=new regexp
r.pattern="[0-9]+"
r.global=true
x=LastJob
Set y=r.execute(x)
For each JobNumber in y
JobNumber = Right("00000" & JobNumber, 5)
nJobNumber = JobNumber + 1
nJobNumber = Right("00000" & nJobNumber, 5)
' Start recieving input
' Get initials
EmplInit = InputBox ("The last Job Number is: " & VbCrLf & Jobnumber & VbCrLf & "You have been assigned Job Number: " & VbCrLf & nJobNumber & VbCrLf & "Please Typer your initials:","Initials")
If IsEmpty(EmplInit) Then
MsgBox "Canceled"
ElseIf Len(EmplInit) = 0 Then
MsgBox "You Clicked OK but left the box blank"
Else
'Get Customer Name
CustName = InputBox ("Please enter your customer's name:","Customer Name")
If IsEmpty(EmplInit) Then
MsgBox "Canceled"
ElseIf Len(EmplInit) = 0 Then
MsgBox "You Clicked OK but left the box blank"
Else
'Get Job Name
JobName = InputBox ("Please enter your job's name:","Job Name")
If IsEmpty(EmplInit) Then
MsgBox "Canceled"
ElseIf Len(EmplInit) = 0 Then
MsgBox "You Clicked OK but left the box blank"
Else
' Create New Job Folder Name
objNewFolder = ("C:\Test\" & nJobNumber & EmplInit & "-" & CustName & "-" & JobName)
'Create the File System Object
Set objFSO = CreateObject ("Scripting.FileSystemObject")
'Get the folder we want to copy from
OldFolder = "C:\Test\00AA-Working Edit - Folder Template\"
'Check if new folder exists, if not then create it.
If objFSO.FolderExists (objNewFolder) then
WScript.Echo "The Destination Folder " & objNewFolder & " already exists"
Else
WScript.Echo "The Destination Folder " & objNewFolder & " will be created."
Set objNewFolder = objFSO.CreateFolder (objNewFolder)
End If
'Copy source folders to new folder
objFSO.CopyFolder "C:\Test\00AA-Working Edit - Folder Template\*" , (objNewFolder & "\")
'Copy any files in the source root to new location
For Each sFile In objFSO.GetFolder(OldFolder).Files
If Not objFSO.FileExists(objNewFolder & "\" & objFSO.GetFileName(sFile)) Then
objFSO.GetFile(sFile).Copy objNewFolder & "\" & objFSO.GetFileName(sFile),True
End If
Next
End If
End If
End If
Next

Change this:
'Extract JobNumber from name and increment by 1, and format to five numbers
Set r=new regexp
r.pattern="[0-9]+"
r.global=true
x=LastJob
To this:
'Extract JobNumber from name and increment by 1, and format to five numbers
Set r=new regexp
r.pattern="[0-9]+"
r.global=true
x=Left(LastJob,5)
You're just changing one line (the last).

I don't think you need the regular expression. In fact, it sounds like that's part of your problem because in addition to finding the first 5 digits, it's finding any digits within the folder name and operating on those as well.
After you determine LastJob, just do this:
x = Left(LastJob, 5)
If IsNumeric(x) Then
nJobNumber = Right("00000" & x + 1, 5)
' Start your InputBox() prompts...
End If

r.pattern="^[0-9]+"
To avoid more changes in code, just indicate in the regexp that the pattern should be at the start of line.

Related

IF loop to check if file exists in VBS

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

Vbs - File Cont \ File Delete

I am creating a guy script read files in a folder, (Scripting.FileSystemObject), but I would like to relate a indice inpubox type int to determine which file in the folder I'll write on the screen.
Ex: indice = inputbox "" ← 4 grab the indice file in the folder 4 and esquever your name on the screen.
  I wonder if this is possible because already tried in many ways and even by matrix, but without result.
This and my code. I do not know but where to go!
Dim sFO, NovaPasta, Folder,File, Indice
Dim inpast(4)
'Setup
Set sFO = CreateObject("Scripting.FileSystemObject")
Set Folder = sFo.GetFolder("C:\Users\502526523\Documents\Control")
NovaPasta = "Control"
'Development
If Not sFO.FolderExists (NovaPasta) = True Then
sFO.CreateFolder (NovaPasta)
Wscript.Sleep 900
WScript.Echo "Pasta Criada"
Else
WScript.Echo "Pasta Existente "
End If
' Line Verificas a quantidade de inpastas dentro da pasta, se > 5
' deleta os exedentes com data mais antiga
For Each file In folder.Files
If Folder.Files.Count > 5 And (DateDiff("d", file.DateLastModified, Now) > 7) Then
WScript.Echo (file.Name & vbLf)
WScript.Echo ("Total files :" & Folder.Files.Count)
File.Delete
End If
Next
For Each file In folder.Files
inpast(0) = (file.Name)
inpast(1) = (file.Name)
inpast(2) = (file.Name)
inpast(3) = (file.Name)
inpast(4) = (file.Name)
Indice = Inputbox ("Digite o valor do Indice de 0...30")
Select Case Indice
Case 0
WScript.Echo inpast(0)
Case 1
WScript.Echo inpast(1)
Case 2
WScript.Echo inpast(2)
Case 3
WScript.Echo inpast(3)
Case 4
WScript.Echo inpast(4)
End Select
Next
Still not sure if I understand your question correctly. You mean you have a list of filenames and you want to display the filename corresponding to the number the user entered via an InputBox? If that's what you want you should change your second For Each loop like this:
i = 0
For Each file In folder.Files
inpast(i) = file.Name
i = i + 1
Next
Indice = InputBox("Digite o valor do Indice de 0...30")
WScript.Echo inpast(CInt(Indice))
Note, however, that the condition in your first For Each loop does not guarantee you'll only ever have 5 files left after the loop. If for some reason the folder contains more than 5 files that were modified within the past 7 days the second loop would fail with a "subscript out of range" error.
There are several ways you could handle this:
Dynamically resize the inpast array so it can hold more than 5 items.
Sort the files in the folder by last modification date (e.g. like this) and delete everything except the 5 most recent files.
Cut off the second For Each loop after the 5th iteration (Exit For).
Note also, that you should sanitize your input. (What happens when users enter text, an invalid number, or press "Cancel"?)
Set fso = CreateObject("Scripting.FileSystemObject")
Dirname = InputBox("Enter Dir name")
'Searchterm = Inputbox("Enter search term")
ProcessFolder DirName
Sub ProcessFolder(FolderPath)
' On Error Resume Next
Set fldr = fso.GetFolder(FolderPath)
msgbox fls.count
Msgbox fls.item("computerlist.txt")
End Sub
To do the 7th
Set Fls = fldr.files
For Each thing in Fls
Count = Count + 1
If count = 7 then msgbox Thing.Name & " " & Thing.DateLastModified
Next

vbscript need to detect drive letter and ask for user input

I already have the script that ask user input to install the file "install1.exe" to "install6.exe" with default drive letter path D:\, I have another drive can get the drive letter like "C:", not sure how to integrate
First I need to have drive letter check to confirm the computer have drive D physical local disk (not cdrom), if yes prompt user confirm to proceed
or user can click no to enter a drive letter, the drive letter also need to update on current install script {D}:\temp\install1.exe
drive letter script
Dim query
Dim objWMI
Dim diskDrives
Dim diskDrive
Dim partitions
Dim partition ' will contain the drive & partition numbers
Dim logicalDisks
Dim logicalDisk ' will contain the drive letter
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set diskDrives = objWMI.ExecQuery("SELECT * FROM Win32_DiskDrive") ' First get out the physical drives
For Each diskDrive In diskDrives
query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + diskDrive.DeviceID + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition" ' link the
physical drives to the partitions
Set partitions = objWMI.ExecQuery(query)
For Each partition In partitions
query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition.DeviceID + "'} WHERE AssocClass = Win32_LogicalDiskToPartition" ' link
the partitions to the logical disks
Set logicalDisks = objWMI.ExecQuery (query)
For Each logicalDisk In logicalDisks
' Wscript.Echo logicalDisk.DeviceID & " - " & partition.Caption
Wscript.Echo logicalDisk.DeviceID
'else
Next
Next
Next
Install script
Dim objShell
Dim Message, result
Dim Title, Text1, Text2
' Define dialog box variables.
Message = "Please enter a path"
Title = "Install Started"
Text1 = "Install Cancelled"
Text2 = "You entered value is incorrect, please select from 1,2,3,4,5 or 6" & vbCrLf
result = InputBox("Please select the by number"& Chr(13) & "A" & Chr(13) & "B" & Chr(13) & "C" & Chr(13) & "D" & Chr(13) & "E" & Chr(13) & "F", Title, "Please enter the number", 100, 100)
Set objShell = WScript.CreateObject( "WScript.Shell" )
' Evaluate the user input.
If result = "" Then ' Canceled by the user
WScript.Echo Text1
ElseIf result = "1" Then
objShell.Run("7z.exe x temp.7z -oD:\ -bd -y")
wscript.sleep (3000)
objShell.Run("D:\temp\install1.exe")
wscript.sleep (150000)
wScript.Echo "install Completed"
ElseIf result = "2" Then
......
......
......
Else
WScript.Echo Text2 & result
End If
wscript.quit
thank you

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.

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.

Resources