2021年4月29日

【PowerShell】WORDのdocファイルをdocxに変換するスクリプト


最近仕事で、昔作られたWordの仕様書を見る機会があったのですが、ファイル形式が古くて「doc」形式だったんです。 docでも見るぶんにはなんら問題はないのですが、今後のことを考えて一つ一つ開いて「docx」形式で保存するということやっていたんです。

しかし、ファイル数が多いんです。100近くもあるんです。

それでまた思ったんですよ、「めんどくせぇー!」って。笑

というわけで「doc」形式のファイルを「docx」形式に変換するスクリプトを作りました。
###############################################################################
# docファイルをdocxに変換するスクリプト
###############################################################################

$targetPath = "C:\work"

#docファイルを取得
$files = Get-ChildItem -Path $targetPath | ? { $_.Extension -like "*.doc" }

#文書の保存形式(DOCX形式)
$wdFormatDocumentDefault = 16

foreach ($f in $files)
{
    Write-Host $f
    
    #Wordオブジェクトを生成
    $word = New-Object -ComObject Word.Application

    #ファイルをオープン
    $doc = $word.Documents.Open($f.FullName)
    
    #保存ファイル名(拡張子を変更)
    $outputfile = $f.FullName.Replace("doc", "docx")
    Write-Host $outputfile
    
    #保存
    $doc.SaveAs2([ref]$outputfile, [ref]$wdFormatDocumentDefault)
    
    #閉じる
    $doc.Close()
    
    #終了
    $word.Quit()
}

Write-Host "処理が完了しました。"
少し解説すると、最初の$targetPathはターゲットとなるフォルダを指定します。このフォルダ内にあるdocファイルを全て取得して順番に一つ一つ変換していきます。

やってることは単純なのでコードを見ていただければ分かると思いますが、ポイントは保存ファイル名と保存時のSaveAs2のパラメータです。

最初、保存ファイル名はただの文字列で指定していたのですが、保存時にエラーになってしまいうまくいかなかったのでこのようなやり方になりました。おそらくオブジェクト型でないとダメなのだと思います。

次にSaveAs2のパラメータですが、こちらは頭に[ref]を付ける必要があります。最初これに気付かずに非常に苦労しました。 なぜ参照渡しにしなければいけないのかよく分かりませんが、メソッドがそのように定義されているからなんでしょう。

<参考>
http://mtgpowershell.blogspot.com/2010/10/wordhtml.html
https://docs.microsoft.com/ja-jp/office/vba/api/word.wdsaveformat


2021年4月25日

ARCHISS ProgresTouch RETRO TKL(茶軸)を買ってしまいました。

最近、久し振りにキーボードを新調しました。

買ったのは、ARCHISS ProgresTouch RETRO TKL(茶軸)

はじめてのメカニカルキーボードです。
フルキーボードと迷いましたが、コンパクトなテンキーレスにしました。


外箱はこんな感じになってます。


箱を開けるとマニュアルが入っていました。


日本語配列91キーです。
キーにはカナ印字はありません。
まあ、ローマ字入力してるんで無くても困らないですね。


さっそくPCに繋いでみました。
ちなみに有線です。
テンキーが無いのでコンパクトですね。
幅は約36cmです。


裏側はこんな感じです。
USBのコードは左右、中央、3か所から出せるようになってます。


あと、めちゃくちゃ重いです。
量ったら1kg近くもありました。
作りもかなり頑丈に作られてる感じがするんで、ハードパンチャーが使っても壊れなさそうです。笑


横からだとこんな感じですね。
奥行きは約14cm。


あと、結構高さがあるので慣れないと打ちにくいですね。
リストレストがあったほうがあったほうがいいかもしれません。


キーボード奥側
足を折りたたんだ状態。


足を立てた状態。
キーの上部まで5cm以上あります。


DIPスイッチ
このスイッチで特定のキーの配置を交換したり、無効にすることができます。

打鍵感ですが、今まで使ってたパタングラフ式と比べると全然違います。
標準的な打鍵感とされる茶軸を選んだのですが、それでもキーを押すときのストーロークが深いので力が必要だなと感じます。 ただ、このあたりの感覚は使っていくうちに慣れていくと思うので問題ないと思います。

あと、音は大きいなと感じました。筐体の剛性がしっかりしてるので、その分音が響く感じがします。 なのでこれ、会社では使えないですね。
隣の人に「うるせぇ!静かにしろー!」と怒鳴られると思います。笑

あと、今回キーを打ってるところを動画に撮ってみました。
参考になるか分かりませんが、よかったら見ていただければと思います。



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ドキュメント