Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Loop through array - combine specific strings into another string 1

Status
Not open for further replies.

PPettit

IS-IT--Management
Sep 13, 2003
511
0
0
US
I have the following filenames in an array:
30000001.pdf
30000002.pdf
30000101.pdf
30011601.pdf
30011602.pdf
30011603.pdf

I need to:
1. Combine each filename with the same first six digits into one string.
Example:
string = "30011601.pdf 30011602.pdf 30011603.pdf"
Note: Filenames could range from xxxxxx01.pdf to xxxxxx99.pdf. Must be in numerical order with lowest number first. Separated by a space.
2. Execute a DOS command with the string.
3. Move on to the next group of filenames


How do I build the string dynamically?
 
You could start with sorting the file names which you can find examples of in the FAQ's.

Once they're in order then you can do use something like this to build the string like you mentioned.

Code:
Option Explicit

Dim arrFileNames : arrFileNames = Array("30000001.pdf", "30000002.pdf", _
							  "30000101.pdf", "30011601.pdf", _
							  "30011602.pdf", "30011603.pdf")
Dim objDict : Set objDict = CreateObject("Scripting.Dictionary")
Dim strFileName, strTemp
For Each strFileName In arrFileNames
	strTemp = Left(strFileName, 6)
	If Not objDict.Exists(strTemp) Then
		objDict.Add strTemp, strFileName
	Else
		objDict(strTemp) = objDict(strTemp) & " " & strFileName
	End If
Next

Dim strFiles
For Each strFiles In objDict.Keys
	WScript.Echo objDict(strFiles)
Next

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
My syntax may be a little off, but this is basically how to do it, simple loop, easy since the filenames are in order already.

'begin Script

Dim arrFiles(filename1, filename2, filename3)
Dim strLastFirstSix, strThisFirstSix, strDosCommand

'need a starting point
strLastFirstSix = arrFiles(0)

for each file in arrFiles 'read every filename
strThisFirstSix = Left(file, 6)

if strThisFirstSix = strLastFirstSix then
strDosCommand = strDosCommand & file & " "
else
<code to execute your dos command, maybe wscript.shell>
strDosCommand = file & " "
end if

strLastFirstSix = strThisFirstSix
next

'End Script

Basically this loops through your array of file names, reading the name and finding the first 6 characters of it. It then compares it to the previous filename's first 6. if they match, then this belongs to the same file family, so add the filename to the string list. If it doesn;t match, then it's a new family, execute your previous list and add this new filename to the new list. (I hope that makes sense)
 
Maybe I should have specified that the filenames I used are for example purposes only. They change after each session and there may be hundreds of them in the directory that I'm working with.

I just thought I'd post this so that everyone would have a better idea of what I'm trying to accomplish. The script is supposed to combine similarly named PDF files into one multi-page PDF file.
Code:
'Script uses PDFToolkit ([URL unfurl="true"]http://www.pdfhacks.com/pdftk/)[/URL] to merge files.
Option Explicit
Const strPath = "X:\Test\" 
Dim colFile, colFiles
Dim counter
Dim i
Dim fso
Dim MyArray
Dim objShell
Dim pdfFile, pdfFolder
Dim re
Dim strFilesToCombine
Dim strOutputFile

