Search code examples
excelpowershellrenameworksheet

Rename multiple worksheet and multiple files with powershell


Sorry for my bad english I'm French.

I'm new at Powershell and I wanted to rename all of my worksheet in multiple files. So far i got that code that rename all files in a directory

    Function Rename()
{
$path = Get-Location
$files = Get-ChildItem
$counter = 1

foreach($file in $files)
    {
       Rename-Item $file.FullName "$counter" + ".xlsx"
       $counter++
    }
}

Then I tried on a specific file to rename all of the sheets that are inside but it doesn't work. The loop works only one time while it has 4 worksheets.

Function RenameTab ($ExcelFileName)
{
#Emplacement du fichier
$excelFile = "C:\Users\Donosaure\Documents\Magister\" + $excelFileName + ".xlsx"

#Ouverture d'excel
$xldoc =  New-Object -ComObject "Excel.Application"

#Message de confirmation
$xldoc.Visible = $false
$xldoc.DisplayAlerts = $false

#Ouverture du fichier
$workbook = $xldoc.Workbooks.Open($excelFile)
$inc = 1
$i=1
foreach ($worksheet in $workbook.Worksheets.count)
{
    $worksheet = $workbook.Sheets.Item($i)
    $worksheet.Name = $inc
    $inc++
    $i++

    $workbook.SaveAs("C:\Users\Donosaure\Documents\Magister\1.xlsx")
    $workbook.Close()
}
$xldoc.Quit()
}

RenameTab("Magister")

Can somebody help me ?

Thanks for your time


Solution

  • A few remarks about your code:

    • Parameters sent to a function in PowerShell are separated by space, you should not use brackets around them as in RenameTab("Magister")
    • When using COM objects, always make sure you release them from memory when done, otherwise they will linger in memory and if you run this again and again, you will run out of resources otherwise
    • Please check for Excel Worksheets Naming Convention, so you do not create worksheet names with invalid characters. At the moment, that is not the case, but you never know how this evolves.
    • Please use the PowerShell function 'Verb-Noun' naming convention for functions you create.

    Below should do what you want:

    Function Rename-ExcelTabs ($ExcelFileName) {
        #Emplacement du fichier
        $excelFile = "C:\Users\Donosaure\Documents\Magister\" + $excelFileName + ".xlsx"
    
        #Ouverture d'excel
        $xldoc =  New-Object -ComObject "Excel.Application"
    
        #Message de confirmation
        $xldoc.Visible = $false
        $xldoc.DisplayAlerts = $false
    
        #Ouverture du fichier
        $workbook = $xldoc.Workbooks.Open($excelFile)
        for ($i = 1; $i -le $workbook.Worksheets.Count; $i++) {
            $workbook.Sheets.Item($i).Name = $i
        }
        $workbook.SaveAs("C:\Users\Donosaure\Documents\Magister\" + $excelFileName + "_1.xlsx")
        $workbook.Close()
        $xldoc.Quit()
    
        # clean-up used COM objects
        $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
        $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xldoc)
        [System.GC]::Collect()
        [System.GC]::WaitForPendingFinalizers()
    }
    
    Rename-ExcelTabs "Magister"
    

    As per your comment, the function could be rewritten to not only change the tab names in one Excel file, but process all .xlsx files inside a folder and rename these files aswell.

    One way would be do remove the original file after the tabs have been renamed and a new file is created with $workbook.SaveAs(), as in the code above.

    The following function does this by renaming the file first and next change the tab names in it.

    function Rename-ExcelTabsAndFiles {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [ValidateScript({Test-Path -Path $_ -PathType Container})]
            [Alias('Path')]
            [string]$SourceFolder
        )
        # get a list of xlsx files
        $allFiles = Get-ChildItem -Path $SourceFolder -Filter '*.xlsx' -File
    
        # create an Excel object
        $xldoc = New-Object -ComObject Excel.Application
    
        # Message de confirmation
        $xldoc.Visible = $false
        $xldoc.DisplayAlerts = $false
    
        $fileCount = 1
        foreach ($excelFile in $allFiles) {
            # rename the file. use -PassThru to get the FileInfo object of the renamed file
            # apparently you want the files to be called '1.xlsx', '2.xlsx' etc.
            $newName = '{0}.xlsx' -f $fileCount++
            Write-Host "Renaming file '$($excelFile.Name)' to '$newName'"
            $excelFile = Rename-Item -Path $excelFile.FullName -NewName $newName -PassThru
    
            # Ouverture du fichier
            $workbook = $xldoc.Workbooks.Open($excelFile.FullName)
            # rename all worksheets in the file
            Write-Host "Renaming all worksheets in '$newName'"
            for ($i = 1; $i -le $workbook.Worksheets.Count; $i++) {
                $workbook.Sheets.Item($i).Name = $i
            }
            $workbook.Save()
            $workbook.Close()
        }
    
        $xldoc.Quit()
    
        # clean-up used COM objects
        $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
        $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xldoc)
        [System.GC]::Collect()
        [System.GC]::WaitForPendingFinalizers()
    }
    
    Rename-ExcelTabsAndFiles "C:\Users\Donosaure\Documents\Magister"