简体   繁体   中英

Run a macro on multiple worksheets in a workbook via powershell

I am using the following Powershell script to run some macro's on worksheets within a workbook. What I want to do is open a workbook, run a certain macro on specific worksheets, and save the workbook to a different location. For testing purposes, I am just running it on all the worksheets.

Here is what I have so far:

$excel = New-Object -ComObject excel.application
$xlfileformat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbook
$workbook = $excel.Workbooks.Open($(join-path -path R:\TestOutput\Nick -childpath tmp.xlsm))
$worksheets = $Workbook.Worksheets | ForEach-Object {$_.name}
ForEach ($Worksheet in $Worksheets) {
    $WS = $Workbook.Worksheets.Item($Worksheet)
    $excel.Run("RunMacro")
    $workbook.save()
} #End ForEach
$workbook.saveas($(join-path -path "R:\TestOutput\Nick" -childpath "Test_Output-post"), $xlfileformat)
$excel.quit()

With this script I would expect the macro to run on all the worksheets within the workbook, however, only the last worksheet has the macro applied to it. At first I didn't have the $workbook.save() in there. I added it because I though it was reinitialize the workbook every time it loaded a new worksheet, therefor losing the changes from the last run. This didn't fix the issue though.

I know I could modify the VBA script itself, but I want to eventually turn this into a function with the macro and worksheet(s) as variable inputs.

As I was typing this out, I found the answer. The problem was, I never activated the worksheet I selected. The following code fixed the problem:

$excel = New-Object -ComObject excel.application
$excel.DisplayAlerts = $false
$xlfileformat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbook
$workbook = $excel.Workbooks.Open($(join-path -path R:\TestOutput\Nick -childpath tmp.xlsm))
$worksheets = $Workbook.Worksheets | ForEach-Object {$_.name}
ForEach ($Worksheet in $Worksheets) {
    $WS = $Workbook.Worksheets.Item($Worksheet)
    $WS.Activate()
    $excel.Run("RunMacro")
} #End ForEach
$workbook.saveas($(join-path -path "R:\TestOutput\Nick" -childpath "Test_Output-post"), $xlfileformat)
$excel.quit()

The fix was adding the $WS.Activate() command in the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM