等待刷新在Excel工作簿中每个工作表中的外部数据连接,然后再使用PowerShell保存/关闭

时间:2018-09-21 14:27:28

标签: excel powershell

我已经到处寻找了很多解决方案,没有看到任何仅PowerShell解决方案。我见过一些PowerShell/VBA solutions,但没有什么可以说不能仅使用PowerShell来完成。如果可能的话,我宁愿不使用VBA,仅限PowerShell。

我有一些工作簿,其中有多张工作表,当前需要手动刷新这些工作簿以从SQL Server(2008 R2)数据库实例检索数据。如果我逐行运行并等待刷新操作完成,我可以使用以下代码来完成我需要做的所有事情:

$Excel = New-Object -ComObject Excel.Application
$Workbook = $Excel.Workbooks.Open('C:\test.xlsx')
$Excel.Visible = $True
$Workbook.RefreshAll()
$workbook.Save()
$Workbook.Close()
$Excel.Quit()

唯一的问题是,当我按预期方式运行整个脚本时,Save()方法将在刷新操作仍在运行时执行,从而导致此提示,从而中断Save()Close() ,和Quit()方法:

enter image description here

我当然可以在循环中使用Start-Sleep cmdlet以静态间隔等待数据库连接完成,但是,执行的存储过程的范围为2秒-3分钟,看起来像一个每次这样的刷新都会浪费资源。

我上面链接的“堆栈溢出”答案列出了3种可能的解决方案,但是我看不到PowerShell对象中列出的那些可用属性(例如,使用PowerShell不存在QueryTable.Refreshing)。尽管代码示例是使用PowerShell编写的,但它们似乎在VBA中可用。例子是错误的还是我在这里错过了什么?

我的问题:是否可以通过仅使用PowerShell使用某种“ Excel刷新/忙碌”属性在RefreshAll()之后和Save()之前添加动态的“等待”操作来完成上述代码? ?

1 个答案:

答案 0 :(得分:0)

我能够通过添加以下代码来解决这个问题:

$conn = $Workbook.Connections

while($conn | ForEach-Object {if($_.OLEDBConnection.Refreshing){$true}}){
    Start-Sleep -Seconds 1
}

Refreshing属性位于OLEDBConnection对象中。

最终代码:

$Excel = New-Object -ComObject Excel.Application
$Workbook = $Excel.Workbooks.Open('C:\test.xlsx')
$Excel.Visible = $True
$conn = $Workbook.Connections
$Workbook.RefreshAll()
while($conn | ForEach-Object {if($_.OLEDBConnection.Refreshing){$true}}){
    Start-Sleep -Seconds 1
}
$workbook.Save()
$Workbook.Close()
$Excel.Quit()