VB Script Files Collection - vbscript

I'm working on some logic that will remove files from a particular folder if the disk space reaches a defined max capacity, I have the following code:
'Remove files if disk space falls below 100GB
While hDisk.FreeSpace < 100000000000
Set Directory = Fso.GetFolder("C:\backups")
Set Files = Directory.Files
Dim file1
Dim file2
For n = Files.Count - 1 to 0 Step - 1
If IsEmpty(file1) or IsNull(file1) Then
ERROR Here -->Set file1 = Files.Item(n)
ElseIf n > 0 Then
Set file2 = Files.Item(n)
If hDisk.FreeSpace > 100000000000 Then
Exit For
ElseIf file2.DateLastModified < file1.DateLastModified And DateDiff("D", file2.DateLastModified, Now) > 7 Then
file2.Delete
ElseIf file1.DateLastModified < file2.DateLastModified And DateDiff("D", file1.DateLastModified, Now) > 7 Then
file1.Delete
Set file1 = Files.Item(n)
Else
'Nothing
End If
Else
'Nothing
End If
Next
Wend 'End loop when drive is below max capacity
What it's supposed to do is loop through a collection of files in a folder and remove the oldest file(s) until the disk space is above capacity. So there is some file comparison that must be done. I'm encountering a Invalid procedure call or argument error on the line above (see comment). I'd also like to know if this is the best approach, I'm open to better suggestions, preferably ones that will cut down on code.
UPDATE:
Tried adding Set, in front of the assignment statement, but still get the same error.
UPDATE 2 (WORKING SCRIPT!!):
Played with it a bit more and was able to get the script working, here it is in its entirety in case anyone else wants to use it. I added comments to indicate custom values, it can be safely assumed that any other similar value is also customizable, i.e. the disk size is defined in multiple locations.
Dim Fso
Dim hDisk
Dim Directory
Dim Files
Dim myArray()
Set Fso = CreateObject("Scripting.FileSystemObject")
Set hDisk = Fso.GetDrive("c:") 'Custom Value - drive to monitor
If hDisk.FreeSpace < 100000000000 Then
'Delete files until free space is below max capacity (defined here as 100GB)
While hDisk.FreeSpace < 100000000000 'Custom Value - disk size in bytes
Set Directory = Fso.GetFolder("C:\backups") 'Custom Value - Directory to monitor
Set Files = Directory.Files
Redim myArray(Files.Count)
i=0
For Each fl in Files
Set myArray(i)=fl
i=i+1
Next
Dim file1
Dim file2
For n = Files.Count - 1 to 0 Step - 1
'1st PASS: Instantiate first file
If IsEmpty(file1) or IsNull(file1) Then
Set file1 = myArray(n)
'Compare 1st file with next file and current date, remove oldest if it's older than a week
ElseIf n > 0 Then
Set file2 = myArray(n)
If hDisk.FreeSpace > 100000000000 Then
Exit For
ElseIf file2.DateLastModified < file1.DateLastModified And DateDiff("D", file2.DateLastModified, Now) > 7 Then 'Custom Value - File age in number of days
file2.Delete
ElseIf file1.DateLastModified < file2.DateLastModified And DateDiff("D", file1.DateLastModified, Now) > 7 Then
file1.Delete
Set file1 = myArray(n)
Else
'Nothing
End If
'Remove remaining file if it's older than a week
Else
Set file1 = myArray(n)
If DateDiff("D", file1.DateLastModified, Now) > 7 Then
file1.Delete
End If
End If
Next
Wend 'End loop when drive is below max capacity
End If
UPDATE 3:
To clarify what's being done, the pseudocode is as follows:
If disk space is maxed
While disks space is maxed
For each file
If 1st File is empty
Get 1st File
If disk space is below max
Exit
Else Get Next File
If Next File is older than 1st File and older than a week
Delete Next File
Continue
Else if 1st File is older and older than a week
Delete current 1st File
Set 1st File to Next File
Continue
Else if 1st file is the only file and is older than a week
Delete 1st File

Reinventing the wheel. You're trying to create a script to perform a task that already exists in Windows.

Related

vbscript won't read file after 8Mb

