Powershell で Excel の操作を行います。
実行するスクリプトと開くExcelファイルは、同じフォルダに置きます。 また、Excelファイルの保存は実行スクリプトと同じフォルダに保存されます。
# excels1.ps1 Excel操作例
Set-StrictMode -Version latest
$sExlfnamer = $PSScriptRoot + "\exlTest.xlsx" # 開くExcel ファイル名
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true # 表示状態とする
# 新規のワークブック
#$wbook = $excel.Workbooks.Add()
# Excelファイルを開く場合
$wbook = $excel.Workbooks.Open($sExlfnamer)
$sheet = $wbook.Sheets(1) # 1番目のシートを取得
$sheet.Activate() # シートを前面に
Write-Host $sheet.Name # シート名を表示
# $sheet.Range("B1").Value = "日本123abc" # セルB1に値セット
$sheet.Cells(1, 2).Value = "日本123abcABC" # セルB1に値セット
# $cell変数に置き換える場合
# $cell = $sheet.Cells(1, 2)
# $cell.Value = "千葉県xyz678"
# $range変数に置き換える場合
$range = $sheet.Range("C2")
$range.Value = "C2のデータ"
$sr = $sheet.Cells(3, 2).Value() # セルB3の値を取得
Write-Host $sr
$sr = Read-Host "保存しますか? y/n"
if ($sr -eq "y"){
$sExlfnames = $PSScriptRoot + "\exlTestn.xlsx" # 保存 Excel ファイル名
if (Test-Path $sExlfnames){
Remove-Item $sExlfnames # 削除
}
$wbook.SaveAs($sExlfnames) # 保存
}
$wbook.Saved = $true # 終了時の保存確認メッセージを表示しない
$excel.Quit()
#$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($cell)
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($range)
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wbook)
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
新規のワークブック追加は、「$excel.Workbooks.Add()」 とします。また、Excelファイルを開く時は 「$excel.Workbooks.Open($sExlfnamer)」 で開くExcelファイルを指定します。「$PSScriptRoot」は、スクリプトが存在するフォルダパスです。
以下の例における変数 $wbook, $sheet, $cell, $range については、上記プログラム例を参照して下さい。
$excel.Visible = $true # 表示状態とします。 $false で非表示 デフォルト値は、$false です。
$excel.DisplayAlerts = $false # 確認メッセージを非表示とします。 $true で表示します。
$br = $wbook.Saved # 保存後に変更されたかの状態 $true:変更なし状態 $false:変更あり状態
$wbook.Saved = $true # 変更なし状態とし、終了時の保存確認メッセージを表示しない
[void]$wbook.Sheets("Sheet1").Delete() # [void] で戻り値の表示を非表示とします。※1
# Excel定数を参照
[Microsoft.Office.Interop.Excel.XlCutCopyMode]::xlCopy # 直接参照
$exlpasteType = "Microsoft.Office.Interop.Excel.XlPasteType" -as [type] # 変数に置き換える 例1 ※2
$exlpasteType = [Microsoft.Office.Interop.Excel.XlPasteType] # 変数に置き換える 例2 ※2
Excelファイル(ブック)、csvファイルを開きます。
ブックを開く関数 Open((FileName, UpdateLinks, ReadOnly, Format, Password)
Workbooks.Open メソッド (Excel)
$sExlfnamer = $PSScriptRoot + "\exlTest.xlsx" # xlsx 形式ファイル名
# $sExlfnamer = $PSScriptRoot + "\exlTestn.xlsm" # xlsm 形式ファイル名
# $sExlfnamer = $PSScriptRoot + "\exlTestn.xls" # xls 形式ファイル名
# $sExlfnamer = $PSScriptRoot + "\exlSjis.csv" # csv 形式ファイル 文字コード シフトJIS
# $sExlfnamer = $PSScriptRoot + "\exlUtf8BOM.csv" # csv 形式ファイル 文字コード utf8 BOM付き ※1
$wbook = $excel.Workbooks.Open($sExlfnamer)
# パスワード保護されたブックを開くのに必要なパスワードを指定
$wbook = $excel.Workbooks.Open($sExlfnamer, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing,"password") # ※2
※2 値を指定しない引数には、[System.Type]::Missing をセットします。
※1 BOMなしの utf8 csv ファイルでは文字化けします。
utf8ファイル BOMなしからBOM付きファイルに変換 PowerShell 5.1 で使用して下さい。
# utf8 BOMなし->BOM付き
$sUtf8NoBOMfName = $PSScriptRoot + "\utf8NoBOM.csv" # utf8 BOMなしファイル名
$sUtf8BOMfName = $PSScriptRoot + "\utf8BOM.csv" # utf8 BOMありファイル名
Get-Content -encoding:utf8 $sUtf8NoBOMfName | Out-File -encoding:utf8 $sUtf8BOMfName
$ic = $excel.WorkBooks.Count # 開いているワークブックの数
Write-Host $ic
$wbk1 = $excel.ActiveWorkBook # アクティブワークブックを取得
$wbk = $excel.Workbooks.item("wkBook.xlsx") # ワークブック名(ファイル名) でワークブック選択 ※1
$wbk = $excel.WorkBooks.item(2) # インデックス番号でワークブック選択
Write-Host $wbk.Name # ワークブック名表示
$wbk.Activate() # ワークブックをアクティブにする
※ 1 ワークブック名は、Excelファイル名です。
複数ワークブックの操作例
$ic = $wbook.Sheets.count # シート数
$sheet = $wbook.Sheets(2) # シートのインデックス番号でシートを取得 1~
$sheet = $wbook.Sheets("Sheet1") # シート名でシートを取得
$sheet = $wbook.ActiveSheet # アクティブシートを取得
# シート名の一覧を取得
$sshname = @() # シート名セット用配列
foreach($sa in $wbook.Sheets){
$sshname += $sa.Name
}
Write-Host $sshname
$sheet.Activate() # シートをアクティブに 前面に
Write-Host $sheet.Name # シート名を表示
Write-Host $sheet.Index # シートのインデックス番号
$sheet.Name = "日報12日" # シート名変更
$sheet.Delete() # シートの削除 ※1
# シートの非表示、表示
$exlXlSheetVisibility = [Microsoft.Office.Interop.Excel.XlSheetVisibility] # ※1
$sheet.Visible = $exlXlSheetVisibility::xlSheetHidden # シートの非表示 $false でも可
$sheet.Visible = $exlXlSheetVisibility::xlSheetVisible # シート表示 $true でも可
$sheet.Visible = $exlXlSheetVisibility::xlSheetVeryHidden # シートの非表示 ユーザでの表示操作は出来ません。
$br = $sheet.Visible # 表示、非表示状態取得
Write-Host $br # -1, 0 または、 2
シート追加関数 Sheets.Add(Before, After)
Before: 指定されたシートの直前に追加 After: 指定されたシートの直後に追加
指定しない場合は、[System.Reflection.Missing]::Value をセット
$sheet = $wbook.Sheets.Add() # アクティブシートの前に追加
$sheet = $wbook.Sheets.Add([System.Reflection.Missing]::Value, $sheet) # 現在シートの後ろに追加
$sheet = $wbook.Sheets.Add([System.Reflection.Missing]::Value, $wbook.Sheets(1)) # 1番目のシートの後ろに追加
$sheet = $wbook.Sheets.Add($wbook.Sheets(3)) # 3番目のシートの前に追加
$sheet = $wbook.Sheets.Add([System.Reflection.Missing]::Value, $wbook.Sheets($wbook.Sheets.count)) # 最後に追加
戻り値は、シートのオブジェクトです。Before、After 両方を指定しない場合は、アクティブシートの前に追加されます。
シートコピー関数 Sheet.Copy(Before, After)
Before: 指定されたシートの直前に追加 After: 指定されたシートの直後に追加
指定しない場合は、[System.Reflection.Missing]::Value をセット
$sheet = $wbook.Sheets("Sheet1") # コピー元 Sheet1 を取得
$sheet.Copy($wbook.Sheets("Sheet2")) # Sheet2 の前にコピー
$sheet.Copy([System.Reflection.Missing]::Value, $wbook.Sheets("Sheet2")) # Sheet2の後にコピー
$sheet.Copy([System.Reflection.Missing]::Value, $wbook.Sheets($wbook.Sheets.Count)) # 最後にコピー
# コピーしたシートを取得 例
$idx = $wbook.Sheets("Sheet2").Index # コピー先
$sheet.Copy([System.Reflection.Missing]::Value, $wbook.Sheets($idx)) # Sheet2の後にコピー
$sheet = $wbook.Sheets($idx + 1) # コピーしたシートを取得 前を指定した時は、 -1とします。
Write-Host $sheet.Name # コピーしたシートのシート名
$sheet.Copy() # 新しいワークブックにコピー ※1
$wbookn = $excel.ActiveWorkBook # 新ワークブックを取得
Write-Host $wbookn.Sheets(1).Name # シート名
$wbook.Sheets("Sheet2").Copy([System.Reflection.Missing]::Value, $wbookn.Sheets($wbookn.Sheets.Count)) # Sheet2 を新ワークブックの最後にコピー
シート移動関数 Sheet.Move(Before, After)
Before: 指定されたシートの直前に移動 After: 指定されたシートの直後に移動
指定しない場合は、[System.Reflection.Missing]::Value をセット
$sheet = $wbook.Sheets("Sheet1") # 移動元 Sheet1 を取得
$sheet.Move($wbook.Sheets("Sheet3")) # Sheet3 の前に移動
$sheet.Move([System.Reflection.Missing]::Value, $wbook.Sheets("Sheet3")) # Sheet3の後に移動
$sheet.Move([System.Reflection.Missing]::Value, $wbook.Sheets($wbook.Sheets.Count)) # 最後に移動
$sheet.Move() # 新しいワークブックに移動 ※1
[void]$wbook.Sheets("Sheet1").Delete() # シート名を指定してシートを削除 ※1
[void]$wbook.Sheets(2).Delete() # インデックス番号を指定してシートを削除
□ WorkSheets を使用した場合
$ic = $wbook.WorkSheets.Count # シート数
$sheet = $wbook.WorkSheets(1) # インデックス番号で1番目のシートを取得
$sheet = $wbook.WorkSheets("Sheet2") # シート名で "Sheet2" を取得
$wbook.WorkSheets(1).Delete() # 1番目のシートを削除
WorkSheets は、ワークブック内のワークシートのみ処理対象とし、Sheets は、ワークブック内のすべてのシートを処理対象と します。シートには、ワークシート、グラフシート、マクロシート、ダイアログシートがあります。
$sheet.Cells(1, 2).Value = "日本123abcABC" # セルB1に値セット Valueは省略可 Cells(行インデックス、列インデックス)
$sheet.Range("B1").Value = "日本123abc" # セルB1に値セット Valueは省略可
$sheet.Cells(8, 3) = "鉛筆`n消しゴム" # セル内で改行する文字列をセット 改行箇所に `n (LF) を入れます
$dr = $sheet.Cells(3, 2).Value() # セルB3の値を取得 ※1
$dr = $sheet.Range("B4").Value2 # セルB4の値を取得 ※1 ※2
$sr = $sheet.Cells(2, 2).Text # セルB2の表示している内容 ※1
$ir = $sheet.Cells(1, 2).Clear() # B1の内容をすべてクリア
$ir = $sheet.Range("B3").ClearContents() # 数式と文字列を削除
$ir = $sheet.Range("B4").ClearFormats() # 書式設定を削除
複数セル指定
$sheet.Range("B5:D6") = "濃溝の滝" # B5:D6 全セルに同じ値がセットされます。
# Cellsで複数セル指定
$sheet.Range($sheet.Cells(2, 2), $sheet.Cells(3, 4)) = "地獄覗き" # B2:D3 全セルに同じ値がセットされます。
# セル内容を配列で読み込み
$arr = $sheet.Range("B9:D10").Value() # セル B9:D10 の値を読み込む
# $arr = $sheet.Range($sheet.Cells(9, 2), $sheet.Cells(10, 4)).Value() # Cellsで指定
Write-Host $arr[1, 1], $arr[1, 2], $arr[1, 3] # セル B9 の値が 配列 $arr[1, 1] にセットされます。
Write-Host $arr[2, 1], $arr[2, 2], $arr[2, 3]
# セルへ配列で書き込み
$arw = New-Object "object[,]" 2, 4 # 書き込み用配列定義 2行4列
$arw[0, 0] = "果物"; $arw[0, 1] = "りんご"; $arw[0, 2] = "みかん"; $arw[0, 3] = "バナナ"
$arw[1, 0] = "個数"; $arw[1, 1] = 12; $arw[1, 2] = 25; $arw[1, 3] = 15
$sheet.Range("B12:E13") = $arw # B12:E13 にセット
# $sheet.Range($sheet.Cells(12, 2), $sheet.Cells(13, 5)) = $arw # Cellsで指定
配列での読み込みでは、0行目、0列目にセットされません。また、書き込み用の配列は、非ジャグ配列を使用します。
上記配列定義では、文字、数字が混在しているため「object」型を使用しています。書き込みデータがすべて同じ型であれば、
その型で宣言することも可能です。
例 すべて整数の場合 「$arw = New-Object "int[,]" 2, 4 」
データは、行0、列0からのセットで動作します。データをセットしないセルには、 $null をセットします。
配列での読み書きは、Value2 でも可能ですが、Text では出来ません。
# セルのコピーペースト PasteSpecial
[void]$sheet.Range("B9:D10").Copy() # B9:D10 の内容をコピーし B12:D13, B15:D16 へ貼り付け
[void]$sheet.Range("B15").PasteSpecial() # すべての内容がコピーされます。
[void]$wbook.Sheets("Sheet2").Range("B9").PasteSpecial() # 別シート Sheet2 へすべてコピー
# 貼り付ける内容を選択
$exlpasteType = "Microsoft.Office.Interop.Excel.XlPasteType" -as [type] # ※1
[void]$sheet.Range("B12").PasteSpecial($exlpasteType::xlPasteValues) # 値を貼り付けます。
[void]$wbook.Sheets("Sheet2").Range("B9").PasteSpecial($exlpasteType::xlPasteValues) # 別シート Sheet2 へ値を貼り付け
# セルのコピーペースト Paste
[void]$sheet.Range("B9:D10").Copy() # B9:D10 の内容をコピーし B12:D13, B15:D16 へ貼り付け
[void]$sheet.Range("B12").Select(); $sheet.Paste() # すべての内容がコピーされます
# コピーモードの解除 ※2
# $excel.CutCopyMode = $false # <<= エラーとなります。
$excel.CutCopyMode = [Microsoft.Office.Interop.Excel.XlCutCopyMode]::xlCopy # xlCut でも可
# $excel.CutCopyMode = 1 # 数値で指定 2 でも可
# [System.Windows.Forms.Clipboard]::Clear() # CutCopyMode を使用しない方法
# コピー先を直接指定
$sheet.Range("B9:D10").Copy($sheet.Range("B13")) # B9:D10 から B13:D14 へコピー すべてコピーされます。
# カットペースト
[void]$sheet.Range("B9:D10").Cut() # B9:D10 -> B18:D19 へ移動
[void]$sheet.Range("B18").Select(); $sheet.Paste()
# 移動先を直接指定
[void]$sheet.Range("B9:D10").Cut($sheet.Range("B18"))
[void]$sheet.Range("B9:D10").Cut($wbook.Sheets("Sheet2").Range("B18")) # 別シート Sheet2 へ移動
# セルのフォント設定
$cell = $sheet.Cells(3, 2) # B3 セル
$cell.Value = "日本千葉"
$cell.Font.Name = "MS Pゴシック" # フォント指定
$cell.Font.Size = 15 # フォントのサイズ
$cell.Font.Bold = $true # 太字 $false で太字解除
$cell.Font.Italic = $true # 斜体 $false で斜体解除
$cell.Font.Underline = [Microsoft.Office.Interop.Excel.XlUnderlineStyle]::xlUnderlineStyleSingle # 一重下線 ※1
$sheet.Range("B1").Font.Bold = $true # 太字 $false で太字解除 Rangeで指定
$sheet.Range("B1").Font.Italic = $true # 斜体 $false で斜体解除 Rangeで指定
# 色 ※2
$cell.Font.Color = [System.Drawing.Color]::White # 文字色 白
$cell.Interior.Color = [System.Drawing.Color]::Red # セルバック色 赤
# 取り消し線
$sheet.Range("B12").Font.Strikethrough = $true # 取り消し線を引く $false で消します
$sheet.Cells(12, 2).Font.Strikethrough = $true # 取り消し線を引く $false で消します。
# 数式
$sheet.Cells(5, 3).Formula = "=SUM(C2:C4)" # 数式をセット
$sheet.Range("C5").Formula = "=SUM(C2:C4)" # 数式をセット Range
$br = $sheet.Range("D3").HasFormula # セルに数式が設定されているか判定 Trueで数式あり
Write-Host $br
$sf = $sheet.Range("D3").Formula # 数式を取得
Write-Host $sf
$sheet.Cells(3, 4).NumberFormatLocal = "#,##0" # 3桁区切り 34,567
$sfmt = $sheet.Range("D3").NumberFormatLocal # 表示形式の取得
Write-Host $sfmt
# 表示形式の例
$sheet.Cells(1, 2).NumberFormatLocal = "@" # 文字列
$sheet.Cells(2, 2).NumberFormatLocal = "#,##0" # 3桁区切り 34,567
$sheet.Cells(3, 2).NumberFormatLocal = "#0.000" # 小数点以下3桁 234.500
$sheet.Cells(4, 2).NumberFormatLocal = "\#,##0" # 円記号 3桁区切り \234,567
$sheet.Cells(5, 2).NumberFormatLocal = "[青]#,##0;[赤]-#,##0;[黒]06" # プラスで青色 マイナスで赤色 0で黒色 ※1
$sheet.Cells(6, 2).NumberFormatLocal = "#,##0;△#,##0" # マイナスで △付き表示
$sheet.Cells(7, 2).NumberFormatLocal = "yy/mm/dd" # 日付 23/01/08
$sheet.Cells(8, 2).NumberFormatLocal = "yy/mm/dd hh:mm:ss" # 日付時間 24/10/09 09:08:02 ※2
# 和暦表示 ※3
$sheet.Range("A3:A7").Value = "2024/10/05"
$sheet.Cells(3, 1).NumberFormatLocal = "g e/mm/dd" # R 6/10/05
$sheet.Cells(4, 1).NumberFormatLocal = "g ee/mm/dd" # R 06/10/05
$sheet.Cells(5, 1).NumberFormatLocal = "gg e年mm月dd日" # 令 6年10月05日
$sheet.Cells(6, 1).NumberFormatLocal = "ggg e年mm月dd日" # 令和 6年10月05日
$sheet.Cells(7, 1).NumberFormatLocal = "yyyy(ge)/mm/dd" # 2024(R6)/10/05
$sheet.Range("B4:D5").Merge() # B4:D5がセル結合 Merge($false) でも可
$sheet.Range("B4:D5").Merge($true) # B4:D4 と B5:D5 がセル結合 横方向にセル結合 ※1
$sheet.Range("B4:D5").UnMerge() # セル結合解除
$sheet.Range("B7:D8").MergeCells = $true # B7:D8 がセル結合
$sheet.Range("B7:D8").MergeCells = $false # セル結合解除
$rv = $sheet.Range("B8").MergeCells # セル結合状態取得 $true でセル結合状態
Write-Host $rv
Merge は関数で MergeCells は、プロパティです。
結合内に複数の値が存在する場合、確認メッセージが表示されます。表示を止めるためには、結合前に $excel.DisplayAlerts = $false を実行し、結合終了後 $excel.DisplayAlerts = $true とします。
※1 Merge($true) で横方向にセル結合されます。
# 値のセット、取得 B4:D5 がセル結合されているとします。
$sheet.Range("B4").Value = "養老渓谷" # 値がセットされます。※1
$sheet.Range("C4").Value = "養老渓谷" # セットされません。×
$sheet.Range("D5").MergeArea.Value = "海ほたる" # 値がセットされます。※2
$rv = $sheet.Range("B4").Value() # 値が取得できます。※1
$rv = $sheet.Range("C4").Value() # 取得できません。×
$rv = $sheet.Range("C4").MergeArea.Value() # 値が取得できます。※2
# 結合セル内文字位置 ※3
$xlHAlign = [Microsoft.Office.Interop.Excel.XlHAlign]
$sheet.Range("B5").HorizontalAlignment = $xlHAlign::xlHAlignCenter # 中央揃え
$xlVAlign = [Microsoft.Office.Interop.Excel.XlVAlign]
$sheet.Range("B5").VerticalAlignment = $xlVAlign::xlVAlignBottom # 下揃え
※1 Value セル結合の左上のセルを指定します。
※2 MergeArea 結合セル内のセルを指定します。
※3 結合セル内の文字位置は、6) セル内の文字位置を参照して下さい。
名前定義でセル値の取得、設定を行います。
□ 値の取得、設定 1 単一セルまたはセル結合に名前定義されている場合
$sv = $excel.Range("名前1").Value()
#$sv = $sheet.Range("名前1").Value() # シート指定で行う場合
Write-Host $sv
$excel.Range("名前1").Value = "谷津干潟"
#$sheet.Range("名前1").Value = "谷津干潟" # シート指定で行う場合
□ 値の取得、設定 2 複数セルに名前定義されている場合
$sv = $excel.Range("品名一覧").Value() # 配列として取得されます。
Write-Host $sv
Write-Host $sv[1, 2]
$excel.Range("都道府県名").Value = "県名" # すべてのセルに同じ値がセットされます。
# 配列で書き込み
$arw = New-Object "object[,]" 2, 3 # 書き込み用配列定義
$arw[0, 0] = "青森県"; $arw[0, 1] = "秋田県"; $arw[0, 2] = "岩手県"
$arw[1, 0] = "宮城県"; $arw[1, 1] = "山形県"; $arw[1, 2] = "福島県"
$excel.Range("都道府県名").Value = $arw
# セル単位で取得、設定
$sva = $excel.Range("都道府県名")[1, 1].Value(); $svb = $excel.Range("都道府県名")[1, 2].Value()
$excel.Range("都道府県名")[1, 1].Value = $svb; $excel.Range("都道府県名")[1, 2].Value = $sva
$excel.Range("都道府県名")[2, 2].Font.Color = [System.Drawing.Color]::Blue # 文字色変更
配列については、2) セル内容を配列で読み書き を参照して下さい。
複数のワークブックに同じ名前定義が存在し、同時に開かれている場合は、アクティブなワークブックが処理対象となります。
□ 名前定義の取得、変更
$ic = $wbook.Names.Count # 名前定義されている個数
Write-Host $ic
$namesd = $wbook.Names("品種") # 定義名で取得
#$namesd = $wbook.Names[1] # 順番号で取得 1~
#$namesd = $wbook.Names.Item(1) # Item で取得 1~
Write-Host $namesd.Name, $namesd.RefersTo # 定義名、参照先 表示 ※1
$namesd.Name = "製品名" # 名前定義名変更
$namesd.RefersTo = "=Sheet3!`$C`$3:`$C`$4" # 参照先変更 または '=Sheet3!$C$3:$C$4'
# ワークブック内の名前定義一覧
$ic = $wbook.Names.Count
for($ia = 1; $ia -le $ic; $ia++){
$namesd = $wbook.Names[$ia] # 1~
Write-Host $namesd.Name, $namesd.RefersTo # 名前定義名、参照先
}
※1 表示例 品種 =Sheet1!$B$9:$D$10
□ 名前定義の追加、削除
# ブックレベルで追加
[void]$wbook.Names.Add("商品コード", $sheet1.Range("B3:B6"))
# シートレベルで追加
$sheet1 = $wbook.Sheets("Sheet1")
$sheet1.Names.Add("原料コード", $sheet1.Range("B3:B6"))
# ブックレベルの名前定義削除
$wbook.Names("品種").Delete()
# シートレベルの名前定義削除
$wbook.Sheets("Sheet3").Names("住所").Delete()
$xlHAlign = [Microsoft.Office.Interop.Excel.XlHAlign] # 水平方向配置定数 ※1
$sheet.Range("B2:B7") = "利根川"
$sheet.Cells(2, 2).HorizontalAlignment = $xlHAlign::xlHAlignCenter # 中央揃え
$sheet.Cells(3, 2).HorizontalAlignment = $xlHAlign::xlHAlignDistributed # 均等割り付け
$sheet.Cells(4, 2).HorizontalAlignment = $xlHAlign::xlHAlignFill # ページ幅に合わせる
$sheet.Cells(5, 2).HorizontalAlignment = $xlHAlign::xlHAlignJustify # 両端揃え
$sheet.Cells(6, 2).HorizontalAlignment = $xlHAlign::xlHAlignLeft # 左揃え
$sheet.Cells(7, 2).HorizontalAlignment = $xlHAlign::xlHAlignRight # 右揃え
$xlVAlign = [Microsoft.Office.Interop.Excel.XlVAlign] # 垂直方向配置定数 ※1
$sheet.Range("D2:D6") = "江戸川"
$sheet.Cells(2, 4).VerticalAlignment = $xlVAlign::xlVAlignBottom # 下揃え
$sheet.Cells(3, 4).VerticalAlignment = $xlVAlign::xlVAlignCenter # 中央揃え
$sheet.Cells(4, 4).VerticalAlignment = $xlVAlign::xlVAlignDistributed # 均等割り付け
$sheet.Cells(5, 4).VerticalAlignment = $xlVAlign::xlVAlignJustify # 両端揃え
$sheet.Cells(6, 4).VerticalAlignment = $xlVAlign::xlVAlignTop # Top
$sheet.Range("B2").HorizontalAlignment = $xlHAlign::xlHAlignRight # 右揃え Rangeで指定
$sheet.Range("B2").VerticalAlignment = $xlVAlign::xlVAlignBottom # 下揃え Rangeで指定
$sheet.Cells(1, 2).WrapText = $true # 折り返して全体を表示 $false で解除
※1 水平方向配置定数 XlHAlign 列挙 (Excel) 垂直方向配置定数 XlVAlign 列挙 (Excel)
# 罫線 ※1
$exlBordersIndex = "Microsoft.Office.Interop.Excel.XlBordersIndex" -as [type] # 罫線の箇所
$exlLineStyle = "Microsoft.Office.Interop.Excel.XlLineStyle" -as [type] # 線の種類
$exlBorderWeight = "Microsoft.Office.Interop.Excel.XlBorderWeight" -as [type] # 線の太さ
$cell = $sheet.Cells(3, 2) # $sheet.Range("B3") でも可
# 下側の罫線を直線とし、色、太さを指定
$cell.Borders($exlBordersIndex::xlEdgeBottom).LineStyle = $exlLineStyle::xlContinuous # 線の種類
$cell.Borders($exlBordersIndex::xlEdgeBottom).Color = [System.Drawing.Color]::Red # 線の色
$cell.Borders($exlBordersIndex::xlEdgeBottom).Weight = $exlBorderWeight::xlThick # 線の太さ
# 指定されたセル範囲に罫線 セルの上下左右
$range = $sheet.Range("B5:C6")
$range.Borders.LineStyle = $exlLineStyle::xlContinuous # セル範囲に罫線
$range.Borders.Color = [System.Drawing.Color]::Blue
$range.Borders.Weight = $exlBorderWeight::xlMedium
# 罫線消去
$range.Borders.LineStyle = $exlLineStyle::xlLineStyleNone
# セルの幅取得
$iw = $sheet.Range("B1").ColumnWidth # ※1
$iw = $sheet.Range("C2").Width # Width ポイント単位
$iw = $sheet.Columns("B").Width
$iw = $sheet.Columns(2).Width # B
$iw = $sheet.Columns("B").ColumnWidth # ColumnWidth 標準フォントの1文字単位
$iw = $sheet.Columns(2).ColumnWidth
# セルの幅設定 ※2
$sheet.Range("B1").ColumnWidth = 10.5 # B列
$sheet.Range("C1:D1").ColumnWidth = 5.5 # C,D列
$sheet.Range("E:F").ColumnWidth = 8.5 # E,F列
$sheet.Columns(1).ColumnWidth = 10 # 列 A
# セルの高さ取得
$ih = $sheet.Range("A1").RowHeight # 1行目
$ih = $sheet.Range("C4").Height # 4行目
$ih = $sheet.Rows(2).Height # 2行目 Height ポイント単位
$ih = $sheet.Rows(2).RowHeight # RowHeight ポイント単位
# セルの高さ設定 ※1
$sheet.Range("A1").RowHeight = 2.5 # 1行目 ポイント単位
$sheet.Range("A2:A3").RowHeight = 15.0 # 2,3行目
$sheet.Range("4:5").RowHeight = 6.75 # 4,5行目
$sheet.Rows(3).RowHeight = 30 # 3行目
$sheet.Range("A4").EntireRow.RowHeight = 35 # 4行目 35ポイント
※1 Height での設定は不可
# 列幅自動調整
$sheet.Range("B2").Value = "雨にも負けず、`n風にも負けず"
$sheet.Range("C3").Value = "雪にも夏の暑さにも負けぬ"
$sheet.Rows("2").AutoFit() # 2行目最大高さに合わせる
$sheet.Columns("C").AutoFit() # C列の最大幅に合わせる
# 最終行
$eXlDirection = "Microsoft.Office.Interop.Excel.XlDirection" -as [type] # ※1
$irow = $sheet.Cells(2, 3).End($eXlDirection::xlDown).Row # セル C2 から下へ移動 表の最終行番号取得
Write-Host $irow
$obje = $sheet.Cells(2, 3).End($eXlDirection::xlDown) # セル C2 から下へ移動 表最終行セルのオブジェクト取得
Write-Host $obje.Value(), $obje.Row # セルの値、行番号
$obje = $sheet.Cells($sheet.Rows.Count, 2).End($eXlDirection::xlUp) # シート最終行から上に移動 表最終行セルのオブジェクト取得 ※2
Write-Host $obje.Value(), $obje.Row # セルの値、行番号
# 最終列
$icol = $sheet.Cells(2, 2).End($eXlDirection::xlToRight).Column # セル B2 から右へ移動 表の最終列取得
Write-Host $icol
$obje = $sheet.Cells(2, 2).End($eXlDirection::xlToRight) # セル B2 から右へ移動 表最終列のオブジェクト取得
Write-Host $obje.Value(), $obje.Column # セルの値、列番号
$obje = $sheet.Cells(2, $sheet.Columns.Count).End($eXlDirection::xlToLeft) # シート最終列から左に移動 表最終列のオブジェクト取得 ※3
Write-Host $obje.Value(), $obje.Column # セルの値、列番号
上記例における表の左上は、"B2"です。
※1 XlDirection 列挙 (Excel) xlDown:-4121、xlUp:-4162、xlToRight -4161、xlToLeft:-4159
※2 $sheet.Rows.Count は、シートの行数です。
※3 $sheet.Columns.Count は、シートの列数です。
色指定のプロパティは、ColorIndexとColorの二通りあります。ColorIndexは、1~56の色コードに対応した数字で指定します。 Colorは、RGB値で指定します。Colorは、Excel2007以降で使用出来ます。
# ColorIndex出力例
$ic = 1; $iy = 2
while($true){
for($ix = 2; $ix -lt 10; $ix++){
$cell = $sheet.Cells($iy, $ix)
$cell.Interior.ColorIndex = $ic
$cell.Value = $ic
$cell.Font.Bold = $true
$cell.HorizontalAlignment = [Microsoft.Office.Interop.Excel.Constants]::xlCenter
$ic++
}
$iy++
if ($ic -gt 56){
break
}
}
Colorで指定
$sheet.Range("B10") = "日本千葉"
$sheet.Range("B10").Interior.Color = [System.Drawing.Color]::Red # セルバック色 赤
$sheet.Range("B10").Font.Color = [System.Drawing.Color]::White # 文字色 白
$sheet.Range("B10").Interior.Color = [System.Drawing.Color]::FromArgb(0xFF, 0, 0) # RGB値で指定
名前を付けて保存関数 SaveAs(保存ファイル名, 保存形式)
保存ファイル名は、フルパスで指定します。
# 名前を付けて保存
$wbook.SaveAs($sExlfnames) # 保存形式を指定しない
$xlFileFormat = "Microsoft.Office.Interop.Excel.XlFileFormat" -as [Type] # 保存形式 ※1
$sExlfnames = $PSScriptRoot + "\exlTestn.xlsx" # 保存ファイル名
$wbook.SaveAs($sExlfnames, $xlFileFormat::xlOpenXMLWorkbook) # xlsx 形式で保存
$sExlfnames = $PSScriptRoot + "\exlTestn.xlsm"
$wbook.SaveAs($sExlfnames, $xlFileFormat::xlOpenXMLWorkbookMacroEnabled) # xlsm 形式で保存
$sExlfnames = $PSScriptRoot + "\exlTestn.xls"
$wbook.SaveAs($sExlfnames, $xlFileFormat::xlExcel8) # xls 形式で保存
# csv 形式で保存 ※2
$sExlfnames = $PSScriptRoot + "\exlTestn.csv" # csv 形式ファイル名
$wbook.SaveAs($sExlfnames, $xlFileFormat::xlCSV) # csv 保存 文字コード シフトJIS
# $wbook.SaveAs($sExlfnames, $xlFileFormat::xlCSVUTF8) # csv 保存 文字コード utf8 <<= エラーとなります
$wbook.SaveAs($sExlfnames, 62) # csv 保存 文字コード utf8 保存形式を数字で指定
utf8ファイル BOM付きからBOMなしファイルに変換
# utf8 BOM付き->BOMなし
$utf8CsvData = Get-Content ($PSScriptRoot + "\utf8BOM.csv") # BOM付きutf8 csv ファイル読み込み
$sNoBOMfname = $PSScriptRoot + "\utf8NoBOM.csv" # BOMなしutf8 csv ファイル名
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False # BOMなしを指定
[System.IO.File]::WriteAllLines($sNoBOMfname, $utf8CsvData, $Utf8NoBomEncoding)
# 上書き保存
$wbook.Save()
上書き保存で保存ファイル名が確定してない場合、「既定のローカルファイルの保存場所」にファイル名「Book1.xlsx」で保存されます。
「既定のローカルファイルの保存場所」は、[ファイル]-[オプション]-[Excelのオプション] の「保存」にあります。(Excel2016の場合)
印刷関数 PrintOut(印刷開始ページ番号, 印刷終了ページ番号, 印刷部数, 印刷プレビューの有無, 印刷プリンター)
印刷プレビューの有無は、$true で印刷プレビューを表示します。不要の場合は、$false とします。また、印刷プリンターを指定しない場合は、通常使うプリンタに出力されます。
値を指定しない引数は、[System.Type]::Missing をセットします。
$sheet.PrintOut() # シートを印刷
$sheet.PrintOut([System.Type]::Missing, [System.Type]::Missing, 2, $false) # 印刷部数 2 を指定
$sheet.PrintOut(1, 1, 1, $true, "LBP***") # 1ページ目を1部、印刷プレビュー有で指定プリンタに印刷
# 印刷ダイアログボックスを表示
$excel.Application.Dialogs([Microsoft.Office.Interop.Excel.XlBuiltInDialog]::xlDialogPrint).Show()
# プリンタ一覧を表示
Get-WmiObject -Class win32_Printer | Format-Table name
pdfファイル保存関数 ExportAsFixedFormat(保存形式, 保存ファイル名, Quality, IncludeDocProperties、
IgnorePrintAreas, From, To, OpenAfterPublish)
保存形式: XlFixedFormatType 列挙 (Excel) で、必ず指定します。xlTypePDF (0) または、xlTypeXPS (1)
Quality: 出力品質 XlFixedFormatQuality 列挙 (Excel) で指定します。xlQualityMinimum: 最小限の品質 xlQualityStandard: 標準品質
IncludeDocProperties: $true: ドキュメントプロパティを含める $false: 省略
IgnorePrintAreas: $true: 印刷範囲を無視 $false: 発行時の印刷範囲を使用
From: 開始ページ
To: 終了ページ
OpenAfterPublish: $true: 発効後にビュアーにファイルを表示 $false: 発行後表示しません。
$xlFixedFormatType = [Microsoft.Office.Interop.Excel.XlFixedFormatType]
$sheet.ExportAsFixedFormat($xlFixedFormatType::xlTypePDF) # 保存ファイル名省略 ※1
# ファイル名を指定してpdfファイル保存
$sPdfName = $PSScriptRoot + "¥日報20230305.pdf"
$sheet.ExportAsFixedFormat(0, $sPdfName) # 保存形式を数字 0 で指定
# 標準品質, ドキュメントプロパティ省略, 発行時の印刷範囲を使用, 2~3 ページ出力, 出力後ビュアーに表示
$exlFormatQuality = [Microsoft.Office.Interop.Excel.XlFixedFormatQuality]
$sheet.ExportAsFixedFormat(0, $sPdfName, $exlFormatQuality::xlQualityStandard, $false, $false, 2, 3, $true)
# 開始、終了ページを指定しない場合 ページに [System.Type]::Missing を指定 します。先頭から最後のページまで出力されます。
$sheet.ExportAsFixedFormat(0, $sPdfName, $exlFormatQuality::xlQualityStandard, $false, $false, [System.Type]::Missing, [System.Type]::Missing, $true)
※1 保存ファイル名を省略した場合は、「既定のローカルファイルの保存場所」に保存されます。
ExportAsFixedFormat メソッド
Excel のワークシート関数を使用します。
# ワークシート関数の使用例
$sheet = $wbook.Sheets("Sheet3") # シートを選択
$ir = $excel.WorksheetFunction.SUM($sheet.Range("B3:B8")) # SUM 関数で B3:B8 の合計取得
Write-Host $ir
$ir = $excel.WorksheetFunction.MAX($sheet.Range("B3:B8")) # MAX 関数で B3:B8 での最大値取得
Write-Host $ir
$ir = $excel.WorksheetFunction.MIN($sheet.Range("B3:B8")) # MIN 関数で B3:B8 での最小値取得
Write-Host $ir
$ir = $excel.WorksheetFunction.AVERAGE($sheet.Range("B3:B8")) # AVERAGE 関数で B3:B8 での平均値取得
Write-Host $ir
$ir = $excel.WorksheetFunction.COUNTIF($sheet.Range("B3:B8"), ">=50") # COUNTIF 関数で B3:B8 での 50以上の数
Write-Host $ir
$ir = $excel.WorksheetFunction.COUNTBLANK($sheet.Range("D3:D8")) # COUNTBLANK 関数で D3:D8 での空白の数
Write-Host $ir
VLOOKUPの使用例
Excel のダイアログを表示します。
$xlDialog = [Microsoft.Office.Interop.Excel.XlBuiltInDialog] # Excel ダイアログ定数
# [名前を付けて保存] ダイアログ ボックス
$br = $excel.Application.Dialogs($xlDialog::XlDialogSaveAs).Show()
# [印刷] ダイアログ ボックス
$br = $excel.Application.Dialogs($xlDialog::xlDialogPrint).Show()
# [ページ設定 (ページ)] ダイアログ ボックス
$br = $excel.Application.Dialogs($xlDialog::XlDialogPageSetup).Show()
# [プリンターの設定] ダイアログ ボックス
$br = $excel.Application.Dialogs($xlDialog::XlDialogPrinterSetup).Show()
# [印刷プレビュー] ダイアログ ボックス
$br = $excel.Application.Dialogs($xlDialog::XlDialogPrintPreview).Show()
戻り値は、「OK」を選択した時は、$true, 「キャンセル」を選択した時は $false となります。
Excel ダイアログ定数 XlBuiltInDialog 列挙 (Excel)
InputBox関数 InputBox(メッセージ,タイトル,初期値,X座標,Y座標,ヘルプファイル,ヘルプファイルID,タイプ)
X座標,Y座標,ヘルプファイル,ヘルプファイルID は、使用出来ません。
タイプは、戻り値の型を指定します。 0:数式, 1:数値, 2:文字列, 4:論理値 など
$sr = $excel.InputBox("名前を入力して下さい。", "名前入力") # メッセージ、タイトル を指定
$sheet.Cells(1, 2) = $sr # セルB1に値セット
$smes = $sr + " 様`r`n登録番号を入力して下さい。`r`n例 12345"
$sr = $excel.InputBox($smes, "登録番号入力", "", 0, 0, [System.Type]::Missing, [System.Type]::Missing, 1) # タイプを数値に指定
$sheet.Range("B2") = $sr
InputBox InputBox メソッド
PowerShell から Excel マクロを実行します。下記は、テスト用マクロの例です。標準モジュールに記述して下さい。
' PowerShellから実行するExcelマクロの例
Sub test()
msgdisp ("マクロのテスト")
End Sub
Sub msgdisp(ByVal smsg As String)
MsgBox smsg
End Sub
Function add(ByVal ix As Integer, ByVal iy As Integer)
add = ix + iy
End Function
Function inputStr(ByVal smsg As String)
inputStr = InputBox(smsg)
End Function
PowerShell から 上記 Excel マクロを実行します。
Run 関数 Run(マクロ名, 引数1, 引数2, 引数3, ...... 引数30)
マクロ名は、Subプロシージャ、Functionプロシージャの名前を指定します。Sheet1、ThisWorkbook に記述したマクロを実行する時は、"Sheet1.test"、"ThisWorkbook.test" とします。引数は、object型です。
# macroRun.ps1 マクロ実行例
Set-StrictMode -Version latest
$sExlfnamer = $PSScriptRoot + "\exlMacro.xlsm" # 開くExcel ファイル名
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$wbook = $excel.Workbooks.Open($sExlfnamer)
$sheet = $wbook.Sheets(1) # 1番目のシートを取得
$sheet.Activate() # シートを前面に
$excel.Run("test") # 引数なし
pause
$excel.Run("msgdisp", "PowerShellから実行") # 文字列引数
pause
$ir = $excel.Run("add", 2, 5) # 2個の数値引数 数値の戻り値
Write-Host $ir
pause
$sr = $excel.Run("inputStr", "名前を入力して下さい。") # 文字列引数 文字列の戻り値
Write-Host $sr
pause
$excel.Quit()
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wbook)
$ir = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
シート上に図形が設定されているものとします。
$ic = $sheet.Shapes.Count # シート上の図形の個数
Write-Host $ic
$shape = $sheet.Shapes(1) # 順番号で図形選択 1~
$shape = $sheet.Shapes("楕円 3") # 図形名で図形選択 ※1
Write-Host $shape.Name # 図形名表示
$shape.Name = "だえん" # 図形名設定
Write-Host $shape.AutoShapeType # 図形のタイプ ※2
$shape.TextFrame().Characters().Text = "千葉市美浜区" # テキストを設定
$shape.TextFrame().Characters().Font.Name = "MS 明朝" # 文字フォント
$shape.TextFrame().Characters().Font.Size = 12 # 文字サイズ
$shape.TextFrame().Characters().Font.Bold = $true # $true で太字
$shape.TextFrame().Characters().Font.Italic = $true # $true で斜体
$shape.TextFrame().Characters().Font.Color = [System.Drawing.Color]::Red # 文字色
$shape.Fill.ForeColor.RGB = [System.Drawing.Color]::Blue # 背景色