Link to home
Start Free TrialLog in
Avatar of Luis Diaz
Luis DiazFlag for Colombia

asked on

VB Script, move files if a file contains specific value

Hello Experts,

I have in a folder a thousand of csv files with the following structure:

ID;Name;Period Month;Period YEAR;Project ID;Project name;Task ID;Task
38980;Th, Paul;02;2015;179GA300;AGSR_TT_IMPORT;14810082;
358590;Th, Paul;02;2015;MVSPEP2;AGSR_TT_IMPORT;19510165

The highlight values represent the month and year of the current date.

The script that I need should be able to read the various files located at C:\test\, read the various lines related to Period Month and Period YEAR and if the value is not equal to the current date move the files to C:\wrong file\ otherwise keep the file.

Ex: file.csv with the following structure doesn't need to me moved

ID;Name;Period Month;Period YEAR;Project ID;Project name;Task ID;Task
38980;Th, Paul;02;2015;179GA300;AGSR_TT_IMPORT;14810082
358590;Th, Paul;02;2015;MVSPEP2;AGSR_TT_IMPORT;19510165

Ex2: file2.csv with the following structure needs to me moved

ID;Name;Period Month;Period YEAR;Project ID;Project name;Task ID;Task
3890;TF, Seb;01;2015;179GA300;AGSR_TT_IMPORT;14810082
3890;TF, Seb;01;2015;MVSPEP2;AGSR_TT_IMPORT;19510165

Ex3: file.csv with the following structure needs to be moved

ID;Name;Period Month;Period YEAR;Project ID;Project name;Task ID;Task
38980;Th, Paul;02;2014;179GA300;AGSR_TT_IMPORT;14810082
358590;Th, Paul;02;2014;MVSPEP2;AGSR_TT_IMPORT;19510165

Thank your for your help.
Avatar of Dany Balian
Dany Balian
Flag of Lebanon image

unfortunately i can't test the code because i'm on my mac, but i guess you need something like this:

dim FS, fsFolder, strMainFolder, strWrongFolder
dim monthyear, month, year
'Set Script Parameters
strMainFolder="C:\test\"
strWrongFolder="C:\wrong file\"
month=2
year=2015

Set FS = CreateObject("Scripting.FileSystemObject")
If Right(strMainFolder, 1) <> "\" Then strMainFolder = strMainFolder & "\"
If Right(strWrongFolder, 1) <> "\" Then strWrongFolder = strWrongFolder & "\"
Set fsFolder = FS.GetFolder(strMainFolder)
dim moved, kept
kept=0
moved=0
monthyear= "0" & month & ";" & year
monthyear=right(monthyear,7)
monthyear=";" & monthyear & ";"

For Each ofile In FSfolder.files
	if filecontains(ofile.name, monthyear) then
		fs.movefile strMainFolder & ofile.name, strWrongFolder & ofile.name
		moved=moved+1
	else
		kept=kept+1
	end if
Next
msgbox "Operation Complete: " & vbcrlf & "Total Files: " & moved+kept & vbcrlf & "Moved Files: " & moved & vbcrlf & "Retained Files: " & kept

function filecontains(f, t) 
	'Const ForReading = 1, ForWriting = 2, ForAppending = 8
	'Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
	Dim fso, MyFile, TextLine
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set MyFile = fso.OpenTextFile(f, 1)
	Do While MyFile.AtEndOfStream <> True
    		TextLine = MyFile.ReadLine
    		if instr(textline,t, 1) > 0 then
    			'we found the month and year
    			filecontains=true
    			MyFile.close
    			exit function
    		end if
	Loop
	MyFile.Close
	filecontains=false
end function

Open in new window

Avatar of Luis Diaz

ASKER

Hello Dany,

Thank you for your script, I will test it.

Is not a way to dynamically assign the the month and year variables?

Something like this

month =DatePart("yyyy", Now)
year=DatePart("m",Now)
well i did the code in a way it's very easy to modify that:

just replace
m=2 with m=month(now)
and
y=2015 with y=year(now)
Final Code:

dim FS, fsFolder, strMainFolder, strWrongFolder
dim monthyear, m, y
'Set Script Parameters
strMainFolder="C:\test\"
strWrongFolder="C:\wrong file\"
m=month(now) '2
y=year(now) '2015

