2015-06-08 8 views
8

ich jetzt dieses Problem für eine lange Zeit hatte und hatte es nur aus Faulheit ignoriert, aber ich brauche jetzt eine Lösung zu finden. Ich habe ein Skript, das das Aktualisieren einer großen Anzahl von Excel-Dokumenten automatisiert. Das funktioniert gut und gut, aber es schlägt fehl, wenn ich die Visible-Eigenschaft auf falsch auf Arbeitsmappe haben, die auf einer Netzwerkfreigabe gespeichert werden.

Um es noch einmal zu wiederholen, funktioniert die Aktualisierung mit der auf false gesetzten Eigenschaft visible auf LOCAL-Dateien, aber jede Arbeitsmappe, die an einem Speicherort gespeichert wurde, schlägt mit dem Fehler "Aufruf wurde von Aufrufer abgelehnt" fehl. Alle Aktualisierungen funktionieren einwandfrei, wenn die Eigenschaft visible auf true festgelegt ist.

Hier ist mein Code:

  1. Hinzufügen von Start-Sleep 30 zwischen der Erstellung der Excel-Objekt und die Einstellung der Eigenschaft visible
  2. Einstellung sichtbar vor Displayalerts:

    #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); 
    

    ich folgendes versucht haben,

  3. Wishing wirklich hart für es einfach zu arbeiten

Irgendwelche Ideen?

+0

Sie sagen, dass es für eine große Anzahl von Dateien der Fall ist, haben Sie für jede Datei ein neues Excel-COM-Objekt erstellen? Oder öffnen Sie Excel, und dann die Schleife durch die Dateien mit einem Öffnen/Refresh/Datei schließt Zyklus vor Excel Verlassen und Freigeben des COM-Objekts? – TheMadTechnician

+0

Ich erstelle es, mache meine Schleife, dann schließe es. Das Beispiel, das ich gab, wird ohne die Schleife kondensiert. Das ganze Skript ist ziemlich lang. – Ethan

+0

Benötigt Excel Anmeldeinformationen für den Zugriff auf den Netzwerkspeicherort? Erscheint eine Anmeldeinformationen-Eingabeaufforderung, wenn "Sichtbar" wahr ist? – acelent

Antwort

2

Es scheint, dass RefreshAll() nicht auf die Aktualisierung warten, um im Hintergrund mit Visible = $False tatsächlich erfolgreich zu sein.

Einführung eine künstliche Verzögerung zwischen RefreshAll() und Save(), etwa so:

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

Alternativ können Sie in der Lage sein, die RefreshAll() zu zwingen synchron BackgroundQuery = $False auf allen Abfragetabellen in Ihrer Arbeitsmappe, indem Sie ausführen, as suggested in this answer auf eine ähnliche Frage:

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

ichhinzufügen würdeBlock:

[System.Windows.Forms.Application]::DoEvents() 

Diese in die Warteschlange, um durch alles erlauben Sie Excel haben gesagt & dann zurück in die Skriptausführung zu tun. Eine andere Sache wäre, UserControl = false zu setzen, so dass Excel nicht einfach versteckt ist, aber ist eindeutig außerhalb der Fähigkeit des Benutzers, auf Ereignisse zu reagieren.

Schließlich gibt es möglicherweise etwas über die Einstellung Visible, nachdem Sie andere Eigenschaften festgelegt haben - es kann der Fall sein, dass Excel reagiert auf das sichtbare Ereignis durch Umschalten ein paar andere Dinge (erinnere mich nicht aus der Hand, aber etwas in meinem Hinterkopf sagt, das ist der Fall oder war es früher).