PowerShellからExcelを操作!ワークシートのセルに値を設定する方法

Excel コンピュータ
Microsoft Excel

ひな形のエクセルファイルに値を入力する作業を自動化するために必要そうな処理を調べてサンプルスクリプトを書いてみました。

サンプルに使ったエクセルファイル
社会保険事務所に提出する賞与支払届

セルに値をセットするサンプル。

<#
.SYNOPSIS
エクセルのワークシートのセルに値をセットするサンプル。

.EXAMPLE
.\Auto-Excel01.ps1 -Path エクセルファイルのパス

Windows11(10)で.ps1を初回実行する場合は、powershell.exe又はpwsh.exeで管理権限で以下のコマンドを実行
Set-ExecutionPolicy RemoteSigned
#>
param(
    [string]$Path = "C:\265.xlsx", # エクセルファイルのパス
    [switch]$Help

)
if ($Help -Or $SearchWord -eq "") {
    Get-Help $PSCommandPath
    Exit 1
}

# A1形式をから行と列番号を取得
function Convert-A1toR1C1 {
    param (
        [string]$str
    )

    # 列番号の抽出(アルファベット部分)
    $columnLetters = [regex]::Match($str, "[A-Za-z]+").Value.ToUpper()

    # 行番号の抽出(数字部分)
    $rowNumber = [int]([regex]::Match($str, "\d+").Value)

    # 列番号を数値に変換
    $columnNumber = 0
    $letters = [char[]]$columnLetters
    for ($i = 0; $i -lt $letters.Length; $i++) {
        # アルファベットは26文字
        $columnNumber = $columnNumber * 26 + ([int][char]$letters[$i] - [int][char]'A' + 1)
    }

    # 結果をオブジェクトとして返す
    [PSCustomObject]@{
        Row = $rowNumber
        Column = $columnNumber
    }
}


# 操作するシートの名前
$SheetName = "賞与支払届"

$Excel = New-Object -ComObject Excel.Application # Excel起動
$Excel.Visible = $True # 可視モード

$Workbook = $Excel.Workbooks.Open($Path) # ワークブック(エクセルファイル)を開く

# ワークシートの取得
$Sheet = $Workbook.Worksheets | Where-Object { $SheetName -eq $_.Name } # ワークシート名で取り出す

# ワークシート取得されたか確認
if ($Sheet -eq $null)
{
    Write-Host ("{0}の取得失敗" -f $SheetName )
    $Workbook.Close($false) # ワークブック(エクセルファイル)を閉じる
    $Excel.Quit(); $Excel = $null # エクセルの終了
}

# A1形式のセルの座標を行と列を取得
$position = Convert-A1toR1C1("O12")
#Write-Host $position
#@{Row=12; Column=15}

# O12のセルに4という値をセットする
$Sheet.Cells($position.Row, $position.Column).Value = "4"

# O12のセルの値を取り出す
# $v = $Sheet.Cells($position.Row, $position.Column).Value

# E55のセルから10行ごと離れたセルに10階(10セル分)値をセットする
$position = Convert-A1toR1C1("E55")
$interbal = 10 # 間隔
$time = 10 # 繰り返し数
$column = $position.Column # 列
$i = 1;
for($row = $position.Row; $row -lt ($position.Row+$interbal*$time); $row += $interbal)
{
    $Sheet.Cells($row, $column).Value = ("{0}行目" -f $i++)
}


$Workbook.Save() # ワークブック(エクセルファイル)を上書き保存
$Workbook.Close($false) # ワークブック(エクセルファイル)を閉じる

$Excel.Quit(); $Excel = $null # エクセルの終了

「4」がセットされている様子

ワークシートをコピーする例

<#
.SYNOPSIS
エクセルのワークシートのワークシートをコピーするサンプル。

.EXAMPLE
.\Auto-Excel02.ps1 -Path エクセルファイルのパス

Windows11(10)で.ps1を初回実行する場合は、powershell.exe又はpwsh.exeで管理権限で以下のコマンドを実行
Set-ExecutionPolicy RemoteSigned
#>
param(
    [string]$Path = "C:\265.xlsx", # エクセルファイルのパス
    [switch]$Help

)
if ($Help -Or $SearchWord -eq "") {
    Get-Help $PSCommandPath
    Exit 1
}


# 操作するシートの名前
$SheetName = "賞与支払届"

$Excel = New-Object -ComObject Excel.Application # Excel起動
$Excel.Visible = $True # 可視モード

$Workbook = $Excel.Workbooks.Open($Path) # ワークブック(エクセルファイル)を開く

# ワークシートの取得
$Sheet = $Workbook.Worksheets | Where-Object { $SheetName -eq $_.Name } # ワークシート名で取り出す

# ワークシート取得されたか確認
if ($Sheet -eq $null)
{
    Write-Host ("{0}の取得失敗" -f $SheetName )
    $Workbook.Close($false) # ワークブック(エクセルファイル)を閉じる
    $Excel.Quit(); $Excel = $null # エクセルの終了
}

# 最後のシートの位置を取得
$lastSheetIndex = $workbook.Worksheets.Count

# 最後のシートを取得
$lastSheet = $workbook.Worksheets.Item($lastSheetIndex)

# ワークシートのコピー(最後のシートの後に挿入される)
$Sheet.Copy([System.Reflection.Missing]::Value, $lastSheet)

# 追加されたシートの位置を取得
$newSheetIndex = $workbook.Worksheets.Count

# 追加されたのシートを取得
$newSheet = $workbook.Worksheets.Item($newSheetIndex)

# 確認のためシート名を出力
# Write-Host $newSheet.Name
# 賞与支払届 (2)

$Workbook.Save() # ワークブック(エクセルファイル)を上書き保存
$Workbook.Close($false) # ワークブック(エクセルファイル)を閉じる

$Excel.Quit(); $Excel = $null # エクセルの終了

感想

ワークシートのコピーのコードなどは結果思った通り動作しますが、なぜこれで末尾にコピーされるかは理解していません。理解していなくとも使えれば良い人向けです。

PowerShellで書いてはいますが、内容的にはVBAです。

サンプルコードにはエクセルファイルを上書きするコードが含まれています。

使用する場合、エクセルファイルファイルのバックアップ(コピー)をお勧めします。

バックアップを取らなかったため、この記事を書くために何度もダウンロードするハメに成りました。

 

以上

コメント