複数のエクセルファイルの中から、特定のキーワードを用いて検索をかける。
この時、対象のファイルが少ない場合は手動で見てまわる事も、まぁ少数でも苦行なのですが、
多数の設計書の中からひたすら検索をかけて、検索結果をまた別のエクセルにまとめて
とにかくエクセルをたくさん触らせたい!みたいなお仕事を度々頂きます。
勉強になりますね。
あんまり勉強になるので、勉強がてらスクリプトにやってもらうことにしました。
オートシェイプの中は未対応なのですが、大好きなCtrl+Fでも見てないので、
この際無視することにしました。
searchExcel.ps1
Param(
$targetDir ,
$searchWord ,
$resultCsvFileName
)
if($targetDir -eq $null) {
'-targetDir オプションを指定して、検索対象のフォルダーを指定してください。'
return
}
if($searchWord -eq $null) {
'-searchWord オプションを指定して、検索対象のキーワードを指定してください。'
return
}
if($resultCsvFileName -eq $null) {
$resultCsvFileName = Split-Path $myInvocation.MyCommand.Path -Parent
$resultCsvFileName = Join-Path $resultCsvFileName "defaultResultFile.csv"
}
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$datas = New-Object System.Collections.ArrayList
Get-ChildItem $targetDir -Recurse -Include "*.xlsx" , "*.xls" | ForEach-Object {
$fullName = $_.FullName
$fullName
$fileOpen = $true
try {
$workBook = $excel.Workbooks.open($fullName)
} catch {
Write-Host "$fullName のオープンに失敗しました。このファイルに対する処理はスキップします。" -ForegroundColor Red
$fileOpen = $false
}
if($fileOpen) {
$workBook.WorkSheets | ForEach-Object {
$sheet = $_
$sheetName = $sheet.Name
$first = $result = $sheet.Cells.Find($searchWord)
while ($result -ne $null) {
$data = New-Object psobject | Select-Object FullName , SheetName , Column , Row , Value2 , Formula
$data.FullName = $fullName
$data.SheetName = $sheetName
$data.Column = $result.Column
$data.Row = $result.Row
$data.Value2 = $result.Value2
$data.Formula = $result.Formula
[void]$datas.Add($data)
$result = $sheet.Cells.FindNext($result)
try {
$result.Address() | Out-Null
} catch {
break
}
if(${result}.Address() -eq ${first}.Address()) {
break
}
}
}
[void]$workBook.close()
}
}
$sheet = $null
$excel.quit()
[System.GC]::Collect([System.GC]::MaxGeneration)
$resultCsvFileNameParent = Split-Path $resultCsvFileName -Parent
if((Test-Path $resultCsvFileNameParent) -eq $false) {
New-Item -ItemType Directory $resultCsvFileNameParent
}
$datas | Export-Csv $resultCsvFileName -Encoding Default -NoTypeInformation
検索部分の処理は、こちらを参考にさせていただいております。
PowerShellで複数のExcelファイルを一括検索する
実行時には、下記の引数が必要になります。
変数名 | 指定内容 | 例 |
---|---|---|
-targetDir | 検索対象のフォルダー名 | C:\temp |
-searchWord | 検索キーワード | test |
-resultCsvFileName | 結果を格納するCSVファイル名 | C:\temp\result.csv |
(上記の例で実行すると、C:\temp配下のフォルダー内にある.xlsx/.xlsファイルを開いて、
test 文字列を検索し、その結果をC:\temp\result.csv に書き出します。)
出来上がったcsvファイルには下記の情報が含まれます。
FullName | SheetName | Column | Row | Value2 | Formula |
---|---|---|---|---|---|
ファイルのフルパス(含むファイル名) | シート名 | 列 | 行 | Value2(表示上の値) | 計算式 |
上記の情報からValue2とかFormulaとかを書き換えて、書き戻すことによって | |||||
単純な置換だと対応しきれないようなケースを処理したりしたいわけです。 | |||||
なので、このcsvを同じように一覧舐めて、FullNameを元にエクセルを開いて | |||||
sheetNameのcolumn,rowのValue2とかFormulaとかを書き換えるスクリプトが | |||||
欲しいのですが、また今度にします。 |
読み取り専用のチェックとかパスワードとか、ファイル開くときに出てくる
ポップアップについては対応していないので、必要に応じて修正が必要になるかと思います。