プログラミング未経験でもできる(はず)
※当記事に登場する人名地名等はすべて架空です。実在の人物地名その他いかなる個人情報とも関係ありません。
※※当記事は随時サイレント修正しています。コードの修正や重大なバグがあった場合のみお知らせいたします。
あ~っ!レビュー記録票フォーマットの誤字に工程の終わりごろ気づいたよ~
ひとつひとつ直すにも、誤字フォーマットを使ったファイルが無数にあるため、かなり手がかかる状況です。
やりたいこと
複数のExcelファイルのB2セルに「レビュー記録票」って入れたい
どうやる
① ファイルを2つ作る
下記コードをメモ帳にコピーして、指定の通りに名前を付けて保存します。
特定のセルに特定の文字を入力.bat
powershell -NoProfile -ExecutionPolicy Unrestricted "./特定のセルに特定の文字を入力.ps1" >> 特定のセルに特定の文字を入力.log
exit
特定のセルに特定の文字を入力.ps1
$dir = Convert-Path .
$regex = ".*\.xl(s|t|a|w|r|sx|sm|sb|tx|tm|am)$"
$filePathList = Get-ChildItem $dir -File | Where-Object { $_.Name -match $regex } | ForEach-Object { $_.FullName }
# アセンブリの読み込み インプットボックス表示に必要
[void][System.Reflection.Assembly]::Load("Microsoft.VisualBasic, Version=8.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a")
Add-Type -Assembly System.Windows.Forms
function Log($str) {
$timestamp = Get-Date
Write-Host "$timestamp $str"
}
try {
Log "********* 特定のセルに特定の文字列を入力.ps1 起動 ***********"
if ($filePathList.Length -lt 1) {
$msg = "対象ファイルがありません。"
[System.Windows.Forms.MessageBox]::Show($msg, '情報', 'OK', 'Information') | Out-null
log $msg
exit
}
#宣言
$targetSheetStr = ""
$targetCellStr = ""
$targetTxt = ""
try {
# インプットボックスの表示
$targetSheetStr = [Microsoft.VisualBasic.Interaction]::InputBox("対象とするシートを入力してください。すべての場合は「all」と入力", "ダイヤログ")
$targetCellStr = [Microsoft.VisualBasic.Interaction]::InputBox("対象とするセルを入力してください", "ダイヤログ")
$targetTxt = [Microsoft.VisualBasic.Interaction]::InputBox("入力したい文字列を入力してください", "ダイヤログ")
}
catch {
Log "インプットボックスでエラーが発生しました。"
throw
}
$msgBoxTxt = "次の通り実行します。よろしいですか?対象シート:$targetSheetStr 対象セル:$targetCellStr 入力文字列:$targetTxt"
$msgBoxInput = [System.Windows.Forms.MessageBox]::Show($msgBoxTxt,'アプリの実行確認','YesNo','Question')
if($msgBoxInput -ne "Yes") {
Log "ユーザー入力により処理を中止します。"
Exit
}
Log "対象シート:$targetSheetStr 対象セル:$targetCellStr 入力文字列:$targetTxt"
# エクセルを開く準備
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplAyalerts = $false
$filePathList | ForEach-Object{
$filePath = $_
$updateLinks = 0
$isReadOnly = $false
try {
#エクセルを開く
$book = $excel.Workbooks.Open($filePath, $updateLinks, $isReadOnly)
$bookName = $book.Name
}
catch {
Log "エクセルのオープンでエラーが発生しました。"
throw
}
Log "$bookName を編集中..."
$cnt = 0 #処理したかどうかを判定する。対象シートがなければ0になる
try {
$book.Sheets | ForEach-Object{
$sheet = $_
if (($targetSheetStr -eq "all") -or ($targetSheetStr -eq $sheet.name)) {
$sheet.Activate()
$sheet.Range($targetCellStr) = $targetTxt
$excel.ActiveWindow.Zoom = 100
$sheet.Cells.Item(1, 1).Select() | Out-Null
$cnt += 1
}
}
}
catch [System.MissingMemberException]{
$msg = "対象セル:$targetCellStr は無効です。初めからやり直してください。"
[System.Windows.Forms.MessageBox]::Show($msg,'エラー', 'OK', 'Error') | Out-null
Log $msg
throw
}
catch {
Log "シートのオープンまたはセルへの入力でエラーが発生しました。"
throw
}
if ($cnt -eq 0) {
$book.Close($false)
Log "$bookName:対象シートがありませんでした。保存せずにブックを閉じました。"
}
else {
try {
$book.Sheets.Item(1).Activate()
$book.Save()
$isSaveChanges = $true
$book.Close($isSaveChanges)
Log "$bookName:$cnt 件のシートを更新し、保存しました。"
}
catch {
Log "ファイルの保存でエラーが発生しました。"
throw
}
}
} #$filePathList | ForEach-Object ここまで
}
catch {
$errorStr = $error[0] | Out-String
Log $errorStr
Log "エラーが発生したため、処理を終了します。"
}
finally {
try {
if ($excel -ne $null) {
$excel.Quit()
}
$sheet = $null
$book = $null
$excel = $null
[System.GC]::Collect()
}
catch {
Log "finally処理の中でエラーが発生しました。"
$errorStr = $error[0] | Out-String
Log $errorStr
}
Log "********* 特定のセルに特定の文字列を入力.ps1 終了 ***********"
pause
}
exit
② ①で作ったファイルと同じフォルダに編集したいExcelファイルを入れる
③ 特定のセルに特定の文字を入力.bat をダブルクリックで実行
ダイヤログが出てくるので指示の通りに入力します。
今回は「レビュー記録」シートだけ編集しますが、all指定もできます
文字を入力するセルを指定します。
B2,D2って指定するとB2とD2に文字が入ります。
B2:D2って指定するとB2,C2,D2に文字が入ります。
処理中はPCを操作しないでください。
この表示になったら処理終了です。Enterキーを押してください。
④実行結果
ちゃんと直っていました。
ちなみにこのエクセルファイルには「setting」というシートもあるのですが、
今回は「レビュー記録」だけを対象に指定したため、「setting」のほうは無傷です。
課題
- 使う場面がそんなにない
- 文字入力ダイヤログはSystem.Windows.Formsにもあったので、そっちを使ってもよかった
参考資料