テストを科学する

2013/06/19

Excelの関数をPowerShellから使ってみよう

Mirosoft PowerShellは.NETやCOMのオブジェクトをPowerShellとオブジェクトとして扱えるということを以前お話しました。Microsoft Excelもワークシートの操作や関数などあらゆるAPIをCOMインターフェースとして公開しています。

そこで今回はExcelをPowerShellから使ってみましょう。

平均値を求めるExcelの関数をAverageを使ってみます。

C:\> Get-Content .\Run-ExcelFunction.ps1

$xl = New-Object -ComObject Excel.Application

$wf = $xl.WorksheetFunction

try {

$wf.Average(@(1, 2, 3, 4, 5))

} finally {

    $wf, $xl | ForEach {

    [void][Runtime.Interopservices.Marshal]::ReleaseComObject($_)

    }
}

C:\> .\Run-ExcelFunction.ps1
3

 
殆どはCOMオブジェクトの準備と破棄で、実体は下記の1行です。WorksheetFunctionオブジェクトを取得できれば、以後は簡単にExcelの関数をPowerShellから呼ぶことができます。

$wf.Average(@(1, 2, 3, 4, 5))

 
全体をtry, finallyでくくっているのは、処理が失敗した場合でも生成したExcelオブジェクトを破棄できるにするためです。

任意の関数を呼べるように、Excel関数の呼び出し部分をスクリプトブロック化してみましょう。以降はコードのみ示します。

$RunExcelFunction = {

    param([scriptblock] $script = {param($xl) });

    $xl = New-Object -ComObject Excel.Application

    $wf = $xl.WorksheetFunction

    try {

    & $script $wf

    } finally {

        $wf, $xl | ForEach {

    [void][Runtime.Interopservices.Marshal]::ReleaseComObject($_)

        }

    }

}

$average = {
    $wf.Average(@(1, 2, 3, 4, 5))
}

$median = {
    $wf.Median(@(1, 2, 3, 4, 5))
}

& $RunExcelFunction $average
& $RunExcelFunction $median

 
開始終了の定型処理がスクリプトブロックになって任意のExcelの関数が簡単に呼び出せるようになりましたね。

さらに、呼び出し側のスクリプトブロックも関数化して、コマンドレットのように引数を撮って呼び出せるようにしてみましょう。引数をパイプラインからも受け取れるようにしてみました。

$RunExcelFunction = {

    param([scriptblock] $script = {param($xl) });

    $xl = New-Object -ComObject Excel.Application

    $wf = $xl.WorksheetFunction

    try {

    & $script $wf

    } finally {

        $wf, $xl | ForEach {

    [void][Runtime.Interopservices.Marshal]::ReleaseComObject($_)

        }

    }

}

function Average {

    param(
        [Parameter(ValueFromPipeline = $true) ]

    $array)

    $average = {
    param($wf)

    $wf.Average($array)

    }.GetNewClosure()

    & $RunExcelFunction $average

}

function Median {

    param(
    [Parameter(ValueFromPipeline = $true) ]
    $array)

    $median = {
    param($wf)

    $wf.Median($array)

    }.GetNewClosure()

& $RunExcelFunction $median

}

,@(1, 2, 3, 4, 5) | Average
,@(1, 2, 3, 4, 5) | Median

 
このようにPowerShellからExcelを始めとしたCOMオブジェクトのインターフェースを利用することは非常に簡単です。

今回のようにExcelなど豊富な統計解析のAPIをもつソフトウェアをPowerShellから利用できれば、PowerShellの標準コマンドレットにない機能でも簡単に自動化できますね。是非、色々なAPIを調べてみて、PowerShellから利用してみてください。

ソフトウェアテストに関するお悩みなど、まずはお気軽にお問い合わせください。

  • お問い合わせフォーム【お問い合わせはコチラ】
  • 電話でのお問い合わせ【0120-142-117】