Files and directory structure

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Files and directory structure

Post by Robbyn » Tue Dec 27, 2005 7:35 pm

Is there a way of moving down through each directory within "my documents and within each sub directory is it possible to step through each file in turn filtering on the extension.
Robin

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Tue Dec 27, 2005 8:15 pm

Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Post by Robbyn » Sat Dec 31, 2005 3:14 pm

I tried the dos approach first because it looked the easier to understand. However when I run the script in debug mode it steps through each line but there is no activity. THe cmd dos window does not open, and no file is created in I:\temp\

This is all I put into the macro. There is nothing before it:

Let>RP_WINDOWMODE=2
Let>RP_WAIT=1
Run>cmd /c dir i:\testms\*.pdf /s /b > I:\temp\temp.txt
ReadFile>I:\temp\temp.txt,dir_list
//Separate the variable dir_list by %CRLF% and you have your list all assigned to variables. This has the added attraction that the full path will be included with each file name.
//set your path here ...
Robin

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Post by Robbyn » Sat Dec 31, 2005 3:29 pm

I also tried the VB approach with no success. This is because the script jumps over all the lines between vbstart and vbend.

Another problem is that I think I should have changed some of the items in brackets, but I am unsure which need to be changed. Is folderspec needing to be changed to the actual folder path. Where do I specify the file types to be sent to listed? I would substitute folderspec for *.pdf but then that is not a folder description, so I have left it alone.

Assuming all the files are in i:\testms\ and I am only interested in pdf files, how do I change your script. Here is the beginning:

