Prevent VBScript Folder Loop From Looping Through Newly Created Folders - for-loop

I have a simple loop that goes through all the folders in a directory and if a certain condition is true, it creates a copy of the folder with a new foldername.
My problem is that after a new folder is created it gets processed later in the loop and I don't want that.
The loop is checking folder names and if it is 7, 6 or 5 characters long, do a certain action. A 7 length folder gets renamed to a 6 digit folder, but later in the loop that new 6 digit folder is getting included and further processed. I do not want this.
Thanks

I ended up using a Dictionary object to save the original folder list and then check if the looped folder existed on that list before proceeding.
Set FSO = CreateObject("Scripting.FileSystemObject")
Set startingSubFoldColl = CreateObject("Scripting.Dicitonary")
Set Folder = FSO.GetFolder(*targetFolderPath*)
For Each Subfolder in Folder.Subfolders
startingSubFoldColl.add Cstr(Subfolder),Cstr(Subfolder)
Next
For Each SubFolder in Folder.Subfolders
If startingSubFoldColl.Exists(Cstr(Subfolder)) Then
'Do Stuff
End If
Next

Related

Move first 10 files from a folder to another

I would like to know how I can move the first 10 files in folder to another folder? I have a folder which contains more than 50K files that need to be moved to another location for processing. I want to move 10 files at a time.
Please help to find a way using VBScript.
If you just need to move any 10 files from a folder, just maintain a file count as you iterate the Files collection of a Folder object.
For example:
intCount = 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each objFile In objFSO.GetFolder("c:\path\to\your\files").Files
objFile.Move "c:\new\path\"
intCount = intCount + 1
If intCount = 10 Then Exit For
Next
As I mentioned in the comments, there's no guarantee here which 10 files will get moved. Also of note, make sure to use a blackslash \ at the end of the path you're moving the file to (c:\new\path\) so that it's treated as a folder and not a new file name.

Compare two files in two different folders and replace it by the newer

