社内SEの話

日々起きたことの記録用

【PowerShell】Excel列挙型が呼び出せない

↓プログラミングで副業を考えたらこちら↓

Excel操作中に罫線の種類や太さ、その他様々なところでExcelでは列挙型(enum)が使われています。

直接数値を指定してもいいのですが、可読性、メンテナンス性を考えたらenumを使ったほうがパフォーマンスが高いです。

しかしPowerShell5の時に作ったps1を7環境で実行したら、列挙型が機能せず、意図した動作になりませんでした。

ただPowershell 5では正常に動作しているため、Powershellのバージョンアップの影響を受けていると推察しています。

バージョンの動作の違いを確認

確認コマンド

$excel = New-Object -ComObject Excel.Application

$excel.GetType().Assembly.GetExportedTypes() | Where-Object {$_.Name -like "Line"}

Powershell 7の結果

PowerShell 5の結果

5の場合は列挙が取得できています。

7になって列挙の取得の仕方に変化があったのか確認してみます。

learn.microsoft.com

一通り確認してみましたが、これといって変更箇所は見当たりませんでした。

XlLineStyleがあるか確認してみます。

PowerShell 7の結果

・・・ない

PowerShell 5の結果

XlLineStyleがあり、列挙で呼び出せます。

同一端末でPowerShellのバージョンだけで結果が変わっています。

原因

色々確認しならがコマンドを叩いていると、

Add-Type -AssemblyName Microsoft.Office.Interop.Excel

を実行すると

Add-Type: Cannot find path 'D:\PowerShell\Microsoft.Office.Interop.Excel.dll' because it does not exist.

というエラーが発生し、エイリアスのパスが通っていない事が原因と踏みました。

Microsoft.Office.Interop.Excel.dllを探す

インストールしたProgramFileからMicrosoft.Office.Interop.Excel.dllを探し出します。

以下の3ファイルが見つかりました。

"C:\Program Files (x86)\Microsoft Office\root\Office16\ADDINS\PowerPivot Excel Add-in\Microsoft.Office.Interop.Excel.dll"

"C:\Program Files (x86)\Microsoft Office\root\Office16\ADDINS\PowerPivot Excel Add-inv16\Microsoft.Office.Interop.Excel.dll"

"C:\Program Files (x86)\Microsoft Office\root\Office16\ADDINS\Microsoft Power Query for Excel Integrated\bin\Microsoft.Office.Interop.Excel.dll"

Visual Studioがある環境なので、必ずしも同じ結果にはならないかも知れません。

Add-Type で登録する

取得したパスをAdd-Typeします

Add-Type -AssemblyName "C:\Program Files (x86)\Microsoft Office\root\Office16\ADDINS\PowerPivot Excel Add-in\Microsoft.Office.Interop.Excel.dll"

Add-Type後はこれまで同様に使えます。

$xlLineStyle = [Microsoft.Office.Interop.Excel.XlLineStyle]

$xlLineStyle::xlDash.value__

ただこの状態ではenumなのに結果はStringで返しているので [int] で数値に変換する必要があります

$LineStyle = [Microsoft.Office.Interop.Excel.XlLineStyle]

$cell = $sheet.cells.item(1,1)

$cell.borders.LineStyle = [int]$LineStyle::xlDashDotDot

以上です。

5と7では大きな変更点が無いものと思っていた分、原因究明に少し時間がかかってしまいました。

これまでのプログラムに対して大幅な変更を加える必要がなくて良かったです。

終わりに

これまでExeclの列挙を取得して使っていましたが、今回のようなエラーがに悩まされます。

それだったら個別の値をEnumとして登録しておくのもありかなと思うところです。

参考サイト

powershellmagazine.com

social.technet.microsoft.com

blog.goo.ne.jp