Let>path=i:\testms\
VBSTART
Function GetFolderList(folderspec)
Dim fso, f, f1, fc, s, sf
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(folderspec)
Set fc = f.SubFolders
For Each f1 in fc
s = s & f1.name & ";"
sf = GetFolderList(folderspec & "\" & f1.name)
if sf "" then
s = s & f1.name & "\" & sf & ";"
end if
Next
If s "" then
s = Mid(s,1,Len(s)-1)
End If
GetFolderList = s
End Function
VBEND
Robin

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Sat Dec 31, 2005 8:11 pm

Your DOS approach looks good with a few comments:

1. The command window does not show open with RP_WINDOWMODE=2. Perhaps remove that line and let the default of "1" work for you.

2. Depending on your version of Windows you may need to use command.com vs. cmd.exe. Here is some script that will work in both

Code: Select all

MidStr>%OS_VER%,1,2,OS
If>%OS%=95,WIN9X,NT

Label>WIN9X
Let>COMSPEC=Command.com
//Let>Set other WIN 95/98 conditions
Goto>Start

Label>NT
Let>COMSPEC=Cmd.exe
//Let>Set other WIN NT/2K/XP conditions
Goto>Start

Label>Start
...
...
Run Program>%COMSPEC% /c dir i:\testms\*.pdf /s /b> I:\temp\temp.txt
ReadFile>I:\temp\temp.txt,dir_list
//Separate the variable dir_list by %CRLF% and you have your list all assigned to variables. This has the added attraction that the full path will be included with each file name.
//set your path here ...
...
Label>End
You should have no problem single stepping and will see the command window open without the WindowMode line.
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Post by Robbyn » Sat Dec 31, 2005 9:31 pm

I:\temp\temp.txt
ReadFile>I:\temp\temp.txt,dir_list
//Separate the variable dir_list by %CRLF% and you have your list all assigned to variables. This has the added attraction that the full path will be included with each file name.
Bob:

Thanks for your help. I now have that part working but I would like some further help as to what to do next.

How do I step through the list of files in the temptxt file? I am used to dbase commands which would have allowed me to read the file into a database and then step through the database. What do I do in MS?
Robin

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Sat Dec 31, 2005 10:37 pm

Depends on what you want to do, and the content of what you are reading.
Are you looking for a particualr word, number, phrase?
Do you want to make flow decisision base on the content?
Do you want to change the format of a date? Strip out a work, etc?

You have a directory listing now in a file. You can treat that like an ASCII text database, one record per line. Use ReadLn to read each line until reaching #EOF#. Store the results of each line into a variable? Parse the variable and save in another variable? Send the results into a "regular" database?
Then read the next line. Repeat until you reach EOF.

Check out the Help examples on ReadLn

From the Help section:

Code: Select all

Let>k=1 
Label>start 
ReadLn>c:\temp\test.txt,k,line 
If>line=##EOF##,finish 
Message>line 
Let>k=k+1 
Goto>start 
Label>finish 
The two lines starting with Message can be anything that you want to do with the variable %line%. Since you used dir /b /s so you only have the basic name and path. You might read until you see a particular filename, then branch out of the ReadLn loop and do something based on the filename. If you had not used the /b then you might make decisions based on the date. You could read the date with MidStr> function.

Bottom line, is that lots can be done, but you need to explain what it is that you want to do. Let us know "what", and we can help you with the "how".

Happy New Year
:D
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Post by Robbyn » Sun Jan 01, 2006 11:24 am

Thank you very much for that very clear and extremely helpful answer. I now understand a way forward using that example code. I will come back again if I have problems.
Robin

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Post by Robbyn » Sun Jan 01, 2006 10:05 pm

My macro is proceeding very well. At one point it is in a sub routine and I want it to leave it and go back to the top of the calling routine that is marked by a label>start.

Could goto>start in the middle of the subroutine cause any instability?
Robin

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Sun Jan 01, 2006 10:57 pm

Robbyn wrote:Could goto>start in the middle of the subroutine cause any instability?
No, that's fine.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

User avatar
Captive
Macro Veteran
Posts: 213
Joined: Sun Oct 20, 2002 8:37 pm
Location: Colorado, USA

Post by Captive » Mon Jan 02, 2006 9:00 pm

Robbyn wrote: [...]
Here is the beginning:

Let>path=i:\testms\
VBSTART
[...]
I see that you decided to abandon the VBScript approach. If you're still interested in using VBScript to get your filename list, read on. I have provided an example script that contains a few specifics to what you were trying to do.

Your VBSTART / VBEND section should be before any commands. You declare the VB subroutines (and vb variables) in this block, then later on you can use them using the VBRun and VBEval commands.


Here is a very (somewhat dirty, slightly overkill, but functional and fast) VB method to obtaining a list of filenames that match a specific pattern. Instead of using a seperate IsMatchingFilename function to check if the filename ends in .exe (or whatever), I could have just used something like:

Changing
If IsMatchingFilename(objFile.name,sRegPattern) = 1 Then
...with...
If Right(myfilename,4) = ".exe" Then

I also put the list in to both a Global vb array aFiles(), and a general string %sFileList% ... it actually only needs to go in one, but again I am just showing you examples of specific ways to acomplish something.

There are many ways to then do what you want with each filename. You can use the Seperate command and act upon each filename in a loop, or put the code you want in the VB procedure. You could even add a seperate vbscript procedure to act upon each entry in aFiles().

I hope this helps.


' Obtain a list of files, including in sub-dirs that match our specified pattern.

VBSTART

'------------------------------ Begin - Global Variables --------------------

Set fso = CreateObject("Scripting.FileSystemObject")

Dim ngFileCount ' File Count (global)
Dim aFiles() ' array of Files (global)
Dim sFiles
Dim sRegPattern

'------------------------------ End - Global Variables --------------------

'------------------------------ Begin - ProcessSubFolder --------------------
Sub ProcessSubFolder(objFolder)
Dim fcFiles

Set fcFiles = objFolder.files

' For each file in the folder...
For each objFile in fcFiles

' If the filename matches sRegPattern...
If IsMatchingFilename(objFile.name,sRegPattern) = 1 Then
ngFileCount=ngFileCount+1

' And add the filename to the list
ReDim Preserve aFiles(ngFileCount - 1) ' Resize the array
aFiles(ngFileCount - 1) = objFile.name ' Last entry is a N - 1
sFiles = sFiles & objFolder.Path & "" & objFile.name & "%CRLF%"
End If

Next ' Move on to the next filename

' Do the same for each subdirectory
For Each Subfolder in objFolder.SubFolders
Set objfolder = fso.GetFolder(Subfolder.Path)
ProcessSubFolder Subfolder
Next


End Sub
'------------------------------ End - ProcessSubFolder --------------------

Function IsMatchingFilename(sFName,sCheckPattern)
Dim regEx, Match, Matches, RetStr ' Create variable.
RetStr = 0 ' Set the result to 0
Set regEx = New RegExp ' Create a regular expression.
regEx.Pattern = SCheckPattern ' Set pattern.
regEx.IgnoreCase = True ' Set case insensitivity.
regEx.Global = False ' Set global applicability
Set Matches = regEx.Execute(sFName) ' Execute search.
For Each Match in Matches ' Iterate Matches collection.
RetStr = 1
Next
IsMatchingFilename = RetStr
End Function


Function GetMatchingFileList(sRootPath,sPattern)

On Error Resume Next

ngFileCount = 0
sRegPattern = sPattern

' Put the files from the root (sRootPath) in to the list
ProcessSubFolder(fso.GetFolder(sRootPath))

' MsgBox("Found: " & ngFileCount & " file(s)")
GetMatchingFileList = sFiles

End Function

VBEND

Let>sFolder=C:\Program Files

GetTime>sTimeStart

' Note: Params are (RootFolder,Expression)
' The expression must be a RegExp pattern.
' Example: VBEval>GetMatchingFileList("%sFolder%",".pdf$"),sFileList

VBEval>GetMatchingFileList("%sFolder%",".exe$"),sFileList


GetTime>sTimeEnd
Rem>MessageModal>%sFileList%

' Here's how I put the value of the VB Variable "ngFileCount" in to a general msched variable %nfilesfound% ...
VBEval>ngFileCount,nfilesfound
Message>Done!%CRLF%Start: %sTimeStart%%CRLF%End: %sTimeEnd%%CRLF%Count=%nfilesfound%

Last edited by Captive on Wed Jan 04, 2006 6:30 pm, edited 1 time in total.

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Isblank?

Post by Robbyn » Tue Jan 03, 2006 7:35 pm

Is there a way of testing if a text variable is blank/ empty?
Robin

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Tue Jan 03, 2006 7:41 pm

Of course there is. Compare it to an empty (null) string:

If>textvar=
MessageModal>textvar is empty
Else
MessageModal>textvar is not empty
Endif
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

Robbyn
Junior Coder
Posts: 43
Joined: Tue Feb 15, 2005 9:55 pm

Run Program>%COMSPEC% /c dir i:\testms\*.pdf /s /b> I:

Post by Robbyn » Mon Jan 09, 2006 7:35 pm

Is there a way of adding to this Dos command so that it filters out the file names with say "dogs" in them? What I mean is temp does not contain files with the word dog in them. I can see how it could be done using MS but can it be done with dos?
Robin

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Mon Jan 09, 2006 9:20 pm

I do not believe that is possible with DOS.
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts