当.visible = $ false

时间:2015-06-08 20:03:03

标签: excel powershell com

我已经有这个问题已经有很长一段时间了,并且因为懒惰而忽略了它,但我现在需要找到解决方案。我有一个脚本可以自动刷新大量的Excel文档。这很好用,但是,如果我将Visible属性设置为false,则存储在网络共享上的工作簿上会失败。

重申一下,将visible属性设置为false的刷新在LOCAL文件上工作正常,但保存在\ _位置的任何工作簿都会失败,并显示错误“调用被被调用者拒绝”。所有刷新工作正常,可见属性设置为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);

我尝试了以下内容:

  1. 在创建excel对象和设置可见属性之间添加Start-Sleep 30
  2. 在DisplayAlerts
  3. 之前设置可见
  4. 真的很难让它工作
  5. 有什么想法吗?

2 个答案:

答案 0 :(得分:3)

It seems that RefreshAll() doesn't wait for the refresh to actually succeed in the background with Visible = $False set.

Introduce an artificial delay between RefreshAll() and Save(), like so:

$excelworkbook.RefreshAll();
Start-Sleep -Seconds 30
$excelworkbook.Save();

Alternatively, you might be able to force the RefreshAll() to execute synchronously by setting BackgroundQuery = $False on all query tables in your workbook, as suggested in this answer to a similar question:

foreach ($Sheet in $excelworkbook.Worksheets) {
    foreach ($QTable in $Sheet.QueryTables) {
        $QTable.BackgroundQuery = $false
    }
}

答案 1 :(得分:1)

我会添加一个volatile块:

DoEvents

这将允许队列循环通过你告诉Excel做的任何事情&然后回到脚本执行。另一件事是设置[System.Windows.Forms.Application]::DoEvents() 以便Excel不简单隐藏,但显然不符合用户响应事件的能力。

最后,在设置其他属性后可能会有一些关于设置UserControl = false的事情 - 可能是Excel通过切换其他一些事情来响应Visible事件(不记得副手) ,但是我脑子里的东西说是这种情况,或曾经是这样的。