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で処理した方が、個人的には楽だと思います。

















この記事へのコメントはありません。