I have a file written in vbs that wont read a file after about 8MB. I am currently using "Scripting.FileSystemObject". When I test the code, I notice that it runs fine until line ~79500, thats when the "AtEndOfStream" just results in True. I was looking for documentation, but it seems not to exist.
The code is supposed to show duplicate file information and put it in a separate file, which works well enough till around that line.
This is the section of code giving me the problem (it is the second reading function I have in the code):
Set first = fso.OpenTextFile(filePath + firstFileName)
Set secondFile = fso.OpenTextFile(filePath + secondFileName)
count = 0
countInLine = 0
Do Until secondFile.AtEndOfStream
lineMatches = false
lineOfSecond=secondFile.ReadLine
If count > 79440 Then
MsgBox("first line" & first.AtEndOfStream)
End If
Do Until first.AtEndOfStream
lineOfFirst =first.ReadLine
if lineOfSecond = lineOfFirst Then
lineMatches = True
Exit Do
End If
Loop
If Not lineMatches Then
writeFl.Write(count & "second" & lineOfSecond & vbCrLf)
End If
count = count + 1
Loop

Searching the rest of the folder using the last few letters of a filename that is in a for loop VBS

Hello all~ I am new to VBS and I'm trying to find the code to search for the rest of the files in the folder that countains a specific number in the file that is in the for loop. Let me try to visualize it for you.
Current code that prints out the documents that I have to manually print out everyday:
'' To set the path to the current folder
set shApp = CreateObject("shell.application")
currentPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".")
set shFolder = shApp.NameSpace( currentPath )
'' To set the items in the current folder as "files"
set files = shFolder.Items()
'Open excel sheet to print the paper for shipping side to sign'
set objsheet = getobject(,"Excel.Application").activeworkbook.activesheet
''Start of code''
count = 1
for each files in files
' If name contains "DN" '
if inStr(files, "DN") then
' Print 1 time if SO'
if inStr(files, "SO") then
'print 1 time'
files.InvokeVerbEx("Print")
' Pop up to show what has been printed '
CreateObject("WScript.Shell").Popup "Printed "+ files , 3, "\(o.o)/ The Magic Script \(o.o)/"
objsheet.cells(count,1) = files
count = count + 1
'Pause in the script'
WScript.Sleep 5000
end if
if inStr(files, "SM") then
'print 4 time using loop function and "i" as a counter'
'Do
' i = i + 1
' files.InvokeVerbEx("Print")
'Loop until i>= 4
'i = 0
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
'Pop up to show what has been printed'
CreateObject("WScript.Shell").Popup "Printed "+ files , 3, "\(o.o)/ The Magic Script \(o.o)/"
objsheet.cells(count,1) = files
count = count + 1
' Pause in the script '
WScript.Sleep 15000
end if
end if
' if name contains "INV" '
if inStr(files, "INV") then
' Print 6 times using loop function and "j" as a counter '
'Do
' j = j + 1
' files.InvokeVerbEx("Print")
'Loop until j >= 6
'j = 0
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
' Pop up to show what has been printed '
CreateObject("WScript.Shell").Popup "Printed "+ files , 3, "\(o.o)/ The Magic Script \(o.o)/"
WScript.Sleep 18000 ' Prevent Lag '
end if
' if name contains "PO" '
if inStr(files, "PO") then
'print out 2 times'
'Do
' k = k + 1
' files.InvokeVerbEx("Print")
'Loop until k >= 2
'k = 0
files.InvokeVerbEx("Print")
files.InvokeVerbEx("Print")
' Pop up to show what has been printed '
CreateObject("WScript.Shell").Popup "Printed "+ files , 3, "\(o.o)/ The Magic Script \(o.o)/"
WScript.Sleep 6000 'Prevent Lag'
end if
' if name contains "OF" '
if inStr(files, "OF") then
' print out 1 time '
files.InvokeVerbEx("Print")
objsheet.cells(count, 1) = files
CreateObject("Wscript.Shell").Popup "Printed "+ files , 3, "\(o.o)/ The Magic Script \(o.o)/"
count = count + 1
Wscript.Sleep 5000
end if
next
objsheet.printout
CreateObject("WScript.Shell").Popup "Successfully Printed " , 10, "\(o.o)/ The Magic Script \(o.o)/"
Now im trying to improve the code by matching the file containing "DN" to its corresponding file that contains "PO" or "INV" so when it prints out, it would be in order ( thus easier to staple it together ) and would save up a lot of time for people at my workplace.
An example of the saved files in a folder would be:
DN_789456 SO 13371337
DN_963258 SO 12341234
INV_785412 SO 13371337
PO_632541 SO 12341234
as you can tell, the only way to match them would be using the last 8 numbers in the file name. However, I could not find a guide/tutorial that I could follow to extract these 8 numbers and continue searching for the corresponding file in the folder.
It would be great if anyone could guide me along. Thank you in advance
To find the last occurrence of a substring you can use
InStrRev(string1,string2[,start[,compare]])
This will do what InStr() does but starting from the end of the string.
You can then find all files containing 'DN' and upon every match search the items again to obtain the matching 'INV' and/or 'PO' files.

