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

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.

Related

Get number first and second and third from text line

I have the following format in my txt file:
1 1,30705856804525E-7 2,64163961816166E-8
1,12201845645905 1,24157281788939E-7 2,45690063849224E-8
1,25892543792725 1,18248813407718E-7 2,29960868125545E-8
1,41253757476807 1,13006606738963E-7 2,16654658657944E-8
1,58489322662354 1,0842624220686E-7 2,05472137082552E-8
1,77827942371368 1,04479198625995E-7 1,96135836461053E-8
1,99526226520538 1,01119816520168E-7 1,8839035220708E-8
2,23872113227844 9,82917924829962E-8 1,82003176973922E-8
2,51188635826111 9,59338279926669E-8 1,76765304615856E-8
2,81838297843933 9,39840489877497E-8 1,72491425587395E-8
3,16227769851685 9,23831819932275E-8 1,69019571671924E-8
3,54813385009766 9,10766573269939E-8 1,66210121221866E-8
3,98107171058655 9,00157104410937E-8 1,63944182673958E-8
4,46683597564697 8,91577514039454E-8 1,62121711611007E-8
5,01187229156494 8,8466336478632E-8 1,60659361370108E-8
5,6234130859375 8,7910699164695E-8 1,59488209305891E-8
6,30957365036011 8,74651959748007E-8 1,58551749507296E-8
7,07945775985718 8,71086527354237E-8 1,57803938805046E-8
7,94328212738037 8,68237393092386E-8 1,57207402651238E-8
8,91250896453857 8,65963372120859E-8 1,56731942979604E-8
10 8,64150138113473E-8 1,56353241465013E-8
11,2201843261719 8,62705391568852E-8 1,5605175818223E-8
I need to get only value for integers on left and right value so in this example I need to get:
1
2,64163961816166E-8
10
1,56353241465013E-8
This is what I've tried:
' Check Noise Spectral Density.txt exists
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FileExists(fso.GetParentFolderName(WScript.ScriptFullName) + "\Projects\Noise Spectral Density.txt")) Then
' Open the file for input.
Set NoiseSpectralDensity = fso.OpenTextFile(fso.GetParentFolderName(WScript.ScriptFullName) + "\Projects\Noise Spectral Density.txt", 1)
' Noise Variables
Dim Noise
' Read from the file and display the results.
Do While NoiseSpectralDensity.AtEndOfStream <> True
' Read Line By Line
TextLine = NoiseSpectralDensity.ReadLine
' Check If Number
'If (IsNumeric(Left(TextLine, 5))) Then
' Get Noise
' Noise # 1kHz
Noise = Right(TextLine, InStr(Mid(TextLine, 2), InStr(TextLine, " ")-1))
x = MsgBox("SNR: " & Split(Left(TextLine, 5), " ")(0) & " NOISE: " & Noise & "",0, "Noise Spectral Density")
'End If
Loop
' Close the file for input.
NoiseSpectralDensity.Close
Else
x = MsgBox("Noise Spectral Density.txt NOT Found!" & vbCrLf & "Wave->Save As Text...", 0, "Noise Spectral Density")
End If
But I could not get left and right numbers in VBScript using Split(TextLine, " ")(0).
Your data seems to be tab-separated, so you could do something like this:
arr = Split(TextLine, vbTab)
If Not (InStr(arr(0), ",") > 0) Then
'first number doesn't have decimals
snr = arr(0)
noise = arr(2)
End If
Though the solution provided by #AnsgarWiechers should work but in case, if it doesn't, you can make use of regular expressions(Replace the whole Do-while loop with the following):
Set objReg = New RegExp
objReg.Pattern = "^(\d+)(?=\s).*\s+([\d,Ee-]+)$" 'See the explanation below
Do While NoiseSpectralDensity.AtEndOfStream <> True
'Read Line By Line
TextLine = NoiseSpectralDensity.ReadLine
' Check If Number
Set objMatches = objReg.Execute(TextLine)
For Each objMatch In objMatches
SNR = objMatch.submatches.item(0)
Noise = objMatch.submatches.item(1)
MsgBox "SNR: "&SNR&"; Noise: "&Noise
Next
Loop
Click for Regex Demo
Regex Explanation:
^ - asserts the start of the string
(\d+) - matches 1+ occurrences of a digit and captures it in Group 1
(?=\s) - positive lookahead to find the position immediately preceded by a white-space. So the digits in the step 2 will be matched until a whitespace(spaces,tabs etc.) is encountered
.* - matches 0+ occurrences of any character except a newline
\s+ - matches 1+ occurrences of a whitespace
([\d,Ee-]+) - matches 1+ occurrences of a digit or , or - or the letter E or e and capture it in group 2
$ - asserts the end of the string

Copying parts of the bar code and write to the file txt

