使用PowerShell并行打开多个Excel工作簿

问题描述 投票:0回答:1

我有一个脚本,可以在单个 Excel 实例中打开一组 Excel 工作簿并更新连接和数据透视缓存。最终用户报告说,他们通常并行打开所有工作簿并刷新连接(而不是像脚本那样“串行”)。看起来使用 PowerShell 并行处理是可能的,但到目前为止我无法使用脚本块和

Start-Job
方法打开 Excel 工作簿。所发生的只是 Excel 实例启动并且作业永远运行而没有完成,并且没有打开工作簿。

迄今为止最大的努力:

$filePath = "C:\testpath"

#Array: FileName, SaveAs
$files = @()
$files += , @("tst1.xlsx", $false)
$files += , @("tst2.xlsx", $false)

Write-output "$(Get-Date -Format yyyy-MM-dd.hh:mm:ss): Starting loop"
$x1 = New-Object -ComObject "Excel.Application"
$x1.Visible = $true

ForEach($file in $files) {
    
    # Define what each job does
    $ScriptBlock = {

        param([Object[]]$x1,
              [string]$filePath,
              [array]$file) 

        $wb = $x1.workbooks.Open("$filePath\$($file[0])")
            
        ForEach ($cache in $wb.PivotCaches()) {
            #Refresh this cache
            $cache.Refresh()
        }
    }
        
    # Execute the jobs in parallel
    Start-Job $ScriptBlock -ArgumentList $x1, 
                                         $filePath,
                                         $file
}

Get-Job
 
# Wait for it all to complete
While (Get-Job -State "Running") {
    # Pause for 10 seconds
    Start-Sleep 10
}
 
# Getting the information back from the jobs
Get-Job | Receive-Job

Write-output "$(Get-Date -Format yyyy-MM-dd.hh:mm:ss):Loop complete"

所有这些都可以在没有并行处理的情况下正常工作:

$filePath = "C:\testpath"

#Array: FileName, SaveAs
$files = @()
$files += , @("tst1.xlsx", $false)
$files += , @("tst2.xlsx", $false)

Write-output "$(Get-Date -Format yyyy-MM-dd.hh:mm:ss): Starting loop"
$x1 = New-Object -ComObject "Excel.Application"
$x1.Visible = $true

ForEach($file in $files) {
    
    $wb = $x1.workbooks.Open("$filePath\$($file[0])")
            
    ForEach ($cache in $wb.PivotCaches()) {
        #Refresh this cache
        $cache.Refresh()
    }
}

有关如何让 Excel 在脚本块中启动工作簿的线索?我在

$wb = $x1.workbooks.Open("$filePath\$($file[0])")
上添加了代码中断,代码不会停止,它只是永远运行。这是返回的输出:

身份证 姓名 PS作业类型名称 状态 有更多数据 地点 命令
1 工作1 后台作业 跑步 正确 本地主机 ...
3 工作3 后台作业 跑步 正确 本地主机 ...
1 工作1 后台作业 跑步 正确 本地主机 ...
3 工作3 后台作业 跑步 正确 本地主机 ...
excel powershell parallel-processing comobject
1个回答
0
投票

我希望这就是您所寻找的:

#Define the Filepath
$filePath = "C:\testpath\"

#Define the Files
$files = @("tst1.xlsx", "tst2.xlsx")

#Clear the workbootPaths Array
$workbookPaths = @()

foreach ($file in $files) {
    #Create an PSobject that hold the filepath and the state (state is alway $false)
    $wbary = New-Object -TypeName psobject -Property @{
        Filepath = $filepath + $file
        State    = $false
    }
    #Add the PSObject to the $workbookpaths array
    $workbookPaths += $wbary
}

# Define the Job
$scriptBlock = {
    param(
        [string]$filePath,
        [string]$workbookPath
    )

    $x1 = New-Object -ComObject Excel.Application
    $x1.Visible = $true

    $wb = $x1.Workbooks.Open($workbookPath)

    foreach ($cache in $wb.PivotCaches()) {
        $cache.Refresh()
    }
}

Write-output "$(Get-Date -Format yyyy-MM-dd.hh:mm:ss): Starting loop"

#Than start the job for each file
ForEach ($file in $workbookPaths) {        
    Start-Job -ScriptBlock $scriptBlock -ArgumentList $filePath, $file.Filepath
}

Get-Job

# Wait for it all to complete
While (Get-Job -State "Running") {
    # Pause for 1 seconds
    Start-Sleep 1
}
 
# Getting the information back from the jobs
Get-Job | Receive-Job

Write-output "$(Get-Date -Format yyyy-MM-dd.hh:mm:ss): Loop complete"
© www.soinside.com 2019 - 2024. All rights reserved.