2021年4月18日

【PowerShell】複数のWordファイルの文字列を一括置換するスクリプト


最近、仕事で複数のWordファイルを編集する作業がありまして、ある文字列を別の文字列に置換するというものだったのですが、ファイル数が結構あり、こういうのって自動でやらせたいなと思ってスクリプトを作ってみました。

ネットで探すとVBAを使ったやり方は結構たくさん見つかるんですが、PowerShellを使ったやり方はなかなか見つからないんですよね。
それで作るのに苦労したのですが、VBAのやり方を参考にいろいろ試しながらなんとか出来上がりました。
###############################################################################
# 複数のWordファイルの文字列を一括置換するスクリプト
###############################################################################

#Wordファイルが格納されているフォルダ
$targetPath = "C:\work"

#WdFindWrap定数
$wdFindContinue = 1 #検索範囲の先頭または末尾まで検索しさらに検索を続ける

#WdReplace定数 
$wdReplaceAll = 2 #すべて置換する

#パラメーター
$findText = "東京都"        #検索する文字列
$matchCase = $false         #大文字小文字の区別する
$matchWholeWord = $true     #完全に一致する単語だけを検索する
$matchWildcards = $false    #ワイルドカードを使用する
$matchSoundsLike = $false   #あいまい検索
$matchAllWordForms = $false #すべての単語の活用形を検索する
$forward = $true            #検索方向(Trueで末尾へ)
$wrap = $wdFindContinue     #検索が文書の末尾に達した場合にどうするか(WdFindWrap定数)
$format = $false            #書式を検索する場合
$replaceWith = "神奈川県"   #置換文字列
$replace = $wdReplaceAll    #置換する文字列の個数(Wdreplace 定数)
$matchKashida = $false      #アラビア語のドキュメントでの kashida のテキストを区別
$matchdiacritics = $false   #右から左への言語の文書内には、発音区別符号が一致するテキストを区別
$matchalefhamza = $false    #アラビア語ドキュメント内の alef hamza が一致するテキストを区別
$matchControl = $false      #右から左への言語の文書で双方向制御文字が一致するテキストを区別

#Wordファイルを取得
$files = Get-ChildItem -Path $targetPath -Filter *.docx 

foreach ($f in $files)
{
    Write-Host $f

    $word = New-Object -ComObject Word.Application
    $word.Visible = $false
    
    $doc = $word.Documents.Open($f.FullName)

    #置換
    $word.Selection.Find.Execute($findText, `
                                 $matchCase, `
                                 $matchWholeWord, `
                                 $matchWildcards, `
                                 $matchSoundsLike, `
                                 $matchAllWordForms, `
                                 $forward, `
                                 $wrap, `
                                 $format, `
                                 $replaceWith, `
                                 $replace, `
                                 $matchKashida, `
                                 $matchdiacritics, `
                                 $matchalefhamza, `
                                 $matchControl) 

    #保存
    $doc.Save()

    #閉じる
    $doc.Close()

    #終了
    $word.Quit()
}

少し解説すると、$targetPathはWordファイルが格納されているフォルダです。このフォルダ内にある全てのWordファイルの文字列を置換します。

次にFind.Executeメソッドで指定するパラメーターを設定しています。通常、VBAで実行するときは必要なパラメーターだけ指定すればいいのですが、PowerShellの場合すべて指定しないといけません。最初このパラメーターの指定方法がよく分からなくて苦労しました。

$findTextに検索する文字列、$replaceWithに置換後の文字列を指定します。この例では、「東京都」を「神奈川県」に置換しています。
$wdFindContinueはWdFindWrap定数を指定します。今回はwdFindContinue(値:1)を指定して末尾まで検索してもさらに検索するようにしています。
$replaceはWdReplace定数を指定します。今回はwdReplaceAll(値:2)を指定して全て置換するようにしています。

あとは、foreachで見つかったWordファイルに対して同じ処理をくり返しています。


<参考>
http://mtgpowershell.blogspot.com/2010/11/word_12.html
https://touch-sp.hatenablog.com/entry/2017/04/11/185127
https://tonari-it.com/word-vba-replace-replacement/
Find.Execute メソッド | Microsoftドキュメント
WdFindWrap 列挙型 | Microsoftドキュメント
WdFindWrap 列挙型 | Microsoftドキュメント


スポンサーリンク