当 .visible=$false 时,Powershell excel 刷新失败并显示 "Call Was Rejected by Callee"
Powershell excel refresh fails with "Call Was Rejected by Callee" when .visible=$false
这个问题我已经有很长时间了,只是因为懒惰而忽略了它,但是我现在需要找到一个解决方案。我有一个脚本可以自动刷新大量 excel 文档。这很好用,但是,如果我在存储在网络共享上的工作簿上将 Visible 属性 设置为 false,它就会失败。
重申一下,将可见 属性 设置为 false 的刷新在 LOCAL 文件上工作正常,但保存在 \ 位置的任何工作簿都会失败并出现错误 "Call was rejected by callee"。所有刷新都可以正常工作,可见 属性 设置为 true。
这是我的代码:
#Create Excel COM object and set it up for use.
$excel = new-object -comobject Excel.Application;
$excel.DisplayAlerts = $false;
#If this is set to false, saving the file on a network share will fail. Reason : Unknown.
$excel.Visible = $true;
#Open workbook which should be refreshed.
$excelworkbook = $excel.workbooks.Open($workbook);
#Refresh WB
$excelworkbook.RefreshAll();
#Save
$excelworkbook.Save();
#Quit Excel
$excel.Quit();
#Destroy COM object. (VERY IMPORTANT!!!!!)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel);
我尝试了以下方法:
- 在创建 excel 对象和设置可见 属性
之间添加 Start-Sleep 30
- 在 DisplayAlerts 之前设置可见
- 真希望它能正常工作
有什么想法吗?
似乎 RefreshAll()
并没有等待刷新在后台真正成功并设置了 Visible = $False
。
在 RefreshAll()
和 Save()
之间引入人为延迟,如下所示:
$excelworkbook.RefreshAll();
Start-Sleep -Seconds 30
$excelworkbook.Save();
或者,您可以通过在工作簿中的所有查询表上设置 BackgroundQuery = $False
来强制 RefreshAll()
同步执行,as suggested in this answer 类似的问题:
foreach ($Sheet in $excelworkbook.Worksheets) {
foreach ($QTable in $Sheet.QueryTables) {
$QTable.BackgroundQuery = $false
}
}
我要添加一个 DoEvents
块:
[System.Windows.Forms.Application]::DoEvents()
这将允许队列循环执行您告诉 Excel 执行的任何操作,然后返回到脚本执行。另一件事是设置 UserControl = false
以便 Excel 不是 简单地 隐藏,而是显然超出了用户响应事件的能力。
最后,在您设置了其他属性之后可能需要设置 Visible
- 可能 Excel 通过切换其他一些东西来响应 Visible 事件(不要不记得了,但我脑子里的某些东西说是这种情况,或者曾经是)。
这个问题我已经有很长时间了,只是因为懒惰而忽略了它,但是我现在需要找到一个解决方案。我有一个脚本可以自动刷新大量 excel 文档。这很好用,但是,如果我在存储在网络共享上的工作簿上将 Visible 属性 设置为 false,它就会失败。
重申一下,将可见 属性 设置为 false 的刷新在 LOCAL 文件上工作正常,但保存在 \ 位置的任何工作簿都会失败并出现错误 "Call was rejected by callee"。所有刷新都可以正常工作,可见 属性 设置为 true。
这是我的代码:
#Create Excel COM object and set it up for use.
$excel = new-object -comobject Excel.Application;
$excel.DisplayAlerts = $false;
#If this is set to false, saving the file on a network share will fail. Reason : Unknown.
$excel.Visible = $true;
#Open workbook which should be refreshed.
$excelworkbook = $excel.workbooks.Open($workbook);
#Refresh WB
$excelworkbook.RefreshAll();
#Save
$excelworkbook.Save();
#Quit Excel
$excel.Quit();
#Destroy COM object. (VERY IMPORTANT!!!!!)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel);
我尝试了以下方法:
- 在创建 excel 对象和设置可见 属性 之间添加 Start-Sleep 30
- 在 DisplayAlerts 之前设置可见
- 真希望它能正常工作
有什么想法吗?
似乎 RefreshAll()
并没有等待刷新在后台真正成功并设置了 Visible = $False
。
在 RefreshAll()
和 Save()
之间引入人为延迟,如下所示:
$excelworkbook.RefreshAll();
Start-Sleep -Seconds 30
$excelworkbook.Save();
或者,您可以通过在工作簿中的所有查询表上设置 BackgroundQuery = $False
来强制 RefreshAll()
同步执行,as suggested in this answer 类似的问题:
foreach ($Sheet in $excelworkbook.Worksheets) {
foreach ($QTable in $Sheet.QueryTables) {
$QTable.BackgroundQuery = $false
}
}
我要添加一个 DoEvents
块:
[System.Windows.Forms.Application]::DoEvents()
这将允许队列循环执行您告诉 Excel 执行的任何操作,然后返回到脚本执行。另一件事是设置 UserControl = false
以便 Excel 不是 简单地 隐藏,而是显然超出了用户响应事件的能力。
最后,在您设置了其他属性之后可能需要设置 Visible
- 可能 Excel 通过切换其他一些东西来响应 Visible 事件(不要不记得了,但我脑子里的某些东西说是这种情况,或者曾经是)。