MSDNフォーラムに「PowerShellを使って、Word文書の透かし文字を変更したい」、との質問がありました。
すぐに思いつくのは、PowerShellからWordアプリケーションを操作することですが、下記コードのようにCOMオブジェクトの解放処理が必要になるので、非常に冗長です。
function ModifyWaterMarkText($file_path, $new_text){ $objApp = New-Object -ComObject Word.Application $objApp.Visible = $true $objDocs = $objApp.Documents #Word.Documents $objDoc = $objDocs.Open($file_path) #Word.Document $objWin = $objDoc.ActiveWindow #Word.Window $objPane = $objWin.ActivePane #Word.Pane $objView = $objPane.View #Word.View $tmpSv = $objView.SeekView $objView.SeekView = 9 #WdSeekView.wdSeekCurrentPageHeader $objSel = $objApp.Selection #Word.Selection $objHF = $objSel.HeaderFooter #Word.HeaderFooter $objShapes = $objHF.Shapes #Word.Shapes If($objShapes.Count -gt 0){ $objShape = $objShapes.Item(1) #Word.Shape $objTef = $objShape.TextEffect #Word.TextEffectFormat $objTef.Text = $new_text } $objView.SeekView = $tmpSv $objDoc.Close(-1) #WdSaveOptions.wdSaveChanges [Runtime.Interopservices.Marshal]::ReleaseComObject($objTef) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objShape) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objShapes) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objHF) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objSel) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objView) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objPane) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objWin) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objDoc) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objDocs) > $null [GC]::Collect() [GC]::WaitForPendingFinalizers() [GC]::Collect() $objApp.Quit() [Runtime.Interopservices.Marshal]::ReleaseComObject($objApp) > $null [GC]::Collect() [GC]::WaitForPendingFinalizers() [GC]::Collect() } ModifyWaterMarkText "C:\wk\SampleWaterMark.docx" "Internal"
すべてのセクションをループさせれば多少はコードが短くなるかと思いましたが↓、やはりこちらも冗長です。
function ModifyWaterMarkText($file_path, $new_text){ $objApp = New-Object -ComObject Word.Application $objApp.Visible = $true $objDocs = $objApp.Documents #Word.Documents $objDoc = $objDocs.Open($file_path) #Word.Document $objSecs = $objDoc.Sections #Word.Sections for($i=1; $i -le $objSecs.Count; $i++){ $objSec = $objSecs.Item($i) $objHdrs = $objSec.Headers #Word.HeadersFooters for($j=1; $j -le $objHdrs.Count; $j++){ $objHdr = $objHdrs.Item($j) #Word.HeaderFooter $objShapes = $objHdr.Shapes If($objShapes.Count -gt 0){ $objShape = $objShapes.Item(1) #Word.Shape $objTef = $objShape.TextEffect #Word.TextEffectFormat $objTef.Text = $new_text [Runtime.Interopservices.Marshal]::ReleaseComObject($objTef) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objShape) > $null } [Runtime.Interopservices.Marshal]::ReleaseComObject($objShapes) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objHdr) > $null } [Runtime.Interopservices.Marshal]::ReleaseComObject($objHdrs) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objSec) > $null } [Runtime.Interopservices.Marshal]::ReleaseComObject($objSecs) > $null $objDoc.Close(-1) #WdSaveOptions.wdSaveChanges [Runtime.Interopservices.Marshal]::ReleaseComObject($objDoc) > $null [Runtime.Interopservices.Marshal]::ReleaseComObject($objDocs) > $null [GC]::Collect() [GC]::WaitForPendingFinalizers() [GC]::Collect() $objApp.Quit() [Runtime.Interopservices.Marshal]::ReleaseComObject($objApp) > $null [GC]::Collect() [GC]::WaitForPendingFinalizers() [GC]::Collect() } ModifyWaterMarkText "C:\wk\SampleWaterMark.docx" "Internal"
WordやExcelといったOfficeアプリケーションを外部のプログラムから操作する場合、特にPowerShellを使わなければならない理由が無いのであれば、VBSやVBAで処理した方が、個人的には楽だと思います。
この記事へのコメントはありません。