Jsen Fruge
Jsen Fruge

Reputation: 579

How to recursively rename files in subfolders using VBScript

I wrote this script to organize my video library. To keep consistent naming standards, I want a method to rename files in subfolders. The problem with the code below is that when I set fso = Nothing at the end, it breaks the FileSystemObject, and I cannot figure out a way to recall it with the standard For Each Next statement. In the meantime, I've turned it off, but if I step through all of the folders to rename, the appending numbers continue to ascend with each file regardless of folder. Ideally, this is the result I'm looking for:

(Let's use a TV Show as example) Folder: Breaking Bad Subfolder: Season 1 Files: Breaking S01E01, Breaking S01E02, Breaking S01E03 Subfolder: Season 2 Files: Breaking S02E01, Breaking S02E02, Breaking S02E03

Current results: Folder: Breaking Bad Subfolder: Season 1 Files: Breaking S01E01, Breaking S01E02, Breaking S01E03 Subfolder: Season 2 Files: Breaking S02E04, Breaking S02E05, Breaking S02E06

Note: I set up logging, so you can ignore all AddLog lines.

Option Explicit

Dim fso, oFolder, oFile, iCount, strSeries, strSeason, folder, fsoSubFolders, msg, objLogFile, strLogFile, sMsg
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFolder = fso.GetFolder(fso.GetAbsolutePathName("."))
Set fsoSubFolders = oFolder.SubFolders
strLogFile = oFolder & "\" & "Rename.log"
iCount = 0

CreateLogFile
AddLog(sMsg)

'CREATE LOG FILE ROUTINE
Sub CreateLogFile()
    Set objLogFile = Nothing
    If fso.FileExists(strLogFile) Then
        Set objLogFile = fso.GetFile(strLogFile)
        Set objLogFile = fso.OpenTextFile(strLogFile, 8, True)
        AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
        AddLog "|||||||||||||||||||||||||||||||||||||||||| NEW LOG FILE EVENT STARTED |||||||||||||||||||||||||||||||||||||||||||"
        AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
        AddLog "Preparing log file."
        AddLog "Log File found."
        AddLog "Appending to existing Log File: " & strLogFile
    Else
        Set objLogFile = fso.CreateTextFile(strLogFile)
        objLogFile.Close
        Set objLogFile = fso.OpenTextFile(strLogFile, 2, True)
        AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
        AddLog "|||||||||||||||||||||||||||||||||||||||||| NEW LOG FILE EVENT STARTED |||||||||||||||||||||||||||||||||||||||||||"
        AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
        AddLog "Preparing log file."
        AddLog "Log File found not."
        AddLog "Creating new Log File: " & strLogFile
    End If
End Sub

'APPEND TO LOG ROUTINE
Sub AddLog(sMsg)
    If Not ObjLogFile Is Nothing Then
        If sMsg = "" Then
            objLogFile.WriteLine(sMsg)
        Else
            objLogFile.WriteLine( Date & " - " & Time & ": " & "|" & sMsg)
        End If
    End If
End Sub

'SEARCH SUBFOLDERS
AddLog "||||||||||||||||||||||||||||||||||||||||||||||||| START SCRIPT ||||||||||||||||||||||||||||||||||||||||||||||||||"
For Each folder in fsoSubFolders
    AddLog " "
    AddLog "Working folder: " & folder
    msg = MsgBox("CAUTION!" & vbCrLf & vbCrLf & _
    "You are about to rename files in folder: " & folder.Name & ". " & _
    "Do you want to continue?", vbYesNo, "Renaming Service")
    If msg = vbYes Then
        GetSeries
    Else
        AddLog "Skipping folder: " & folder
    End If
Next

'GET SERIES NAME
Sub GetSeries()
    strSeries = InputBox("ENTER SERIES NAME:" & vbCrlf & "(e.g.: Breaking Bad, The Walking Dead, Firefly, etc)", "Rename Series")
    If strSeries = "" Then
        AddLog "Exiting script before complete."
        QuitApp()
    ElseIf IsBlank(strSeries) = True Then
        AddLog "ERROR: No value entered, restarting."
        MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field cannot be blank. Try again."
        GetSeries
    ElseIf IsNumeric(strSeries) Then
        AddLog "ERROR: Value cannot be numeric, restarting."
        MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field does not support numeric values. Try again."
        GetSeries
    Else
        AddLog "Series Title Set: " & strSeries
        GetSeason
    End If
End Sub

'GET SEASON NAME
Sub GetSeason()
    strSeason = InputBox ("ENTER SEASON:" & vbCrlf & "(e.g.: 01, 02, 03, etc)", "Rename Season")
    If strSeason = "" Then
        AddLog "Exiting script before complete."
        QuitApp()
    ElseIf IsBlank(strSeason) = True Then
        AddLog "ERROR: No value entered, restarting."
        MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field cannot be blank. Try again."
        GetSeries
    ElseIf Not IsNumeric(strSeason) Then
        AddLog "ERROR: Value cannot be non-numeric, restarting."
        MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field does not support non-numeric values. Try again."
        GetSeason
    Else
        AddLog "Season Title Set: " & strSeason
        AddLog "================================================================================================================="
        Rename
    End If
End Sub

'CHECK FOR BLANK VALUES
Function IsBlank(Value)
    If IsEmpty(Value) or IsNull(Value) Then
        IsBlank = True
    ElseIf IsObject(Value) Then
        If Value Is Nothing Then
            IsBlank = True
        End If
    Else
        IsBlank = False
    End If
End Function

'RENAME FILES
Sub Rename()
    For Each oFile In folder.Files
        iCount = iCount + 1
        If oFile.Name <> "Rename.vbs" Then
        AddLog "Old file name: " & oFile.Name
            If iCount = 1 Or iCount = 2 Or iCount = 3 Or iCount = 4 Or iCount = 5 Or iCount = 6 Or iCount = 7 Or iCount = 8 Or iCount = 9 Then
                oFile.Name = strSeries & " S" & strSeason & "E0" & iCount & "." & fso.GetExtensionName(oFile.Name)
                AddLog "New file name: " & oFile.Name
            Else
                oFile.Name = strSeries & " S" & strSeason & "E" & iCount & "." & fso.GetExtensionName(oFile.Name)
                AddLog "New file name: " & oFile.Name
            End If
    End If
    Next
    Set oFile = Nothing
    Set folder = Nothing
    'Set fso = Nothing
End Sub

'PREMATURE QUIT
Sub QuitApp()
    AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||| END SCRIPT |||||||||||||||||||||||||||||||||||||||||||||||||||"
    WScript.Quit()
End Sub

Upvotes: 1

Views: 1546

Answers (1)

Syberdoor
Syberdoor

Reputation: 2619

The file system object is needed for each access to your disk. Because of that you cannot set it to nothing as long as you still need to handle files. So in your case you can only set it to nothing at the end.

The reason why the numbering is wrong is a different one however. Icount is a global variable and only set to 0 at the beginning of the script. As within each season folder the episodes start at 1 again you also have to reset the icount whenever you enter one of these folders. Set it to 0 at the first line of the rename function (before the for) and it should work.

One thing to keep in mind is that the folder.files will give you the current list of episodes sorted alphabetically. So your renaming will only work if the episodes are named in a format so they are in the right order when sorted alphabetically.

Upvotes: 0

Related Questions