Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login




Remember Me
Forgot Password?
Join Us!

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Donate Today!

Do you enjoy these
technical forums?
Donate Today! Click Here

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.
Jobs from Indeed

Link To This Forum!

Partner Button
Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

patriciaxxx (Programmer) (OP)
2 Mar 12 9:23
I have the following vbscript which works as follows.
Giving that the specified directory contains 72 pics.
It renames them sequencially 01 to 72.
Must begin 01 and not 00

I need to modify it to include the following an optional mixed character prefix. The problem is when I add one that begins with a letter lets say I use "p12ax_" it adds it but the numbering begins 00 so I get p12ax_00 to p12ax_71 but I need p12ax_01 to p12ax_72.

Option Explicit

Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strLeadingZero
Dim intFileParts
Dim strFileParts

    'Define file path.
    strPath = "C:\Documents and Settings\Rename Pictures for Web Use\pic\"

    'Create the instance of the FSO.
    Set FSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set FLD = FSO.GetFolder(strPath)

    'Loop through each file in the folder.
    For Each fil in FLD.Files
        'Get complete file name with path.
        strOldName = fil.Path
        'Build the new file name.
        strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
        strNewName = strPath & strFileParts & Right(strOldName, 4) 'Right function keep file extension.
        'Use the MoveFile method to rename the file.
        FSO.MoveFile strOldName, strNewName
    Next

    'Cleanup the objects.
    Set FLD = Nothing
    Set FSO = Nothing
 
guitarzan (Programmer)
2 Mar 12 10:19
If the old code worked, then all you should need is this

CODE

...
Dim intFileParts
Dim strFileParts
Dim strPrefix
strPrefix = "p12ax_"


....

strNewName = strPath & sPrefix & strFileParts & Right(strOldName, 4)
patriciaxxx (Programmer) (OP)
4 Mar 12 4:31
I thought so too, and I tried it, but like I said it adds the string but the numbers begin 00 and not 01.

Without the additional string it works properly, the numbers begin 01.

The strange thing is that if the additional string begins with a number instead of a letter then it works properly and the numbers begin 01.

But I need the flexibility of the additional string beginning with number or letter and the numbers must always begin 01.

The additional string is obviously affecting it but I cannot work out why and therefore don't know how to correct the problem.

 
MakeItSo (Programmer)
4 Mar 12 10:37
This is not logical.

Post your code with the prefix addition. I'm sure you mixed up the order of string manipulation at some point.

"Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family." (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.

patriciaxxx (Programmer) (OP)
5 Mar 12 6:26
Here is the code with the pefix. I agree its not logical. Never the less the following is true.
If the prefix begins with a letter then the number begins 00 which is no good it must always begin 01
If the prefix begins with a number for example 3k13ab_ then the number begins 01
And of course if there is no prefix the number begins 01
Is there maybe a better way to code this.

Option Explicit

Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strLeadingZero
Dim intFileParts
Dim strFileParts
Dim strPrefix 'Optional.

    'Define file path.
    strPath = "C:\Documents and Settings\Rename Pictures for Web Use\pic\"

    'Create the instance of the FSO.
    Set FSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set FLD = FSO.GetFolder(strPath)

    'Loop through each file in the folder.
    For Each fil in FLD.Files
        'Get complete file name with path.
        strOldName = fil.Path
        'Build the new file name.
        strPrefix = "k13ab_"
        strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
        strNewName = strPath & strPrefix & strFileParts & Right(strOldName, 4) 'Right function keep file extension.
        'Use the MoveFile method to rename the file.
        FSO.MoveFile strOldName, strNewName
    Next

    'Cleanup the objects.
    Set FLD = Nothing
    Set FSO = Nothing
 
MakeItSo (Programmer)
5 Mar 12 7:17
It should not depend on the prefix at all as you are doing nothing with it save concatenating it!
3eyes
Perhaps the problem lies here:

CODE

intFileParts = intFileParts + 1

In contrast to full VB, you do not dim AS a type in VBScript, hence the type is determined when the variable is initialised. However, you are not initialising intFileParts but directly incrementing it.
I haven't come across such weird behaviour before but try by simply adding this before your loop:

CODE

intFileParts = 0
This way you are initialising the variable as a proper Integer variable. Perhaps there's the rub.
ponder

"Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family." (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.

patriciaxxx (Programmer) (OP)
5 Mar 12 9:31
I tried the setting and discovered the following.
The setting seems to have no effect.
I discovered something I had not noticed before which is that the code works and numbers begin 01 with or without the setting but only if there are around 21 files if there are more files we are back to the 00 again.
I was originally testing a folder with 71 files and this still numbers 00 with or without your setting.
I am just not good enough with vbscript to understand why this happens or how to solve it.
MakeItSo (Programmer)
5 Mar 12 10:00
Umm...lol...
Do you happen to have a... ummm... test version of your script with somewhat fixed numbers or so?
tongue

Anyway, try this: replace

CODE

strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
with this:

CODE

intFileParts = intFileParts + 1
strFileParts = Format(intFileParts, "00")

And make sure the code is not in some number-limited loop.

Cheers,
MakeItSo

"Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family." (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.

PHV (MIS)
5 Mar 12 10:05
MakeItSo (Programmer)
5 Mar 12 10:09
Ah damnit!
Sorry.

Thanks PHV.

"Knowledge is power. Information is liberating. Education is the premise of progress, in every society, in every family." (Kofi Annan)
Oppose SOPA, PIPA, ACTA; measures to curb freedom of information under whatever name whatsoever.

guitarzan (Programmer)
5 Mar 12 12:37
patriciaxxx,

Not sure what to tell you. As MakeItSo put it, "not logical". Your code works fine. I am seeing no reason why the code snippet you provided would behave any different from what you want.

For example, try the code below. The MsgBox should read "strFileParts = 01" regardless of how many files are in the folder

CODE

Option Explicit

Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strLeadingZero
Dim intFileParts
Dim strFileParts
Dim strPrefix 'Optional.

    'Define file path.
    strPath = "C:\Documents and Settings\Rename Pictures for Web Use\pic\"

    'Create the instance of the FSO.
    Set FSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set FLD = FSO.GetFolder(strPath)

    'Loop through each file in the folder.
    For Each fil in FLD.Files
        'Get complete file name with path.
        strOldName = fil.Path
        'Build the new file name.
        strPrefix = "k13ab_"
        strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
        strNewName = strPath & strPrefix & strFileParts & Right(strOldName, 4) 'Right function keep file extension.
        'Use the MoveFile method to rename the file.
        'DONT MOVE THE FILE YET
        'FSO.MoveFile strOldName, strNewName

        MsgBox "strFileParts = " & strFileParts

        Exit For

    Next

    'Cleanup the objects.
    Set FLD = Nothing
    Set FSO = Nothing
patriciaxxx (Programmer) (OP)
6 Mar 12 7:50
Yes I agree its not logical never the less if you create a folder with 70 jpegs and run the script as follows you will see what I see.

Set
strLeadingZero = "000"
strPrefix = ""
It number them correct 001 to 070

I notice if you number them correctly as above then change zeros to less amount it all goes wrong again either beginning 0 or getting file exists error. However if you increase zeros it works.

With these settings
strLeadingZero = "000"
strPrefix = "L_"
It number them wrong 000 to 069

When you add the prefix as above I notice that the files count down through all the numbers from the amount of zeros until it reaches 000. so in the above example when I refresh the folder I see the files counting down from 999 until they reach 000 which is no good becouse with lots of leading zeros the count down takes forever. Also it must begin 001 not 000.

However if you move the prefix to after the fileparts it does not count down
strFileParts & strPrefix.

This needs an expert VBScriptor to run tests to unravel these issues and come up with a script that works in all situations.
 
jges (TechnicalUser)
6 Mar 12 8:50
I don't think it is a good idea to move files into the same folder in which you are looping through the files. To see why, add a counter to report how many files get processed; the results may surprise you.

As an alternative, you may want to create a subdirectory and move your renamed files there. When the script is done renaming, it can move the files back to the main folder and delete the subdirectory you created.
guitarzan (Programmer)
6 Mar 12 10:09
Ahhhhh I think jges may have nailed it... I had not noticed that behavior before, but yes in some cases that routine seems to "move" files that were already moved... This would screw up the numbering.

As a simpler implementation of jges' idea, why not try just changing the name attribute of the file:

CODE

   strNewName = strPrefix & strFileParts & Right(strOldName, 4) 'Right function keep file extension.
   'Rename the file
   fil.Name = strNewName
guitarzan (Programmer)
6 Mar 12 10:13
On second thought, no... same issue. I'm with jges... move to subfolder with the new names, and then move back when done.
jges (TechnicalUser)
6 Mar 12 10:40
An alternative, possibly simpler approach to the subfolder idea would be to add the file names to an array in the 'for each' loop, then process the files outside of the loop using the information in the array.
patriciaxxx (Programmer) (OP)
7 Mar 12 9:10
Yes the array sounds like it maybe the solution.
Can you modify my code below to show exactly how you would achieve this for it to work.

Option Explicit

Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strLeadingZero
Dim intFileParts
Dim strFileParts
Dim strPrefix 'Optional.

    'Define file path.
    strPath = "C:\Documents and Settings\Rename Pictures for Web Use\pic\"

    'Create the instance of the FSO.
    Set FSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set FLD = FSO.GetFolder(strPath)

    'Loop through each file in the folder.
    For Each fil in FLD.Files
        'Get complete file name with path.
        strOldName = fil.Path
        'Build the new file name.
        strPrefix = "k13ab_"
        strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
        strNewName = strPath & strPrefix & strFileParts & Right(strOldName, 4) 'Right function keep file extension.
        'Use the MoveFile method to rename the file.
        FSO.MoveFile strOldName, strNewName
    Next

    'Cleanup the objects.
    Set FLD = Nothing
    Set FSO = Nothing
 
PHV (MIS)
7 Mar 12 9:16
[i]Can you modify my code below to show exactly[/i]
Can't you even try by your own ?
What have YOU tried so far and where in YOUR code are you stuck ?

Hope This Helps, PH.
FAQ219-2884: How Do I Get Great Answers To my Tek-Tips Questions?
FAQ181-2886: How can I maximize my chances of getting an answer?

patriciaxxx (Programmer) (OP)
7 Mar 12 10:07
This is my code so far PHV

Option Explicit

Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strLeadingZero
Dim intFileParts
Dim strFileParts
Dim strPrefix 'Optional.

    'Define file path.
    strPath = "C:\Documents and Settings\Rename Pictures for Web Use\pic\"

    'Create the instance of the FSO.
    Set FSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set FLD = FSO.GetFolder(strPath)

    'Loop through each file in the folder.
    For Each fil in FLD.Files
        'Get complete file name with path.
        strOldName = fil.Path
        'Build the new file name.
        strPrefix = "k13ab_"
        strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
        strNewName = strPath & strPrefix & strFileParts & Right(strOldName, 4) 'Right function keep file extension.
        'Use the MoveFile method to rename the file.
        FSO.MoveFile strOldName, strNewName
    Next

    'Cleanup the objects.
    Set FLD = Nothing
    Set FSO = Nothing

jges suggests an array would solve the problems I was asking to be shown how becouse I don't know how to do it. This is not my area and my VBS skills are at learning level. If you know what he was suggesting or how to solve the problems it will be helpful if you could post the modifycation to my existing code for me to test and learn.
jges (TechnicalUser)
7 Mar 12 11:14
Here is a version that uses a dictionary object.

CODE

Option Explicit

Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strNewName
Dim strLeadingZero
Dim intFileParts
Dim strFileParts
Dim strPrefix
strPrefix = "p12ax_"
Dim fileExt
Dim fileDic
Set fileDic = CreateObject("Scripting.Dictionary")
Dim key

    'Define file path.
    strPath = "C:\Documents and Settings\Rename Pictures for Web Use\pic\"

    'Create the instance of the FSO.
    Set FSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set FLD = FSO.GetFolder(strPath)

    'Loop through each file in the folder.
    For Each fil in FLD.Files
        'Get complete file name with path.
        fileExt = FSO.GetExtensionName(fil)
        'Build the new file name.
        strLeadingZero = "00" 'Maximum files in folder 100.
        intFileParts = intFileParts + 1
        strFileParts = strLeadingZero & CStr(intFileParts)
        strFileParts = Right(strFileParts, Len(strLeadingZero))
        strNewName = strPrefix & strFileParts & "." & fileExt
        'add new name and file object to the dictionary object
        fileDic.Add strNewName, fil
    Next
    
    'rename each file in the dictionary: key = new name, item = file object
    For Each key in fileDic
        Set fil = fileDic.Item(key)
        fil.Name = key
    Next
    
    'Cleanup the objects.
    Set FLD = Nothing
    Set FSO = Nothing
    Set fileDic = Nothing
patriciaxxx (Programmer) (OP)
8 Mar 12 8:33
Wow.
Thank you very much for your time jges.
I have studied your changes and tested in all kinds of scenarios and it works perfectly.
I would say problems have been solved. It's been great learning for me too. I never knew of the Dictionary Object much less how to implement it.

I have updated my script somewhat believing my new script to be more robust and better scripted and of course with your suggestions it is now free of those illogical annoyances.

I do have one question.
Below the line:-
Set objDict = Nothing
Do I need to add:-
'Erase the contents of the dictionary object
objDict.RemoveAll
I don't think I do because that's what "Set objDict = Nothing " is doing.

Here is my new script. I would be interested in any comments you may have.

Option Explicit

Const NUMBER_STEP = 1 'File numbering will increment by this amount.
Const NUMBER_DIGITS = 2 'Numbers will have this many digits (with leading zeros).
Const NUMBER_STRING = "F_" 'The characters that follows the leading number.

Dim objFSO, objFolder, objFiles, objDict, objKey, strPath, strFileExt, _
    strNewName, lngNumber

    'Define file path.
    strPath = "C:\pics\"
    lngNumber = 0 'Initialise the variable.

    'Create the instance of the objFSO.
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    'Set the folder you want to search.
    Set objFolder = objFSO.GetFolder(strPath)
    'Create the instance of the objDict.
    Set objDict = CreateObject("Scripting.Dictionary")

    'Loop through each file in the folder.
    For Each objFiles in objFolder.Files
        'Get the file extension.
        strFileExt = objFSO.GetExtensionName(objFiles)
        'Build the new file name.
        lngNumber = lngNumber + 1
        strNewName = NUMBER_STRING & Right(String(NUMBER_DIGITS, "0") & _
            Cstr(lngNumber), NUMBER_DIGITS) & "." & strFileExt
        'Add new name and file object to the dictionary object.
        objDict.Add strNewName, objFiles
    Next

    'Rename each file in the dictionary.
    For Each objKey in objDict
        Set objFiles = objDict.Item(objKey)
        objFiles.Name = objKey
    Next

    'Cleanup the objects.
    Set objFolder = Nothing
    Set objFSO = Nothing
    Set objDict = Nothing
 
jges (TechnicalUser)
8 Mar 12 10:48

Quote (patriciaxxx):

I do have one question.
Below the line:-
Set objDict = Nothing
Do I need to add:-
'Erase the contents of the dictionary object
objDict.RemoveAll
I don't think I do because that's what "Set objDict = Nothing " is doing.

If you want to clear out the dictionary, do it before "Set objDict = Nothing", otherwise you will likely get an error. I think "Set objDict = Nothing" is sufficient to release the memory resources, and even that may not be necessary. It is my understanding that for the VB languages (VB, VBA, VBScript), Windows keeps a reference count for each object. When the count hits zero, the memory is freed. Once the script finishes executing, all the resources it used should be freed whether you "Set objDict = Nothing" or not. I hope someone on the forum with more insight into such matters will correct me if I am wrong.

Also, I'd like to suggest one addition. Before the file is renamed, you should check to see if a file with that name already exists. I left it out of my example code for brevity and also because I don't know what you want to happen if such a file already exists.
guitarzan (Programmer)
8 Mar 12 11:37
jges: Yes, that is my understanding also. Once the object goes out of scope (the script ends, or the function/sub ends), the object is cleared anyway, so setting it to Nothing is redundant.

The only time it may be important is if you have two objects that interact with each other, and have to be cleared in a certain order, but that is very rare. This article explains it somewhat.

http://blogs.msdn.com/b/ericlippert/archive/2004/04/28/122259.aspx
patriciaxxx (Programmer) (OP)
8 Mar 12 11:38
So if I understand correctly Set objDict = Nothing not only releases the memory resources but also clears out the dictionary.

As for the if files exists I would like to include it but it just gets more complicated. Ideally if a file name already exists I wolud like the script to ignore that one and keep going with the rest.

Thank you for your continued help your input has helped me understtand vbs a little better.
patriciaxxx (Programmer) (OP)
8 Mar 12 11:43
woops my reply was as guitarzan was replying.
So my understanding now is do not need any of the following.
    Set objFolder = Nothing
    Set objFSO = Nothing
    objDict.RemoveAll
    Set objDict = Nothing
  
Helpful Member!  jges (TechnicalUser)
8 Mar 12 12:13

Quote (patriciaxxx):

Ideally if a file name already exists I would like the script to ignore that one and keep going with the rest.
Then you will need to add the check; as it stands now, the code will either:
  1. halt execution with an error condition
  2. overwrite the existing file
(I'm not 100% sure which will happen).

Quote:

Set objDict = Nothing not only releases the memory resources but also clears out the dictionary.
It's a technicality, but I wouldn't say it "clears out the dictionary". Those memory addresses simply get marked by Windows as unused. Windows can then assign those addresses to the next process that requests some memory. The next process will initialize and use that memory as it sees fit, it doesn't care if the memory is 'zeroed' out or if it has leftovers from your script.
patriciaxxx (Programmer) (OP)
9 Mar 12 6:01
Thank you for all your help and comments.
Its been a good learning curve for me.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Back To Forum

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close