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

gbe*_*ven 1 excel powershell

我已经四处寻找解决方案,但没有看到任何仅适用于 PowerShell 的解决方案。我见过一些PowerShell/VBA 解决方案,但没有说单独使用 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()
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

我当然可以Start-Sleep在循环中使用 cmdlet 使用静态时间间隔等待数据库连接完成,但是,执行的存储过程的时间范围为 2 秒到 3 分钟,每次刷新时休眠似乎浪费资源像那样。

我上面链接的 Stack Overflow 答案列出了 3 种可能的解决方案,但我没有看到 PowerShell 对象中列出的可用属性(例如,使用 PowerShell 时不存在 QueryTable.Refreshing)。尽管代码示例是使用 PowerShell 编写的,但它们似乎可以在 VBA 中使用。这些例子是错误的还是我在这里遗漏了一些东西?

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

gbe*_*ven 5

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

$conn = $Workbook.Connections
Run Code Online (Sandbox Code Playgroud)

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

属性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()
Run Code Online (Sandbox Code Playgroud)