Help us understand the problem. What is going on with this article?

PowerShellで、特定のフォルダーにあるExcelファイルから特定の検索ワードを用いた検索を行い、結果の一覧をcsvに出力する

複数のエクセルファイルの中から、特定のキーワードを用いて検索をかける。
この時、対象のファイルが少ない場合は手動で見てまわる事も、まぁ少数でも苦行なのですが、
多数の設計書の中からひたすら検索をかけて、検索結果をまた別のエクセルにまとめて
とにかくエクセルをたくさん触らせたい!みたいなお仕事を度々頂きます。
勉強になりますね。

あんまり勉強になるので、勉強がてらスクリプトにやってもらうことにしました。
オートシェイプの中は未対応なのですが、大好きな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()


$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とかを書き換えるスクリプトが
欲しいのですが、また今度にします。

読み取り専用のチェックとかパスワードとか、ファイル開くときに出てくる
ポップアップについては対応していないので、必要に応じて修正が必要になるかと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away