Set FS = CreateObject("Scripting.FileSystemObject")
If Right(strMainFolder, 1) <> "\" Then strMainFolder = strMainFolder & "\"
If Right(strWrongFolder, 1) <> "\" Then strWrongFolder = strWrongFolder & "\"
Set fsFolder = FS.GetFolder(strMainFolder)
dim moved, kept
kept=0
moved=0
monthyear= "0" & m & ";" & y
monthyear=right(monthyear,7)
monthyear=";" & monthyear & ";"

For Each ofile In FSfolder.files
	if filecontains(ofile.name, monthyear) then
		fs.movefile strMainFolder & ofile.name, strWrongFolder & ofile.name
		moved=moved+1
	else
		kept=kept+1
	end if
Next
msgbox "Operation Complete: " & vbcrlf & "Total Files: " & moved+kept & vbcrlf & "Moved Files: " & moved & vbcrlf & "Retained Files: " & kept

function filecontains(f, t) 
	'Const ForReading = 1, ForWriting = 2, ForAppending = 8
	'Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
	Dim fso, MyFile, TextLine
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set MyFile = fso.OpenTextFile(f, 1)
	Do While MyFile.AtEndOfStream <> True
    		TextLine = MyFile.ReadLine
    		if instr(textline,t, 1) > 0 then
    			'we found the month and year
    			filecontains=true
    			MyFile.close
    			exit function
    		end if
	Loop
	MyFile.Close
	filecontains=false
end function
                                          

Open in new window


the old variable names were month and year, which are reserved words (i didn't notice) so i just changed them now to m and y respectively
Hello Dany,

I got an error message (file not found) in line 35 char.

I have check the folders variable declaration and all is ok.
Avatar of Bill Prew
Bill Prew

Can there be lines with different dates in the same file?  For example could this happen?

ID;Name;Period Month;Period YEAR;Project ID;Project name;Task ID;Task
38980;Th, Paul;01;2015;179GA300;AGSR_TT_IMPORT;14810082
358590;Th, Paul;02;2015;MVSPEP2;AGSR_TT_IMPORT;19510165

Open in new window

Or, if the current month is found on one line in a file, can we assume the whole file is okay?

~bp
Give this a try, adjust folder names near top.  You may want to comment out the display of each file after testing.

' Define needed constants
Const ForReading = 1
Const ForWriting = 2
Const TriStateUseDefault = -2

' Specify from and to folders
strBaseDir = "B:\EE\EE28621689\From"
strDestDir = "B:\EE\EE28621689\Dest"

' Build search string from current month (;MM;YYYY;)
strCurrentMonth = ";" & Right("0" & Month(Now), 2) & ";" & Year(Now) & ";"

' Access from folder
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strBaseDir)

' Initialize counters
intKeep = 0
intMove = 0

' Process each file in from folder
For Each objFile In objFolder.Files

   ' Read file into a  variable
   Set objReadFile = objFSO.OpenTextFile(objFile.Path, ForReading, False, TriStateUseDefault)
   strData = objReadFile.ReadAll
   objReadFile.Close

   ' See if it contains current month string, if so keep it, if not move it
   If InStr(strData, strCurrentMonth) > 0 Then
      Wscript.Echo "Keep:" & objFile.Name
      intKeep = intKeep + 1
   Else
      Wscript.Echo "Move:" & objFile.Name
      objFSO.MoveFile objFile.Path, strDestDir & "\"
      intMove = intMove + 1
	End If

Next

' Display counts
Wscript.Echo "Files Kept : " & intKeep
Wscript.Echo "Files Moved : " & intMove

Open in new window

~bp
Lol bill that's my exact code!
Sorry LD i'm on mobile, i will check the code again when i'm on my laptop!

Can u just post me the full code that i tried? Thanks
ok there were 2 problems in the code:
1. i was not sending the strmainfolder to the function that checks the files (only filename was being sent, so it was not finding the file path)
2. the instr function in vbscript takes the first argument as where to start the search from.. (an integer number)
the full working, tested code is below

dim FS, fsFolder, strMainFolder, strWrongFolder
dim monthyear, month, year
'Set Script Parameters
strMainFolder="C:\ee\src\"
strWrongFolder="C:\ee\dest\"
month=2
year=2015