I have a VBScript:
Dim Stuff, myFSO, WriteStuff, dateStamp
Stuff = "Whatever you want written"
Set myFSO = CreateObject("Scripting.FileSystemObject")
Set WriteStuff = myFSO.OpenTextFile("C:\Label_1\yourtextfile.txt", 8, True)
WriteStuff.WriteLine(var1)
WriteStuff.Close
SET WriteStuff = NOTHING
SET myFSO = NOTHING
which is placed in action in the key.
In the variable "var1" is read barcode reader, bar code EAN13 and after pressing a key to a text file "C:\Label_1\yourtextfile.txt"
is written to a new line with a value of "var1", ie. the bar code
2914750018247
Then again, when we will scan the bar code
2914750007463
and press the button
also will be saved in a text file.
Recording will look like this:
2914750018247
2914750007463
Of course, the scanned file "C:\Label_1\yourtextfile.txt" will be more, eg. 70 different codes but always EAN13.
How you can using VBScript copy or distribute 5 characters namely:
01824
00746
...
with previously stored all values (5 characters each) in the file "C:\Label_1\ yourtextfile.txt" and yet they all add up and save a new file txt when codes (with five characters each) will be just 70 in line?
Take a look at the below example, it processes the lines of source file and cut each line to substring:
sSrc = "C:\Users\DELL\Desktop\barcode.txt"
sDst = "C:\Users\DELL\Desktop\barcode_part.txt"
' Read content of the source file
sCont = ReadTextFile(sSrc, 0) ' ASCII
' Split source file string into array of lines
aLines = Split(sCont, vbCrLf)
' Loop through each of the lines in array
For i = 0 To UBound(aLines)
' Change the value of the element to cut substring
aLines(i) = Mid(aLines(i), 8, 5)
Next
' Join processed array into resulting string with line breaks
sCont = Join(aLines, vbCrLf)
' Write content to the destination file
WriteTextFile sCont, sDst, 0 ' ASCII
Function ReadTextFile(sPath, lFormat)
' lFormat -2 - System default, -1 - Unicode, 0 - ASCII
With CreateObject("Scripting.FileSystemObject").OpenTextFile(sPath, 1, False, lFormat)
ReadTextFile = ""
If Not .AtEndOfStream Then ReadTextFile = .ReadAll
.Close
End With
End Function
Sub WriteTextFile(sContent, sPath, lFormat)
' lFormat -2 - System default, -1 - Unicode, 0 - ASCII
With CreateObject("Scripting.FileSystemObject").OpenTextFile(sPath, 2, True, lFormat)
.Write sContent
.Close
End With
End Sub

combine pipe delimited lines of text in multiple lines with vbscript?

I've got a text file of output that looks essentially like this:
SMITHERSON, SMITH|00012345|15-Jan-1999|000885340
619649339|29-Sep-2015 00:09:30|Black|JOHNERSON, JOHN
00067890|02-Dec-1996|000490365|620094551
29-Sep-2015 23:06:01|Green|DAVISON, DAVE|00086543|06-Jun-2001|000938585
226438332|28-Sep-2015 00:12:12|Yellow
Seven pieces of data, they are always in the correct order but unfortunately they run together and onto different lines. There are carriage return + line feeds at the end of each line and there aren't pipe delimiters. The individual pieces of data are never split over multiple lines - I'm having a hard time explaining so here's another example:
DATA 1|DATA 2|DATA 3
DATA 4
DATA 5|DATA 6|DATA 7
DATA 1|DATA 2|DATA 3|DATA 4
DATA 5|DATA 6|DATA 7
etc...
They will have spaces between them but each piece of data will always stay on it's own line.
And I'm trying to turn it into this:
SMITHERSON, SMITH|00012345|15-Jan-1999|000885340|619649339|29-Sep-2015 00:09:30|Black
JOHNERSON, JOHN|00067890|02-Dec-1996|000490365|620094551|29-Sep-2015 23:06:01|Green
DAVISON, DAVE|00086543|06-Jun-2001|000938585|226438332|28-Sep-2015 00:12:12|Yellow
DATA 1|DATA 2|DATA 3|DATA 4|DATA 5|DATA 6|DATA 7
DATA 1|DATA 2|DATA 3|DATA 4|DATA 5|DATA 6|DATA 7
etc.
Seven pieces of data each on their own line, but still seperated by the '|' for another piece of software to read correctly.
I am spending about one hour every day correcting the text files by hand, so I've been trying to find an example I can work from to do this for a while but have not had any luck wrapping my head around this.
This code is ok. I only tested your sample text, not big files.
It will replace line feeds with the delimiter, then convert the entire file into one big array:
Set fso = CreateObject("Scripting.FileSystemObject")
Set input = fso.OpenTextFile("input.txt", 1)
Set output = fso.OpenTextFile("output.txt", 2, True)
Dim data: data = input.ReadAll
input.Close()
data = Replace(data, vbCrlf, "|")
data = Split(data, "|")
For i=0 To UBound(data) Step 7
output.WriteLine data(i) & "|" & data(i+1) & "|" & data(i+2) & "|" & data(i+3) & "|" & data(i+4) & "|" & data(i+5) & "|" & data(i+6)
Next
output.Close()
Untested, but something like this might do it. (Essentially it copies input to output as a stream, but newlines in the input are converted to pipe characters and every seventh pipe in the output is converted to a newline)
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.OpenTextFile("D:\data\thefile.txt", 1)
Set o = fs.OpenTextFile("D:\data\combined.txt", 2, True)
pipecount = 0
Do While f.AtEndOfFile <> True
If f.AtEndOfLine = True Then
c = f.Read(2) ' Skip the CR+LF
c = "|" ' and pretend we got a pipe character
Else
c = f.Read(1)
End If
If c = "|" Then
pipecount = pipecount + 1
If pipecount = 7 Then
pipecount = 0
o.WriteLine()
Else
o.Write("|")
End If
Else
o.Write(c)
End If
End While
o.Close()

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? =)

VB Script Files Collection

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.

Resources