Downloading content from txt file to a variable

I made a counter that works when you press the button as the action in VBScript.
my code:
Licznik_ID = Licznik_ID + 1
Dim Stuff, myFSO, WriteStuff, dateStamp
Stuff = "Whatever you want written"
Set myFSO = CreateObject("Scripting.FileSystemObject")
Set WriteStuff = myFSO.OpenTextFile("c:\tmp\yourtextfile.txt", 2, True)
WriteStuff.WriteLine(Licznik_ID)
WriteStuff.Close
SET WriteStuff = NOTHING
SET myFSO = NOTHING
the counter variable named "Licznik_ID"
indicated by the arrow.
It is written to the file "c:\tmp\yourtextfile.txt"
And it works well.
For each time the number increases by one and is replaced and stored in the txt file.
The file contains the number 1 and the increase in the txt file appears the number 2 and so on ...
How now download the data stored with the file "c: \tmp\yourtextfile.txt" back to the variable to use it in such a way that when you start NiceForm or button has been loaded with the contents of txt file into a variable?
Set myFSO = CreateObject("Scripting.FileSystemObject")
Licznik_ID = myFSO.OpenTextFile("C:\tmp\yourtextfile.txt").ReadAll
Licznik_ID = Licznik_ID + 1
myFSO.OpenTextFile("C:\tmp\yourtextfile.txt",2,True).Write(Licznik_ID)
FSO is kinda weird the way it does its file modes sometimes.
edit: If you want to allow this to create the file without errors if it doesn't exist, replace line 2 with this:
If myFSO.FileExists("C:\tmp\yourtextfile.txt") Then
Licznik_ID = myFSO.OpenTextFile("C:\tmp\yourtextfile.txt").ReadAll
End If
If the file doesn't exist, Licznik_ID will be Empty. Empty + 1 = 1 in vbscript.

vbscript compare string contents (folder directory) of text files and creates the missing folders

I am currently working on a school assignment to compare strings within text files. These text files contains paths of folder directories. If a directory is not found on the other textfile, it will create that directory, else nothing will happen.
diretory1.txt contains directory strings that are:
C:\mcgfiles\avp
C:\mcgfiles\temp
C:\mcgfiles\logs\activity
C:\mcgfiles\logs\program
C:\mcgfiles\logs\status
C:\mcgfiles\generatedhtml
and diretory2.txt, contains the following
C:\mcgfiles
C:\mcgfiles\avp
C:\mcgfiles\temp
C:\mcgfiles\logs
C:\mcgfiles\logs\activity
C:\mcgfiles\logs\program
C:\mcgfiles\logs\status
C:\mcgfiles\generatedhtml
In the case of my textfiles, directories "C:\mcgfiles" and "C:\mcgfiles\logs" will be created on my drive C:\ since they are missing.
Here is the code I used:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Set objFile1 = objFSO.OpenTextFile("C:\scripts\directory1.txt", ForReading)
strAddresses = objFile1.ReadAll
objFile1.Close
Set objFile2 = objFSO.OpenTextFile("C:\scripts\directory2.txt", ForReading)
Do Until objFile2.AtEndOfStream
strCurrent = objFile2.ReadLine
If InStr(strAddresses, strCurrent) = 0 Then
objFSO.CreateFolder(strCurrent)
End If
Loop
It works fine when I use "C:\mcgfiles\temp" as the missing directory. But it cant differentiate what's missing when I use "C:\mcgfiles" or "C:\mcgfiles\logs". Maybe its because I used InStr function and it considers "C:\mcgfiles" and "C:\mcgfiles\logs" not missing since it can also be found in "C:\mcgfiles\logs\activity" etc.
I tried to use strComp but still nothing happens. Please help. Thank you
InStr() "returns the position of the first occurrence of one string within another". So "C:\mcgfiles" is found in "C:\mcgfiles\logs". If all of the pathes in the string you search in are terminated by an EOL marker (eg.g vbCrLf) you can use target & EOL as the needle:
>> haystack = "c:\a\b;c:\a;"
>> eol = ";"
>> needle = "c:\a" & eol
>> WScript.Echo InStr(haystack, needle)
>>
8
Other techniques - e.g. using a dictionary of the pathes - are possible, but would need more work.