Set FS = CreateObject("Scripting.FileSystemObject")
If Right(strMainFolder, 1) <> "\" Then strMainFolder = strMainFolder & "\"
If Right(strWrongFolder, 1) <> "\" Then strWrongFolder = strWrongFolder & "\"
Set fsFolder = FS.GetFolder(strMainFolder)
dim moved, kept
kept=0
moved=0
monthyear= "0" & month & ";" & year
monthyear=right(monthyear,7)
monthyear=";" & monthyear & ";"

For Each ofile In FSfolder.files
	if filecontains(strMainFolder & ofile.name, monthyear) then
		fs.movefile strMainFolder & ofile.name, strWrongFolder & ofile.name
		moved=moved+1
	else
		kept=kept+1
	end if
Next
msgbox "Operation Complete: " & vbcrlf & "Total Files: " & moved+kept & vbcrlf & "Moved Files: " & moved & vbcrlf & "Retained Files: " & kept

function filecontains(f, t)
	'Const ForReading = 1, ForWriting = 2, ForAppending = 8
	'Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
	Dim fso, MyFile, TextLine
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set MyFile = fso.OpenTextFile(f, 1)
	Do While MyFile.AtEndOfStream <> True
    		TextLine = MyFile.ReadLine
    		if instr(1,textline,t) > 0 then
    			'we found the month and year
    			filecontains=true
    			MyFile.close
    			exit function
    		end if
	Loop
	MyFile.Close
	filecontains=false
end function

Open in new window

@Dany: I tested your last script with a csv file containing the following date 4/2014. The file should be moved and the script doesn't move the file. Additionnally the date are not dynamically set up.

@Bill: I tested your script and it works however is it possible to move with an overwrite set up If the file already exists in the strDestDir?
we just need to replace these 2 lines:
m=month(now)
y=year(now)

could it be that the file: contains both of 02;2015 and 04;2014 ? in that case it will not move the file..

i updated the code below to reflect the dynamic date building and also to replace the file if it exists in the destination folder. (there's no such thing as move with overwrite.. but what we need to do is to copy with overwrite, then delete the file)

dim FS, fsFolder, strMainFolder, strWrongFolder
dim monthyear, m, y
'Set Script Parameters
strMainFolder="C:\test\"
strWrongFolder="C:\wrong file\"
m=month(now) '2
y=year(now) '2015

Set FS = CreateObject("Scripting.FileSystemObject")
If Right(strMainFolder, 1) <> "\" Then strMainFolder = strMainFolder & "\"
If Right(strWrongFolder, 1) <> "\" Then strWrongFolder = strWrongFolder & "\"
Set fsFolder = FS.GetFolder(strMainFolder)
dim moved, kept
kept=0
moved=0
monthyear= "0" & m & ";" & y
monthyear=right(monthyear,7)
monthyear=";" & monthyear & ";"

For Each ofile In FSfolder.files
	if filecontains(strMainFolder & ofile.name, monthyear) then
		'fs.movefile strMainFolder & ofile.name, strWrongFolder & ofile.name
                fs.CopyFile strMainFolder & ofile.name, strWrongFolder & ofile.name, True
                fs.DeleteFile strMainFolder & ofile.name, True
		moved=moved+1
	else
		kept=kept+1
	end if
Next
msgbox "Operation Complete: " & vbcrlf & "Total Files: " & moved+kept & vbcrlf & "Moved Files: " & moved & vbcrlf & "Retained Files: " & kept

function filecontains(f, t) 
	'Const ForReading = 1, ForWriting = 2, ForAppending = 8
	'Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
	Dim fso, MyFile, TextLine
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set MyFile = fso.OpenTextFile(f, 1)
	Do While MyFile.AtEndOfStream <> True
    		TextLine = MyFile.ReadLine
    		if instr(1,textline,t) > 0 then
    			'we found the month and year
    			filecontains=true
    			MyFile.close
    			exit function
    		end if
	Loop
	MyFile.Close
	filecontains=false
end function

Open in new window

it is important to know what you want to do if two dates are found in the same file, keep or move?
@Dany each file contains a unique date.
ASKER CERTIFIED SOLUTION
Avatar of Dany Balian
Dany Balian
Flag of Lebanon image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Tested. Both scripts works!
Thank you!
Thanks, glad that was useful, check back if you have any questions.

~bp