I have a system that's running an old FoxPro program which generates 8 character long DBF files. We make a back up of the program folder each day, but at 5pm the program has generated so many of these garbage dbf's that it's a nuisance. I would just set a del *.dbf in the back up script but there are a few dbf with letters in their name that are needed to run the program.
Files are located in F:\Clean This\
Any numerically titled .dbf files need to be deleted
Any alphabetically titled .dbf file should be left alone
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "F:\Clean This\"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
collide = "ABCEDFGHIJKLMNOPQRSTUVWXYZ"
For Each objFile in colFiles
If UCase(objFSO.GetExtensionName(objFile.name)) = "DBF" Then
num = 1
For num = 1 to 26 'find files with names start with # 0-9
If Left(objFile.Name,1) = Left(collide,num) Then
Wscript.Echo "Save " & objFile.Name
Else If int(Left(objFile.Name,1)) > 0 Then
Wscript.Echo "Delete!"
End IF
End If
Next
End If
Next
As you can tell the If statements can be done better, I'm unsure how to better work it out. The two Wscript.Echo commands are just placeholders because if anything else I can't get find a suitable delete function that would work in a dos environment (I've already tried kill, no).
Suggestions and improvements would be much appreciated!
Use IsNumeric() to check for file names consisting of digits only:
>> For Each sN In Split("abc 123 1O1 101")
>> If IsNumeric(sN) Then
>> WScript.Echo "delete", sN
>> Else
>> WScript.Echo "keep", sN
>> End If
>> Next
>>
keep abc
delete 123
keep 1O1
delete 101
Your check fails, because you use Left() where you should use Mid():
>> collide = "ABCEDFGHIJKLMNOPQRSTUVWXYZ"
>> num = 5
>> WScript.Echo Left(collide,num)
>> WScript.Echo Mid(collide,num,1)
>>
ABCED
D
and even then Left(objFile.Name,1) will look at only the first character of the file name.
Update (wrt comments):
Apply IsNumeric() to the base name:
Dim oFile
For Each oFile In goFS.GetFolder("..\testdata\17817161").Files
WScript.Stdout.Write oFile.Name
If "dbf" = LCase(goFS.GetExtensionName(oFile.Name)) Then
If IsNumeric(goFS.GetBaseName(oFile.Name)) Then
WScript.Stdout.WriteLine " delete"
Else
WScript.Stdout.WriteLine " keep"
End If
Else
WScript.Stdout.WriteLine " ignore"
End If
Next
output:
123.dbf delete
123.txt ignore
abc.dbf keep
I did finally got it working, and here's what the end result was. It works wonderfully and the higher ups and others were rather impress that it worked better than the built in utility of the program we're backing up. Score!
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "..\System Folder"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set DirFiles = objFolder.Files
Dim oFile
For Each objFile in DirFiles
If "dbf" = LCase(objFSO.GetExtensionName(objFile.Name)) Then
If IsNumeric(objFSO.GetBaseName(objFile.Name)) Then
objFSO.DeleteFile(objFile)
End If
End If
Next
Related
Good morning,
I'm a beginner in programming code, so i'm sorry if I do something wrong.
I've wrote a code in VBS for backup some files from a folder to another.
My problem it is to compare the files date in both folders and allow the copy only if the file is new or the date has been changed.
Here my code, someone can help me to find the problem please?
I have tried but it is not working
' Copy a Folder
'Const OverWriteFiles = False
Dim strSourceFolder, strDestFolder
strSourceFolder = "E:\test1"
strDestFolder = "C:\test1"
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.CopyFolder "strSourceFolder" , "strDestFolder"
For each file in StrSourceFolder
ReplaceIfNewer ("file, strDestFolder")
Next
Sub ReplaceIfNewer (SourceFile, DestFolder)
Dim DateModifiedSourceFile, DateModifiedDestFile
DateModifiedSourceFile = SourceFile.DateModified()
DateModifiedDestFile = DestFolder & "\" & SourceFile.DateModified()
If DateModifiedSourceFile < DateModifiedDestFile then
Copy SourceFile to SourceFolder Else
End If
' Verify that a Folder Exists
'Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists("strDestFolder") Then
MsgBox "Backup Copy Done." & vbCrLf & (Day(Now) & "\" & Month(Now) & "\" & Year(Now)) , Vbinformation
Set objFolder = objFSO.GetFolder("strDestFolder")
Else
MsgBox "Folder does not exist." , vbCritical , "Folder does not exist."
End if
Thanks and Be patient !
.DateModified is not VBScript. Start reading here. There is DateDiff, but as Dates are Doubles under the hood, comparisons with < will work too. In code:
>> Set f = CreateObject("Scripting.FileSystemObject").GetFile(WScript.ScriptFullName)
>> dlm = f.DateLastModified
>> WScript.Echo TypeName(dlm), dlm, "(german locale)"
>> dlmn = DateAdd("s", 2, dlm)
>> WScript.Echo TypeName(dlmn), dlmn, "(german locale)"
>> WScript.Echo DateDiff("s", dlmn, dlm), DateDiff("s", dlm, dlmn), CStr(dlm < dlmn)
>> WScript.Echo CDbl(dlm)
>> WScript.Echo CDbl(dlmn)
>>
Date 22.11.2013 13:09:53 (german locale)
Date 22.11.2013 13:09:55 (german locale)
-2 2 Wahr
41600,5485300926
41600,5485532407
Im writing a batch script to help me collect some bandwidth data about numerous offices on our WAN. It uses random data file creator to help me avoid wan optimisers affecting the results.
How can I copy a file by spawning a standard windows copy window that shows transfer rate?
If i use the 'copy' method, it just copies silently in the cmd window and i cant see the rate.
if not exist "C:\temp\xfertest" mkdir C:\test\xfertest
rdfc C:\test\xfertest\random100.dat 100000000
copy C:\test\xfertest\random100.dat \\nat-srv-007\Deliver
exit
This vbscript wrappped in a batch file will do what you want. Save it with a .bat/.cmd extension. Or without the first line with a .vbs extension.
The technic used is based on com and works with every script language supporting it.
Just to see start/end date time, total bytes and bytes per/s it outputs these values to the console after the copy dialog window has vanished.
rem^ &#cscript //nologo //e:vbscript "%~f0" %* & exit /b
' Copy with the windows dialog box
Option Explicit
Dim cArgs : Set cArgs = WScript.Arguments
Dim iArgCnt : iArgCnt = cArgs.Count
Dim sSource : sSource = cArgs.Item(0)
Dim sDest : sDest = cArgs.Item(1)
Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim oSH : Set oSH = CreateObject("shell.application")
Dim oFile, Size, dStart, dEnd
If iArgCnt <> 2 Then
Wscript.Echo "Wrong args, need SourceFile and DestFolder"
Wscript.Quit
End if
If oFS.FileExists(sSource) Then
Set oFile = oFS.GetFile(sSource)
Size = oFile.Size
If oFS.FolderExists(sDest) Then
dStart = Now()
Wscript.Echo "Copy : " & sSource & " " & sDest
Wscript.Echo "Start: " & dStart & " Size : " & Size
FolderCopyHere sSource, sDest
dEnd = Now()
Wscript.Echo "End : " & dEnd & " per/s: " & _
Int(Size / DateDiff("s", dStart, dEnd))
Else
Wscript.Echo "Destination Folder doesn't exist" & sDest
End if
Else
Wscript.Echo "Source file doesn't exist" & sSource
End if
Wscript.Quit
function FolderCopyHere(sSource,sDest)
dim oFld
set oFld = oSH.NameSpace(sDest)
if not oFld is nothing then
oFld.CopyHere(sSource)
end if
set oFld = nothing
end function
Returning this output on my pc
20:28:24 C:\Test________________________________________
> k:\Bat\CopyExpl.cmd c:\test\big.file Q:\Test
20:28:36 C:\Test________________________________________
> rem &
Copy : c:\test\big.file Q:\Test
Start: 2016-10-30 20:28:36 Size : 2147483648
End : 2016-10-30 20:29:10 per/s: 63161283
20:29:10 C:\Test________________________________________
The Rem stems from the wrapper the dialog box is widely known. HTH
I was looking for a way to move the 5 oldest modified files in a folder to a different folder.
I came across some helpful pieces of code and I revised it to this:
Dim files
Dim startFolder
Dim destinationFolder
Dim oldestFile
Dim file
Dim FSO
startFolder = "C:\logs\current"
destinationFolder = "C:\logs\backup"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set files = FSO.GetFolder(StartFolder).files
Set oldFiles = CreateObject("System.Collections.ArrayList")
If files.Count <= 5 Then
WScript.Quit
End If
For i = 0 To 4
Set files = FSO.GetFolder(StartFolder).files
Set oldFiles = Nothing
For Each file In files
If Not IsObject(oldestFile) Then
Set oldestFile = file
Else
If file.DateLastModified < oldestFile.DateLastModified Then
Set oldestFile = file
End If
End If
Next
WScript.Echo "OLDEST: " & oldestFile.Name
oldestFile.Move destinationFolder & "\" & oldestFile.Name
Next
Basically what it supposed to do is:
loop 5 times,
each time loop through the files and assign the oldest to oldestFile,
move the file to a different location.
However, it doesn't work, it's echoing the first file's name 5 times and move just this one.
I thought I should set the objects to Nothing to start fresh but to no avail.
You need to reset the variable oldestFile at the beginning (or end) of your loop, not the variable oldFiles.
For i = 0 To 4
Set files = FSO.GetFolder(StartFolder).files
Set oldestFile = Nothing
For Each file In files
...
Next
WScript.Echo "OLDEST: " & oldestFile.Name
oldestFile.Move destinationFolder & "\" & oldestFile.Name
Next
Otherwise the value of oldestFile will never change, because even after being moved the referenced file ramains the oldest file compared to the files in the source folder.
I need to make a vbs file that asks for the minimum file size when you drag and drop a folder to it. It's a little wierd. But then, it should return the input as a string that will be turned into an integer. Then it should look for files that are bigger than this minimum file size(all, i guess) and list their folder(if it's in a sub-folder), name and size.
I found some stuff on the internet but I'm a bit lost
Option Explicit
Dim FolderPath, objFSO, objFolder, objFile, input, objArgs
input = InputBox("Minimum size: ")
Set objArgs = Wscript.Arguments
Set objFSO = CreateObject("Scripting.FileSystemObject")
For i = 0 to objArgs.count
on error resume next
Set objFolder = objFSO.GetFolder(objArgs(i))
If err.number <> 0 then
ProcessFile(objArgs(i))
Else
For Each file In folder.Files
ProcessFile(file.path)
Next
End if
On Error Goto 0
Next
Function ProcessFile(sFilePath)
msgbox "Now processing file: " & sFilePath
For each objFile in objFolder.Files
WScript.Echo objFile.Name, objFile.Size & "bytes" & VbCR_
& "created: " & objFile.DateCreated & VbCR_
& "modified: " & objFile.DateLastModified
Next
You've got some issues in your code. You're using folder.files but you don't have folder declared (or defined) anywhere. The only reason you're not getting an error is because you have On Error Resume Next specified. There's no need to use On Error here and it should be removed so that you can properly debug your script. Here's a starting point for you.
' Get the folder dropped onto our script...
strFolder = WScript.Arguments(0)
' Ask for minimum file size...
intMinSize = InputBox("Minimum size: ")
' Recursively check each file with the folder and its subfolders...
DoFolder strFolder
Sub DoFolder(strFolder)
' Check each file...
For Each objFile In objFSO.GetFolder(strFolder).Files
If objFile.Size >= intMinSize Then
WScript.Echo "Path: " & objFile.Path & vbCrLf & "Size: " & objFile.Size
End If
Next
' Recursively check each subfolder...
For Each objFolder In objFSO.GetFolder(strFolder).SubFolders
DoFolder objFolder.Path
Next
End Sub
This isn't a complete script. Notice I haven't declared objFSO anywhere. I haven't checked that strFolder is a valid folder or that intMinSize is actually a number. I'll leave it up to you to fill in the missing pieces. But this should get you going.
Hiya Guys I have a text file with locations of files I'm looking for a way to read the text file and then use those locations as a source location and copy the files to a seperate destination.
I've been playing around and have seen about dynamic arrays but cant seem to understand how to put the contents of the array into variables to read as source location.
example of what I have done so far
Dim TxtFile
dim strDestinationFolder
strDestinationFolder = "\\SERVER\DESTLOGS"
TxtFile = "c:\windows\temp\SOFTWARELOG.txt"
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim f: Set f = fso.OpenTextFile(TxtFile)
Do Until f.AtEndOfStream
WScript.Echo "PSTLocation: " & f.ReadLine ; I can read each line here in the txt file
fso.CopyFile strDestinationFolder, f.REadline
Loop
I've also tried playing with, but not sure where to start though it looks the most reliable?
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
(TxtFile, ForReading)
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
arrServiceList = Split(strNextLine , ",")
WScript.Echo "Server: " & arrServiceList(0)
WScript.Echo "Service: " & objTextFile
For k = 1 to UBound(arrServiceList)
WScript.Echo vbTab & "Service: " & arrServiceList(i)
Next
Loop
Any Guidance please as to what is the best way I should go about this with vbs.
Thanks
WScript.Echo "PSTLocation: " & f.ReadLine
fso.CopyFile strDestinationFolder, f.REadline
Your code echoes one line read from the file, and then tries to copy the destination folder to the next line read from the file.
If you want to do more than one thing with a line read from a file you need to assign the read line to a variable and then use that variable. Also, you need to switch the arguments of the CopyFile method. Source comes first, then destination. Plus, if you want the destination to be a folder, it needs a trailing backslash (otherwise you'd try to overwrite a folder with a file, which raises an error).
Do Until f.AtEndOfStream
line = Trim(f.ReadLine)
WScript.Echo "PSTLocation: " & line
If fso.FileExists(line) Then fso.CopyFile line, strDestinationFolder & "\"
Loop
The Trim() accounts for spurious leading/trailing spaces in the read line, and it's always a good idea to check if a file actually exists before you try to do anything with it.
Edit: For detecting an existing destination file and appending a running number to the file name try something like this:
basename = fso.GetBaseName(line)
extension = fso.GetExtensionName(line)
destinationFile = fso.BuildPath(strDestinationFolder, basename & "." & extension)
i = 1
Do While fso.FileExists(destinationFile)
filename = basename & i & "." & extension
destinationFile = fso.BuildPath(strDestinationFolder, filename)
i = i + 1
Loop
fso.CopyFile line, destinationFile