With this VBScript code I was able to copy files. If the file exists it does nothing, if not it will copy the files needed.
Dim Photo
SourceFolder = "C:\Photo1"
DistinationFolder = "C:\Photo2"
Set ObjPhoto = CreateObject("Scripting.FileSystemObject")
For Each Photo In ObjPhoto.GetFolder( SourceFolder).Files
If Not ObjPhoto.FileExists(ObjPhoto.BuildPath(DistinationFolder, Replace(Photo.Name, ".jpg", ".bmp"))) Then
photo.Copy ObjPhoto.BuildPath(DistinationFolder, Photo.Name), True
End If
Next
I want to compare the files if the source files also exists in the destination folder and replace it by the newer.
If you want to overwrite based on the last modified date, then the File object has the property you want: DateLastModified. (You can check all properties of the File object here.)
You already have access to the source file objects (your code's Photo variable) so you just need to get the target's file object.
Something like this should work:
Dim Photo
Dim targetFile, bmpTargetFilename, jpgTargetFilename
SourceFolder = "C:\Photo1"
DistinationFolder = "C:\Photo2"
Set ObjPhoto = CreateObject("Scripting.FileSystemObject")
For Each Photo In ObjPhoto.GetFolder(SourceFolder).Files
bmpTargetFilename = ObjPhoto.BuildPath(DistinationFolder, Replace(Photo.Name, ".jpg", ".bmp"))
jpgTargetFilename = ObjPhoto.BuildPath(DistinationFolder, Photo.Name)
If ObjPhoto.FileExists(bmpTargetFilename) Then
' Get the target file object
Set targetFile = ObjPhoto.GetFile(jpgTargetFilename)
' Now compare the last modified dates of both files
If Photo.DateLastModified > targetFile.DateLastModified Then
Photo.Copy jpgTargetFilename, True
End If
Else
Photo.Copy jpgTargetFilename, True
End If
Next
A couple of notes:
It seems you are checking for the existence of a .BMP file yet copying a .JPG file, so I made it explicit by using two variables.
I am also assuming you want to compare the JPG files, since those are the ones being copied.

QTP: How to copy file from onle location and paste it into another and verify file count at the end

I need to write a vbscript for Copying files from local directory(Windows) to another(shared drive) and verify the counts at the end to make sure everything copied successfully. Any ideas on what the script will look like?
Here is what I recorded using GUI UFT:
SystemUtil.Run "C:\Users\Downloads"
Window("Documents").WinObject("Items View").WinList("Items View").Activate "Unified Functional Testing"
Window("Documents").WinObject("Items View").WinList("Items View").Select "APITest1"
Window("Documents").WinObject("ShellView").WinMenu("ContextMenu").Select "Copy"
Window("Documents").Restore Window("Documents").WinTreeView("WinTreeView").Select "Desktop;This PC;Downloads"
Window("Documents").WinObject("ShellView").WinMenu("ContextMenu").Select "Paste"
To copy files from one foler to another, Why do you record using QTP/UFT? The script recorded by QTP will not be reliable. (might not work everytime.) QTP supports VBScript. It is easy to copy files from one folder to another folder using VBScript.
To copy all files from temp1 to temp2 folder - just these 2 lines will do
Set oFSO = CreateObject("Scripting.FileSystemObject")
oFSO.CopyFile "C:\vIns\temp1\*.*" , "C:\vIns\temp2\" , TRUE
Once files are moved, You want to compare the files count. (I assume temp2 folder was empty before copying the files)
iTemp1Count = oFSO.getFolder("C:\vIns\temp1\").Files.Count
iTemp2Count = oFSO.getFolder("C:\vIns\temp2\").Files.Count
If iTemp1Count = iTemp2Count Then
Msgbox "all files are copied"
Else
Msgbox "Something is wrong!!!"
End If

VBS: For-each loop (sometimes) iterates through file collection indefinitely

The goal of the following VBscript is to prepend a user-defined string to all files with a particular extension within a specified directory:
directory = "C:\Users\xxxxxxxx\Desktop\Test\" 'include final backslash
extension = ".doc" 'include period, ex: ".tab"
''''''''''''''''''''''''''''''''''''''''''
addStr = InputBox("Enter the text you would like to prepend:", , "xxxxxxxx_xxxxxxxxxx_x_xx_xxx_")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(directory)
Set colFiles = objFolder.Files
For Each file In colFiles
absPath = objFSO.GetAbsolutePathName(file)
currentExtension = objFSO.GetExtensionName(absPath)
If StrComp(currentExtension, Mid(extension, 2)) = 0 Then
file.Name = addStr & objFSO.GetFileName(file)
End If
Next
The script generally works well, but occasionally demonstrates this problematic behavior:
When running the script on a directory with lots of files and/or with files with long names, the script appears to iterate back over the collection of files (i.e. prepends to files that have already been prepended) and does so until the filenames become too long to be recognized by the FSO, crashing the script.
The threshold of the number of files/length of filenames at which this occurs appears to be very distinct and reproducible. For example, if I create a target directory (e.g. "...\Desktop\Test") with a file named '1.doc' that is copied/pasted several times, the script will properly rename up to 31 files, but it demonstrates the problematic behavior with 32+ files. Similarly, if I run the script twice over 31 files (generated in the same manner), the script demonstrates the problematic behavior on the second run.
Any thoughts as to the underlying issue are very much appreciated--thanks in advance!
You may have issues here because you're modifying files while iterating them. Try creating an array of file names first and then iterate over the array, changing the names.
ReDim a(colFiles.Count - 1)
i = 0
For Each File In colFiles
a(i) = File.Path
i = i + 1
Next
For i = 0 To UBound(a)
If StrComp(objFSO.GetExtensionName(a(i)), Mid(extension, 2)) = 0 Then
With objFSO.GetFile(a(i))
.Name = addStr & .Name
End With
End If
Next
The reason the above behaviour occurs is, because when you initially call Set colFiles = objFolder.Files, the first 32 files are retrieved, and placed into a cache. Once those 32 files are processed, then the system retrieves the first 32 filenames which have not been processed yet.
Since you have renamed the files after the initial call, the system sees those as new filenames that have not been processed yet. Since their names are still first alphabetically, they are placed into the 32-file cache, and processed again.
The solution by #Bond is the standard workaround for this issue. Due to limitations of vbs, this is the only practical resolution of this issue.

Looking for a way to execute a batch file once a folder hits 10 files

I am looking for a way to monitor a folder so that it executes a batch file once it hits 10 files. It would be cool if it used vbscript or any other type of solution like that.
any help would be appreciated
thanks
Refer to this question: batch file to monitor additions to download folder
Note Nick's final solution where he counts files.
I would recommend that any test like this is executed via Task Scheduler.
Simple Example
rem Counting files...
set /a count = 0
for /f "tokens=*" %%P IN ('dir "C:\examplefolder" /A /b') do (set /a count += 1)
rem 10 or more files?
if %count% GEQ 10 call AnotherBatchFileHere.bat
The equivalent VBScript for this would involve obtaining a folder object and checking the count of its files collection. The Last Modified Date for the folder could also be examined to determine if something has changed or when.
Looping through the folder's .Files collection will let you examine the dates, size etc. of each file individually. Since this is a collection of file objects, any file object method can be executed directly or the file object can be passed off to a subroutine for processing. A similar .Subfolders collection enumerates folders created within this folder as folder objects in case you wish to monitor that situation as well.
File methods include .Copy .Move .Delete .OpenAsTextStream and the file properties .DateLastModified .DateLastAccessed .Attributes and .Name are updateable.
Note that the .Name property includes the file extension and if you change the name you may need to call FSO.GetExtensionName() to get that extension and append it to the new name before assigning it back to the property.
The Subfolders collection also has a .Add() method which can create a new child folder
.SubFolders.Add("NewFolderName")
and instead of the file object's .OpenAsTextStream method, folder objects have a .CreateTextFile() method which returns an open text stream object to a new text file created in that folder. A clever use could be to create a text stream used by your subroutines to log your file processing activities to a log file. Or read a text file directly and process its contents.
A basic example script to watch for 10 files in folder
Set FSO = WScript.CreateObject("Scripting.FileSystemObject")
WatchFolder FSO.GetFolder("c:\watched")
WScript.Quit
Sub WatchFolder(oFldr)
While True
If oFldr.Files.Count >= 10 Then
WScript.Echo oFldr.Files.Count , "files in" , ofldr.Path , _
"Last Modified" , oFldr.DateLastModified
For Each oFile In oFldr.Files
WScript.Echo "File" , oFile.Name , _
"Last Modified" , oFile.DateLastModified , _
"Created" , oFile.DateCreated , _
"Size" , oFile.Size
' call subroutine to optionally process file
KillJunkFile oFile
Next
Exit Function
End If
WScript.Sleep 2000 ' wait 2 seconds before checking again.
Wend
End Sub
Sub KillJunkFile(oTestFile)
' delete any file named junk.txt
If LCase(oTestFile.Name) = "junk.txt" Then
oTestFile.Delete True ' true forces the delete
End If
End Sub
Note that the WatchFolder() function will loop until at least 10 files are in the watched folder. You have to kill the task to stop it otherwise or add some termination logic that checks something on your system that can tell it to quit looping. Something like a specially named file, a registry entry, an environment variable, etc. You could also comment out the While Wend loop keywords and have Windows Task Scheduler run the script every hour if it takes that long for enough files to appear.

Resources