Office関連

[PowerShell]Word文書の透かし文字を変更するスクリプト

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

参考Webページ

2019年9月の人気記事前のページ

アイカツオンパレード!が始まりました。次のページ

関連記事

  1. Office関連

    オフィス祭り 2018 in 東京が9月15日(土)に開催されます。

    突然ですが、私はMicrosoft Officeが大好きです。20…

  2. Office関連

    Office 2016関連資料のリンク

    Office 2016関連資料のリンクをメモしておきます。特に「O…

  3. Office関連

    Gmail APIを使ってメール送信するVBAマクロ(3)

    前回、前々回とGmail APIを扱ってきましたが、今回は前々回の記事…

  4. Office関連

    Adobe Reader XIを利用してPDFファイルのページ数を取得するVBAマクロ

    先日Adobe Readerを利用してPDFファイルのページ数を取得す…

  5. Office アドイン

    [Office用アプリ]カレンダーから日付を入力するコンテンツアプリ。

    ※ この情報はOffice 2013 カスタマー プレビュー版を元にし…

コメント

  • コメント (0)

  • トラックバックは利用できません。

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

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

PAGE TOP