2010年6月14日月曜日

◆Excelサンプル

Excelへ書き込むサンプル。
Get-Processの結果をシートに設定してみる。

$excel = New-Object -Com Excel.Application
$excelBook = $excel.Workbooks.Add()
$excelSheet = $excelBook.WorkSheets.Item(1)
$excelCells = $excelSheet.Cells
Get-Process | %{$i = 1}{
    $excelCells.Item($i,1) = $_.Id
    $excelCells.Item($i,2) = $_.ProcessName
    $i++
}
$xlOpenXMLWorkbook = 51 #Excel2007形式
$OutputPath = "D:\test.xlsx"
$excelBook.SaveAs($OutputPath,$xlOpenXMLWorkbook)
$excel.Quit()

Foreach-Object(Aliasは%)はスクリプトブロックの配列が指定できる。

%{前処理}{ループ処理}{後処理}の形式。

Excelの保存形式はEnumの値を指定する。Excel2007形式は「51」。

これで問題なさそうだが、Comオブジェクトは参照を解放しないとプロセスが残ってしまう。
(ps Excelで確認できる)
乱暴に、kill –name Excel とする方法もあるが、もう少しスマートに。(まっとうに)

[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($excel)

とすると開放してくれるようだ。

これを各変数に対して行うと、
foreach($obj in $excel,$excelBook,$excelSheet,$excelCells){
    [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($obj)
}

もう少し汎用的にしてみる。

Get-Variable excel* | %{
    [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($_.value)
}

戻り値がうっとうしいときは、

Get-Variable excel* | %{
    [System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($_.value)  | Out-Null
}

voidにキャストしても良い。

Get-Variable excel* | %{
    [void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($_.value)
}

0 件のコメント:

コメントを投稿