2017-06-23 5 views
0

wordで表を作成しようとしていて、処理を少しスピードアップしたい場合は、ジョブがなくてもうまく動作しますが、遅いです。私はこのスクリプトを実行すると、スクリプトがバックグラウンドジョブで作業中のCOMオブジェクト

$Table.Cell($x,<column>).Range.Text = <string>  

に取得した時点ではエラーに

You cannot call a method on a null-valued expression. 
    + CategoryInfo   : InvalidOperation: (Cell:String) [], 
    RuntimeException 
    + FullyQualifiedErrorId : InvokeMethodOnNull 

を与え、それが

$table = $doc.tables.item(1) 

に取得した時点ではエラーに

を与える以外すべてが正常に動作します
You cannot call a method on a null-valued expression. 
    + CategoryInfo   : InvalidOperation: (item:String) [], RuntimeException 
    + FullyQualifiedErrorId : InvokeMethodOnNull 

I'm guエッシンクそれは

は、ここに私のコードです...

[System.Runtime.InteropServices.Marshal]::GetActiveObject('Word.Application') 

文書の情報のすべてを取っていないとは何かを持っている

#More code above 
$owners = Import-CSV $ownerspath -header @("Owners") 
foreach($name in $owners) { 
    #Document creation 
    [ref]$SaveFormat = "microsoft.office.interop.word.WdSaveFormat" -as [type] 

    $Word = New-Object -comobject word.application 
    $Word.Visible = $false 
    $Doc = $Word.Documents.Add() 
    $Range = $Doc.Range() 

    $owner = $name.Owners 
    $g = import-csv $exportpath$owner.csv -header @("Server name", "Description", "OS", "OS EOL", "SQL", "SQL EOL") 
    $path = "$exportpath$owner.docx" 

    if(($g.count + 1) -eq 1) { 
     $rows = 2 
    } 
    else { 
     $rows = $g.count + 1 
    } 

    #Table creation 
    $Selection = $word.selection 

    $Doc.Tables.Add($Range,$Rows,6) | Out-Null 

    $Table = $Doc.Tables.item(1) 

    $Table.Style = "Medium Shading 1 - Accent 1"  
    $Table.Cell(1,1).Range.Text = "Server name" 
    $Table.Cell(1,2).Range.Text = "Server description" 
    $Table.Cell(1,3).Range.Text = "OS Version" 
    $Table.Cell(1,4).Range.Text = "OS EOL Date" 
    $Table.Cell(1,5).Range.Text = "SQL Version" 
    $Table.Cell(1,6).Range.Text = "SQL EOL Date" 

    $x = 2 
    foreach($l in $g) { 
     $sn = $l.'Server name' 
     $d = $l.Description 
     $oper = $l.OS 
     $opereol = $l.'OS EOL' 
     $sequel = $l.SQL 
     $sequeleol = $l.'SQL EOL' 
     $scriptblock = { 
      param($sn, $d, $oper, $opereol, $sequel, $sequeleol, $x) 
      $word = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Word.Application') 
      $doc = $word.documents 
      $table = $doc.tables.item(1) 
      #Server names, OS, OS EOL, SQL, SQL EOL, and coloring for the EOL dates if the need them are added in this foreach loop. 
      $Table.Cell($x,1).Range.Text = $sn 
      $Table.Cell($x,2).Range.Text = $d 
      $Table.Cell($x,3).Range.Text = $oper 
      if($l.'OS EOL' -eq 'Out of date') { 
       $Table.Cell($x,4).Range.shading.BackgroundPatternColor = 255 
       $Table.Cell($x,4).Range.Text = $opereol 
       $OoDTotal += 1 
      } 
      elseif($l.'OS EOL' -like "*!*") { 
       $Table.Cell($x,4).Range.shading.BackgroundPatternColor = 65535 
       $Table.Cell($x,4).Range.Text = $opereol 
       $CloseTotal += 1 
      } 
      else { 
       $Table.Cell($x,4).Range.Text = $opereol 
       $UtDTotal += 1 
      } 
      $Table.Cell($x,5).Range.Text = $sequel 
      if($l.'SQL EOL' -eq 'Out of date') { 
       $Table.Cell($x,6).Range.shading.BackgroundPatternColor = 255 
       $Table.Cell($x,6).Range.Text = $sequeleol 
       $OoDTotal += 1 
      } 
      elseif($l.'SQL EOL' -like "*!*") { 
       $Table.Cell($x,6).Range.shading.BackgroundPatternColor = 65535 
       $Table.Cell($x,6).Range.Text = $sequeleol 
       $CloseTotal += 1 
      } 
      else { 
       $Table.Cell($x,6).Range.Text = $sequeleol 
       $UtDTotal += 1 
      } 
     } 
     Start-Job $scriptblock -ArgumentList $sn, $d, $oper, $opereol, $sequel, $sequeleol, $x 
     $x++ 
    } 
    while(get-job -state "Running") { 
     start-sleep -seconds 1 
    } 
    Get-Job | Receive-Job 
    Get-Job | Remove-Job 

#More code below 

編集:私はオフィスでポッシュV2にこのスクリプトを実行していますWord 2007

答えて

0

これはスコープ上の問題です。必要なすべてのオブジェクト(たとえば、少なくとも最も具体的には、Word COMオブジェクト)をスクリプトブロックに渡すわけではありません。 PowerShellジョブは、実際には完全に別々のPowerShellプロセスのインスタンスを作成します。先に行くとチェック:

Start-Job -ScriptBlock { start-sleep -Seconds 20 } 
Start-Job -ScriptBlock { start-sleep -Seconds 20 } 

PS C:\Users\hiyo!> Get-Process powershell 

Handles NPM(K) PM(K)  WS(K) VM(M) CPU(s)  Id SI ProcessName                         
------- ------ -----  ----- ----- ------  -- -- -----------                         
    388  22 40336  48820 ...54  0.45 2720 1 powershell                         
    443  25 54360  66860 ...75  0.58 7240 1 powershell 

そして、あなたが実際に仕事にあなたが望むように、これを試してみると、すべての右のparamsに渡す場合、あなたはのためのファイルの複数のインスタンスを開こうとすると、書き込みロックの問題に遭遇するかもしれませんR/W ...

関連する問題