Reputation: 189
I am developing a script to divide the number of files in a folder into four groups. These will be turned into four batch files but for now the issue is dividing them up as evenly as possible.
The script below will work somewhat - if I have a Count that will be divided by 4 evenly but if I have an odd number, no go and less than four will crash. You can run the script just replace the "C:\1_SourceData\Section_16\" with your own path of files. If you un-comment the section 'Add remainder to front', it was to thow any extra files, like an odd number, to the first batch but that does not quite work. The number of files in the folder will range from 1 to 25.
Any help would be most appreciated.
Option Explicit
Dim fileList : Set fileList = GetFileList("C:\1_SourceData\Section_16\")
Dim NumOfFiles : NumOfFiles = fileList.Count - 1
Dim modNumber : modNumber = NumOfFiles/4
Dim remainder : remainder = NumOfFiles Mod modNumber
Dim string1 : string1 = "batch" & batchCounter
Dim string2 : string2 = ""
'Add remainder to front
'Dim i : i = 0
'For i = NumOfFiles - remainder To NumOfFiles
' string2 = string2 & vbTab & fileList(i) & vbNewLine
'Next
Dim batchCounter : batchCounter = 1
Dim file
Dim j : j = 0
For Each file In fileList
string2 = string2 & vbTab & file & vbNewLine
j = j + 1
If j Mod modNumber = 0 Then
WScript.Echo string1 & vbNewLine & string2
batchCounter = batchCounter + 1
string1 = "batch" & batchCounter
string2 = ""
End If
Next
Public Function GetFileList(path)
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim fileList : Set fileList = CreateObject("System.Collections.ArrayList")
Dim InfFolder : Set InfFolder = objFSO.GetFolder(path)
Dim File
For Each File In objFSO.GetFolder(path).Files
fileList.Add File
Next Set GetFileList = fileList
End Function
Upvotes: 0
Views: 170
Reputation: 338228
You could structure your loop differently.
There are F files that should be devided into B batches of X files each. Two things can happen:
Therefore we can write two loops that (together) count from 1 to F:
Option Explicit
Const BATCHES = 4
Const PATH = "C:\1_SourceData\Section_16"
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
Dim fileList : Set fileList = GetFileList(PATH)
Dim b, i, f, x
f = fileList.Count
x = CInt(f / BATCHES)
If x * BATCHES < f Then x = x + 1
For b = 0 To BATCHES - 1
If (b * x < f) Then WScript.Echo "batch" & (b + 1)
For i = b * x To (b + 1) * x - 1
If (i < f) Then WScript.Echo vbTab & fileList(i)
Next
Next
Function GetFileList(path)
Dim file
Set GetFileList = CreateObject("System.Collections.ArrayList")
For Each file In FSO.GetFolder(path).Files
GetFileList.Add File
Next
End Function
Upvotes: 0
Reputation: 38755
The problem is: the .Files collection is accessible via For Each
only. A 'distribution by number' (think modulo) needs an extra counter. Demo script:
Option Explicit
ReDim a(3) ' 4 groups/collections
Dim i
For i = 0 To UBound(a)
Set a(i) = CreateObject("System.Collections.ArrayList")
Next
i = 0
Dim f
' fake a list of elms accessible via For Each only
For Each f In Split("a b c d e f g h i j k l m n")
a(i Mod 4).Add f ' use Mod to determine the 'bucket'
i = i + 1 ' counter needed for Mod
Next
For i = 0 To UBound(a)
WScript.Echo i, Join(a(i).ToArray())
Next
output:
cscript 40639293.vbs
0 a e i m
1 b f j n
2 c g k
3 d h l
Upvotes: 2