使PowerShell等待Excel完成刷新数据透视表

时间:2015-02-18 11:25:19

标签: excel vba powershell

所以我开发了一个PowerShell脚本来刷新大约40个大型excel文件并保存它们,在这个脚本中我运行一个excel宏来传递excel(ODBC)连接参数,然后在刷新后从excel文件中删除它们。完成。我唯一的问题是(对于这40个文件中的5个文件)当启动RefreshAll命令时,powershell不会等待Excel完成刷新并转到下一个命令,该命令是使连接无效的宏,这会导致错误" 1004"在宏中(当文件仍在刷新时无法访问excel连接。)

经过一些研究,我知道在powershell v2中,有后台作业的概念,但在我的情况下,这不是一个旁过程,它属于Excel过程,所以我的powershell souldn&#39 ; t必须等待Excel退出才能继续执行,相反,我需要excel保持打开以继续执行powershell。

我也知道start-sleep命令对我的情况不是最好的,因为刷新结束没有时间的固定值,每个文件都有它的时间,并且每个月的每个时段都有它的时间(数据量每天都在增加,直到月末结束)

所以我的问题是:如果Excel文件刷新了数据,是否有可能进行PowerShell测试,如果是,它会继续,否则它会等待更多?

任何帮助将不胜感激,并提前感谢您。 PS:请原谅我的一年级英语:)。

2 个答案:

答案 0 :(得分:2)

Shotgun方法:

  1. Excel具有Application.Ready属性。 应该指示何时 Excel已准备好进行自动化通信,但details are unclear。尝试这样的事情:

    $Excel = New-Object -ComObject Excel.Application
    
    # Do your stuff here
    
    # Wait for Excel to became ready
    while (!$Excel.Ready)
    {
        Start-Sleep -Seconds 1
    }
    
     # Do other stuff
    
  2. QueryTable具有Refreshing属性。试试这个:

    $Excel = New-Object -ComObject Excel.Application
    $Workbook = $Excel.Workbooks.Open('C:\Path\To\Workbook\Data.xlsx')
    
    # Are any of the QueryTables refreshing?
    # Don't have Excel right now, so expression below might need some tweaking
    While (($Workbook.Sheets | ForEach-Object {$_.QueryTables | ForEach-Object {if($_.QueryTable.Refreshing){$true}}}))
    {
        Start-Sleep -Seconds 1
    }
    
  3. ODBCConnection具有Refreshing属性。请尝试:

    $Excel = New-Object -ComObject Excel.Application
    $Workbook = $Excel.Workbooks.Open('C:\Path\To\Workbook\Data.xlsx')
    
    # Is ODBCConnection refreshing?
    # Don't have Excel right now, so expression below might need some tweaking
    While ($Workbook.ODBCConnection.Refreshing)
    {
        Start-Sleep -Seconds 1
    }
    
  4. 也许这5个文件的PivotCache.BackgroundQueryODBCConnection.BackgroundQueryQueryTable.BackgroundQuery属性设置为true?

答案 1 :(得分:0)

对我来说,这个简单的代码片段成功了:

$sheet.Calculate()
$null = $sheet.QueryTables.QueryTable.Refreshing

看起来只要获取Refreshing-Attribute就足以等待刷新/计算周期的结束。