VBScript keep last 14 files, delete anything older then 14 days

i have a VB Script file that goes thru many files and folders within a specific directopry path, and it deletes any files thats older then 30 days
but i want to add an exception, to keep the last 14 files, so lets say if i dont have any new files yesterday, then today it will delete the file older then 14 days, and i will be left with 13 files
i want to keep the last 14 files, no matter of its age, but if there is more then 14 files, then delete the oldest
can anyone assist me where i add it in my script, and how ? here is the script im using
On Error Resume Next
Set oFileSys = WScript.CreateObject("Scripting.FileSystemObject")
sRoot = "C:\Program Files (x86)\Syslogd\Logs" 'Path root to look for files
today = Date
nMaxFileAge = 14 'Files older than this (in days) will be deleted
DeleteFiles(sRoot)
Function DeleteFiles(ByVal sFolder)
Set oFolder = oFileSys.GetFolder(sFolder)
Set aFiles = oFolder.Files
Set aSubFolders = oFolder.SubFolders
For Each file in aFiles
dFileCreated = FormatDateTime(file.DateCreated, "2")
If DateDiff("d", dFileCreated, today) > nMaxFileAge Then
file.Delete(True)
End If
Next
For Each folder in aSubFolders
DeleteFiles(folder.Path)
Next
End Function
I think you could do this a few ways. One would be to use the DIR command to sort the files and then you can just iterate that list and delete the ones starting at the 15th position. For example, this command would return just the filenames, sorted by date in descending order:
dir /o-d /a-d /b
and you could run that using Shell.Run or Shell.Exec to capture its output. The "problem" with Shell.Run is that you'd need to send the output to a file, then open the file, and read it. Not a big deal but requires file I/O. If you use Shell.Exec, you can capture the standard output directly but you have to deal with the command prompt window flashing open whenever a DIR command runs.
If you're fine with either of those "problems", then that method should work fine.
But you could do everything using the FileSystemObject. The key is to just get the date of the 14th most-recent file. Here's how you could do that.
' Only run if we actually have more than 14 files...
If oFolder.Files.Count > 14 Then
' Create an array to the hold the dates of each file in this folder...
ReDim a(oFolder.Files.Count - 1)
' Store the dates...
i = 0
For Each oFile In oFolder.Files
a(i) = oFile.DateLastModified ' Or use DateCreated, if you wish
i = i + 1
Next
' Sort the array...
Sort a
' Get the 14th most-recent date...
dtmCutOff = a(13)
' Iterate the files once more and delete any files older than our cut-off...
For Each oFile In oFolder.Files
If oFile.DateLastModified < dtmCutOff Then oFile.Delete
Next
End If
' Simple bubble sort...
Sub Sort(a)
For i = UBound(a) - 1 To 0 Step -1
For j = 0 To i
If a(j) > a(j + 1) Then
temp = a(j + 1)
a(j + 1) = a(j)
a(j) = temp
End If
Next
Next
End Sub
The only issue I think you'll have is if two files with the exact same date and time occupy the 14th position. Using this method, the script would keep both, and you'd end up with 15 files (or more, if there were more matches). But that's going to be an issue no matter what method you use. If your 20 most-recent files have the same date and time, how you do choose 14 from amongst those 20 to keep? =)

Resources