Set fso = CreateObject("Scripting.FileSystemObject")
Set pdfFolder = fso.GetFolder("X:\Test\")
Set colFiles = pdfFolder.Files
Set objShell = Wscript.CreateObject("Wscript.Shell")

Set re = New RegExp
re.IgnoreCase = False
re.Pattern = "^\d{8}.pdf$"

'determine how big to make the array
counter = 0
For Each colFile In colFiles
  If re.Test(colFile.Name) = True Then
    counter = counter + 1
  Else
  End If
Next

'set the array size
ReDim MyArray(counter-1)

'populate the array
counter = 0
For Each colFile In colFiles
  If re.Test(colFile.Name) = True Then
	  MyArray(counter) = colFile.Name
    counter = counter + 1
  Else
  End If
Next

'add something here to look through the array and find filenames with the same
' first 6 characters then add them all to one string (strFilesToCombine)
'filenames must be: one after the other, numerical order, space between each
strFilesToCombine = strPath + MyArray(0) + " " + strPath + MyArray(1)
'using two static items for'testing purposes only


'the output file needs to be dynamic to reflect the name of the file
'or files being used in strFilesToCombine
strOutputfile = strPath + "test.pdf"

'find a way to make this run without displaying a DOS window
'decide what to do if a file already exists - replace or leave it?
objShell.Run "pdftk " + strFilesToCombine + " cat output " + strOutputFile

It's a work in progress. As you can tell from the notes I left for myself, I still have a few other things to work out. I think I can figure out the rest on my own. I just "hit a wall" when trying to figure out how to build the string. When I get that worked out, the rest should be easy.
 
The example I posted should work...you might even be able to use it to build your strings without having to add the file names to an array first.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
I got it working. It still needs a bit of refinement (hide DOS window, set to always overwrite, delete old files, etc.) but this will ease my burden for now.


Thanks, guys.

Here's the functional code:
Code:
'Script uses PDFToolkit ([URL unfurl="true"]http://www.pdfhacks.com/pdftk/)[/URL] to merge files.
Option Explicit
Const strPath = "X:\" 
Dim colFile, colFiles
Dim counter
Dim i
Dim fso
Dim MyArray
Dim objDict, objShell
Dim pdfFile, pdfFolder
Dim re
Dim strFileName, strFiles, strFilesToCombine, strOutputFile, strTemp

Set fso = CreateObject("Scripting.FileSystemObject")
Set pdfFolder = fso.GetFolder("X:\")
Set colFiles = pdfFolder.Files
Set objDict = CreateObject("Scripting.Dictionary")
Set objShell = Wscript.CreateObject("Wscript.Shell")

Set re = New RegExp
re.IgnoreCase = False
re.Pattern = "^\d{8}.pdf$"

'determine how big to make the array
counter = 0
For Each colFile In colFiles
  If re.Test(colFile.Name) = True Then
    counter = counter + 1
  Else
  End If
Next

'set the array size
ReDim MyArray(counter-1)

'populate the array
counter = 0
For Each colFile In colFiles
  If re.Test(colFile.Name) = True Then
	  MyArray(counter) = colFile.Name
    counter = counter + 1
  Else
  End If
Next

For Each strFileName In MyArray
  strTemp = Left(strFileName, 6)
  If Not objDict.Exists(strTemp) Then
    objDict.Add strTemp, strPath & strFileName
  Else
    objDict(strTemp) = objDict(strTemp) & " " & strPath & strFileName
  End If
Next

For Each strFiles In objDict.Keys
  strOutputfile = strPath + Mid(objDict(strFiles),4,6) + ".pdf"
  strFilesToCombine = objDict(strFiles)
  objShell.Run "pdftk " + strFilesToCombine + " cat output " + strOutputFile
Next
 
You should be able to get rid of that initial array you build with something like this.

Code:
Option Explicit

Const strPath = "X:\"
Dim colFile, colFiles
Dim counter
Dim i
Dim fso
Dim MyArray
Dim objDict, objShell
Dim pdfFile, pdfFolder
Dim re
Dim strFileName, strFiles, strFilesToCombine, strOutputFile, strTemp

Set fso = CreateObject("Scripting.FileSystemObject")
Set pdfFolder = fso.GetFolder("X:\")
Set colFiles = pdfFolder.Files
Set objDict = CreateObject("Scripting.Dictionary")
Set objShell = Wscript.CreateObject("Wscript.Shell")

Set re = New RegExp
re.IgnoreCase = False
re.Pattern = "^\d{8}.pdf$"

For Each colFile In colFiles
	strFileName = colFile.Name
	If re.Test(strFileName) = True Then
		strTemp = Left(strFileName, 6)
		If Not objDict.Exists(strTemp) Then
			objDict.Add strTemp, strPath & strFileName
		Else
			objDict(strTemp) = objDict(strTemp) & " " & strPath & strFileName
		End If
	End If
Next

For Each strFiles In objDict.Keys
  strOutputFile = strPath + Mid(objDict(strFiles),4,6) + ".pdf"
  strFilesToCombine = objDict(strFiles)
  objShell.Run "pdftk " + strFilesToCombine + " cat output " + strOutputFile 
Next

To hide the DOS window just do something like
objShell.Run command, 0

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
Thanks for saving me some time and trouble. You rock.
 
There's one more thing that I'm having some trouble with. What's the best way to deal with overwriting files when running my script?

Say I run the script and then run it again immediately afterwards for some reason, the DOS command appears to be waiting for me to "ok" overwriting of the files if one already exists. (In Task Manager There's a pdftk.exe process still running for each file that needs to be overwritten. I'm assuming that it's the overwrite prompt since that is what I normally get if I don't hide the DOS window.) Should I just add a bit of code to delete the files before trying to create them again, or is there a better way to handle this?
 
Never mind. I discovered that pdftk has a "dont_ask" switch that I can use to keep the overwrite prompt from occurring.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top